Justo este pasado fin de semana Europa ha comenzado la hora de verano. Todos tuvieron que reajustar sus relojes, pero ¿qué pasa con el microcontrolador? Muchos programas en el arduino y otros microcontroladores mantienen el tiempo y hacen que con uno de lo RTC popular chips como el DS1307 o el DS3231. Mantienen muy bien el tiempo (pero prefiero el DS3231) y hay un alzamiento de bibliotecas disponibles para ellos. Una cosa que no es cambiar automáticamente entre hora y hora de verano (DST). Obviamente sería muy difícil ya que existen diferentes condiciones de DST en todo el mundo
Aunque uno podría por supuesto restablecer el chip RTC manualmente dos veces al año pero eso es tedioso, especialmente cuando se puede solucionar fácilmente con unas pocas líneas de código.
Diferentes partes del mundo tienen diferentes reglas para cuando ocurre el horario y muchos países no tienen por supuesto ningún horario: sólo tiene sentido (si en absoluto) para hacerlo entre los trópicos y los círculos árticos, así que de hecho entre el Trópico de cáncer y el círculo polar ártico y el Trópico de Capricornio y el círculo polar antártico.
En Australia el horario es una cuestión de los Estados y territorios, pero en general el horario es entre el primer domingo de octubre y el primer domingo de abril (Recuerde que es bajo)
En Canadá en gran parte depende de donde vives, algunos Estados siguen los Estados Unidos. En Newfoundland Nunavut tiene su propia regla y muchos de los territorios del Norte no tienen horario
Los E.e.u.u. tiene horario del 2 º domingo de marzo hasta el primer domingo de noviembre.
La EU por supuesto tiene una guía que determina la hora de verano comience el último domingo de marzo y terminan el último domingo de octubre. En la UE la hora para cambiar es a las 1:00 UTC. En la práctica el UTC es igual a GMT (Greenwich Mean Time). UTC sí mismo no es una abreviatura sino un compromiso entre la abreviatura francesa "TUC" y la inglesa "CUT" (Temps Universel Coordonné resp tiempo Universal coordinado).
Catering para su programa de ahorro de luz local suele ser bastante fácil: dejar que el programa busque el mes correcto y luego contar el número del domingos (el cambio es generalmente el domingo). Cuando llegaron al domingo verificar la hora y si es decir 2:00, adelantar el reloj una hora (= set de 3) si el DST tiene que iniciar, o esperar hasta el 3:00 y restablecer las horas reloj a '2'. Obviamente también debe establecer una bandera para hacer la corrección de reloj sólo una vez.
Bastante simple... A menos que usted vive en la UE (o Nunavut). En la Unión Europea el cambio no es hecho en el primer, segundo, tercer o cuarto domingo de marzo y octubre, pero en el último domingo del mes.
¿Bien, un mes tiene derecho cuatro domingos? Mal. Si por ejemplo octubre comienza un el viernes, el sábado o el domingo, tiene 5 domingos. ¿Qué hacer? Bien por supuesto podría determinar si el primer día comienza el viernes, el sábado o el domingo y si es así, contar hasta 5 y en caso contrario la cuenta a 4. Pero hay una manera más simple, en que aún no se tiene que contar.
Deja de poner eso en un programa para Europa occidental, lo que significa que los tiempos de interruptor son 2 y 3:00 (que es 1:00 UTC)
Pongámonos de acuerdo que tienes un RTC que mantendrá el "día de la semana" (como el DS1307 y el DS3231). Como establece estos mismo permite de acuerdo en que ha definido el día de la semana que el lunes es día 1 y el domingo día 7. Algunas personas les gusta comenzar la semana el domingo, pero eso es sólo una cuestión de gusto. De todas formas, tenemos las siguientes variables de la RTC
Dow = día de la semana (como en 1-7)
mo = mes
d = día (como en el 1-31)
h = hora
DST es una bandera que ponemos cuando DST comienza y que tenemos claro el final de DST para evitar que el programa Inicie corrigiendo el tiempo de una hora y que incluso en un bucle sin fin cuando el reloj vuelve como octubre tiene 31 días, sabemos que el domingo pasado siempre caerá de la 25 a la 31 así nuestro cheque al final del día ahorro será como sigue :
if (dow == 7 && mo == 10 && d >= 25 && h == 3 && DST==1)
{
setclockto 2 am;
DST=0;//store this in your NVRAM
}
Como usted puede ser el comando bibliotecas diferentes ' setclockto 2:00 ' es sólo un marcador de posición para su rutina específica para establecer su RTC a 2:00. Aconsejaría para almacenar en algún lugar la bandera de DST en memoria no volátil, en el caso de usted necesita desconectar su arduino. El DS1307 tiene algunas en el chip no volátil Espolón donde puede guardarlo, no el DS3231. Ambos sin embargo generalmente vienen como un módulo con una EEPROM en él, lo contrario que del EEPROM del Arduino puede ser utilizado.
De todos modos permite hacer una verificación si tenemos la rutina correcta: Supongamos que el 1 de octubre es domingo. Eso significa que el 25 es un miércoles y el día 29 un domingo (el domingo pasado y 5 º), por lo que la rutina de hecho se activará el día 29 que se cumplan todas las condiciones. Supongamos que octubre comienza un lunes. Eso significa que sólo hay 4 domingos y el último domingo caerá el día 28. Una vez más, es entre 25 y 31 por lo que la condición se cumple. Supongamos que la primera de Octubre cae en jueves, entonces el 25 será un domingo (el cuarto) y el 31 será un sábado, así que otra vez la condición se cumplirá para la última (y en este caso 4 º domingo).
Para iniciar el tiempo de verano/daylightsaving en el último el domingo de marzo mutatis mutandis es la misma:
if (dow == 7 && mo == 3 && d >= 25 && h ==2 && DST==0)
{
setclockto 3 am;
DST=1; //store this in your NVRAM
}
Marzo también tiene 31 días, por lo que los cálculos son los mismos. Esta vez aunque Compruebe 2 y una bandera de DST de reset y luego el reloj a 3 am y establece el indicador de DST para indicar ya está hecho.
Ahora si no utilizas un RTC que guarda el día de la semana o si podrás mantener el control de hora y la fecha de alguna otra manera que con un RTC, entonces hay una fórmula fácil para determinar el día de la semana de la fecha con algoritmo de Sakamoto
//gives day of week for a given date Sunday=0, Saturday=6
int dow(int y, int m, int d)
{ static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; static int t[] = y -= m < 3; return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; }0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4;
y -= m < 3; return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
cuenta sin embargo que esta rutina se cuenta de 0 (domingo) a 6 (sábado)
He sido informado que el Avr-libc tiene time.h con apoyo de DST pero no sólo tienes que decirle a la biblioteca que desee utilizar DST pero también tienes que incluir un archivo de utilidad muy amplia, dependiendo de si estás en Europa o los Estados Unidos. Me atrevo a decir que mi código es substancialmente más corto.