Descripción general de RTC
Este wiki presenta cómo usar la funcionalidad RTC integrada dentro del núcleo SAMD51 en Wio Terminal para que puedas hacer seguimiento del tiempo. ¡Esta característica te ahorra tener que agregar un módulo RTC externo al sistema!
Instalación de la librería Seeed_Arduino_RTC para Wio Terminal
-
Visita los repositorios de Seeed_Arduino_RTC y descarga todo el repositorio a tu unidad local.
-
Ahora, la librería Seeed_Arduino_RTC puede ser instalada en el IDE de Arduino. Abre el IDE de Arduino, y haz clic en
sketch
->Include Library
->Add .ZIP Library
, y elige el archivoSeeed_Arduino_RTC
que acabas de descargar.
Código de ejemplo
El siguiente código es el uso básico de la librería RTC para SAMD51:
Para más referencia de la API, por favor revisa aquí
#include "RTC_SAMD51.h"
#include "DateTime.h"
RTC_SAMD51 rtc;
void setup()
{
rtc.begin();
Serial.begin(115200);
while (!Serial)
{
;
}
DateTime now = DateTime(F(__DATE__), F(__TIME__));
Serial.println("adjust time!");
rtc.adjust(now);
now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
DateTime alarm = DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second() + 15);
rtc.setAlarm(0,alarm); // match after 15 seconds
rtc.enableAlarm(0, rtc.MATCH_HHMMSS); // match Every Day
rtc.attachInterrupt(alarmMatch); // callback whlie alarm is match
}
void loop()
{
}
void alarmMatch(uint32_t flag)
{
Serial.println("Alarm Match!");
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
}
Uso Avanzado de RTC
También puedes usar NTP para obtener la hora para el RTC.
- Para esta demostración, primero debes revisar la wiki de Red de Wio Terminal.
Librerías dependientes
-
Librerías relacionadas con la red de Wio Terminal
#include <AtWiFi.h>
#include <millisDelay.h>
#include <Wire.h>
#include "RTC_SAMD51.h"
#include "DateTime.h"
const char ssid[] = "Your-network"; // add your required ssid
const char password[] = "Your-password"; // add your own netywork password
millisDelay updateDelay; // the update delay object. used for ntp periodic update.
unsigned int localPort = 2390; // local port to listen for UDP packets
// switch between local and remote time servers
// comment out to use remote server
//#define USELOCALNTP
#ifdef USELOCALNTP
char timeServer[] = "n.n.n.n"; // local NTP server
#else
char timeServer[] = "time.nist.gov"; // extenral NTP server e.g. time.nist.gov
#endif
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
// declare a time object
DateTime now;
// define WiFI client
WiFiClient client;
//The udp library class
WiFiUDP udp;
// localtime
unsigned long devicetime;
RTC_SAMD51 rtc;
// for use by the Adafuit RTClib library
char daysOfTheWeek[7][12] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
void setup() {
Serial.begin(115200);
while (!Serial); // wait for serial port to connect. Needed for native USB
// setup network before rtc check
connectToWiFi(ssid, password);
// get the time via NTP (udp) call to time server
// getNTPtime returns epoch UTC time adjusted for timezone but not daylight savings
// time
devicetime = getNTPtime();
// check if rtc present
if (devicetime == 0) {
Serial.println("Failed to get time from network time server.");
}
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1) delay(10); // stop operating
}
// get and print the current rtc time
now = rtc.now();
Serial.print("RTC time is: ");
Serial.println(now.timestamp(DateTime::TIMESTAMP_FULL));
// adjust time using ntp time
rtc.adjust(DateTime(devicetime));
// print boot update details
Serial.println("RTC (boot) time updated.");
// get and print the adjusted rtc time
now = rtc.now();
Serial.print("Adjusted RTC (boot) time is: ");
Serial.println(now.timestamp(DateTime::TIMESTAMP_FULL));
// start millisdelays timers as required, adjust to suit requirements
updateDelay.start(12 * 60 * 60 * 1000); // update time via ntp every 12 hrs
}
void loop() {
if (updateDelay.justFinished()) { // 12 hour loop
// repeat timer
updateDelay.repeat(); // repeat
// update rtc time
devicetime = getNTPtime();
if (devicetime == 0) {
Serial.println("Failed to get time from network time server.");
}
else {
rtc.adjust(DateTime(devicetime));
Serial.println("");
Serial.println("rtc time updated.");
// get and print the adjusted rtc time
now = rtc.now();
Serial.print("Adjusted RTC time is: ");
Serial.println(now.timestamp(DateTime::TIMESTAMP_FULL));
}
}
}
void connectToWiFi(const char* ssid, const char* pwd) {
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
Serial.println("Waiting for WIFI connection...");
//Initiate connection
WiFi.begin(ssid, pwd);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.println("Connected.");
printWifiStatus();
}
unsigned long getNTPtime() {
// module returns a unsigned long time valus as secs since Jan 1, 1970
// unix time or 0 if a problem encounted
//only send data when connected
if (WiFi.status() == WL_CONNECTED) {
//initializes the UDP state
//This initializes the transfer buffer
udp.begin(WiFi.localIP(), localPort);
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("udp packet received");
Serial.println("");
// We've received a packet, read the data from it
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;
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
// adjust time for timezone offset in secs +/- from UTC
// WA time offset from UTC is +8 hours (28,800 secs)
// + East of GMT
// - West of GMT
long tzOffset = 28800UL;
// WA local time
unsigned long adjustedTime;
return adjustedTime = epoch + tzOffset;
}
else {
// were not able to parse the udp packet successfully
// clear down the udp connection
udp.stop();
return 0; // zero indicates a failure
}
// not calling ntp time frequently, stop releases resources
udp.stop();
}
else {
// network not connected
return 0;
}
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(const char* address) {
// set all bytes in the buffer to 0
for (int i = 0; i < NTP_PACKET_SIZE; ++i) {
packetBuffer[i] = 0;
}
// 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();
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.println("");
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
Serial.println("");
}