After Some Time my Serial Port Stops Refreshing

Hi all, how are you doing? I hope everything is doing good for you all. I'm pretty new here and at the programming world, though i have some prior knowledge. I'm creating a programm that will be responsible for activating and deactivating solenoid valves at the field, basically; an irrigation system. What happens here is that after a while my serial port stops refreshing continuously the time read from a RTC 1302 device and the information flow stops. The result: nothing more works. If i remove all the lines responsible for each valvle, it works again and if i re-write them, it works for a while and then it stops updating again. I've been searching through the web but haven't found anything about such problem. All the wiring is working good as the software works for a while. All i need to do is read the time and activate or deactivate the valves at a specific time.

#include <virtuabotixRTC.h>
virtuabotixRTC myRTC (12, 13, 7);

int V1HON = 16;
int V1MON = 22;
int V1HOFF = 16;
int V1MOFF = 23;
int relay1 = 2;
void Relay1 ();
void setup() {

Serial.begin (9600);
pinMode (relay1, OUTPUT);

//myRTC.setDS1302Time (40, 59, 23, 7, 28, 8, 2021);

// put your setup code here, to run once:

}

void loop() {

myRTC.updateTime ();
Serial.print("Data Atual / Hora Local: ");
Serial.print(myRTC.dayofmonth); //You can switch between day and month if you're using American system
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
if(myRTC.hours < 10) Serial.print("0");
Serial.print(myRTC.hours);
Serial.print(":");
if(myRTC.minutes < 10) Serial.print("0");
Serial.print(myRTC.minutes);
Serial.print(":");
if(myRTC.seconds < 10) Serial.print("0");
Serial.println(myRTC.seconds);
delay (1000);

do{
digitalWrite (relay1, HIGH);
}

while (((V1HON) != (myRTC.hours)) && (V1MON) != ((myRTC.minutes)));
if(((V1HON) == (myRTC.hours)) && (V1MON) == ((myRTC.minutes))){
Relay1();
}

}

void Relay1(){

  digitalWrite (relay1, LOW);
}

The code is very simple and it works but i don't know what happens that the serial port stops updating the time values.

Best Regards,

EngDSS.

You should use code tags (</> on the toolbar), it makes reading the code much easier.

How do you think the serial port is the issue? i.e what are your symptoms? Does the relay still go on an off as expected?

} while (((V1HON) != (myRTC.hours)) && (V1MON) != ((myRTC.minutes)));
if (((V1HON) == (myRTC.hours)) && (V1MON) == ((myRTC.minutes))) {
In the above tests, you require exact matches. Is it possible the variables could be off by one count.

i.e. if ( i ==10)....... is not as tolerant of conditions as
if (i >=10 ) this will be true at 10 and an number above.

What is your goal and is the RTC really needed? The milli's function is good for 49 days.
Perhaps you could start each day as a function of the RTC then use millis for on/off timing. This way the RTC will make sure the cycle is the same time every day but the millis will determine the on / off times.

#include <virtuabotixRTC.h>
virtuabotixRTC myRTC(12, 13, 7);

int V1HON = 16;
int V1MON = 22;
int V1HOFF = 16;
int V1MOFF = 23;
int relay1 = 2;
void Relay1();

void setup() {

  Serial.begin(9600);
  pinMode(relay1, OUTPUT);

  //myRTC.setDS1302Time (40, 59, 23, 7, 28, 8, 2021);

  // put your setup code here, to run once:
}

void loop() {

  myRTC.updateTime();
  Serial.print("Data Atual / Hora Local: ");
  Serial.print(myRTC.dayofmonth);  //You can switch between day and month if you're using American system
  Serial.print("/");
  Serial.print(myRTC.month);
  Serial.print("/");
  Serial.print(myRTC.year);
  Serial.print(" ");
  if (myRTC.hours < 10) Serial.print("0");
  Serial.print(myRTC.hours);
  Serial.print(":");
  if (myRTC.minutes < 10) Serial.print("0");
  Serial.print(myRTC.minutes);
  Serial.print(":");
  if (myRTC.seconds < 10) Serial.print("0");
  Serial.println(myRTC.seconds);
  delay(1000);

  do {
    digitalWrite(relay1, HIGH);
  } while (((V1HON) != (myRTC.hours)) && (V1MON) != ((myRTC.minutes)));



  if (((V1HON) == (myRTC.hours)) && (V1MON) == ((myRTC.minutes))) {
    Relay1();
  }
}

void Relay1() {

  digitalWrite(relay1, LOW);
}

First of all, thanks a lot for your answer and attention to help me out. Well, i wanted to add the desire time to turn the valves on and off. Like a timer. I used the RTC to program a local time and then based on it input the time i want. As you can see, i compared hours and minutes to activate and deactivate them. Yes, the relay worked as expected before the code got "jammed". i have a 4 channel relay and i'm checking and updating the source code adding one - by - one. Before writing this message, it worked good again and after a while the RX led indicating transmission was not blinking anymore. This is very strange.

Try this....

do {
digitalWrite(relay1, HIGH);
Serial.println("in do loop");
} while (((V1HON) != (myRTC.hours)) && (V1MON) != ((myRTC.minutes)));

if (((V1HON) == (myRTC.hours)) && (V1MON) == ((myRTC.minutes))) {
Serial.println("in relay loop");
Relay1();
}
}

If Serial stops, the problem is most likely the i2c bus is hung trying to read the RTC. the latest version of the Wire library supports timeouts which may be useful.

I would also suggest that you simply calculate the number of minutes from midnight as your on/off times and simply things

const unsigned int onTime = V1HON * 60 + V1MON;
const unsigned int offTime = V1HOFF * 60 + V1MOFF;
....

unsigned currentTime = myRTC.hours * 60 + myRTC.minutes;
if ( currentTime < onTime || current Time > offTime ) {
  // turn relays off
}
else {
  // turn relays on
}

Since you dealing on the minutes scale, you also do not need to read your RTC every second. You could easily make you delay much larger.

I have noticed something strange. Everytime the hours and minutes reach a full number the system time stops refreshing. For example: 17:00, 20:00, 02:00, 03:00, 20:00 and so on... That's what's going on. IIt stays this way from 00 until 10. After that,i rewrite the new time to turn on and off and it starts working again. Does anyone have an idea about this? Also, huge thanks for the time and attention to help me.

Could you please not use the DS1302 ? Use the DS3231.
It is part of some starter kits, but that is only because no one wants them.

engdss and JohnRob, could you edit your posts that have no code tags yet ?

```
Your sketch
```

There is no need for your do...while() loops since loop() will run continuously. Just do your calculation, and, based on time, turn the relay on or off and then let loop() repeat.

The reason for all these do.. while is that it's a 0V triggered 4 channel relay, so it needs to be on high to be turned off. Unless i define the high state at the beginning. What do you think?

Get rid of the do...while() loop. The mystery to me is how you ever get out of it to report new times.
Write the pins high in setup to start with the relays off. Write them low when the time is correct and then set them high again when you want to turn the relays off.

Thank you guys for the suggestions. Well, as suggested, i removed the "do... while" structure and it's working better. i've been keeping the system running and all seems to be working much better than before. The system did not stop updating and the flow seems to be smoother. I'll keep watching how it's going to react and then i'll tell you guys. Thanks so much for all the help.

Hey guys, thanks a lot for the all the help. It worked really good after removing the "do...while" structure. Now i'm updating the code with new features for the system, like an automatic and manual mode, valve and working days, trying to make an interaction with the operator. I think it'll look good. Thanks a lot for the help!