RTC time stays the same

Hi Nick

Sorry for the misunderstanding.
No there are no pull ups on the RX0 pin of the Arduino Mega 2560.

GND on PCB to GND on Mega
12V from PCB to Vin on Mega
5V from Mega to 5V on PCB for SD card, RTC and DS18B20.
I use Pin10 to 13 for the SD card.
The rest are used for DS18B20s, Limit switches with pull ups and output to Relays.

So the solution is to add a 2K2 to RX0 and 5V and add checking to the code?

Thank you for your patience and understanding I appreciate it.



Gosh it's hard to get detail out of you. :)

What PCB?

Anyway, I would put some sort of pull-up (eg. 4K7) on the Rx line to try to keep noise out of the system. I would also add checking to the code. Make sure you get the clock started (by setting the time) before you reinstall it. As a general rule, accepting data from the serial port, without any checks at all that it is valid (eg. you didn't check even if you are getting numbers) is going to lead to unreliable or unpredictable behaviour.

... and output to Relays.

In the absence of any further detail we have to hope that the wiring for the relays is correct, both in that they can handle the current and in the use of diodes to stop current flowing back into the Arduino when the relay opens.


I still want to know the following:

How do I make sure (check) that the CH bit is set?
How do I only write to the CH bit without changing the seconds or bit 0-6?

PS pic of me just out side Canberra :slight_smile:


Actually you want it clear. From the specs:

When this bit is set to 1, the oscillator is disabled. When cleared to 0, the oscillator is enabled.

Thus, setting the clock, with valid seconds, will clear the bit and allow the clock to run. I don't see how you can clear the bit without putting some seconds there.

Just as a tip, on the GPS clock I have, the designer added a switch. If you hold the switch down while it resets it goes into "configure mode" where it prompts you on the terminal (serial port) for configuration data.

You could test this switch in setup, and then go into a query/response for getting the time. That would be safer than constantly checking the serial port "in the field".

Here is the rest of my connections:

Thank you for all your help so far It is getting late here. I will add the Pull up on RX0 tomorrow.


Sensors.pdf (22.4 KB)

RLY.pdf (19.8 KB)

SD.pdf (18.4 KB)

Luan: Hi Nick

Thank you for your input so far.

The farmer needs to be able to set the time using terminal without loading different code.

GetDateDs1307() is for saving the time and date on the SD card. now = RTC.now() is used for date/time calculations.

Now back to my problem. RTC_config() only works if it gets data on the Serial port. The only time the Serial port gets any data is when it is connected to a PC and a sting is send to the Arduino, this does not happen in normal operation. I would like to know what causes the CH bit to change (by it self), I need to understand why it happens and solve the root of the problem.

But as Nick pointed out you definitely have a problem here. And it is generally good debugging practice to resolve known problems before moving on trying to find and resolve unresolved issues/problems because the issues might be related.

You have 2 calls to RTC_Config() in your loop() routine?

While RTC_Config() only starts looking for what to do when a character is available, it does call setDateDs1307() without any further checking. setDateDs1307() does no checking for characters being available and blindly calls Serial.read() for each needed character. Serial.Read() does not block waiting for a character and returns -1 if no characters are available. So now, depending on the arrival timing of the characters coming in, you are potentially using -1 for character values, which creates totally garbage values for things like second, minute, hour, et.... If the data is arriving from human typing using a terminal program, then is almost certain to happen. When testing with something like the Arduino Console window, you may or may not see this as the characters are buffered up and sent back to back rather than sent 1 at a time as they are typed.

Further down in setDateDs1307() you take the second, minute, hour, .etc... values and convert them to BCD. Given that they can be wonky values, these conversions may create values that are outside normal BCD digit ranges for those fields and cause problems.

You haven't said how the serial connection is made to the arduino board or what OS is being used. What board, what connections are used and what OS and terminal program is used to connect to this board?

Some OS's probe the serial ports looking for devices either at connection time or periodically. This kind of stuff might cause issues for your code.

Before you go off and mess with any sort of hardware changes like adding pullups to serial lines (which shouldn't be necessary on something like a stock mega2560 board if it is using the USB port for the serial connection), I'd use some debugging indicators to detect if certain parts of code is actually triggering like the function RTC_config(). Do something visible to know if this is being called. i.e. turn on a led etc...

But a bigger question is where did the RTC code come from? It looks like it is a modified version of the adafruit RTClib library code. Why do that? Why not build your functionality on top of working library? That's the intent of a library. By inserting unrelated code into a library code function, it increases the risk of breaking something.

One general word of advice I'd offer is that when designing code, and this is more of a development style thing than a rule, try to avoid mixing multiple i/o types or multiple pieces of functionality in same function. Especially for things like user interface/input and normal runtime code or code to initialize hardware. For example, in setDateDs1307() the code is not only setting the date/time in the chip but it is also performing user interface stuff by reading the data from the serial port and parsing it as well. This style of programming is more difficult to debug and harder to modify since the overall functionality is not compartmentalized into distinct tiny functional bite sized pieces. In other words, when possible, try to have smaller functions that are very focused functionality. That way it is easier to debug and modify the functionality for future needs. For example, lets say you decide that you want to set the clock using menus on the LCD with menus that are controlled by buttons or an IR remoter ather than a terminal program. The way that setDateDS1307() routine works today, it requires changes to that function for any user interface change. Whereas, if it merely set the chip based on the date/time data, all that would be necessary to change the user interface is new user interface code that knows how to read the buttons or the IR led to control the menus and then code to create the date/time data before calling the function to set the date/time in the chip. As it is now, any changes to the user interface requires changes to the routine that sets the hardware clock. For debugging it is very useful to use this methodology as it allows writing the code in layers and as each layer starts working it can be ignored and attention can be focused on the higher layers.

For readability, I'd also suggest that you not use decimal numbers like 48 when you really mean the character '0' instead. Using the decimal numbers makes the code less obvious. Not sure what editor you are using but to change it can be as easy as single line global substitution to change all 14 of them. There are also other compares to character values like 84, 81, 49, etc that also could use some cleanup.

--- bill

Hi Bill

Thank you for your input so far.

I need to got to the farm now and get the system working again.

So I think the best thing for now is to remove RTC_config() from the code to prevent any problems. When I get back I will sort out the code like you are suggesting..

What RTC library for the DS1307 do you suggest is the best which already include set time functions?

Thank you