Index
1. Introduction
2. Requirements
3. Problems using the RTC
4. Example
5. Related posts
6. How to create an HTTP Server in an M-Duino PLC
Introduction
With the RTC included by some of the Industrial Shields' PLC families, you can obtain time measurements in the temporary units that we use on a daily basis (Seconds, Minutes, Hours, Days, ...).
The RTCs that the industrial Arduino PLCs from Industrial Shields incorporate are formed by a crystal resonator integrated with the electronics necessary to count the passage of time correctly. RTC electronics take into account the peculiarities of our way of measuring time, such as the sexagesimal system, months with different days, or leap years.
The RTCs provide the advantage of reducing energy consumption, providing greater precision and freeing the PLC CPU from having to perform time counting. In addition, the integrated RTC chips incorporate a lithium battery that keeps the value of time in case of power loss.
Requirements
Industrial Shields' programmable logic controllers (PLCs) with the necessary hardware:
- Ethernet PLC Controller Family >>>
- GPRS & GSM Controller Family >>>
- WiFi & Bluetooth Controller Familiy >>>
Industrial Shields' Boards:
-Â Installing the Industrial Shields Boards in the Arduino IDE (Updated) >>>
Problems using the RTC
 Â
But the use of the RTC has the following problems:
Temperature variations that affect the measurement of the time of the resonator crystals result in errors in a cumulative lag. This causes the RTC to suffer from a temporary lag, which can be about 5-7 seconds a day.
In many countries, there is a practice called DST (daylight saving time), which consists of moving the schedule one hour in summer in comparison with winter.
The RTC is not scheduled to change its current time on the two days of the time change per year.
Synchronizing the RTC with the NTP solves these problems and implies improvements in the following aspects:Â
It is a very accurate matter. Because you can select the best source for synchronization, it has a theoretical resolution in a nanosecond range of 2-32 seconds (that is, 0.233 nanoseconds).
It can solve temporary network connection problems. To do this, the protocol uses the information stored to determine the current time or deviations.
Â
NTP
NTP uses UDP as its transport layer, so we will need to use a UDP port on the sketch.Â
Next, you can see the description of the NTP / SNTP version 4 package format (32 bits), which follows after the IP and UDP headers:
Parts of the package:Â
LI (Leap Indicator)
2-bit code used to indicate that a second will be added/removed at the last minute of this day.
LI Value Operation 00 0 Without modification 01 1 the last minute has 61 seconds 10 2 the last minute has 59 seconds 11 3 alarm condition (clock not synchronized)
VN(Version Number)
3-bit integer indicating the version number. Version 3 indicates version 3 (IPv4 only) and 4 for version 4 (IPv4, IPv6 and OSI). If it is necessary to distinguish between IPv4, IPv6 and OSI, the encapsulated context must be examined.
Mode
Three-bit integer used to indicate the mode, defined as follows:
Mode Operation 0 Reserved 1 symmetric active 2 symmetric passive 3 client 4 server 5 broadcast 6 reserved for NTP control messages 7 reserved for private use
Stratum
It is an unsigned 8-bit integer that indicates the level (stratum) of the local server, the defined values are as follows:
Stratum Significado 0 no especificado o no disponible 1 referencia primaria (ej., radio clock) 2-15 referencia secundaria (vÃa NTP o SNTP) 16-255 reservado
Poll Interval
It is a signed 8-bit integer that indicates the maximum time interval between two successive messages, expressed in seconds and as the nearest 2 power. Most applications use the range from 6 bits (64 ") to 10 (1024")
Precision
It is a signed integer that indicates the accuracy of the local clock expressed in seconds at the nearest 2 power.
Example
In this example, we are connecting through the es.ntp.pool.org NTP server (NTP Server in Spain). You can search for a public NTP Server in your country by following this link
/*Copyright (c) 2019 Boot&Work Corp., S.L. All rights reservedThis program is free software: you can redistribute it and/or modifyit under the terms of the GNU Lesser General Public License as publishedthe Free Software Foundation, either version 3 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU Lesser General Public License for more details.You should have received a copy of the GNU Lesser General Public Licensealong with this program. If not, see <http://www.gnu.org/licenses/>.*/ Â #include <Ethernet.h> Â #include <RTC.h> uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(10, 10, 10, 6); IPAddress nameServer(8, 8, 8, 8); IPAddress gateway(10, 10, 10, 1); IPAddress netmask(255, 255, 255, 0); IPAddress server(147, 156, 7, 26); // es.ntp.pool.org unsigned int udpPort = 2390; EthernetUDP udp; const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets //////////////////////////////////////////////////////////////////////////////////////////////////// void setup() { Serial.begin(9600L); Ethernet.begin(mac, ip, nameServer, gateway, netmask); Serial.print("IP address: "); Serial.println(Ethernet.localIP()); udp.begin(udpPort); Serial.println("rtc-from-ntp started"); sendRequest(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void loop() { if (udp.parsePacket()) { udp.read(packetBuffer, NTP_PACKET_SIZE); unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); unsigned long secsSince1900 = highWord << 16 | lowWord; const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; Serial.print("timestamp: "); Serial.println(epoch); RTC.setTime(epoch); RTC.write(); char datetime[50]; sprintf(datetime, "%04d-%02d-%02d %02d:%02d:%02d", RTC.getYear(), RTC.getMonth(), RTC.getMonthDay(), RTC.getHour(), RTC.getMinute(), RTC.getSecond()); Serial.print("time: "); Serial.println(datetime); } delay(1); } //////////////////////////////////////////////////////////////////////////////////////////////////// unsigned long sendRequest() { memset(packetBuffer, 0, NTP_PACKET_SIZE); packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; Serial.println("Send request"); if (!udp.beginPacket(server, 123)) { Serial.println("Begin packet error"); } else { udp.write(packetBuffer, NTP_PACKET_SIZE); if (!udp.endPacket()) { Serial.println("End packet error"); } } }
Sync RTC clock with NTP Server (PLC Arduino)