RTC - REAL TIME CLOCK
RTC (Real Time Clock – Reloj en Tiempo Real) es una clase de la librería machine de MicroPython.
Una clase es una forma de empaquetar datos y funcionalidad juntos. En este caso se empaquetan las funciones relativas al RTC (init(), datetime() y memory()).
En el siguiente script se conecta el microprocesador ESP32 con una red WiFi local, para sincronizar su reloj interno con el del servidor pool.ntp.org.
Para ello se utiliza la función settime() de la librería ntptime que implementa el Network Time Protocol (NTP), que es el protocolo de Internet para sincronizar los relojes de los sistemas informáticos.
En el script se realiza también la corrección entre la hora local del servidor y hora local de la ubicación del microprocesador (España). En este caso GMT+2.
SCRIPT
# FUNCIÓN PARA ESTABLECER LA CONEXIÓN WIFI (STATION) def do_connect(SSID, PASSWORD): import network # importa el módulo network global sta_if sta_if = network.WLAN(network.STA_IF) # instancia el objeto -sta_if- para realizar la conexión en modo STA if not sta_if.isconnected(): # si no existe conexión... sta_if.active(True) # activa el interfaz STA del ESP32 sta_if.connect(SSID, PASSWORD) # inicia la conexión con el AP print('Conectando a la red', SSID +"...") while not sta_if.isconnected(): # ...si no se ha establecido la conexión... pass # ...repite el bucle... print('Configuración de red (IP/netmask/gw/DNS):', sta_if.ifconfig()) # do_connect("<nombre_de_red>","<clave_de_red>") # DESCOMENTAR Y PONER nombre/clave_de_red RED PARA EJECUTAR #____________________________________________________________________________________________________________ # OBTENCIÓN DESDE INTERNET DE NTP - NETWORK TIME PROTOCOL import ntptime #NTP-time (obtenida desde pool.ntp.org) ntptime.settime() #https://github.com/micropython/micropython/blob/master/ports/esp8266/modules/ntptime.py #____________________________________________________________________________________________________________ # SINCRONIZACIÓN DEL RELOJ INTERNO E IMPRESIÓN DE FECHA Y HORA from machine import RTC (year, month, mday, weekday, hour, minute, second, milisecond)=RTC().datetime() RTC().init((year, month, mday, weekday, hour+2, minute, second, milisecond)) # GMT corrección -ESPAÑA-: GMT+2 (verano) o GMT+1 (invierno) print ("Fecha: {:02d}/{:02d}/{}".format(RTC().datetime()[2], RTC().datetime()[1], RTC().datetime()[0])) print ("Hora: {:02d}:{:02d}:{:02d}".format(RTC().datetime()[4], RTC().datetime()[5], RTC().datetime()[6]))
Así se verá la ejecución del script con Thonny:
RELOJ CON HORARIO DE INVIERNO/VERANO AUTOMATIZADO -ESPAÑA-
import network, socket, struct, utime from machine import RTC # FUNCIÓN PARA ESTABLECER LA CONEXIÓN WIFI (STATION) def do_connect(SSID, PASSWORD): global sta_if sta_if = network.WLAN(network.STA_IF) # Instancia el objeto -sta_if- para realizar la conexión en modo STA if not sta_if.isconnected(): # Si no existe conexión... sta_if.active(True) # ...activa el interfaz STA del ESP32 sta_if.connect(SSID, PASSWORD) # ...inicia la conexión con el AP print('Conectando a la red', SSID +"...") while not sta_if.isconnected(): # ...si no se ha establecido la conexión... pass # ...repite el bucle... #____________________________________________________________________________________________________________________ ''' Network Time Protocol (NTP) es un protocolo de Internet para sincronizar los relojes de los sistemas informáticos a través del enrutamiento de paquetes en redes con latencia variable. NTP utiliza UDP como su capa de transporte, usando el puerto 123. EPOCH es una magnitud que da a la fecha en un valor numérico expresado en segundos contando desde una fecha de referencia. ''' host = "hora.roa.es" # El servidor proporciona el EPOCH con referencia a 1900-01-01 00:00:00 UTC (Coordinated Universal Time) NTP_DELTA = 3155673600 # El RTC (Real Time Clock) del microcontrolador utiliza el EPOCH con referencia a 2000-01-01. Es preciso corregirlo. # (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60 = 3155673600 def time(): # Función para obtener el EPOCH del servidor NTP_QUERY = bytearray(48) NTP_QUERY[0] = 0x1B addr = socket.getaddrinfo(host, 123)[0][-1] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.settimeout(1) res = s.sendto(NTP_QUERY, addr) msg = s.recv(48) finally: s.close() val = struct.unpack("!I", msg[40:44])[0] return val - NTP_DELTA def settime(): # Función para sincronizar el RTC t = time() tm = utime.localtime(t) # Conversión de hora de EPOCH a fecha: año[0], mes[1], día[2], hora[3], minuto[4], segundo[5], díaDeLaSemana[6], díaDelAño[8] def sec_lastSundayMonth_1hUTC (month): # Función para conocer el EPOCH de la 01:00:00 UTC del último domingo de un mes de 31 días y poder corregir la hora UTC con la oficial de España sw = (tm[0], month, 31, 1, 0, 0, 0, 0, 0) # El cambio de hora en ESPAÑA se hace los últimos domingos de los meses de marzo y octubre a la 01:00:00 UTC sw_secs = utime.mktime(sw) # Horario de verano UTC+2 - horario de invierno UTC+1 swm = utime.localtime(sw_secs) weekday_swm = swm[6] if swm[6] != 6: sw = (tm[0], month, 31-(swm[6] + 1), 1, 0, 0, 0, 0, 0) sw_secs = utime.mktime(sw) return sw_secs if sec_lastSundayMonth_1hUTC (3) <= t < sec_lastSundayMonth_1hUTC (10):# Sincronización con el RTC: año[0], mes[1], día[2], díaDeLaSemana[3], hora[4], minuto[5], segundo[6], subsegundo[7] RTC().datetime((tm[0], tm[1], tm[2], 0, tm[3]+2, tm[4], tm[5], 0)) # Horario de verano subsegundo -> cuenta atras de 255 a 0 else: RTC().datetime((tm[0], tm[1], tm[2], 0, tm[3]+1, tm[4], tm[5], 0)) # Horario de invierno #____________________________________________________________________________________________________________________ # do_connect("<nombre_de_red>","<clave_de_red>") # DESCOMENTAR Y PONER nombre/clave_de_red RED PARA EJECUTAR settime() print ("Fecha: {:02d}/{:02d}/{}".format(RTC().datetime()[2], RTC().datetime()[1], RTC().datetime()[0])) print ("Hora: {:02d}:{:02d}:{:02d}".format(RTC().datetime()[4], RTC().datetime()[5], RTC().datetime()[6]))
1 Comment
Leave your reply.