How to Keep Track of the Date and Time on an Arduino

Содержание

How to Keep Track of the Date and Time on an Arduino

In this tutorial, we will discuss the purposes of getting the current date and time on the Arduino, what are the different ways to get the current date/time, what is an Arduino Ethernet shield, and how to get the current time from an NTP server using an Arduino Uno with Ethernet shield.

PCBWay Ad

Why Keep Track of the Date and Time?

Keeping track of the current date and time on an Arduino is really useful for recording and logging sensor data. For example, an Arduino weather station can use the current date and time in recording weather data. Another example is for an Arduino digital clock or calendar. Arduino-based clocks use the current time as a timer to remind or execute a scheduled command via the Arduino’s I/O pins. Depending on the project, having a way to get the actual time is very useful.

How to Get the Correct Date and Time

There are several ways to get the current date and time. We can get it from a Real-Time Clock (RTC), a GPS device, or a time server.

    An RTC is an IC that keeps track of the current date and time data. It has its own battery source to keep the RTC running even if the main power source is off. Computers have built-in RTC devices. A GPS device communicates with satellites to determine its location anywhere in the world. Its GPS data also contains time data.

  1. Time Server A Time Server is a computer on a network that reads the time from some reference clock and distributes it to the network. The clock source of a time server can be another time server, an atomic clock, or a radio clock.

In this tutorial, we will communicate with an internet time server to get the current time.

Network Time Protocol

The most widely used protocol for communicating with time servers is the Network Time Protocol (NTP). NTP is a networking protocol used to synchronize time between computers in a data network. Time servers using NTP are called NTP servers.

NTP Stratum Model

The NTP Stratum Model represents the interconnection of NTP servers in a hierarchical order. Not all NTP servers are directly connected to a reference clock. Some NTP servers are connected to other NTP servers that are directly connected to a reference clock or to another NTP server. See Figure 1.

NTP-Stratum-model

Figure 1: NTP Stratum Model

The NTP Stratum Model starts with Stratum 0 until Stratum 15. Stratum 0, a.k.a. reference clocks are high-precision timekeeping sources like atomic clocks, GPS sources, or radio clocks. Stratum 1 NTP servers connect to a reference clock or to other servers in the same stratum to get the time. On the other hand, Stratum 2 NTP servers connect to one or more Stratum 1 servers or to other servers in the same stratum to get the current time. This way of getting time between NTP servers go on until Stratum 15. There is also a Stratum 16 to indicate that the device is unsynchronized.

Communication via NTP

NTP communication is based on a Client/Server model. An NTP client initiates a communication with an NTP server by sending a request packet. A basic NTP request packet is 48 bytes long. The NTP server then adds its own timestamp to the request packet and sends it back to the client. This timestamp is the number of seconds since the NTP epoch (01 January 1900). To get the UTC time, we subtract the seconds elapsed since the NTP epoch from the timestamp in the packet received.

Getting the Current Date and Time on the Arduino

For this sample project, we will use an Arduino Uno and an Ethernet Shield to request time data from an NTP server and display it on the serial monitor.

The Arduino Ethernet Shield

To reach an NTP server, first, we need to find a way for the Arduino to connect to the internet.

The Ethernet shield will give the Arduino board network connectivity. It has an Ethernet controller IC and can communicate to the Arduino via the SPI pins. Aside from the ethernet circuit, the board also has a microSD card module built-in. Both circuits can be accessed by pulling their respective Chip Select (CS) pin to LOW . The CS pin for the micro-SD card is pin 4.

This shield can be connected to the Arduino in two ways. One way is to simply stack it on top of the Arduino. The second way is to use jumpers and connect the ICSP headers between the boards. If using wires, pin 10 is the Chip Select (CS) pin. For this tutorial, we will just stack the shield on top of the Arduino.

ethernet shield

Figure 2: Arduino Ethernet Shield

Arduino Sketch

For our project, we will use three libraries the SPI library, the Time library, and the Ethernet library.

  • SPI library SPI.h for communicating with the Ethernet Shield
  • Time Library TimeLib.h for updating and displaying the date and time
  • Ethernet library Ethernet.h for connecting the Arduino to the internet or a network

The SPI and Ethernet libraries come pre-installed with the Arduino IDE. To install the Time library, search and install the library “Time” by Michael Margolis from the IDE’s Library Manager. See Figure 2 below as a guide.

arduino-ide-library-manager

Figure 3. Arduino IDE Library Manager

After installing the libraries into the IDE, use keyword #include to add them to our sketch.

Create Global Variables

The next step is to create global variables and objects. Some variables that are worth mentioning here are the byte mac[] , the IPAddress timeSrvr() , and the byte messageBuffer[48] .

The byte array mac[] contains the MAC address that will be assigned for the ethernet shield. This is a unique identifier for the shield in the network.

The IPAddress timeSrvr(address) is used to create an object with data type IPaddress . The parameter address is the IP address you want to be saved to the created IPAddress object.

For our project, we will use one of the NTP servers from https://tf.nist.gov/tf-cgi/servers.cgi. The server IP we will use is 129.6.15.28

The byte array messageBuffer[48] will contain the request and the response message to/from the NTP server.

Initialization Inside the setup() Section

After creating global variables and objects, we will do the following.

  1. Initialize the Arduino serial interface with baud 9600 bps.
  2. Assign a MAC address to the ethernet shield.
  3. Get an IP address for the shield from DHCP.
  4. Set the function setSyncProvider() .
setSyncProvider()

The function setSyncProvider(getTimeFunction) is used by the Time Library to call the getTimeFunction at fixed intervals. In our project, the getTimeFunction is the function that request current time from the NTP server.

After populating the setup() function, we will create code inside loop() to display the current date and time on the Serial Monitor.

User-Defined Functions

To make our code easy to manage, we will create functions to help us in the process of requesting, parsing, and displaying time data from the NTP server.

digitalClockDisplay() and printDigits()

The function digitalClockDisplay() and its helper function printDigits() uses the Time library functions hour() , minute() , second() , day() , month() , and year() to get parts of the time data and send it to the Serial Monitor for display.

Communicating with the NTP Server

To communicate with the NTP server, we first need to send a request packet. We will initialize all 48 bytes to zero by using the function memset() . Then, we will assign values to selected indices of the array to complete a request packet. The helper function sendRequest() handles the creation of the request packet and sends it to the NTP server.

After sending the request, we wait for a response to arrive. The response can be longer than 48 bytes but we will only need the first 48 bytes. As for our code, if no response arrives after 1500 milliseconds, our function will print an error message to the serial monitor and terminate with return 0; .

Once a response packet is received, we call the function ethernet_UDP.parsePacket() . This function returns the number of bytes received and is waiting to be read. If the returned value is 48 bytes or more, we call the function ethernet_UDP.read() to save the first 48 bytes of data received to the array messageBuffer .

The response packet contains a timestamp at byte 40 to 43. This timestamp is the number of seconds elapsed since NTP epoch ( 01 January 1900 ). To get the current UTC time, we just need to subtract the seconds elapsed since the NTP epoch from the timestamp received. The Time library uses this value to calculate the hours, minutes, seconds, day, month, and year in UTC to be displayed to the Serial Monitor.

Save the sketch as Arduino-ethernet-time-tutorial.ino and upload it to your Arduino Uno.

Project Test

The Arduino Uno with Ethernet Shield is set to request the current time from the NTP server and display it to the Serial Monitor. So now, run our project by connecting the ethernet switch to your router via a LAN cable. Finally, connect the Arduino to the computer via USB cable and open the Serial Monitor.

Our project will request the IP from the DHCP, request the current time from the NTP server and display it on the serial monitor. This cycle will repeat every second. Figure 4 shows the display on my serial monitor when I ran this project.

serial-monitor

Figure 4: Serial Monitor

Источник: www.circuitbasics.com