DS3231 RTC with EEP...
 
Notifications
Clear all

DS3231 RTC with EEPROM, Square wave and alarms.

18 Posts
2 Users
3 Likes
8,356 Views
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  

My intro outlined my project goals. So far, I've been able to set the system time using the RTC and also use the Square Wave function (at 1Hz) to create an interrupt-driven display on the OLED (note that using a delay call in the main loop isn't that smooth and sometimes skips seconds etc). 

Next, I'll be testing the alarms. An alarm will raise the SQW pin HIGH (on the RTC) at the designated alarm time .. .so I can't use the 1Hz signal and the alarm signal together (they use the same pin on the RTC). No biggy, since I intend to put the micro-controller to sleep after setting the alarm and letting the alarm wake the micro-controller with an interrupt). The intent of the push button (see diagram) is to add 1 minute to the current time to set the alarm after turning off the 1Hz square wave and shutting down the micro-controller.

Perhaps my current confusion is pullup vs. pulldown. The interupt pins (two of them on the Nano) have built in resistors so INPUT_PULLUP for mode and "FALLING" for trigger seem to work fine for the RTC signals, but I added a resistor to the push button to stabilize it. It works as wired in the diagram, but I'm not sure it's correct to drain 5V+ to ground through the resister.

clock display v1

   
Quote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  
download 20200210 210710

   
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  

I was able to put the Nano into a deep sleep state (so-called power off) and use the external RTC to wake it back up.  Victory! I initiate the sleep using the push-button, which sets the alarm on the RTC to go off at the top of the next minute. The OLED display shows the time sleep started (S) and scheduled wake-up (W). See attached photo.

I have a pretty good idea that the Nano actually went to sleep (despite the power LED staying on and voltage continued to flow from pins 3v3 and 5V) because when it woke-up, it lost time.  I now reset system time after wake-up by polling the RTC.

I also rewired the RTC and OLED to run off the 3V3 pin. The specs on both these devices indicate that I2C works with either 5V or 3V without a logic converter.  Nice! See attached wiring diagram. 

Next up is storing/retrieving a task schedule from the EEPROM - i.e. a series of date/time to start/stop. I'm exploring JSON or MessagePack for storage format as these seem fairly easy to convert to C data types.

I'll post my sketch once I clean up some of the code I got from various examples. I'm discovering that many examples are poorly written (IMHO). Bill gives good advice when he says "read the [library] code". 

20200213 150457
clock display wiring v2

 

References:
----------------------------
JSON/MessagePack - https://arduinojson.org/
Arduino DS3232RTC Library - https://github.com/JChristensen/DS3232RTC
DS3231 device specs: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
RockScream Low Power library - https://github.com/rocketscream/Low-Power
Adafruit OLED Library for SSD1306 - https://github.com/adafruit/Adafruit_SSD1306
SD1306 I2C device specs: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf

This post was modified 4 years ago 2 times by dxj

   
ZeFerby reacted
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  
This post was modified 4 years ago 3 times by dxj

   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@dxj

Code looks good to me, but in my opinion (whatever that's worth :-)), I would for a start, break up the function "showTimeTemp()" into three functions - Date, Time and Temp to promote loose coupling and re-usability, as a function should only do one thing, but do one thing good. 🙂

Cheers!


   
dxj reacted
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  

@frogandtoad

Thanks for the feedback. Discussions on code readability, maintainability, efficiency and re-usability are generally welcome and well received by me. There is always room for improvement.

In my experience, the re-usability - for the sake de-coupling - argument comes up a lot, but is often opinionated and misses the point. Don't get me wrong ... I strongly agree with the principal if I were writing library functions for general consumption.

Often, a more salient argument for re-usability is general utility.  If nobody wants to use your re-usable de-coupled functions - because they are too narrow in their utility - then are they actually re-usable?

I'm happy to engage in code quality discussions - perhaps elsewhere in the forum - but it is my sincere intent for this topic/message to provide more complete and useful examples of how to incorporate a DS323x RTC into a project. It has some unique and compelling features over other RTC packages.

So far, I've covered the time retrieval, square wave function, alarms, both 3.3/5V on the I2C and the external interrupt. I have yet to play with the 32K oscillator and EEPROM. Those are next.

Maybe we should start a separate forum on code best practice (if there isn't one already). I've injected comments about code quality in other topics. In retrospect, I wasn't adding much value with my comments at a time when the original poster was still trying to figure out how to make a piece of hardware work for them. ?

Regards

This post was modified 4 years ago 2 times by dxj

   
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  

Console output:

DS3231 Basics Monitor

   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@dxj

Posted by: @dxj

Thanks for the feedback. Discussions on code readability, maintainability, efficiency and re-usability are generally welcome and well received by me. There is always room for improvement

Thanks for responding, and glad that you didn't view my comments in a negative way.

Posted by: @dxj

In my experience, the re-usability - for the sake de-coupling - argument comes up a lot, but is often opinionated and misses the point. Don't get me wrong ... I strongly agree with the principal if I were writing library functions for general consumption.

Indeed, I agree with this view in general, as most people here are just happy to just get their device working, and not delve into the structure of their code too deeply.  I personally like to have my functions as small as possible, which being new to electronics help's me debug my code a lot easier.

Posted by: @dxj

Often, a more salient argument for re-usability is general utility.  If nobody wants to use your re-usable de-coupled functions - because they are too narrow in their utility - then are they actually re-usable?

I guess this depends on what "too narrow in their utility" really means?  I do believe that a function should only do one thing and do it well, which becomes a loosely coupled and reusable piece of code by default.  For example, we shouldn't write a sqrt() math function that also performed a count of something and maintained the time... the sqrt() function should only perform the square root of a number and nothing more.  This kind of function is less about loose coupling and more about performing and focusing on it's intended task.

Posted by: @dxj

I'm happy to engage in code quality discussions - perhaps elsewhere in the forum - but it is my sincere intent for this topic/message to provide more complete and useful examples of how to incorporate a DS323x RTC into a project. It has some unique and compelling features over other RTC packages.

Me too, and please don't get me wrong... I'm not questioning your sincerity at all, just passionate about coding clarity and design.  There is a programming area where we can post these types of discussions, so maybe I will start a topic there for us passionate programmers to exchange some views and ideas in the near future.

Looking forward to your next update, on how you incorporate the 32K oscillator and EEPROM 🙂

Cheers!


   
dxj reacted
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  
Posted by: @frogandtoad

I do believe that a function should only do one thing and do it well, which becomes a loosely coupled and reusable piece of code by default. 

Agree whole-hearted. In my mind, my function does one thing ... display a line of data for illustration purposes. ? 

Actually, the showTimeTemp() func was once an OLED display function ... and if you've dealt with the SSD1306 library, you'd like it, I'm guessing. You call seperate functions to clear the buffer, set a font scale, set the color, set the x, y coordinates, draw a box around it and finally paint the display with the buffer. Every function does one thing.

I end up creating an aggregate function to display the clock screen (gets called every sec) and it in turn repeatedly called a wrapper function I created: printAt(x,y,text,scale,color). It saved me a lot of lines of code and made the code a lot easier to read and maintain.

I stripped out all the OLED stuff before publishing my code (to make it simpler and about the RTC and alarm interrupts).

I suppose my pet peeves have to do with readability, maintainability and reducing redundant code.

Regards.


   
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  
Posted by: @frogandtoad

Looking forward to your next update, on how you incorporate the 32K oscillator and EEPROM

I haven't found a good use for the 32K oscillator yet. I can turn it off the save power, however. ? 

For the EEPROM, I've gotten overly ambitious, I'm afraid. I'm looking at a library named littleFS that turns any block storage device into a file system. It's designed to be atomic; meaning all operations either happen or they don't. No corruption if you lose power or receive an interrupt in the middle of an operation. You supply the four functions for block operations and it provides the file level functionality.


   
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  
Posted by: @frogandtoad

Looking forward to your next update, on how you incorporate the 32K oscillator and EEPROM

I haven't found a good use for the 32K oscillator yet. I can turn it off the save power, however. ? 

For the EEPROM, I've gotten overly ambitious, I'm afraid. I'm looking at a library named littleFS that turns any block storage device into a file system. It's designed to be atomic; meaning all operations either happen or they don't. No corruption if you lose power or receive an interrupt in the middle of an operation. You supply the four functions for block operations and it provides the file level functionality.

https://github.com/ARMmbed/littlefs


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@dxj

Posted by: @dxj

I suppose my pet peeves have to do with readability, maintainability and reducing redundant code.

My passion... I love to program, and challenging myself to refactor code to oblivion is good fun! 🙂

Cheers!


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@dxj

Posted by: @dxj

I haven't found a good use for the 32K oscillator yet. I can turn it off the save power, however. ? 

Wish I knew much more about electronics than I currently so, but I'm slowly getting there!  Again, looking forward to your progression on this project.

Cheers.


   
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  
Posted by: @frogandtoad

Wish I knew much more about electronics than I currently so, but I'm slowly getting there!  

We're in the same boat ... which is why I asked to join the forum.


   
ReplyQuote
dxj
 dxj
(@dxj)
Member
Joined: 4 years ago
Posts: 27
Topic starter  

I put this project away for a while as life happened. I discovered a few things in the process:

1) The coin battery on the RTC drains if sharing the same power supply as the Nano. I measured voltage on the coin battery after it recharged - it's good. I attempted a remedy for the drain by putting the RTC on it's own power supply and using a diode to connect the nano to the common ground (effectively isolating the RTC, in theory).

2) The RTC retains alarm data if power off (using the coin battery for backup). If you turn the RTC off after the alarm is set, it triggers an interrupt when turned back on, even if the alarm time has passed. This is not a problem, it just demonstrates that the RTC retains both time and alarm when powered off.

I'll leave it powered down overnight to see if it drains completely again. 

This post was modified 4 years ago 2 times by dxj

   
ReplyQuote
Page 1 / 2