Programación de Eventos con Arduino y RTC por Jesus Ruben Santa Anna Zamudio | Ene 3, 2017 | Tutoriales Arduino | 0 Comments En esta ocasión te vamos a enseñar como realizar la programación de eventos con arduino, o dicho de otra forma: como podemos programar el arduino para ejecutar determinadas funciones en una hora/fecha determinadas. La información de fecha / hora actual proviene de un circuito integrado RTC (Real Time Clock) DS1307. Un RTC está especialmente diseñado para mantener la información horaria, aún cuando nuestro arduino se encuentre sin alimentación. Esto es fantástico en aplicaciones del mundo real, donde no siempre se puede confiar en el suministro de energía eléctrica. Imaginemos por un momento que deseamos encender una lampara con arduino a una hora determinada. ¿Como podemos decirle al arduino que deseamos hacer esto? ¿Como implementamos un programa genérico para realizar cualquier acción con nuestro arduino a una hora / fecha determinada? En este tutorial te explicamos como puedes hacer precisamente eso: Temporizar cualquier acción con arduino para que sea llevada a cabo según la programación de horario elegida. En nuestra foto de portada vemos nuestro laboratorio de domótica con arduino, que estaremos usando durante este tutorial, en conjunto con un arduino UNO y el RTC DS1307. Conexión y uso de un RTC con Arduino. En otra entrada anterior hemos tratado ya como realizar la conexión del RTC DS1307 con Arduino, así como su funcionamiento básico. Vamos a colocar aquí la imagen de la conexión como referencia. Para saber como podemos leer y escribir el RTC, así como más detalles de su funcionamiento, recomendamos leer nuestro tutorial referente a este tema. Una vez que tengamos nuestro arduino funcionando con el RTC y hayamos programado la hora y fecha actual dentro de este, podemos seguir con el resto de este tutorial. Librerías para Programación de Eventos con Arduino. Como ya sabemos, la plataforma arduino tiene un buen número de librerías que nos facilitan bastante algunas tareas, pues la lógica ya ha sido implementada y solamente debemos conocer el API de dichas librerías para acceder a su funcionalidad. En este caso, estaremos trabajando con la librería de gestión de eventos y horarios conocida como “TimeAlarms”. Mediante esta librería podemos programar la ejecución de determinadas funciones en una fecha y hora específica. La librería “TimeAlarms” depende de la librería “Time” para conocer la fecha/hora actual, por lo que también debe ser instalada. Finalmente para la interfaz con el reloj en tiempo real utilizaremos la librería DS1307RTC. A continuación dejamos los enlaces para descargar las librerías requeridas: Time TimeAlarms DS1307RTC Tutorial para instalar una librería de arduino La siguiente es la explicación de que hace cada una de las librerías: Time: Funciona como un reloj en tiempo real por software que lleva la cuenta del tiempo usando el CPU de arduino. Funciona llevando un conteo del número de segundos desde segundos transcurridos desde la medianoche UTC del 1 de enero de 1970 (timestamp de Unix). Este conteo se pierde al apagar el arduino, por lo que NO funciona como base de tiempo confiable sin energía eléctrica. TimeAlarms: Es la encargada de la programación de eventos utilizando la hora/fecha (unix) provista por la librería Time. Esta librería asocia las funciones declaradas dentro del sketch de arduino a un evento que ocurre en una hora/fecha determinada. DS1307RTC: Se encarga de la comunicación con el RTC DS1307 o DS3231 para obtener el tiempo actual y mantener la precisión a largo plazo, esta librería proporciona la base de tiempo permanente para ser usado por la librería “Time” y “TimeAlarms” Programa para temporizador con arduino Con todo esto ya instalado en nuestro IDE podemos comenzar con nuestro primer sketch que permite realizar la programación de eventos con Arduino. En este programa buscamos hacer lo siguiente: Hacer que todos los días a las 14:00, 14:05, 14:10 se ejecute una función elegida por nosotros que imprime un texto al monitor serial de arduino. El código de nuestro sketch queda de la siguiente forma: 1 2 3 4 5 6 /** GeekFactory - "Construye tu propia tecnologia" Distribucion de materiales para el desarrollo e innovacion tecnologica www.geekfactory.mx Ejemplo de Programación de Eventos con Arduino con las librerias Time y TimeAlarms 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 en este programa, la hora se configura en el inicio del arduino y solamente se utiliza el CPU de arduino para llevar el conteo del tiempo, en este ejemplo NO se utiliza el reloj en tiempo real externo. */ #include <Time.h> #include <TimeAlarms.h> void setup() { Serial.begin(9600); // Configurar la fecha / hora manualmente cada vez que se reinicia el arduino // Configurar al lunes 22 de agosto de 2016 a las 13:59:50 setTime(13, 59, 50, 22, 8, 16); // Crear las alarmas y configurar las funciones correspondientes a cada una Alarm.alarmRepeat(14, 0, 0, Alarma1400); // Evento a las 14:00 diario Alarm.alarmRepeat(14, 5, 0, Alarma1405); // Evento a las 14:05 diario Alarm.alarmRepeat(14, 10, 0, Alarma1410); // Evento a las 14:10 diario } void loop() { // Mostrar el reloj en el monitor serial digitalClockDisplay(); // Esperar 1 segundo y procesar las Alarmas mientras tanto... Alarm.delay(1000); } void Alarma1400() { Serial.println("Evento de las 14:00:00"); } void Alarma1405() { Serial.println("Evento de las 14:05:00"); } void Alarma1410() { Serial.println("Evento de las 14:10:00"); } /** Funciones para la impresion del reloj al monitor serial de arduino */ void digitalClockDisplay() { Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.println(); } void printDigits(int digits) { Serial.print(":"); if (digits < 10) Serial.print('0'); 66 67 Serial.print(digits); } Este programa aún no utiliza la fecha / hora proveniente del RTC, en cambio configura una fecha/hora conveniente al arrancar el arduino, pero podemos configurar la librería Time para que haga uso del RTC de una manera muy sencilla. El siguiente programa que realizaremos pretende ser un ejemplo de una aplicación real con el RTC y la librería TimeAlarms, por lo que será necesario que pongamos a tiempo el reloj antes de intentarlo. Si deseamos encender una lámpara realmente en nuestra casa será necesario conectar una tarjeta de relevadores al arduino, como lo haremos en el siguiente ejemplo. Programación del horario de una lámpara con arduino Ahora que ya conocemos el funcionamiento de la librería TimeAlarms vayamos con un ejemplo práctico de algo que se requiere de manera cotidiana: Prender una luz a una hora determinada y apagarla en otro momento. Usando nuestra librería de TimeAlarms creamos un par de funciones que se encargarán de apagar o encender la luz en el momento oportuno. En la parte de hardware utilizamos un módulo de relevador que controla la carga de corriente alterna. El montaje de nuestro circuito se observa de la siguiente forma, incluyendo la parte de control de corriente alterna: Esta imagen muestra más de cerca el detalle de las conexiones al arduino: Nosotros estamos utilizando nuestro kit de laboratorio para domótica, que está diseñado para simplificar en gran medida la parte de la conexión de dispositivos de corriente alterna. Nos ahorra tener que cablear la parte de alterna cada vez que deseamos experimentar, además de permitir un mejor manejo de la corriente alterna que pudiera ser peligrosa. El sketch completo que controla el encendido de una luz en el momento deseado es el siguiente: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 /** GeekFactory - "Construye tu propia tecnologia" Distribucion de materiales para el desarrollo e innovacion tecnologica www.geekfactory.mx Ejemplo de Programación de Eventos con Arduino con las librerias Time y TimeAlarms. En este programa se utiliza el RTC para obtener la fecha y hora actual, por lo que el RTC debe tener una fecha/hora válida para poder correr este programa. Las conexiones de SDA y SCL deben estar correctamente realizadas. Se activará el relevador conectado en el pin 3 digital segun el horario indicado. */ #include <Time.h> #include <TimeAlarms.h> #include <DS1307RTC.h> void setup() { // Preparar la interfaz serial Serial.begin(9600); // Configurar los pines de salida de relevadores desactivados al inicio // recordamos que los modulos de reles se activan con un estado bajo pinMode(OUTPUT, 3); digitalWrite(HIGH, 3); pinMode(OUTPUT, 4); digitalWrite(HIGH, 4); // Cargar la hora actual desde el RTC e indicar que esto suceda de forma automática durante loop() // Utilizamos el método RTC.get() de la libreria DS1307RTC. El RTC debe estar conectado como se // indica en el texto y debe tener la fecha y hora correctas setSyncProvider(RTC.get); if (timeStatus() != timeSet) Serial.println("Fallo de RTC"); else Serial.println("Sincronizado con RTC"); // Crear las alarmas y configurar las funciones correspondientes a cada una Alarm.alarmRepeat(18, 0, 0, EventoEnciendeLuz); // Evento a las 18:00 diario (enciende luz) Alarm.alarmRepeat(7, 0, 0, EventoApagaLuz); // Evento a las 7:05 diario (apaga luz) } void loop() { // Mostrar el reloj en el monitor serial digitalClockDisplay(); // Esperar 1 segundo y procesar las Alarmas mientras tanto... // El metodo Alarm.delay() procesa en el fondo las alarmas y llamara a las funciones indicadas Alarm.delay(1000); } /** Funcion callback que activa el relevador en el pin 3 (enciende la luz) */ void EventoEnciendeLuz() { Serial.println("Encendiendo Luz!!!"); digitalWrite(LOW, 3); } 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 /** Funcion callback que desactiva el relevador en el pin 3 (apaga la luz) */ void EventoApagaLuz() { Serial.println("Apagando Luz!!!"); digitalWrite(HIGH, 3); } /** Funciones para la impresion del reloj al monitor serial de arduino */ void digitalClockDisplay() { Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.println(); } void printDigits(int digits) { Serial.print(":"); if (digits < 10) Serial.print('0'); Serial.print(digits); } Está de más decir que este sketch puede ampliarse para soportar incluso varios canales o patrones más complejos. Por ejemplo podemos conectar más relevadores para controlar otras cargas, por ejemplo bombas para realizar riego, motores que controlen persianas, sirenas de alarma, etc. Como podemos observar la Programación de Eventos con Arduino mediante la librería TimeAlarms es muy sencilla, aún cuando utilizamos el RTC. Palabras finales sobre la Programación de Eventos con Arduino. La Programación de Eventos con Arduino es una de las tareas más básicas cuando deseamos llevar a cabo alguna automatización en el hogar, el trabajo o la industria. Con los ejemplos y librerías que mostramos en esta página, es posible crear un marco de trabajo que nos permita afrontar con mucha sencillez esta tarea. Además las librerías que hemos mostrado en esta página permiten obtener información de fecha/hora no solamente desde el RTC, sino desde otras fuentes también como un servidor NTP o un GPS, por lo que seguramente tienen cabida en muchísimas aplicaciones que requieren control de tiempo preciso a largo plazo. Código Para Mandar El Valor De Un Sensor De Arduino A Excel. El código es el siguiente: /* Envío de datos a Excel en tiempo real */ /* educachip.com */ int V_Previo; float Datos; char Se_Envia[10]; void setup() { Serial.begin(9600); //Se inicia la comunicación serie a 9600 baudios. } void loop() { //Se leen voltajes en la entrada analógica A0. V_Previo = analogRead(A0); //Se convierte la entrada tipo int en float en función de la resolución de Arduino. Datos = V_Previo * (5.0 / 1023.0); //Función que permite la conversión de float a String. Los datos se almacenan en Se_Envia. //char* dtostrf (double _val, signed char _width, unsigned char _prec, char* _s) dtostrf(Datos, 5 , 3 , Se_Envia); //Se envían los datos por el puerto serie. Serial.print(Se_Envia); //Se da tiempo a que Excel capture los datos. delay(30); } Si te fijas, los valores de tu sensor leídos por Arduino tienen formato “int”. Esos valores se transforman en tipo “float” utilizando una pequeña fórmula (que seguramente hayas visto más de una vez). Una vez tienes los valores en el formato “float”, la función dtostrf() se encarga de transformar el valor en una cadena de caracteres. En este caso, los parámetros de la función dtostrf() están fijados para que se almacenen 5 valores, con una precisión de 3 decimales. Considerando el punto “.” para separar enteros de decimales, tu valor se enviará de Arduino a Excel con 4 dígitos. Si tu sensor te proporciona también números negativos, tendrás que ajustar la función. Sea así o no, te recomiendo que le eches un vistazo. Una vez tengas los datos listos para enviar, basta con que utilices un Serial.print() y un delay() para darle tiempo a Excel a coger la información. Como puedes ver, muy facilito todo. Vamos ahora con Excel. smile Cómo Configurar Excel Para Recibir Información Por El USB. El problema está en que Excel no está preparado para recibir información por el USB. Hay que enseñarle. tongue Para enseñar a Excel cómo recibir información por el USB hay que comunicarlo con Windows. Para enseñar a Excel cómo comunicarse con Windows hay que programarlo. Por último, para programar Excel hay que utilizar Macros. Las Macros son básicamente programas escritos en VBA cuyas instrucciones pueden ser ejecutadas por Excel. Si te gusta trabajar con Excel, te recomiendo encarecidamente que le des una oportunidad a las Macros. Las Macros llevan a Excel al siguiente nivel, permitiéndote hacer cosas que ni te imaginas. ¡Hay un sin fin de posibilidades! Volviendo al tema, a nosotros lo que nos interesa es enviar datos de Arduino a Excel. Para ello he utilizado una librería creada por David M. Hitchner y adaptada para trabajar con 64bits por Hal Evensen. El trabajo duro de verdad es el suyo, así que no puedo más que mostrarles mi gratitud a estos auténticos profesionales. Lo único que yo he hecho es utilizar su trabajo (al cuál, por cierto, se le puede sacar mucho más partido del que le he sacado yo). … Y ya que estoy de agradecimientos, tengo que decir que los chicos de Arduino.cc también han puesto su granito de arena a la hora de ayudarme con esto de enviar datos de Arduino a Excel. Un usuario muy activo del foro de nick Lucario448 me ayudó ver dónde estaba el error de uno de los códigos que estuve probando… Así que si lo veis por ahí ¡dadle un saludo de mi parte! smile Cómo Poner La Librería En Una Hoja De Excel Habilitada Para Macros. Como te acabo de comentar, este pequeño trabajo de enviar información de Arduino a Excel se basa en el gran trabajo de David M. Hitchner. El primer paso será añadir su librería a tu libro de Excel. Para incorporar la librería a tu hoja de Excel debes descargártela. Para ello tienes dos opciones: 1. Descargarte la librería desde la web de Hal Evensen: Ésta debería ser tu opción principal. Aunque solo sea por ver su trabajo y proporcionarle algo más de tráfico a su web. 2. Si no te manejas bien con el inglés, te dejo el archivo aquí: vba_com_port. Me gustaría que utilizases esta opción solo si no te ves capaz de manejarte en su web. Recuerda que el trabajo que vas a utilizar es suyo. Una vez te descargues el archivo, verás que se trata de un documento con extensión “.bas”. En él encontrarás implementadas las funciones que se utilizarán en el proyecto (más unos cuantos añadidos). Para agregarlas en tu libro de Excel basta con que vayas a la sección Desarrollador > Importar y selecciones el archivo “.bas”. A partir de ese momento podrás ver la información dándole al botón Visual Basic. Si abres la librería verás todas las funciones que tiene implementadas. Si te fijas, verás que dispones de herramientas no solo para enviar datos de Arduino a Excel, sino también para recibirlos. Originalmente quería hacer un post enseñándote tanto a enviar información de Arduino a Excel como al revés. Ésta librería no solo lo permite, sino que lo deja fácil. Te permite incluso ver el estado de los pines habituales en el envío y recepción de datos por el puerto serie. El problema está en que estas facilidades que te proporciona la librería no te las proporciona Arduino. Tuve problemas de sincronización. En cualquier caso, no desisto. Cuando solucione los problemas que tengo, te traigo el resultado. Eso sí, de momento me voy a tomar un descanso de puertos serie y de enviar información de Arduino a Excel y de Excel a Arduino. smile Cómo Implementar Funciones En VBA Para Leer El Puerto USB. Si has abierto la librería (y sabes algo de VBA), seguramente te habrás dado cuenta de que lo que he hecho para enviar datos de Arduino a Excel es bastante cutre teniendo en cuenta las herramientas disponibles. Para sincronizar la información he utilizado un simple delay() de Arduino. Todo esto a pesar de que siempre te recomiendo que evites los delay() (puedes ver por qué aquí). Como te he dicho, no era la idea inicial. sad En el caso de VBA, la cosa está más o menos igual. Entre que no tengo mucha experiencia con el lenguaje de programación y los problemas de sincronización… al final he optado por no complicarme mucho. Lo que he hecho ha sido asociar funciones a botones de Excel. Si tú tampoco tienes amplios conocimientos de VBA y quieres aplicar el mismo procedimiento que yo, basta con que vayas a la pestaña Desarrollador > Insertar > Controles de ActiveX > Botón de comando. Una vez pulses sobre esa opción, podrás dibujar tu botón. Cuando tengas el botón dibujado, puedes hacer click derecho sobre él y darle a la opción “Ver Código” para agregarle funciones al botón. Ten en cuenta que para hacer esto tendrás que tener la opción “Modo Diseño” activada. Cuando vayas a enviar información de Arduino a Excel y quieras leerla, tendrás que desactivar este modo. Qué Funciones Crear Para Leer Los Datos Enviados De Arduino A Excel. Bueno… primero quiero repetirte que esto de los botones es la opción a la que he recurrido yo. Puedes enviar la información de Arduino a Excel con botones o sin botones. Lo único que tienes que hacer es utilizar las funciones de la librería. Las funciones que debes utilizar dependen de lo que quieras hacer. Si, como es este ejemplo, solo quieres enviar datos de Arduino a Excel pero no al revés, necesitarás cuatro funciones: 1. Función para abrir el puerto serie: CommOpen (númerodelpuertoaabrir, “COM”, formatoquetendrálainformación). 2. Función para cerrar el puerto serie: CommClose(númerodelpuertoacerrar). 3. Función para capturar la información enviada de Arduino a Excel: CommRead(númerodelpuerto, variableparaguardarlosdatos, númerodecaracteresquesevanaleer). 4. Función para limpiar la información del puerto antes de enviar más: CommFlus(númerodelpuerto). Entiendo que todo esto puede bastante complicado si no tienes algo de experiencia con VBA y le dedicas un rato a la librería. No te preocupes, te voy a dar un Excel ya hecho y que funciona con el código de Arduino que te mostré antes. Libro De Excel Que Lee La Información Enviada De Arduino A Excel. Seguro que después de tanto rollo como te he soltado estabas deseando que te lo diera hecho. wink Ya te dije al principio del post que te iba a proporcionar todo lo necesario para enviar datos de Arduino a Excel. Te lo dejo en el link: leer-datos-arduino-educachip También te voy a mostrar una imagen para que veas cómo luce el resultado. Espero que te guste. Ésta es mi versión, pero es muy optimizable. Si te animas a mejorarlo y te queda algo bueno, envíamelo y lo publicamos. smile Información Adicional. Por si todavía no te has saturado de Excel, te cuento más cosas. smile Como te he dicho, he tenido bastantes problemas para hacer esto. Te presento este modelo porque es el más estable, pero también el más simplón. La verdad es que subo este contenido con mal sabor de boca. Tenía muchas y muy buenas ideas sobre cómo mejorar el envío y recepción de datos de Arduino a Excel… La cosa está en que ya le he dedicado demasiado tiempo, tengo otras cosas que hacer y he perdido un poco la motivación. A lo mejor más adelante. smile Te cuento algunas de las cosas que he probado al intentar gestionar la información de Arduino a Excel… por si quieres mejorar mi proyecto: smile Familiarízate con las funciones Serial.flush() para gestionar el Buffer de Arduino. Utiliza Serial.read() para limpiar el Buffer de Arduino si vas a enviarle información. while(Serial.available()==){} puede serte útil para hacer que Arduino espere a que se le envíe un dato. No olvides que tanto Arduino como Excel tienen que estar trabajando a los mismos baudios. Recuerda cambiar el código del puerto de los botones de Excel para que se ajuste al de tu placa (ID_Puerto). Por defecto es 3. Juega con el valor del delay() si ves que se copia más de un dato por celda o no se copian bien. Modifica la función dtostrf() para que se ajuste al tipo de dato que quieres mandar de Arduino a Excel. La función MsgBox puede serte útil para encontrar errores en el Excel. También la variable estado. Recuerda que primero debes abrir el puerto, luego leer y por último cerrarlo. No leas el puerto hasta que Arduino no le esté enviando información a Excel. Las funciones Left() y Mid() de VBA pueden serte útiles para gestionar las cadenas de caracteres. Analiza el resto de herramientas de la librería. Puede que ahí esté tu solución. La información relativa al envío de señales con RS-232 es bastante similar a lo que estás haciendo. Puede serte útil mirar la teoría. Ten paciencia si no te sale bien a la primera. La clave siempre está en los detalles. Pues eso ha sido todo sobre cómo enviar datos de Arduino a Excel. Espero que te haya gustado el post y que disfrutes de tu nuevo Excel. smile Si te gusta lo que hago, recuerda que puedes compartirlo en las redes sociales con los botones que tienes debajo. Pregúntame las dudas que te vayan surgiendo e intentaré ayudarte. Un abrazo, Enrique.