lunes, 14 de diciembre de 2015

Convertir una Raspberry Pi en un despertador de ciclo solar

Actualización 2016/02/11: Añadido "Sincronizar el reloj del sistema con el RTC"

Cada cambio de horario me pregunto lo mismo, ¿es ésta la mejor forma de aprovechar el día?

Me viene a la cabeza la estampa del gallo cantando al amanecer anunciando los primeros rayos del sol. En las ciudades no tenemos gallos pero también podemos simular a la naturaleza. Aquí va mi propuesta.

Se me ocurrió ensamblar un despertador, reciclando elementos que tenía por casa, para que según mi ubicación geográfica calculara cada día a qué hora iba a salir el sol e hiciera sonar la música de mi elección.

¿Porqué cada día? Pues porque en realidad la hora a la que sale el sol varía poco a poco cada día y no me apetecía calcularlo todo de una sola vez, así es más flexible a las necesidades de cada uno.

Por supuesto, entiendo que con el colegio, el trabajo... se crea que es imposible vivir así. Pero ¿la situación no cambia porque es inamovible o porque no queremos intentarlo?


Componentes:
Las instrucciones están basadas en una instalación de Arch Linux ARM.

Tanto el reloj como los pulsadores irán conectados a la interfaz GPIO. Dependiendo del modelo de Raspberry Pi ésta tiene una distribución distinta.

El reloj
Dado que la Raspberry Pi no dispone de reloj interno es susceptible a perder la hora durante una pérdida de suministro así que para ésta aplicación se hace imprescindible conectarle un reloj con batería. Gracias a los cables, conectar el reloj a la placa es trivial.

RTCRPi
SCL3
SDA2
VCC5v (rojo)
GNDGround (negro)



Para que el sistema lo reconozca sólo hay que editar el archivo /boot/config.txt y añadir dtoverlay=i2c-rtc,ds3231 (si existe la carpeta overlays en /boot). Una vez reiniciado el sistema el comando timedatectl mostrará la hora del reloj RTC que será sincronizado automáticamente. Para establecer la hora, al tenerlo conectado a internet, he usado un servidor NTP, aunque también se puede hacer a mano.

Los pulsadores
Para montar el invento elegí una caja de registro de instalaciones eléctricas, le hice dos agujeros en la tapa para insertar los pulsadores que quedan fijados mediante una rosca y proceder a soldar los cables. No tiene mucho secreto, dos cables de colores distintos para cada pulsador.

Pulsador STOPRPi
Rojo23
NegroGround (negro)
Pulsador SLEEPRPi
Rojo24
NegroGround (negro)



El script test_button.py (una vez instalado el software) os permitirá verificar que funcionan como deseamos. La función de cada pulsador es bien sencilla, uno terminará con la reproducción del sonido (STOP) y el otro además programará la alarma para que vuelva a sonar según lo configurado, por ejemplo, 5 minutos después (SLEEP).

Detalle de las conexiones en mi Raspberry Pi
Otros componentes
Según la caja de la que dispongamos el resto de componentes se ensamblarán como buenamente se pueda (a falta de impresora 3D...) y se le pueden practicar diversos orificios para hacer pasar los cables de alimentación para la placa, USB y sonido del altavoz.



El software

Como mi placa tiene puerto de red opté por conectarme mediante SSH e identificándome como root una vez dentro, otros modelos pueden requerir otros medios.

Para que funcione el invento será necesario instalar los siguientes paquetes:
python-pip base-devel at gst-python alsa-utils
Dependiendo del formato del audio necesitaremos también alguno de los plugins de gstreamer:
gst-plugins-good gst-plugins-bad gst-plugins-ugly
Además, también serán necesarias las librerías python siguientes
# pip install pyephem
# pip install RPi.GPIO
# pip install pytz
Una vez hecho esto, se puede desinstalar el paquete base-devel si se desea (en mi tarjeta SD voy justo de espacio).

Activamos el servicio at:
# systemctl enable atd.service
# systemctl start atd.service 
Descargamos los scripts necesarios y copiamos los archivos alarm.service y alarm.timer a /etc/systemd/system/. Me pareció adecuado que hiciera los cálculos a la 13h del mediodía.

Activamos el timer:
# systemctl enable alarm.timer
El resto de archivos los copiamos en /root/sca/ junto con los audios que deseemos.

Editamos el archivo config para ajustar el comportamiento del despertador. Es importante indicarle vuestra posición geográfica mediante las coordenadas Latitude y Longitude. Se pueden añadir tantas alarmas como se desee, cada alarma estará indicada por su nombre entre corchetes [sunrise], si no se especifica algún valor se utilizará el valor por defecto [DEFAULT].

Por ejemplo, para mi tengo configuradas dos alarmas, una hace que 20 minutos antes del amanecer (TimeDeltaMinutes = -20) suenen unas campanas (SoundFile = alarm.wav) que se estarán repitiendo (Loop = 1) como máximo durante 10 minutos (AutoMute = 10) hasta que se realice alguna acción. Si se pulsa el botón de SLEEP se volverá a programar la alarma dentro de 5 minutos (RepeatTime = 5).

Y la otra reproduce una música relajante 9 horas antes del amanecer. Como el audio dura 1 hora no necesito que se repita en bucle (Loop = 0) y le he ajustado el volumen (Volume = 0.5) para que suene más suave.

Sincronizar el reloj del sistema con el RTC

El sistema en realidad sólo lee el reloj RTC al iniciarse. En ese momento actualiza el reloj del sistema a partir del reloj RTC. Si está conectado a internet, el reloj del sistema se puede ir ajustando gracias a un servidor NTP y finalmente cuando se apaga actualiza el reloj RTC usando la hora del sistema como referencia.

Dada la naturaleza de este proyecto ésta forma de trabajar podría no funcionar correctamente. El reloj del sistema sólo se actualizará una vez, cuando se inicie, estará una buena temporada sin conectarse a internet y cuando se apague, lo más probable es que sea por un corte eléctrico, no sincronizará la hora del RTC con la del sistema.

¿Cómo de fiable es la hora del sistema sin poderse sincronizar con un servidor NTP? Gracias a Remi Bergsma y su artículo "How accurately can the Raspberry Pi keep time?" vemos que se desvía, aunque no parece que sea mucho y también parece predecible. Pero, ¿siempre es lo mismo en todas las placas Raspberry Pi? ¿Es independiente de la versión del kernel instalada?

Teniendo instalado el DS3231 que tiene una precisión muy elevada (en un año la hora sólo se desviará 1 minuto como máximo) se puede atajar el problema sincronizando el reloj del sistema con la hora del RTC de forma periódica.

En el repositorio se encuentra el servicio hwclock para usarlo tal como se hizo con alarm.timer:
# systemctl enable hwclock.timer
Así, una vez al día, se sincronizarán los relojes. El método es algo bruto y podría dar algún problema. Linux no lleva muy bien viajar al pasado y encontrarse con archivos y sesiones del futuro. Pero, al menos así, difícilmente la alarma de la mañana se pondrá a sonar a media tarde en unos meses.

Lo próximo será averiguar cómo hacer una app para smartphone que haga lo mismo, aunque tiene su encanto haber fabricado mi propio despertador.

¿Qué otras cosas podrían ser útiles usando como referencia los astros?

Código del proyecto en github: Solar Cycle Alarm en github

Si lo deseas te puedo enviar un correo electrónico cada vez que publique algo en Mi backup tan sólo debes inscribir tu dirección de correo. Tú dirección de correo será confidencial y sólo te enviaré información que crea que te puede interesar.

No hay comentarios:

Publicar un comentario