Доработка скетча реле времени

serg-mmm
Offline
Зарегистрирован: 01.04.2016

Есть скетч, реле времени (для полива растений), включает реле, через интервал выключает на заданный интервал, и так по кругу, интервалы изменяются энкодером с кнопкой, информация на 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;
     }  
}

 

serg-mmm
Offline
Зарегистрирован: 01.04.2016

Мой переделанный:

(дисплей без переходной платы 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
p.masyukov аватар
Offline
Зарегистрирован: 14.11.2015

p.masyukov skype, пиши.