You've already forked TEF6686_ESP32
Added NTP time (overrules RDS CT)
This commit is contained in:
@@ -1,58 +1,84 @@
|
||||
#include "NTPupdate.h"
|
||||
|
||||
// send an NTP request to the time server at the given address
|
||||
// Sends an NTP request packet to the specified server address
|
||||
void sendNTPpacket(IPAddress &address) {
|
||||
byte packetBuffer[NTP_PACKET_SIZE];
|
||||
// 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
|
||||
byte packetBuffer[NTP_PACKET_SIZE] = {0}; // Initialize buffer with zeros
|
||||
|
||||
// Set NTP packet header fields as per NTP protocol
|
||||
packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||
packetBuffer[2] = 6; // Polling interval
|
||||
packetBuffer[3] = 0xEC; // Peer clock precision
|
||||
|
||||
// Root Delay & Root Dispersion fields
|
||||
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
|
||||
|
||||
// Send the NTP request to port 123 (NTP standard port)
|
||||
Udp.beginPacket(address, 123);
|
||||
Udp.write(packetBuffer, NTP_PACKET_SIZE);
|
||||
Udp.endPacket();
|
||||
}
|
||||
|
||||
// Retrieves the current time from an NTP server
|
||||
time_t getNtpTime() {
|
||||
IPAddress ntpServerIP; // NTP server's ip address
|
||||
IPAddress ntpServerIP;
|
||||
byte packetBuffer[NTP_PACKET_SIZE];
|
||||
|
||||
while (Udp.parsePacket() > 0) ; // discard any previously received packets
|
||||
WiFi.hostByName(ntpServerName, ntpServerIP);
|
||||
// Clear any previously received UDP packets
|
||||
while (Udp.parsePacket() > 0);
|
||||
|
||||
// Resolve the NTP server's hostname to its IP address
|
||||
if (!WiFi.hostByName(ntpServerName, ntpServerIP)) {
|
||||
return 0; // Return 0 if hostname resolution fails
|
||||
}
|
||||
|
||||
// Send an NTP request
|
||||
sendNTPpacket(ntpServerIP);
|
||||
uint32_t beginWait = millis();
|
||||
while (millis() - beginWait < 1500) {
|
||||
int size = Udp.parsePacket();
|
||||
if (size >= NTP_PACKET_SIZE) {
|
||||
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
|
||||
unsigned long secsSince1900;
|
||||
// convert four bytes starting at location 40 to a long integer
|
||||
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
|
||||
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
|
||||
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
|
||||
secsSince1900 |= (unsigned long)packetBuffer[43];
|
||||
|
||||
// Wait for a response with a 1500ms timeout
|
||||
uint32_t startWait = millis();
|
||||
while (millis() - startWait < 1500) {
|
||||
if (Udp.parsePacket() >= NTP_PACKET_SIZE) { // Check if a valid packet is received
|
||||
Udp.read(packetBuffer, NTP_PACKET_SIZE);
|
||||
|
||||
// Extract "seconds since 1900" from the packet (bytes 40-43)
|
||||
unsigned long secsSince1900 =
|
||||
((unsigned long)packetBuffer[40] << 24) |
|
||||
((unsigned long)packetBuffer[41] << 16) |
|
||||
((unsigned long)packetBuffer[42] << 8) |
|
||||
(unsigned long)packetBuffer[43];
|
||||
|
||||
// Convert to UNIX epoch time (seconds since 1970)
|
||||
return secsSince1900 - 2208988800UL;
|
||||
}
|
||||
}
|
||||
return 0; // return 0 if unable to get the time
|
||||
|
||||
// Return 0 if no valid response is received
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Updates the RTC with the time from an NTP server
|
||||
void NTPupdate() {
|
||||
if (!wifi) { return; }
|
||||
time_t time = getNtpTime();
|
||||
if (time) {
|
||||
rtc.setTime(time);
|
||||
// Abort if Wi-Fi is not connected
|
||||
if (!wifi) {
|
||||
NTPupdated = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the current time from the NTP server
|
||||
time_t currentTime = getNtpTime();
|
||||
|
||||
if (currentTime) {
|
||||
// Set the RTC if valid time is received
|
||||
rtc.setTime(currentTime);
|
||||
rtcset = true;
|
||||
NTPupdated = true;
|
||||
radio.rds.ctupdate = false;
|
||||
} else {
|
||||
// Indicate that the update failed
|
||||
NTPupdated = false;
|
||||
radio.rds.ctupdate = true;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <WiFiUdp.h>
|
||||
#include <ESP32Time.h>
|
||||
#include <TimeLib.h>
|
||||
#include "TEF6686.h"
|
||||
|
||||
static const char ntpServerName[] = "0.pool.ntp.org";
|
||||
static const int localPort = 8944;
|
||||
@@ -15,7 +16,11 @@ const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
|
||||
extern ESP32Time rtc;
|
||||
extern WiFiClient RemoteClient;
|
||||
extern WiFiUDP Udp;
|
||||
extern TEF6686 radio;
|
||||
|
||||
extern bool wifi;
|
||||
extern bool NTPupdated;
|
||||
extern bool rtcset;
|
||||
|
||||
void sendNTPpacket(IPAddress &address);
|
||||
void NTPupdate();
|
||||
|
||||
@@ -1340,7 +1340,7 @@ void TEF6686::readRDS(byte showrdserrors) {
|
||||
} break;
|
||||
|
||||
case RDS_GROUP_4A: {
|
||||
if (!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold) {
|
||||
if (!rdsBerrorThreshold && !rdsCerrorThreshold && !rdsDerrorThreshold && rds.ctupdate) {
|
||||
// CT
|
||||
uint32_t mjd;
|
||||
mjd = (rds.rdsB & 0x03);
|
||||
|
||||
@@ -621,6 +621,7 @@ typedef struct _rds_ {
|
||||
bool filter;
|
||||
bool rdsreset;
|
||||
bool pierrors;
|
||||
bool ctupdate = true;
|
||||
bool sortaf;
|
||||
bool rtbuffer = true;
|
||||
bool afreg;
|
||||
|
||||
@@ -912,6 +912,7 @@ void tryWiFi() {
|
||||
Server.begin();
|
||||
Udp.begin(9031);
|
||||
webserver.begin();
|
||||
NTPupdate();
|
||||
remoteip = IPAddress (WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], subnetclient);
|
||||
if (!setupmode) tftPrint(0, myLanguage[language][57], 155, 128, InsignificantColor, InsignificantColorSmooth, 28);
|
||||
} else {
|
||||
|
||||
@@ -149,4 +149,5 @@ extern void ShowStepSize();
|
||||
extern void startFMDXScan();
|
||||
extern void cancelDXScan();
|
||||
extern void printLogbookCSV();
|
||||
extern void NTPupdate();
|
||||
#endif
|
||||
141
src/rds.cpp
141
src/rds.cpp
@@ -787,89 +787,70 @@ void showCT() {
|
||||
char str[6];
|
||||
time_t t;
|
||||
|
||||
// Check if screen is not muted and the clock should be displayed
|
||||
if (!screenmute && showclock) {
|
||||
// Determine the current time source
|
||||
if (radio.rds.hasCT && !dropout && !NTPupdated) {
|
||||
t = radio.rds.time + radio.rds.offset;
|
||||
} else {
|
||||
t = rtc.getEpoch() + (NTPupdated ? 0 : radio.rds.offset);
|
||||
|
||||
// If RDS CT (Clock Time) is available and no dropout, use RDS time
|
||||
if (radio.rds.hasCT && !dropout) {
|
||||
t = radio.rds.time + radio.rds.offset;
|
||||
// Update RDS time during dropout
|
||||
if (dropout) {
|
||||
radio.rds.time = static_cast<time_t>(rtc.getEpoch());
|
||||
}
|
||||
// If no RDS CT or there is a dropout, fall back to RTC time
|
||||
else {
|
||||
t = rtc.getEpoch() + radio.rds.offset;
|
||||
|
||||
// Update RDS time in case of dropout
|
||||
if (dropout) {
|
||||
radio.rds.time = static_cast<time_t>(rtc.getEpoch());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if USA region, use 12-hour AM/PM format
|
||||
if (radio.rds.region == 1) {
|
||||
// Format time in 24-hour format first
|
||||
strftime(str, sizeof(str), "%I:%M", localtime(&t));
|
||||
|
||||
// Manually determine AM/PM and add it
|
||||
int hour = localtime(&t)->tm_hour;
|
||||
String ampm = (hour >= 12) ? "PM" : "AM";
|
||||
|
||||
// Adjust the hour to 12-hour format, taking care of 12 AM and 12 PM
|
||||
if (hour == 0) {
|
||||
hour = 12; // Midnight case
|
||||
} else if (hour > 12) {
|
||||
hour -= 12; // Convert PM to 12-hour format
|
||||
}
|
||||
|
||||
// Construct the final time string manually
|
||||
rds_clock = String(hour) + ":" + String(localtime(&t)->tm_min) + " " + ampm;
|
||||
} else {
|
||||
// For other regions, use 24-hour format
|
||||
strftime(str, sizeof(str), "%H:%M", localtime(&t));
|
||||
rds_clock = String(str);
|
||||
}
|
||||
|
||||
// If the clock has changed or RDS CT status has changed, update the display
|
||||
if (rds_clock != rds_clockold || hasCTold != radio.rds.hasCT) {
|
||||
|
||||
// If RDS CT is available and RDS status is active, set RTC time
|
||||
if (radio.rds.hasCT && RDSstatus) {
|
||||
rtcset = true;
|
||||
rtc.setTime(radio.rds.time);
|
||||
|
||||
// Display the new time with different coordinates based on advancedRDS setting
|
||||
if (advancedRDS) {
|
||||
tftReplace(1, rds_clockold, rds_clock, 208, 109, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||
} else {
|
||||
tftReplace(1, rds_clockold, rds_clock, 208, 163, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||
}
|
||||
}
|
||||
// If no RDS CT available or status is inactive, handle dropout scenarios
|
||||
else {
|
||||
// If RTC was previously set, show dropout message
|
||||
if (rtcset) {
|
||||
if (advancedRDS) {
|
||||
tftReplace(1, rds_clockold, rds_clock, 208, 109, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
||||
} else {
|
||||
tftReplace(1, rds_clockold, rds_clock, 208, 163, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
||||
}
|
||||
}
|
||||
// If RTC is not set, just print the clock with no background (clear the display)
|
||||
else {
|
||||
if (advancedRDS) {
|
||||
tftPrint(1, rds_clockold, 208, 109, BackgroundColor, BackgroundColor, 16);
|
||||
tftPrint(1, rds_clock, 208, 109, BackgroundColor, BackgroundColor, 16);
|
||||
} else {
|
||||
tftPrint(1, rds_clockold, 208, 163, BackgroundColor, BackgroundColor, 16);
|
||||
tftPrint(1, rds_clock, 208, 163, BackgroundColor, BackgroundColor, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the previous clock and RDS CT status to detect future changes
|
||||
rds_clockold = rds_clock;
|
||||
hasCTold = radio.rds.hasCT;
|
||||
}
|
||||
|
||||
// Apply the GMT offset only if NTPupdated is true
|
||||
if (NTPupdated) {
|
||||
t += NTPoffset * 3600; // Convert offset from hours to seconds
|
||||
}
|
||||
|
||||
// Format the time based on region
|
||||
if (radio.rds.region == 1) { // USA region: 12-hour AM/PM format
|
||||
strftime(str, sizeof(str), "%I:%M", localtime(&t));
|
||||
|
||||
// Determine AM/PM and adjust hour format
|
||||
int hour = localtime(&t)->tm_hour;
|
||||
String ampm = (hour >= 12) ? "PM" : "AM";
|
||||
if (hour == 0) {
|
||||
hour = 12; // Midnight case
|
||||
} else if (hour > 12) {
|
||||
hour -= 12; // Convert PM hours
|
||||
}
|
||||
|
||||
rds_clock = String(hour) + ":" + String(localtime(&t)->tm_min) + " " + ampm;
|
||||
} else { // Other regions: 24-hour format
|
||||
strftime(str, sizeof(str), "%H:%M", localtime(&t));
|
||||
rds_clock = String(str);
|
||||
}
|
||||
|
||||
// Check if the clock or RDS CT status has changed
|
||||
if (!screenmute && showclock && (rds_clock != rds_clockold || hasCTold != radio.rds.hasCT)) {
|
||||
|
||||
// Update RTC if RDS CT is available or NTP was updated
|
||||
if ((radio.rds.hasCT && RDSstatus) || NTPupdated) {
|
||||
rtcset = true;
|
||||
if (!NTPupdated) {
|
||||
rtc.setTime(radio.rds.time);
|
||||
}
|
||||
|
||||
// Display the updated time
|
||||
int yCoord = advancedRDS ? 109 : 163;
|
||||
tftReplace(1, rds_clockold, rds_clock, 208, yCoord, RDSColor, RDSColorSmooth, BackgroundColor, 16);
|
||||
} else { // Handle dropout scenarios
|
||||
int yCoord = advancedRDS ? 109 : 163;
|
||||
|
||||
if (rtcset) { // Display dropout message if RTC was set
|
||||
tftReplace(1, rds_clockold, rds_clock, 208, yCoord, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16);
|
||||
} else { // Clear and reprint the clock
|
||||
tftPrint(1, rds_clockold, 208, yCoord, BackgroundColor, BackgroundColor, 16);
|
||||
tftPrint(1, rds_clock, 208, yCoord, BackgroundColor, BackgroundColor, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update previous clock and RDS CT status
|
||||
rds_clockold = rds_clock;
|
||||
hasCTold = radio.rds.hasCT;
|
||||
}
|
||||
|
||||
void showRadioText() {
|
||||
|
||||
@@ -26,6 +26,7 @@ extern bool haseonold;
|
||||
extern bool hasrtplusold;
|
||||
extern bool hastmcold;
|
||||
extern bool memreset;
|
||||
extern bool NTPupdated;
|
||||
extern bool rdsreset;
|
||||
extern bool RDSSPYTCP;
|
||||
extern bool RDSSPYUSB;
|
||||
@@ -51,6 +52,7 @@ extern byte ECCold;
|
||||
extern byte language;
|
||||
extern byte licold;
|
||||
extern byte MSold;
|
||||
extern byte NTPoffset;
|
||||
extern byte eonptyold[20];
|
||||
extern byte rdsblockold;
|
||||
extern byte rdsqualityold;
|
||||
|
||||
Reference in New Issue
Block a user