Turn on / off relay at a specific time, not working

hi,

this is my first attempt with arduino and I’m having one problem, hope you can help.

I have 4 relays controlled by a bluetooth app.

Relays 3 and 4 are working fine, but not relays 1 e 2.

when the app sends the command for relays 1 or 2 they will turn on for about 25min, no problem here.
But i also want them to turn on/off at a specific time, 3 times a day.
And here is the problem, it only works on the day i upload the code, the next day it doesn’t work any more.

I have connected the rtc to another arduino and the time is correct.

Can any one help, please?

#include <Wire.h>

#include <RTClib.h>

RTC_DS1307 rtc;




#define LED_PIN1  4
#define LED_PIN2  5
#define LED_PIN3  6
#define LED_PIN4  7

#define LED_PIN5  8
#define LED_PIN6  9
#define LED_PIN7  10
#define LED_PIN8  11

const int OnHour = 7; 
const int OnMin = 0;
const int OffHour = 8;
const int OffMin = 0;

const int OnHour1 = 13;
const int OnMin1 = 0;
const int OffHour1 = 14;
const int OffMin1 = 0;

const int OnHour2 = 19;
const int OnMin2 = 0;
const int OffHour2 = 20;
const int OffMin2 = 0;

int firstSensor = 0;    // first analog sensor
int secondSensor = 0;   // second analog sensor
int thirdSensor = 0;    // digital sensor
int inByte = 0;         // incoming serial byte
boolean status_unlock;
boolean status_bluetooth;


// temporização

long interval = 1000;           // interval at which to blink (milliseconds)
long previousMillis = 0;        // will store last time LED was updat
int minite,sec;

unsigned long startTime;
unsigned long currentTime;
unsigned long period = 20*60*1000UL;  //adjust to change period

unsigned long startTime2;

unsigned long period2 = 20*60*1000UL;  //adjust to change period



const byte inputPin = A1;
const byte ledPin = 4;
boolean timing = false;
boolean timing2 = false;


void setup()
{

  // start serial port at 9600 bps:
  Serial.begin(9600);
  //pinMode(2, INPUT);   // digital sensor is on digital pin 2
  //establishContact();  // send a byte to establish contact until receiver responds 


Wire.begin();
   rtc.begin();

   
  pinMode(LED_PIN1, OUTPUT);
  pinMode(LED_PIN2, OUTPUT);
  pinMode(LED_PIN3, OUTPUT);
  pinMode(LED_PIN4, OUTPUT);

  pinMode(LED_PIN5, OUTPUT);
  pinMode(LED_PIN6, OUTPUT);
  pinMode(LED_PIN7, OUTPUT);
  pinMode(LED_PIN8, OUTPUT);
  
  digitalWrite(LED_PIN1, HIGH);  // switch on LED
  digitalWrite(LED_PIN2, HIGH);  // switch on LED
  digitalWrite(LED_PIN3, HIGH);  // switch on LED
  digitalWrite(LED_PIN4, HIGH);  // switch on LED
    
  digitalWrite(LED_PIN5, HIGH);  // switch on LED
  digitalWrite(LED_PIN6, HIGH);  // switch on LED
  digitalWrite(LED_PIN7, HIGH);  // switch on LED
  digitalWrite(LED_PIN8, HIGH);  // switch on LED 

  
  
  status_bluetooth = true;
  status_unlock = false;
  sec = 0;
}

void loop()
{

{
  currentTime = millis();
  
  {
    if (Serial.available() > 0) {   
       
   inByte = Serial.read();             // get incoming byte:  

    if(inByte == 'A'){    
     Serial.print('A');         // send a char
      digitalWrite(LED_PIN1, LOW);        // switch on LED
     status_unlock = false;
      inByte = 0;
    }
    
     startTime = millis();
     timing = true;
    }
 }
  if (currentTime - startTime >= period)
 {
  digitalWrite(LED_PIN1, HIGH); //turn off the LED
  
  }
 
  
  
  }


  
  {
 
    //if (Serial.available() > 0) {
   if(inByte == 'B'){    
      digitalWrite(LED_PIN2, LOW);        // switch on LED
      Serial.print('B');         // send a char
      inByte = 0;     
  
     startTime2 = millis();
      timing2 = true;
   //}
  }
   if (currentTime - startTime2 >= period2)
 {
   digitalWrite(LED_PIN2, HIGH); //turn off the LED
        }
   {
  currentTime = millis();
    }
}
    
    if(inByte == 'C'){    
      digitalWrite(LED_PIN3, LOW);        // switch on LED
      Serial.print('C');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'c'){    
      digitalWrite(LED_PIN3, HIGH);        // switch on LED
      Serial.print('c');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'D'){    
      digitalWrite(LED_PIN4, LOW);        // switch on LED
      Serial.print('D');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'd'){    
      digitalWrite(LED_PIN4, HIGH);        // switch on LED
      Serial.print('d');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'a'){    
      digitalWrite(LED_PIN1, HIGH);        // switch on LED
      Serial.print('a');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'b'){    
      digitalWrite(LED_PIN2, HIGH);        // switch on LED
      Serial.print('b');         // send a char
      inByte = 0;     
   
    } 

DateTime now = rtc.now();
 
  


 if(now.hour() == OnHour  && now.minute() == OnMin){
    digitalWrite(LED_PIN2, LOW);
    
    }
    else if(now.hour() == OffHour && now.minute() == OffMin){
      digitalWrite(LED_PIN2, HIGH);
     
  } 

if(now.hour() == OnHour1  && now.minute() == OnMin1){
    digitalWrite(LED_PIN2, LOW);
    
    }
    else if(now.hour() == OffHour1 && now.minute() == OffMin1){
      digitalWrite(LED_PIN2, HIGH);
     
  } 
  
 if(now.hour() == OnHour2  && now.minute() == OnMin2){
    digitalWrite(LED_PIN2, LOW);
    digitalWrite(LED_PIN1, LOW);
    
    }
    else if(now.hour() == OffHour2 && now.minute() == OffMin2){
      digitalWrite(LED_PIN2, HIGH);
       digitalWrite(LED_PIN1, HIGH);
     
      }  
  }

You have a left bracket { in the wrong place or an extra one.
I am surprise you don’t see it.

Incoming serial byte is a byte, why define it as an integer?

int inByte = 0;         // incoming serial byte

You are setting startTime = millis() every time you receive anything from the serial input, but presumably you only want to set it when you receive an ‘A’. Also, since you set currentTime = millis() at the start of the loop, it would be expected to use currentTime instead of millis() throughout the rest of the code.

  currentTime = millis();
  if (Serial.available() > 0) {
    inByte = Serial.read();             // get incoming byte:
    if (inByte == 'A') {
      Serial.print('A');         // send a char
      digitalWrite(LED_PIN1, LOW);        // switch on LED
      status_unlock = false;
      inByte = 0;
    }
    startTime = millis();
    timing = true;
  }

You have a multitude of if statements testing the value of inByte against various characters, a switch/case statement would be an alternate way to accomplish that, and possibly a bit easier to read.

thanks for the replys, but after several hours of tests i can't figure out i'm doing wrong!

i also tried abandon the millis timing and use the rtc time, but i can't figure out how to add the 20minutes to the current time when 'A' is received to turn off the relay

ieee488: You have a left bracket { in the wrong place or an extra one. I am surprise you don't see it.

Redundant brackets are redundant, but that all there is to it. They are not errors and they don't affect anything.

thanks for the replys, but after several hours of tests i can't figure out i'm doing wrong!

i also tried abandon the millis timing and use the rtc time, but i can't figure out how to add the 20minutes to the current time when 'A' is received to turn off the relay

Please post your latest code.

here it is.

#include <Wire.h>

#include <RTClib.h>

RTC_DS1307 rtc;




#define LED_PIN1  4
#define LED_PIN2  5
#define LED_PIN3  6
#define LED_PIN4  7

#define LED_PIN5  8
#define LED_PIN6  9
#define LED_PIN7  10
#define LED_PIN8  11

const int OnHour = 22; 
const int OnMin = 12;
const int OffHour = 22;
const int OffMin = 13;

const int OnHour1 = 22;
const int OnMin1 = 7;
const int OffHour1 = 22;
const int OffMin1 = 8;

const int OnHour2 = 21;
const int OnMin2 = 37;
const int OffHour2 = 21;
const int OffMin2 = 38;

int firstSensor = 0;    // first analog sensor
int secondSensor = 0;   // second analog sensor
int thirdSensor = 0;    // digital sensor
int inByte = 0;         // incoming serial byte
boolean status_unlock;
boolean status_bluetooth;


// temporização

long interval = 1000;           // interval at which to blink (milliseconds)
long previousMillis = 0;        // will store last time LED was updat
int minite,sec;

unsigned long startTime;
unsigned long currentTime;
unsigned long period = 1000;  //adjust to change period

unsigned long startTime2;

unsigned long period2 = 1000;  //adjust to change period



const byte inputPin = A1;
const byte ledPin = 4;
boolean timing = false;
boolean timing2 = false;


void setup()
{

  // start serial port at 9600 bps:
  Serial.begin(9600);
  //pinMode(2, INPUT);   // digital sensor is on digital pin 2
  //establishContact();  // send a byte to establish contact until receiver responds 


Wire.begin();
   rtc.begin();

   
  pinMode(LED_PIN1, OUTPUT);
  pinMode(LED_PIN2, OUTPUT);
  pinMode(LED_PIN3, OUTPUT);
  pinMode(LED_PIN4, OUTPUT);

  pinMode(LED_PIN5, OUTPUT);
  pinMode(LED_PIN6, OUTPUT);
  pinMode(LED_PIN7, OUTPUT);
  pinMode(LED_PIN8, OUTPUT);
  
  digitalWrite(LED_PIN1, HIGH);  // switch on LED
  digitalWrite(LED_PIN2, HIGH);  // switch on LED
  digitalWrite(LED_PIN3, HIGH);  // switch on LED
  digitalWrite(LED_PIN4, HIGH);  // switch on LED
    
  digitalWrite(LED_PIN5, HIGH);  // switch on LED
  digitalWrite(LED_PIN6, HIGH);  // switch on LED
  digitalWrite(LED_PIN7, HIGH);  // switch on LED
  digitalWrite(LED_PIN8, HIGH);  // switch on LED 

  
  
  status_bluetooth = true;
  status_unlock = false;
  sec = 0;
}

void loop()



 {
  

   if (Serial.available() > 0)    
       
  inByte = Serial.read();             // get incoming byte:  

    if(inByte == 'A'){    
     Serial.print('A');         // send a char
      digitalWrite(LED_PIN1, LOW);        // switch on LED
     status_unlock = false;
      inByte = 0;
       currentTime = millis();
    
    
     startTime = millis();
     timing = true;
    
 
  if (currentTime - startTime >= period)
 
  digitalWrite(LED_PIN1, HIGH); //turn off the LED
  
  }
 
  
  
  


  
  {
 
    //if (Serial.available() > 0) {
   if(inByte == 'B'){    
      digitalWrite(LED_PIN2, LOW);        // switch on LED
      Serial.print('B');         // send a char
      inByte = 0;     
  
     startTime2 = millis();
      timing2 = true;
   //}
  
   if (currentTime - startTime2 >= period2)

   digitalWrite(LED_PIN2, HIGH); //turn off the LED
      
  
  currentTime = millis();
    }
}
    
    if(inByte == 'C'){    
      digitalWrite(LED_PIN3, LOW);        // switch on LED
      Serial.print('C');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'c'){    
      digitalWrite(LED_PIN3, HIGH);        // switch on LED
      Serial.print('c');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'D'){    
      digitalWrite(LED_PIN4, LOW);        // switch on LED
      Serial.print('D');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'd'){    
      digitalWrite(LED_PIN4, HIGH);        // switch on LED
      Serial.print('d');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'a'){    
      digitalWrite(LED_PIN1, HIGH);        // switch on LED
      Serial.print('a');         // send a char
      inByte = 0;     
    }
    
    if(inByte == 'b'){    
      digitalWrite(LED_PIN2, HIGH);        // switch on LED
      Serial.print('b');         // send a char
      inByte = 0;     
   
    } 

DateTime now = rtc.now();
 
  


 if(now.hour()  && now.minute() == OnMin){
    digitalWrite(LED_PIN2, LOW);
    
    }
    else if(now.hour() == OffHour && now.minute() == OffMin){
      digitalWrite(LED_PIN2, HIGH);
     
  } 

if(now.hour() == OnHour1  && now.minute() == OnMin1){
    digitalWrite(LED_PIN2, LOW);
    
    }
    else if(now.hour() == OffHour1 && now.minute() == OffMin1){
      digitalWrite(LED_PIN2, HIGH);
     
  } 
  
 if(now.hour() == OnHour2  && now.minute() == OnMin2){
    digitalWrite(LED_PIN2, LOW);
    digitalWrite(LED_PIN1, LOW);
    
    }
    else if(now.hour() == OffHour2 && now.minute() == OffMin2){
      digitalWrite(LED_PIN2, HIGH);
       digitalWrite(LED_PIN1, HIGH);
     
      }  
  
}

when the app sends the command for relays 1 or 2 they will turn on for about 25min, no problem here. But i also want them to turn on/off at a specific time, 3 times a day. And here is the problem, it only works on the day i upload the code, the next day it doesn't work any more.

i also tried abandon the millis timing and use the rtc time, but i can't figure out how to add the 20minutes to the current time when 'A' is received to turn off the relay

I'm not certain I understand the problem statement. If the delayed turn off code was originally working for the serial read of the letters, you should not have abandoned that.

You also should clean up the brackets to better understand the logic, and what should be nested and what is independent. As previously suggested a switch case arrangement may be less cluttered.

You need to understand why the RTC code for the 3 rtc timed periods was not working correctly.

My thinking is that this code it keeping the led's off after the period and will keep turning them off when the rtc tries to turn them on.

if (currentTime - startTime >= period)
    {
      digitalWrite(LED_PIN1, HIGH); //turn off the LED
    }

You can fix this by using your timing variable For example

void loop()
{
  currentTime = millis();

  if (Serial.available() > 0)
  {
    inByte = Serial.read();             // get incoming byte:
  }
  
  if (inByte == 'A')
  {
    Serial.print('A'); //send a char
    digitalWrite(LED_PIN1, LOW); // switch on LED
    status_unlock = false;
    inByte = 0;
    //currentTime = millis();
    startTime = millis();
    timing = true;
  }

  if (timing && currentTime - startTime >= period)
  {
    timing = false;
    digitalWrite(LED_PIN1, HIGH); //turn off the LED
  }
.
.
.

You have a typo here

if(now.hour()  && now.minute() == OnMin){

now.hour() should have a compare value