0

please can someone help me with code, i want to have automatic trigger on specific hour, also i want to have button switch if needed, in my code i can press the button to trigger light relay, but my specific time trigger just flash at start time and does nothing, here is code:

#include <LiquidCrystal_I2C.h> 
#include <DS3231.h>
LiquidCrystal_I2C lcd(0x27, 2, 1,0,4,5,6,7,3, POSITIVE);
DS3231  rtc(SDA, SCL);
Time t;

const int OnSec = 30;
const int OffSec = 5;
int relay_3 = 5 ;

void setup() { 
 lcd.begin(20,4); 
 rtc.begin();

 pinMode(relay_3,OUTPUT);                 
 pinMode(8, INPUT_PULLUP);
}

void loop() {
  int button_4 = digitalRead(8);
  t = rtc.getTime();
  lcd.setCursor(0,1);
  lcd.print(rtc.getTimeStr());


  if(t.sec == OnSec)                                  //if is hh.mm.30 - just for 1 sec trigger relay
  {
  digitalWrite(5,HIGH);
  }
    else if(t.sec == OffSec)                         //if is hh.mm.05 - release relay
  {
  digitalWrite(5,LOW);
  }   
      else if (button_4 == HIGH)                     //if button is pressed - trigger relay
  {
  digitalWrite(5,HIGH);
  } 
        else
  {
  digitalWrite(5,LOW);
  }

  lcd.clear();
}

i would be gratefull for any advice :)

  • the indentation of the code in the if ... else block is really messed up – jsotola Nov 12 at 5:29
  • the last else command is the culprit .... think very carefully about the whole if ... else block – jsotola Nov 12 at 5:33
0

The else case is executed every time the other if and else if conditions are not true. That means if it is not 5 sec and not 30 sec and no button is pressed, the relay is switched off.

To achieve what you want is not that easy, because you have to synchronize button press and button release with the timer actions. First you must specify what you exactly want to do. e.g What happens if you have already pressed the button and release it in the time interval between 30 and 5. Releasing the button would switch off the light but should it stay on because you are within the on-time? This is just an example of what to think about.

I wrote a little code for fun doing the things as I would do it:

#include <LiquidCrystal_I2C.h> 
#include <DS3231.h>
LiquidCrystal_I2C lcd(0x27, 2, 1,0,4,5,6,7,3, POSITIVE);
DS3231  rtc( SDA, SCL );
Time t;

const int OnSec = 30;
const int OffSec = 5;
int relay_3 = 5;

int timerPhase = -1;
int relayState = LOW;

void setup() 
{ 
 lcd.begin( 20, 4 ); 
 rtc.begin();

 pinMode( relay_3, OUTPUT );                 
 pinMode( 8, INPUT_PULLUP );
}

void loop() 
{
  t = rtc.getTime( );

  int button_4 = digitalRead( 8 );

  lcd.setCursor( 0, 1 );
  lcd.print( rtc.getTimeStr( ) );

  // this only works if the off time is 
  // less than the on time. (OffSec < OnSec)
  timerPhase = ( (t.sec > OffSec) && ( t.sec < OnSec ) ) ? 0 : 1;

  if ( button_4 == HIGH )
  {
    // a button overrides the timer phase
    relayState = HIGH;   
  }
  else
  {
    if ( timerPhase == 0 )
    {
      relayState = LOW;
    } 
    else
    {
      relayState = HIGH;
    } 
  }

  digitalWrite( relay_3, relayState );

  lcd.clear();
}

I could not try the code because I don't know which libraries you used and therefor got compiler errors. So there might be syntax errors in my code but I hope I wrote correct code. It would be nice if you report errors here, if you find one/some ;-).

The line

timerPhase = ( (t.sec > OffSec) && ( t.sec < OnSec ) ) ? 0 : 1;

uses a ternary operator. It means if the condition ( (t.sec > OffSec) && ( t.sec < OnSec ) ) is true, take the first alternative 0 and assign it to the variable timerPhase, if it is false choose the second alternative '1'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.