Ceci est une ancienne révision du document !
It’s about REAL Time Greetings again, fellow Beings. Happy December and a better 2024 to you! This month, we will look at real time clocks on our Microcontrollers and specifically on the RPi Pico/Pico-W. While the RPi Pico boards don’t normally have a RTC built in, many newer third party Pico boards already have one on-board. Even if you are using an ESP-32 or ESP-8266, the general process is pretty much the same for all of them, especially if you are using MicroPython. All of the boards have some sort of time keeping capability, even if it doesn’t know what time it is when you power up the board. You can always set the date and time (grossly) in code at the start of your program and if your microcontroller is BlueTooth or WiFi capable, you should be able to connect to a server, grab the time and then do what is needed.
For today, we’ll skip that discussion, and move on to using a Real TIme Controller chip. There are many versions out there, but the one I’m going to use is the DS1307 RTC I2C module. At the date of this writing, I was able to find them as low as $0.88 USD in single quantities. Of course, the shipping on just one, would cost a TONNE, so look around locally and you will probably find one for less than $15.00 USD possibly with shipping included. This is what mine looks like and as you can see, the left side has spots for 5 pins and the right side has spots for 7 pins. You can choose either side and for this project only use the Gnd, VCC, SDA and SCL pins. Since it’s I2C, it will work on almost any Microcontroller, Arduino or Raspberry Pi board so your investment won’t be wasted.
Breadboarding it I need to repeat that there are MANY different boards that use the DS1307, so I’m going to give generic instructions for the breadboard. Don’t try to follow the image for anything other than the PICO pin positions. In fact, I’ll give you a table instead. But take a look at the image below just to get an idea how small things can be. If you want to use I2C(0) on the pico, Pins 6 and 7 are the suggested pins. If on the other hand you want to use I2C(1), the suggested pins are 9 and 10. In any event, the SDA on the Pico connects to the SDA on the DS1307 and the SCL on the Pico connects to the SCL on the DS1307. The Head bone is also connected to the Neck bone and so on and so on. Now we can get to our code.
The Code There is an added benefit in the code to include output to an OLED display using the SSD1366 I2C display. However, I’ve commented all of the code out, so you can run without it. The DS1307 is (in this software) setup on I2C(0). If you want to include the OLED display, you could have it on the same I2C bus, but I’ve got the software to handle it on I2C(1). Again, I’ve added the optional code for the OLED display. If you want to use it, just un-comment this part of the code and a few lines in the main while loop (top right). While we can take the data directly from the rtc.datetime() function and the time.localtime() functions, it comes back as a tuple and if you just want to glance at the screen or display, it’s somewhat hard (at least for this old guy) to grab the correct information out of 8 values out of the tuples.
The rtc.datetime() function returns it’s values as follows… dt=(2023, 12, 9, 5, 9, 59, 41, 0) For the rtc.datetime tuple, it is works out as: Year, Month, Date, Day of Week, Hour, Minutes, Seconds and Subseconds. On the other hamd, for the time.localtime() values they come in this way… dt=(2023, 12, 9, 9, 59, 41, 5, 343) Which at first glance seems to be the same format. However, it’s not. It works out as… Year, Month, Date, Hour, Minutes, Seconds, Weekday and Day of the Year Local Time: 12/09/2023 - 09:59:41 So, taking all that into consideration, I created a little function that takes in the tuple from either rtc.datetime() or time.localtime() and a second parameter that specifies which one the data is coming from. 0 for rtc.datetime and 1 for time.localtime. It returns two values: date and time. The date value returns a string in the format of MM/DD/YYYY and the time value is a string in the format of HH:MM:SS . If you want to change the formats of the returned data, it is really simple. I’ll show you where below. First let’s look at the start of the function (next page, top right).
The first line in the function simply copies the incoming data from “d” to dtin, which makes more sense. I also wanted to have a value that could be examined easily, rather than just name the parameter dtin. As you can tell, the year is handled the same, whether the data is coming from rtc or timer, so all we do here is step through of the first three items in the tuple, assign them to temporary values, then zero pad them on the left to make sure that 7 minutes after 11 shows like “11” “07” with whatever separator you decide you want. Now we handle the time portion. If we are dealing with the rtc data, we skip (for this project) the fourth item in the tuple (remember it’s zero based so it is actually designated as dtin[3]), since it’s the Day of Week. Then we pull each data item and, as we did with the dates, zero pad the item (top right). If, however, we are dealing with the time.localtime structure (a ‘1’ in the second parameter), we only need to pull in the next three items in the tuple and as above, we convert them into zero padded strings (bottom right).
Now (top middle) is where we use the f-string feature to format the strings. So you can easily see that it would be simple to change the separators or move the items around. That’s it for the formatting function. Finally, we can code the main portion of the program. It’s really very simple. We instantiate the machine.RTC object as rtc. Then we get what the board thinks is the correct date and time. We then send that structure to the ConvertDT function and a 0, since the data is directly from the rtc object. Once we get it back, we print it out. Next we get the local time from the time module and send that to the ConvertDT function with a parameter of 1. Finally we start a loop, making a call to time.localtime, convert it and print it. The program sleeps for 1 second and repeats forever (see below). One other thing I should tell you about. If you use Thonny as your IDE, you might notice that for some reason whenever you check the time on your Pico through the IDE, it is correct. Why would that be?
From what I understand, whenever you connect a Microcontroller to Thonny, one of the first things that happens is that Thonny pulls the date/time information from the local computer and then sets the date/time of the Microcontroller for us. Remember, however, if you connect your Microcontroller directly to power without connecting to your computer, the date and time probably won’t be anywhere close to reality. At that point, you can call Doctor Who for a “wibbly wobbly timey wimey sort of thing”, or you can use a DS1307 RTC module. I’ve created a repository on Github for the code for this month at https://github.com/gregwa1953/MTMT-FCM-200 . Until next time, HAPPY NEW YEAR and, as always; stay safe, healthy, positive and creative.