how to properly interrupt Arduino for RTC update

Hi,
In a project I just started, I have such a setup:

  1. Arduino_1 (A1), driving an LCD
  2. Arduino_2 (A2), all other functionality
  3. A2 < software serial > DFPlayer (mp3 player)
  4. A2 < i2c > DS3231 (AT24C32)
  5. A2 < serial > A1

On the LCD I’d like to have HH:MM:SS being updated every 1000us. I first thought that I must simply have (somehow) RTC to raise an interrupt when time is changed in seconds for A2, and that will send a serial command to update A1, but well I use software serial and that means that I can’t use my interrupts (as long as I know, it will be complex and I am a newbee).

The problem in short is that I don’t imagine how I could update the display, right when a new second is raised.

Could anyone please make me clear which direction to go? There must be a best practice for this, that I don’t know even how to google it.

A block diagram is also attached.

ardu-intrpt.png

I do not know why Software Serial would prevent you from using interrupts, but a self-professed newbie should not be using interrupts because they can be hard to get right and hard to debug.

Also, I do not know why HH:MM:SS is being updated every 1000 microseconds. This means that out of every 1000 updates, 999 of them will have no change.

Why not look at the RTC on A2, and when the RTC seconds change, send the new time to A1. A2 will look at the time every time that the loop() function gets called (which is 1000's of times a second unless you slow it down), and A1 will look for the serial message every time that its loop() function gets called. What have I missed?

Why not put the RTC and LCD on the same arduino? Then you won't have to send a message.
If you use interrupts, you can connect the SQW pin from the RTC to an interrupt pin. Set the RTC to generate the 1Hz signal on the SQW pin and attach an interrupt to that same pin. On every interrupt, set a flag in a byte variable and in then in the loop function, whenever that byte is set, read the RTC time and update the LCD. There are other ways to do this.

Pete

Image from Original Post so we don’t have to download it. See this Image Guide

42d93609ae9c11869fc6379efbd70eff903d4bbf.png

…R

If you want to do something once per second I can't see any need for interrupts. Also, the time is not going to disappear if you are a few millisecs late. Interrupts are for things that happen at short intervals, or things which are of very short duration and might be missed.

You should be able to use millis() to manage the timing (see Several Things at a Time) and occasionally check the RTC to correct for any small error in the natural Arduino timing.

...R

Why two Arduinos?

After you answer odometers question about why two Arduino's, you can answer mine as to why put the rtc on Arduino2 if the data is needed on Arduino1?

why put the rtc on Arduino2

I've already asked that.

Pete

I've already asked that.

:-[ Sorry, too much egg nog before posting.

Ha! I'm almost bursting from too much chocolate.

Pete

Thank you very much for the replies!

Vaj4088,

the reason I started to think about interrupts and why 1000ms:

  1. I wanted to be free of concerning how busy my loop() will ever be.
  2. Suppose it happens that I read RTC (when not using it in a way that it interrupts Arduino) in the middle of the second. Next read I update the display for the change in a second. So if I observe my display of Arduino, I’d perhaps precive a lag of updating this LCD with world clock right? Also, what if loop() gets too busy because of reading sensors, user input (IR-remote, etc.) or any other I/O busyness. I was thinking how to get to freedom of calculating how long it takes so my loop() repeats.
  3. I didn’t know that if I check every 1000ms theen 999 of reading will miss the time change. Now buy reading every one’s reply, I think that what El_supremo suggested is the way to go, using SQW to interrupt Ar2, but then, on Software-Serial tutorials it is written that if to use interrupts together with this lib, there maybe newbee-killing bugs!

===========================

El_supremo

Why 2 Arduinos:
Well, you could see by the phohto I uploaded that one Arduino_1 gives nearly all of its pins to the LCD (which yet has a touch screen). It will be loaded with LCD driver and also my code to read touch screen, get user input, etc. I didn’t calculate how much code there will be, but I wanted to open myself just a plenty of room having 2 Arduinos :smiley:
Reading your kind reply I got to think if it is ever possible to use a pin for two purposes? I mean, is it possible to:
x) connect LCD pin and another sensor to the same pin
y) let Arduino use the pin to load LCD
z) reuse the pin, set it as input, read the sensor (but I don’t know how then to get it back to LCD!)

================================================

odometer:
Why two Arduinos?

Reasons above must make it clear why I was thinking so, anything more needed I’d be happy to explain.

==================================================

cattledog:
why put the rtc on Arduino2 if the data is needed on Arduino1?

Because of Ar1’s pins are (nearly) all connected to the LCD. I still don’t know, if I could ever connect 1 Arduino pin to say 2 sensors, reassigning it in code and reuse it with different purposes.

==================================================

This is my Arduino_1:

arduino-lcd.png

It appears that you have something on pin A4. What is it being used for?

A5 looks free, and if you can move what is on A4 to another pin, you will be able to make the i2c connections to the RTC.

cattledog:
It appears that you have something on pin A4. What is it being used for?

A5 looks free, and if you can move what is on A4 to another pin, you will be able to make the i2c connections to the RTC.

A4 is connected to LCD_RST pin, and yes, I can sure remove it, but as you see on the block diagram, I will have serial mp3 player in this project, IR-remote and other sensors may come in too. I could only connect another Arduino by serial to this one with LCD and load that Arduino_2 with all jobs other than running the LCD. I can't imagine how else it could be done.

In fact my main question is that in such a setup that I use software-serial, how I could efficiently make RTC to raise interrupt on Arduino_2 without making bugs, as from there it is solved: Ar_2 will inform Ar_1 by ordinary serial.

load that Arduino_2 with all jobs other than running the LCD

I understand that. Does Arduino_2 need to know the time?

If the time is just for display on the lcd, then if Arduino_1 runs the lcd and the rtc, and Arduino_2 does everthing else I think it would simplify the project.

However, If Arduino_2 is frequently (i.e. at intervals less than a second) sending lots of information to Arduino_1 for display, then adding the time to the stream may not be a big issue.

Have you considered using a Mega for the project, as you would have all the I/O you need on one Arduino.

cattledog:
Does Arduino_2 need to know the time?
Arduino_1 runs the lcd and the rtc
Have you considered using a Mega for the project, as you would have all the I/O you need on one Arduino.

Excellent idea, I didn’t think about i2c of Ar_1, strange! But then, the exact synchronization with world clock remains a matter: Ar_1 is driving LCD, reading touch, doing lots of things, it’s better that RTC raises an interrupt itself (as it was suggested in replies, SQW) , but where? Any idea please?

Next, why not a Mega:
In case I’d successfully implement what I aimed for, I’d gift the whole item regularly to friends (I do cnc cases from wood). So I try to make it cost effective. Off eBay one could get a mega for min of US $7.35 (now, what I found), but for Pro-mini it is 2 * US $1.46 = US $2.92 < US $7.35.

I could use 3rd Arduino US $4.38 < US $7.35:
Ar1 - LCD, serial to:
Ar2 - all but RTC, soft serial to:
Ar3 - only RTC

I hope I’m correct in arithmetic :smiley:

it’s better that RTC raises an interrupt itself (as it was suggested in replies, SQW) , but where? Any idea please?

For an update of the display every second, I don’t think it makes much difference if the RTC sets an interrupt flag which is checked in loop with code like el supremo suggested in reply#2.

if(flag) readRTC()

or if the loop contains a non blocking millis() timer with code like Robin2 suggested in reply #4.

if ((millis() -  lastRead) > 1000)
  {
    lastRead = millis();
    readRTC();
  }

If sometimes you update the display 0.1 second late, your friends will not know the difference.
If you make an interrupt, and that interrupt messes up another part of your project, then your friends will know the difference.
Also, there is no reason to try to update the display once every 0.001 second. The display might not even be able to update that fast.
Do your friends like to watch movies? Are they aware that, on the movie screen, the image changes maybe once every 0.04 second or so? Do your friends care about this?
If an image on the movie screen waits a whole 0.04 second to change, and your friend does not care, then why would they care about 0.04 second on a digital clock display??
You are trying to solve something that is not really a problem.
By the way, if you want to be obsessive, there is a leap second at the end of this year (2016).

Using a second Arduino to increase the number of I/O is one way to do it. There are other ways to increase the I/O on an Arduino. Shift registers is one way and inexpensive. I2C I/O devices is another.