Доработка скетча реле времени
- Войдите на сайт для отправки комментариев
Сб, 27/08/2016 - 11:06
Есть скетч, реле времени (для полива растений), включает реле, через интервал выключает на заданный интервал, и так по кругу, интервалы изменяются энкодером с кнопкой, информация на 2-х строчный дисплей.
надо:
Чтоб OFF был в минутах, а ON в секундах (и в EEPROM это сохранялось).
Желательно, чтоб включалось не резко, а плавно (вместо реле- насос).
Я переделал чтоб все было в секундах, выглядит коряво да ладно, работает, но... больше 255 сек. в EEPROM не сохраняется (после отключения питания режим OFF сбивается).
Как под спойлер убрать не нашел, оригинал кода:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
LiquidCrystal_I2C lcd(0x27,16,2);
int ON_state = EEPROM.read(0);
int OFF_state = EEPROM.read(1);
int ON_state_current = ON_state;
int OFF_state_current = OFF_state;
int state_position = 0;
int seconds = 60;
int fadeAmount = 1; // изменение на
unsigned long currentTime;
unsigned long loopTime;
unsigned long loopTime2 = 0;
const int pin_A = 12; // пин1 энкодера
const int pin_B = 11; // пин2 энкодера
const int button = 5; // кнопка энкодера
const int relay = 8; // реле
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
int st=0;
int buttonState = 0;
int buttonBlock = 0;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(relay, OUTPUT);
digitalWrite(relay, LOW);
pinMode(pin_A, INPUT);
pinMode(pin_B, INPUT);
pinMode(button, INPUT);
currentTime = millis();
loopTime = currentTime;
lcd_update();
}
void loop() {
// читаем кнопку
buttonState = digitalRead(button);
if (buttonState == LOW) {
if (buttonBlock == 0) {
switch (st) {
case 1:
st=st+1;
EEPROM.write(0, ON_state);
EEPROM.write(1, OFF_state);
break;
case 2:
st=0;
seconds = 60;
EEPROM.write(0, ON_state);
EEPROM.write(1, OFF_state);
ON_state_current = ON_state;
OFF_state_current = OFF_state;
break;
default:
st=st+1;
}
buttonBlock=1;
lcd_update();
}
}
else {
buttonBlock=0;
}
// заходит каждые 2мс
currentTime = millis();
if(currentTime >= (loopTime + 2)){
encoder_A = digitalRead(pin_A); // Read encoder pins
encoder_B = digitalRead(pin_B);
if((!encoder_A) && (encoder_A_prev)){
// УВЕЛИЧЕНИЕ
if(encoder_B) {
switch (st) {
case 1: // редактор ON
if (ON_state + fadeAmount <= 255) ON_state += fadeAmount;
lcd_update();
break;
case 2: // редактор OFF
if (OFF_state + fadeAmount <= 255) OFF_state += fadeAmount;
lcd_update();
break;
default: // начальный экран, редактор текущего режима
// какой текущий режим?
if (state_position==1)
{
if (ON_state_current + fadeAmount <= 255) ON_state_current += fadeAmount;
}
if (state_position==0)
{
if (OFF_state_current + fadeAmount <= 255) OFF_state_current += fadeAmount;
}
lcd_update();
break;
}
}
else {
// УМЕНЬШЕНИЕ
switch (st) {
case 1: // редактор ON
if (ON_state - fadeAmount > 0) ON_state -= fadeAmount;
lcd_update();
break;
case 2: // редактор OFF
if (OFF_state - fadeAmount > 0) OFF_state -= fadeAmount;
lcd_update();
break;
default: // начальный экран, редактор текущего режима
// какой текущий режим?
if (state_position==1)
{
if (ON_state_current - fadeAmount >= 1) ON_state_current -= fadeAmount;
if (ON_state_current <= 0 ) ON_state_current = 1;
}
if (state_position==0)
{
if (OFF_state_current - fadeAmount >= 1) OFF_state_current -= fadeAmount;
if (OFF_state_current <= 0 ) OFF_state_current = 1;
}
seconds = 60;
lcd_update();
break;
}
}
}
encoder_A_prev = encoder_A; // Store value of A for next time
loopTime = currentTime; // Updates loopTime
}
// Второе прерывание - обратный отсчет, заходит каждую 1 сек
if(currentTime >= (loopTime2 + 1000)){
loopTime2 = currentTime;
// какой текущий режим?
if (seconds - 1 >= 0)
{
seconds -= 1;
Serial.print(ON_state_current); Serial.print(" ");
Serial.print(OFF_state_current); Serial.print(" ");
Serial.print(seconds); Serial.print(" ");
Serial.print(state_position); Serial.println(" ");
} else
{
seconds = 60;
if (state_position==1) // ON
{
if (ON_state_current - 1 >= 1) {ON_state_current -= 1;} else {OFF_state_current = OFF_state;ON_state_current = ON_state; state_position = 0; digitalWrite(relay, LOW);}
} else // OFF
{
if (state_position==0)
{
if (OFF_state_current - 1 >= 1) {OFF_state_current -= 1;} else {OFF_state_current = OFF_state;ON_state_current = ON_state; state_position = 1;digitalWrite(relay, HIGH);}
}
}
lcd_update();
}
}
}
void lcd_update() {
lcd.clear();
switch (st) {
case 1: // редактор ON
lcd.setCursor(0, 0); lcd.print("Select value ON");
lcd.setCursor(0, 1); lcd.print("ON:");
lcd.setCursor(4, 1); lcd.print(ON_state);
lcd.setCursor(8, 1); lcd.print("OFF:");
lcd.setCursor(13, 1); lcd.print(OFF_state);
break;
case 2: // редактор OFF
lcd.setCursor(0, 0); lcd.print("Select value OFF");
lcd.setCursor(0, 1); lcd.print("ON:");
lcd.setCursor(4, 1); lcd.print(ON_state);
lcd.setCursor(8, 1); lcd.print("OFF:");
lcd.setCursor(13, 1); lcd.print(OFF_state);
break;
default: // начальный экран, редактор текущего режима
// какой текущий режим?
if (state_position==1)
{
lcd.setCursor(0, 0); lcd.print("Active ON");
lcd.setCursor(11, 0); lcd.print(ON_state_current);
lcd.setCursor(0, 1); lcd.print("ON:");
lcd.setCursor(4, 1); lcd.print(ON_state);
lcd.setCursor(8, 1); lcd.print("OFF:");
lcd.setCursor(13, 1); lcd.print(OFF_state);
}
if (state_position==0)
{
lcd.setCursor(0, 0); lcd.print("Active OFF");
lcd.setCursor(11, 0); lcd.print(OFF_state_current);
lcd.setCursor(0, 1); lcd.print("ON:");
lcd.setCursor(4, 1); lcd.print(ON_state);
lcd.setCursor(8, 1); lcd.print("OFF:");
lcd.setCursor(13, 1); lcd.print(OFF_state);
}
break;
}
}
Мой переделанный:
(дисплей без переходной платы I2C, все в секундах, в Proteus проверил, вроде все как надо, только при сбросе, больше 255 сек. в EEPROM не сохраняются, разбить большое число на байты ума не хватает).
#include <Wire.h> #include <LiquidCrystal.h> #include <EEPROM.h> LiquidCrystal lcd(7, 6, 8, 4, 3, 2); int ON_state = EEPROM.read(0); int OFF_state = EEPROM.read(1); int ON_state_current = ON_state; int OFF_state_current = OFF_state; int state_position = 0; int seconds = 60; int fadeAmountON = 1; // изменение ON на одно число int fadeAmountOFF =10; // изменение OFF на один десяток unsigned long currentTime; unsigned long loopTime; unsigned long loopTime2 = 0; const int pin_A = 12; // пин1 энкодера const int pin_B = 11; // пин2 энкодера const int button = 5; // кнопка энкодера const int relay = 10; // реле unsigned char encoder_A; unsigned char encoder_B; unsigned char encoder_A_prev=0; int st=0; int buttonState = 0; int buttonBlock = 0; void setup() { Serial.begin(9600); lcd.begin(16, 2); pinMode(relay, OUTPUT); digitalWrite(relay, LOW); pinMode(pin_A, INPUT); pinMode(pin_B, INPUT); pinMode(button, INPUT); currentTime = micros(); loopTime = currentTime; lcd_update(); } void loop() { // читаем кнопку buttonState = digitalRead(button); if (buttonState == LOW) { if (buttonBlock == 0) { switch (st) { case 1: st=st+1; EEPROM.write(0, ON_state); EEPROM.write(1, OFF_state); break; case 2: st=0; seconds = 60; EEPROM.write(0, ON_state); EEPROM.write(1, OFF_state); ON_state_current = ON_state; OFF_state_current = OFF_state; break; default: st=st+1; } buttonBlock=1; lcd_update(); } } else { buttonBlock=0; } // заходит каждые 2мс currentTime = micros(); if(currentTime >= (loopTime + 2)){ encoder_A = digitalRead(pin_A); // Read encoder pins encoder_B = digitalRead(pin_B); if((!encoder_A) && (encoder_A_prev)){ // УВЕЛИЧЕНИЕ if(encoder_B) { switch (st) { case 1: // редактор ON if (ON_state + fadeAmountON <= 500) ON_state += fadeAmountON; lcd_update(); break; case 2: // редактор OFF if (OFF_state + fadeAmountOFF <= 500) OFF_state += fadeAmountOFF; lcd_update(); break; default: // начальный экран, редактор текущего режима // какой текущий режим? if (state_position==1) { if (ON_state_current + fadeAmountON <= 500) ON_state_current += fadeAmountON; } if (state_position==0) { if (OFF_state_current + fadeAmountOFF <= 500) OFF_state_current += fadeAmountOFF; } lcd_update(); break; } } else { // УМЕНЬШЕНИЕ switch (st) { case 1: // редактор ON if (ON_state - fadeAmountON > 0) ON_state -= fadeAmountON; lcd_update(); break; case 2: // редактор OFF if (OFF_state - fadeAmountOFF > 0) OFF_state -= fadeAmountOFF; lcd_update(); break; default: // начальный экран, редактор текущего режима // какой текущий режим? if (state_position==1) { if (ON_state_current - fadeAmountON >= 1) ON_state_current -= fadeAmountON; if (ON_state_current <= 0 ) ON_state_current = 1; } if (state_position==0) { if (OFF_state_current - fadeAmountOFF >= 1) OFF_state_current -= fadeAmountOFF; if (OFF_state_current <= 0 ) OFF_state_current = 1; } seconds = 60; lcd_update(); break; } } } encoder_A_prev = encoder_A; // Store value of A for next time loopTime = currentTime; // Updates loopTime } // Второе прерывание - обратный отсчет, заходит каждую 1 сек if(currentTime >= (loopTime2 + 1000)){ loopTime2 = currentTime; // какой текущий режим? if (seconds - 1 >= 0) { seconds -= 1; Serial.print(ON_state_current); Serial.print(" "); Serial.print(OFF_state_current); Serial.print(" "); Serial.print(seconds); Serial.print(" "); Serial.print(state_position); Serial.println(" "); } else { seconds = 60; if (state_position==1) // ON { if (ON_state_current - 1 >= 1) {ON_state_current -= 1;} else {OFF_state_current = OFF_state;ON_state_current = ON_state; state_position = 0; digitalWrite(relay, LOW);} } else // OFF { if (state_position==0) { if (OFF_state_current - 1 >= 1) {OFF_state_current -= 1;} else {OFF_state_current = OFF_state;ON_state_current = ON_state; state_position = 1;digitalWrite(relay, HIGH);} } } lcd_update(); } } } void lcd_update() { lcd.clear(); switch (st) { case 1: // редактор ON lcd.setCursor(0, 0); lcd.print("Select value ON"); lcd.setCursor(0, 1); lcd.print("ON:"); lcd.setCursor(4, 1); lcd.print(ON_state); lcd.setCursor(8, 1); lcd.print("OFF:"); lcd.setCursor(13, 1); lcd.print(OFF_state); break; case 2: // редактор OFF lcd.setCursor(0, 0); lcd.print("Select value OFF"); lcd.setCursor(0, 1); lcd.print("ON:"); lcd.setCursor(4, 1); lcd.print(ON_state); lcd.setCursor(8, 1); lcd.print("OFF:"); lcd.setCursor(13, 1); lcd.print(OFF_state); break; default: // начальный экран, редактор текущего режима // какой текущий режим? if (state_position==1) { lcd.setCursor(0, 0); lcd.print("Active ON"); lcd.setCursor(11, 0); lcd.print(ON_state_current); lcd.setCursor(0, 1); lcd.print("ON:"); lcd.setCursor(4, 1); lcd.print(ON_state); lcd.setCursor(8, 1); lcd.print("OFF:"); lcd.setCursor(13, 1); lcd.print(OFF_state); } if (state_position==0) { lcd.setCursor(0, 0); lcd.print("Active OFF"); lcd.setCursor(11, 0); lcd.print(OFF_state_current); lcd.setCursor(0, 1); lcd.print("ON:"); lcd.setCursor(4, 1); lcd.print(ON_state); lcd.setCursor(8, 1); lcd.print("OFF:"); lcd.setCursor(13, 1); lcd.print(OFF_state); } break; } }p.masyukov skype, пиши.