Доработка скетча реле времени
- Войдите на сайт для отправки комментариев
Сб, 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 не сохраняются, разбить большое число на байты ума не хватает).
p.masyukov skype, пиши.