Skip to content

Use library for NTP data handling #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 24, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 11 additions & 71 deletions libraries/RTC/examples/RTC_NTPSync/RTC_NTPSync.ino
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
* Then the current time from the RTC is printed to the Serial port.
*
* Instructions:
* 1. Change the WiFi credentials in the arduino_secrets.h file to match your WiFi network.
* 2. Upload this sketch to Portenta C33 / UNO R4 WiFi.
* 3. Open the Serial Monitor.
* 1. Download the NTPClient library (https://github.com/arduino-libraries/NTPClient) through the Library Manager
* 2. Change the WiFi credentials in the arduino_secrets.h file to match your WiFi network.
* 3. Upload this sketch to Portenta C33 / UNO R4 WiFi.
* 4. Open the Serial Monitor.
*
* Initial author: Sebastian Romero @sebromero
*/

#include "RTC.h"
#include <NTPClient.h>

#if defined(ARDUINO_PORTENTA_C33)
#include <WiFiC3.h>
Expand All @@ -26,36 +28,9 @@
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)

constexpr unsigned int LOCAL_PORT = 2390; // local port to listen for UDP packets
constexpr int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message

int wifiStatus = WL_IDLE_STATUS;
IPAddress timeServer(162, 159, 200, 123); // pool.ntp.org NTP server
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
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
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;

// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
NTPClient timeClient(Udp);

void printWifiStatus() {
// print the SSID of the network you're attached to:
Expand Down Expand Up @@ -102,56 +77,21 @@ void connectToWiFi(){
printWifiStatus();
}

/**
* Calculates the current unix time, that is the time in seconds since Jan 1 1970.
* It will try to get the time from the NTP server up to `maxTries` times,
* then convert it to Unix time and return it.
* You can optionally specify a time zone offset in hours that can be positive or negative.
*/
unsigned long getUnixTime(int8_t timeZoneOffsetHours = 0, uint8_t maxTries = 5){
// Try up to `maxTries` times to get a timestamp from the NTP server, then give up.
for (size_t i = 0; i < maxTries; i++){
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);

if (Udp.parsePacket()) {
Serial.println("packet received");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

//the timestamp starts at byte 40 of the received packet and is four bytes,
//or two words, long. First, extract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);

// Combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;

// Now convert NTP time into everyday time:
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
unsigned long secondsSince1970 = secsSince1900 - seventyYears + (timeZoneOffsetHours * 3600);
return secondsSince1970;
}
}

return 0;
}

void setup(){
Serial.begin(9600);
while (!Serial);

connectToWiFi();
Serial.println("\nStarting connection to server...");
Udp.begin(LOCAL_PORT);
RTC.begin();
Serial.println("\nStarting connection to server...");
timeClient.begin();
timeClient.update();

// Get the current date and time from an NTP server and convert
// it to UTC +2 by passing the time zone offset in hours.
// You may change the time zone offset to your local one.
auto unixTime = getUnixTime(2);
auto timeZoneOffsetHours = 2;
auto unixTime = timeClient.getEpochTime() + (timeZoneOffsetHours * 3600);
Serial.print("Unix time = ");
Serial.println(unixTime);
RTCTime timeToSet = RTCTime(unixTime);
Expand Down