
This example describes how to use the datetime and ds-rtc libraries, format date and time values, and work with real-time clock (RTC) modules for Arduino. Upon the completion of this guide, you will learn how to create a simple digital clock based on a DS1307 I2C RTC module and I2C LCD display.
You can use a DS3231 or DS1302 breakout board instead of DS1307 because they are interchangeable.

SDL and SDA I2C pins from the Arduino board to the contact lines on the breadboard. The display and RTC have different I2C addresses, they do not interfere with each other, so you can connect them to the same I2C bus.GND and 5V pins from the Arduino board to the corresponding rails on the breadboard.SDA and SDL with the I2C bus on the breadboard. Wire its GND and Vo pins with the GND line on the breadboard. Wire Vcc pin with the 5V line on the breadboard.SDA and SDL with the I2C bus on the breadboard. Wire its V and GND pins with the corresponding lines on the breadboard.If you are using another model of the I2C display or RTC module, look at their pinout and datasheet to connect them correctly.
For this example, the programming process consists of two steps:
Create a new patch set-current-time. We’ll use it only once to write the current time to the memory of RTC module so that it has a proper base point.

rtc-device node from the xod-dev/ds-rtc library onto the patch. This node describes an RTC breakout board which communicates via I2C. By default, the I2C device address of the RTC at the ADDR pin is 68h which is correct for the most DS1307 modules. The DEV pin of the node outputs the rtc-device value which contains everything to operate the device.write node from the xod-dev/ds-rtc library onto the patch. This node’s function is to write time and date to the permanent memory of the RTC board. The DT pin inputs a datetime type value to be written. The UPD pin triggers a new write. The DONE output pin notifies writing complete.DEV pin of the write node with the DEV pin of the rtc-device node.On boot value at the UPD pin means that we write the datetime once after the boot of the device.The write node requires the date and time values having a datetime type. The datetime node is used to pack year, month, day, and hours, minutes, seconds into a datetime type value.

datetime node onto the patch.datetime node with the DT pin of the write node.YEAR, MON, DAY, HOUR, MIN, and SEC pins with values. Each pin contains a description of what form this values should be.For example, we set the current date. Now it is the 17-th of September of the 2018 year, and the time is 14 hours 44 minutes and about 31 seconds. To set this date and time values to the RTC, we fill the datetime pins with values.
2018 year value to the YEAR pin.9 number of the September month to the MON pin.17 number of the day of the month to the DAY pin.14 number of the hours to the HOUR pin.44 number of the minutes to the MIN pin.31 number of the seconds to the SEC pin.The patch to set up the real-time clock is completed. Let’s quickly load it into the Arduino board, to make the difference between the real and written time be only a few seconds.
Once the board is flashed the RTC module will get the correct current time value which automatically ticks and not get lost as long as the module is powered by either its battery or the device itself. However, note that the time gets re-written on every boot to that exact value we have set. So, if you will reset your board after an hour, it will overwrite the correct time with the now-obsolete hour-lagging value. To protect from this effect it is a good idea to remove the uploaded time setting program. Upload an empty patch right after set-current-time to clear.
We won’t need the set-current-time patch anymore.
Create a new patch and name it digital-clock. This is the patch for our digital clock. Strictly speaking, we are going to create a new program. So we need to put an RTC node again. To fetch the data, a node which is named simply rtc might be used. Then we unpack the obtained values for further work.

rtc node onto the patch. This node represents an RTC clock. A pulse at the UPD pin triggers a new reading of a datetime type value. The DONE output pin fires on successful read. By default, the I2C device address at the ADDR pin is 68h.UPD pin value to Continuous.unpack-datetime node onto the patch and link it with the rtc node. The unpack-datetime node destructs the datetime type value and outputs Number values of the date and time for subsequent processing or formatting.Look at descriptions of output pins of the unpack-datetime node to figure out the ranges and formats of the output values.
If the real-time clock takes a small place in your extensive project, and a controller is very loaded, the Continuous pulses on time readings can lead to various unexpected read failures. To solve this problem limit the pulse frequency. For example, you can link the UPD pin with the clock node and set the IVAL value to 1 second. By this, you adjust the real-time clock updates to 1 Hz.
Let’s put this patch aside for a while. Imagine that no time has passed since we written values to the RTC. Thus, if we look at output pins of the unpack-datetime node, the values of date and time are the same format that we entered.
2018 number value at the YEAR pin.9 number value at the MON pin.17 number value at the DAY pin.14 number value at the HOUR pin.44 number value at the MIN pin31 number value at the SEC pin.Besides, the unpack-datetime node calculates the weekday and outputs it through the WD pin in the range from 1 to 7. Now, we need to format this numbers to a proper view and add punctuation before showing them at the display screen.
Different conventions exist all around the world for the date and time representation, both written and spoken. Differences can exist in:
Some time formats are standardized though. For example, you can read about ISO 8601 or Unix time formats. You can check out the xod/datetime library for the format-timestamp node. It formats datetime for use in spreadsheet computer programms. In this example, let’s format date and time as they are shown on the digital clock in the classic American style. Here is the picture of the digital clock we want to make.

Let’s create three additional patch nodes which format our date and time values.
We start the formatting process from the date. Create a patch for the first new patch node and name it format-date. We want this node to get numbers for a year, month, and day and output them as a single string. Also, we want format-date to separate the date values with the / character.

input-number nodes onto the patch and name them YEAR, MON, and DAY.output-string node onto the patch and name it DATE.format-number node and link it with the YEAR node. The year values that comes to the YEAR pin are of Number type. The Number type values are floating point, and the incoming year value looks like 2018.00. We use the format-number node to get rid of those zeroes. If you put the 0 value to the DIG pin string value of the year becomes 2018.pad-with-zeroes nodes from the xod/core onto the patch. Link their input pins with MON and DAY. The pad-with-zeroes node transforms a Number value into String adding zeroes before the value. The number of added zeroes depends on the width of the string. The width value is set at the W input pin. This node is very useful for this guide. The month and day value fields on our display have 2 digit capacity. If we show the 12/22/2018 date on the screen, it is ok. However, if we show, for example the 3rd of September directly without adding zeroes below the month and day, the text on the screen looks will be 3/9/2018. Thus cuts the width of the date by two digits, and the total width of the line on the display screen. The pad-with-zeroes solves this problem. We put the 2 width value to the W pin on both nodes, so the 3rd of September looks like 03/09/2018. By this, the total width of the line with the date will always be static.join node onto the patch. With the join we can separate day, month and year by a character of our choice. As we want to separate date values with /, we link the / string constant with the D delimiter pin. With join we can also set the order of the year, month, and day representation. As we want the MON value to be first, DAY to be second, and YEAR to be third, we make proper links between join input pins and other nodes. After this link the join output to the DATE output-string node.The unpack-datetime node outputs the number of the weekday depending on the date. To show weekday names instead of numbers we need a node. Create a patch for this node and name it format-weekday.

input-number node for the input weekday number onto the patch. Name it IN.output-string node for the string name of the weekday onto the patch and name it OUT.Mon, Tue, Wed, Thu, Fri, Sat, Sun and create constant nodes for them.nth-input node onto the patch. The format-weekday node outputs the number of weekdays in the range from 1 to 7. So, the Monday number is 1, and the Sunday number is 7. The nth-input node is great for this example, it outputs the selected value from X pins based on the IDX index value. Let the input node IN be the index.IN input-node to the IDX pin.X pins of the nth-input node.Ok, we created nodes that format date and weekday. Time is left to format. Create a patch for the new node and name it format-time. This node will take hours, minutes and seconds from the unpack-datetime node and format them as we desire.

input-number node for the time and name them HOUR, MIN, and SEC.output-string node for the formatted time in a string form.pad-with-zeroes nodes onto the patch and link them with HOUR, MIN, and SEC nodes. To display hours, minutes, and seconds in a two-digit format, put the2value to theWpins as we do it in theformat-date node.join node. Put the : delimiter into the D pin of the join node. Also, you can use the join to set the order in which the time is displayed. Make proper links between the pad-with-zeroes outputs and the join inputs.For the American style clock, we decide to use the 12-hour format instead of 24-hour. For the part of the day, we show the AM and PM words on the display screen.

am-pm node between the HOUR input node and the pad-with-zeroes node. The am-pm changes the hour format from 24 to 12. The AM pin is true if it is “before midday” or false if it is not.if-else node onto the patch and set the AM string value for T, and PM string value for F. Link the COND pin with the AM output of the am-pm node.PM and AM labels with a single space. For this, put another join node onto the patch. Put the spacer character to its delimiter D pin.join with the nodes above and the output node TIME to finish the format-time patch.Format nodes are ready, so let’s put them onto the rtc-example-read patch.

format-date, format-weekday, and format-time nodes, that you’ve just created. Link their inputs to the unpack-datetime outputs.When the date, time, and weekday are formatted we can show them on the I2C display screen. Let’s show the date and the weekday at the first line of the I2C display, and time at the second line.

text-lcd-i2c-16x2 node onto the patch.concat nodes for each line. There we added two spaces to indent the text from the edge of the screen and one space to separate the day of the week from the date.concat node of the date and time with the L1 pin of the text-lcd-16x2-i2c node. The second concat node with the L2 pin.Upload the rtc-example-read patch to your Arduino board and look what the digital clock you get.
If you encounter any problems trying to repeat the guide, download the prepared project and open it in the IDE.
We created a digital clock device using xod/datetime and xod/ds-rtc libraries. Try to make your own clock with different styles and timestamp formats.
If you want to practice, find other usages of these libraries. For example, connect a real-time clock to an SD card, log timestamp values using the format-timestamp node, and have a look how it is easy to process timestamps with the computer applications.