APRENDE ARDUINO GUÍA TEÓRICO PRÁCTICA OMAR OTONIEL FLORES Aprende ARDUINO APRENDE ARDUINO – Guía Teórico Práctica ©Omar Otoniel Flores Cortez Depósito de Obra Derechos de Autor - CNR No. 472 – 2013 San Salvador – El Salvador. 005.133 F632a Flores Cortez, Omar Otoniel, 1978Aprende ARDUINO: Guía Teórica Práctica/ Omar Otoniel Flores. -1ª ed. -- San Salvador, El Salv. : [s.n.], 2013. 200 p. ; 28 cm. SV ISBN 978-99961-0-346-9 1. Arduino (Lenguaje de programación de computadores) Controladores programables 3.Control automático 2. La siguiente se edita bajo Derechos Creative Commons – http://creativecommons.org - “Algunos derechos reservados”. En cualquier explotación de la obra autorizada por la licencia hará falta reconocer la autoría. Publicación por – Ingeniería Nacional www.ingnac.com Diseño de Portada – Glenda Fernández Logística – German Castellanos Enero 2014 Muchas de las imágenes, designaciones o marcas usadas en esta obra son propiedad de sus respectivos fabricantes o distribuidores, aquí solo se mencionan con razón informativa y educacional. A pesar de las precauciones tomadas al momento de la preparación de este material, ni el autor ni el editor se responsabilizan por fallas, daños o perjuicios ocurridos por el uso de la información contenida aquí. Tome las precauciones necesarias en el ensamble y manejo de los circuitos electrónicos. 1 Guía Teórico Práctica Aprende ARDUINO Contenido Introducción ....................................................................................................................................................................... 6 1. Conociendo la plataforma ARDUINO ..................................................................................................................... 8 ¿Qué es Arduino? ............................................................................................................................................................. 8 El Hardware Arduino ..................................................................................................................................................... 10 El Software Arduino. ..................................................................................................................................................... 17 2. Iniciando con ARDUINO ........................................................................................................................................ 20 Puesta a punto del Hardware .......................................................................................................................................... 20 Descargado el primer programa Arduino ....................................................................................................................... 23 ¿Problemas con la descarga? .......................................................................................................................................... 26 3. Introducción a la programación de ARDUINO .................................................................................................... 28 Conceptos Básicos de Programación ............................................................................................................................. 28 Proceso de diseño de un Sistema con Arduino ............................................................................................................... 29 Estructura básica de un Sketch ....................................................................................................................................... 30 Aspectos de programación del Lenguaje Arduino. ........................................................................................................ 32 Comentarios. .............................................................................................................................................................. 32 Entre llaves. ................................................................................................................................................................ 32 Punto y coma .............................................................................................................................................................. 32 Tipos de Datos ........................................................................................................................................................... 33 Variables en Lenguaje Arduino. .................................................................................................................................... 33 Partes funcionales de un Sketch en Arduino. ................................................................................................................. 34 1. Expresiones....................................................................................................................................................... 34 Operadores Aritméticos. ............................................................................................................................................ 35 Operadores de Comparación. ..................................................................................................................................... 35 Operadores Lógicos Booleanos. ................................................................................................................................. 36 2. Estamentos o instrucciones ............................................................................................................................... 37 3. Estructuras de control ....................................................................................................................................... 37 4. Funciones.......................................................................................................................................................... 40 Pasos funcionales de un Sketch ...................................................................................................................................... 41 4. Comunicación serial en ARDUINO ........................................................................................................................ 42 Comunicación Serie en Arduino. ................................................................................................................................... 42 Envío de datos desde Arduino hacia la PC..................................................................................................................... 43 Recibir datos desde la PC en Arduino. ........................................................................................................................... 45 5. Entradas y Salidas Digitales de la tarjeta ARDUINO. ......................................................................................... 50 2 Guía Teórico Práctica Aprende ARDUINO Configuración de terminales .......................................................................................................................................... 50 Manejo de Entradas y Salidas Digitales ......................................................................................................................... 51 6. Manejo de LEDs con ARDUINO ............................................................................................................................ 54 Manejo de LED con Arduino ......................................................................................................................................... 54 Activación de cargas de mayor potencia. ....................................................................................................................... 60 Uso del Rele. .............................................................................................................................................................. 60 Buffer ULN2803. ....................................................................................................................................................... 61 7. Entradas y Salidas Analógicas de la tarjeta ARDUINO ....................................................................................... 64 Entradas Analógicas - ADC ........................................................................................................................................... 64 Aplicación del Potenciómetro: El JOYSTICK ............................................................................................................... 68 Salidas analógicas – PWM ............................................................................................................................................. 73 8. Manejo de DISPLAY de 7 segmentos con ARDUINO .......................................................................................... 78 Manejo Directo con Arduino. ........................................................................................................................................ 79 Manejo de DISPLAY usando el IC MAX7219.............................................................................................................. 84 Manejo de DISPLAY usando el IC TM1640 ................................................................................................................ 90 9. Generación de sonido con ARDUINO .................................................................................................................... 94 10. Uso de Matriz de LED con ARDUINO ............................................................................................................. 98 Matriz de LEDs .............................................................................................................................................................. 98 Conexión en Cascada de Matriz de LED ..................................................................................................................... 106 11. Uso de display LCD con ARDUINO................................................................................................................ 110 Manejo con Arduino .................................................................................................................................................... 112 Lectura de botones del LCD Shield. ............................................................................................................................ 117 12. Manejo de teclado matricial con ARDUINO .................................................................................................. 120 Teclado Matricial y Arduino. ....................................................................................................................................... 121 13. Uso del Reloj de Tiempo Real DS1307 con ARDUINO ................................................................................. 128 El circuito integrado RTC - DS1307. ........................................................................................................................... 128 Arduino y el DS1307. .................................................................................................................................................. 129 14. Manejo de Motores Eléctricos con ARDUINO ............................................................................................... 134 Conceptos Básicos ....................................................................................................................................................... 134 Partes que componen un Motor ................................................................................................................................ 135 Tipos de Motores Eléctricos..................................................................................................................................... 135 Motores de Corriente Directa DC y Arduino ............................................................................................................... 135 Uso del IC L293d (SN754410). ............................................................................................................................... 137 Uso del módulo controlador L9110. ....................................................................................................................... 141 Servomotor y Arduino ................................................................................................................................................. 144 Motor Paso a Paso y Arduino ....................................................................................................................................... 148 15. 3 Uso de Fotoresistor LDR con ARDUINO ...................................................................................................... 152 Guía Teórico Práctica Aprende ARDUINO LDR y Arduino. ........................................................................................................................................................... 154 16. Medición de Temperatura con ARDUINO ..................................................................................................... 158 Sensor LM35 ................................................................................................................................................................ 158 Sensor DS18B20 .......................................................................................................................................................... 162 Sensor DHT11.............................................................................................................................................................. 164 17. Uso sensor decodificador de infrarrojo con ARDUINO ................................................................................ 168 Manejo con Arduino del Sensor Receptor de IR. ......................................................................................................... 170 18. Medición de Distancia con ARDUINO ............................................................................................................ 172 Sensor HC-SR04 .......................................................................................................................................................... 172 Manejo con Arduino. ................................................................................................................................................... 173 19. Manejo de tarjetas de memoria SD con ARDUINO ...................................................................................... 178 Tarjetas SD y Arduino ................................................................................................................................................. 178 20. Comunicación Ethernet con ARDUINO. ........................................................................................................ 186 Conceptos básicos de redes de datos. ........................................................................................................................... 186 Configuración de la placa/shield Ethernet.................................................................................................................... 187 Arduino como Servidor Ethernet ................................................................................................................................. 187 Arduino como Servidor Web ....................................................................................................................................... 189 21. Comunicación Bluetooth con ARDUINO. ...................................................................................................... 193 Que es Bluetooth? ........................................................................................................................................................ 193 Arduino y Bluetooth. .................................................................................................................................................... 194 Bibliografía ...................................................................................................................................................................... 198 4 Guía Teórico Práctica Aprende ARDUINO APUNTES: 5 Guía Teórico Práctica Aprende ARDUINO Introducción El equipo que diseñó la plataforma Arduino dice que “La computación física se refiere al diseño de objetos y espacios que reaccionan a cambios en el entorno y actúan en este. Se basa en la construcción de dispositivos que incluyen Microcontroladores, sensores y actuadores y que pueden tener capacidades de comunicación con la red u otros dispositivos. La mejor manera de aprender computación física es mediante la construcción de prototipos. Es un nuevo campo en el que es necesario explorar nuevos estilos de interacción, que dependan de nuevas interfaces y técnicas de representación y visualización. La computación ubicua como tal no se ha convertido en el paradigma que se esperaba para el diseño de productos y espacios electrónicos, y son pocos los nuevos estilos de interacción que llegan al mercado. La idea que promueve la computación física es que casi cualquier cosa se puede convertir en interfaz.” (Equipo Arduino, 2013) Cada proyecto de Computación Física incluye usualmente sensores para traducir los datos análogos, y enviarlos al procesador, donde el software controla actuadores como motores, servos, LEDs, pantallas, y otros. Actualmente el desarrollo de la mayoría de dispositivos embebidos que interactúen con el entorno (p.e. sistemas de domótica, sistemas robóticos, sistemas de seguridad, gadgets electrónicos, microcomputadoras) está basado en un elemento en común: un Microcontrolador, estos pequeños circuitos o chips en cuyo interior traen integrado un microprocesador, memoria y periféricos de comunicación, están teniendo un gran auge en el desarrollo de sistemas utilizados desde el hogar hasta la industria. Actualmente dentro de los planes de estudio actuales de las carreras orientadas al ámbito de las TIC‟s y específicamente en las carreras de Bachilleratos Técnicos, Ingenierías y Licenciaturas en Computación, se ha detectado que pocas o ninguna incluyen en su plan un contenido donde el estudiante “conozca, practique y diseñe” con sistemas computacionales que interactúen con el ambiente que rodea a la computadora. Y debido al rumbo que llevan las nuevas tecnologías y a los avances relacionados, y para no quedar en el último vagón del tren del desarrollo, es muy importante que los graduados de dichas carreras, obtengan este plus que implica una mejor competencia como profesionales de la computación. Es por lo anterior que es surge este libro como una guía teórico-práctica de estudio de la plataforma Arduino, pieza central de los sistemas de Computación Física mencionados anteriormente, el presente documento se divide en secciones donde se aborda el uso del sistema Arduino en el manejo de dispositivos puntuales, que a la larga pueden unirse en un solo proyecto de grandes dimensiones y alcances. 6 Guía Teórico Práctica Aprende ARDUINO La presente guía teórico-práctica está dirigida a todo aquel que desee obtener un conocimiento teórico desde los básico de la plataforma Arduino hasta el uso de sensores y actuadores avanzados, y que a partir de estos pueda programar y construir proyectos más avanzados, además se recomienda su uso en los cursos y programas de asignaturas relacionadas a los sistemas electrónicos programables, en las carreras de secundaria y/o nivel superior. Los conocimientos previos requeridos para el futuro lector son: dominio de las leyes fundamentales de la electricidad, el manejo de dispositivos de Electrónica Analógica, el conocimiento de la Electrónica Digital con sus compuertas lógicas y algebra booleana, además del conocimiento básico de algoritmia y programación estructurada. Cada sección se ha desarrollado de una forma sencilla pero efectiva de abordar cada tema, en el desarrollo de cada capítulo se estudia un componente en específico, sensor o actuador, y su manejo a través de la plataforma Arduino, sentando los conceptos teóricos que involucra el manejo de estos y además de los respectivos ejemplos para reforzar la teoría, se recomienda seguir y desarrollar todos los ejemplos de cada sección para lograr una mejor comprensión de los contenidos. El autor espera que la lectura de este documento sea de mucho agrado y beneficio para el lector. 7 Guía Teórico Práctica Aprende ARDUINO 1. Conociendo la plataforma ARDUINO En este capítulo se describirá el concepto detrás de la plataforma Arduino, se trataran aspectos introductorios para conocer el hardware y software que la componen, así como una breve introducción a los diversos modelos de placas o hardware disponible, sus requerimientos técnicos de hardware y su lenguaje de programación. ¿Qué es Arduino? En su página web oficial (http://www.arduino.cc), se define a Arduino como una plataforma de desarrollo completa (hardware y software) basada en un Microcontrolador y destinada a ser usada en aplicaciones de Computación Física, su hardware está basado en una sencilla placa electrónica con entradas y salidas analógicas y digitales para la conexión de diversos sensores y actuadores, además su software se basa en un entorno de desarrollo implementado en el lenguaje Processing 1 – muy parecido al lenguaje de programación C en estructura y sintaxis. En términos simples, la plataforma Arduino es un pequeño sistema computacional que puede ser programado con nuestras instrucciones para interactuar con su entorno físico por medio de diversas formas de entradas y salidas, figura 1-1. Aunque es posible que no parezca demasiado, lo es, una tarjeta Arduino permite la creación de dispositivos que pueden interactuar con el entorno que lo rodea, mediante el uso de una gama casi ilimitada de dispositivos de entrada y salida: sensores, indicadores, pantallas, motores, y más, se puede programar las interacciones precisas que se requieren para crear un dispositivo funcional. Por ejemplo, los artistas han realizado instalaciones con los patrones de luces parpadeantes que responden a los movimientos de los transeúntes, estudiantes han construido robots autónomos que pueden detectar una llama y apagarla y geógrafos han diseñado sistemas que monitorean la temperatura y la humedad y transmitir estos datos a sus oficinas a través de mensaje de texto. De hecho, se puede encontrar un número casi infinito de ejemplos con una búsqueda rápida en Internet. En alguna forma se podría pensar en la tarjeta Arduino como hijo de una computadora de escritorio tradicional, en sus raíces, el Arduino es esencialmente una pequeña tarjeta madre o motherboard, que puede ser programada por medio de un lenguaje de programación, para ejecutar las acciones que l usuario requiere. La tarjeta Arduino es capaz de tomar los insumos o estímulos del entorno físico (como la pulsación de un botón o un la lectura de un sensor de luz) y a partir de esta información, procesarla a través de su programación para controlar varias salidas (como un luz LED parpadeante o un motor eléctrico). Ahí es 1 8 http://processing.org/ Guía Teórico Práctica Aprende ARDUINO donde el término "computación física" nace - un Arduino es capaz de tomar el mundo de la electrónica y relacionarlo con el mundo físico de manera real y tangible. Figura 1-1. Aspecto y dimensiones de la tarjeta Arduino modelo UNO. (https://www.sparkfun.com) El desarrollo de la plataforma Arduino y sus aplicaciones están basadas en la filosófica open-hardwaresource significa que tanto su diseño electrónico como su distribución en software son libres. Es decir, puede utilizarse libremente para desarrollar cualquier tipo de proyecto sin tener que adquirir ningún tipo de licencia. La plataforma Arduino fue desarrollada en el Instituto de Diseño de Ivrea en Italia, por un equipo de trabajo formado por 5 ingenieros, que buscaban acercar el mundo de la electrónica a los diseñadores de software para la creación de dispositivos interactivos2. El desarrollo de esta herramienta ha dado pie a toda una revolución en el mundo de la computación física ya que ha permitido unir dos grandes campos de las ciencias aplicadas: la electrónica y la informática. Y es un gran apoyo para : programadores experimentados que desean un acercamiento a la electrónica, sin la necesidad de construir sus propias tarjetas de circuito impreso de prototipo, además a diseñadores de hardware electrónicos con poca o nula experiencia en programación, les brinda la facilidad de un entorno y lenguaje de programación sencillo. 2 9 http://spectrum.ieee.org/geek-life/hands-on/the-making-of-arduino/0 Guía Teórico Práctica Aprende ARDUINO El sistema Arduino puede utilizarse en el desarrollo de objetos interactivos autónomos o puede conectarse a un PC a través del puerto serie utilizando lenguajes como Visual Basic, PHP, C++, Flash, Processing, MaxMSP, etc... Las posibilidades de realizar desarrollos basados en Arduino tienen como límite la imaginación. Asimismo, su sencillez y su bajo coste, recomiendan su uso como elemento de aprendizaje e iniciación en el mundo de la electrónica digital. El Hardware Arduino Como se mencionó anteriormente el sistema Arduino es la unión de Hardware y Software, que permite el desarrollo de aplicaciones de Computación Física, el hardware de Arduino lo constituyen sus placas o tarjetas electrónicas basadas en el Microcontrolador ATMEGA, e incluyen una interfaz USB para la descarga del firmware además de terminales que ponen a disposición del diseñador los pines de entrada/salida del Microcontrolador interno a la tarjeta. Los modelos de tarjetas Arduino son variadas en número de entradas/salidas, pero todas responden al mismo lenguaje de programación, algunos de los modelos de tarjetas Arduino disponibles se muestran en la figura 1-3 y en http://arduino.cc/en/Main/Products La tarjeta básica y más popular de Arduino es la modelo UNO, figura 1-2, que contiene para interacción con el usuario catorce entradas/salidas digitales, seis entradas analógicas y un puerto serial que permite realizar comunicación con periférico, además de un puerto serial una conexión USB, en la figura 1-3 se puede observar la localización de las entradas analógicas y digitales disponibles para la interacción entre Arduino y su entorno físico, por medio de sensores y actuadores, además se puede observar la localización de los pines de alimentación y del Microcontrolador Atmega328P. A continuación se explorara a detalle el hardware de la tarjeta Arduino Uno, para observar con las ventajas que se dispone en ella, para comenzar, en el extremo izquierdo de la placa tenemos las conexiones USB y de Alimentación de Voltaje, figura 1-5, en el extremo izquierdo está el conector de bus serie universal que conecta la Arduino tarjeta al computador, por tres razones: para suministrar alimentación a la placa, para descargar las instrucciones o programa a la memoria interna de Arduino, y para la comunicación de datos desde una computadora. A la derecha de la imagen se observa el conector de alimentación de voltaje, a través de este conector se puede alimentar la Arduino con un una fuente de alimentación externa de 9 Vdc, y así hacer la implementación de un sistema autónomo de la alimentación de la computadora. Figura 1-2. Vista frontal y trasera de una tarjeta Arduino modelo UNO. (https://www.arduino.cc) 10 Guía Teórico Práctica Aprende ARDUINO Figura 1.3 – Algunos modelos de tarjetas ARDUINO (www.adafruit.com). Figura 1-4 – El hardware de la tarjeta Arduino modelo UNO. (http://solorobotica.com) 11 Guía Teórico Práctica Aprende ARDUINO Figura 1-5. Conectores USB y de Alimentación de Voltaje de una tarjeta Arduino (http://nostarch.com/) Figura 1-6. Microcontrolador Atmga328p, corazón del Arduino UNO (www.adafruit.com ) En la mitad inferior está el corazón de la tarjeta Arduino: el Microcontrolador3, como se muestra en la Figura 1-6, este es el "cerebro" del Arduino, el elemento que le brinda la capacidad de procesamiento computacional a Arduino, se trata de un pequeño chip que contiene un procesador o CPU para ejecutar las instrucciones de un programa informático almacenado en su memoria interna, este Microcontrolador proporciona diversas vías o pines para poder de enviar y recibir datos para sensores y actuadores. Un Microcontrolador se dice que es una computadora de un solo chip, ya que en su interior se encuentran los bloques funcionales necesarios para implementar un sistema computacional, dentro se encuentra una CPU, además de un bloque de memoria (ROM y RAM), un circuito reloj interno, y periféricos de Entada/Salida para la comunicación externa4. El Microcontrolador dentro de una tarjeta Arduino es el Atmega328p5, en la versión Arduino UNO, es fabricado por la compañía ATMEL dentro de la familia AVR de Microcontroladores RISC de 8 bits. Otras placas Arduino están basadas en diversos modelos de Microcontroladores siempre del fabricante ATMEL y de la familia AVR. 3 http://es.wikipedia.org/wiki/Microcontrolador 4 http://my.safaribooksonline.com/book/electrical-engineering/9780071771337/chapter-13dot-microcontrollers/ch13_html 5 http://es.wikipedia.org/wiki/AVR 12 Guía Teórico Práctica Aprende ARDUINO Figura 1-7. Pines de alimentación y análogos de la tarjeta Arduino UNO (http://nostarch.com/). Siguiendo con la descripción de la partes de la placa Arduino, justo debajo del Microcontrolador se encuentran son dos filas de pines de conexión tipo “hembra”, también llamados female headers, como se muestra en la Figura 1-7, la primera fila a la izquierda ofrece conexiones de alimentación y la capacidad de utilizar un pulsador externo para enviar una señal de RESET a la placa, la fila de la derecha ofrece seis entradas analógicas que se utilizan para medir señales eléctricas que varían en voltaje, es en estas entradas que se podrá conectar sensores de tipo analógico. En la parte superior de la tarjeta se encuentran dos filas más de pines de conexión o headers, como se muestra en la Figura 1-8, están numerados de 0 a 13, y son pines de entrada/salida digital, con estos se pude detectar si una señal eléctrica está presente o se puede generar una señal de activación, además los pines 0 y 1 son también conocidos como el Puerto serie de Arduino, que se utiliza para enviar y recibir datos a otros dispositivos, tales como un computador a través del conector USB. Los pines marcados con una virgulilla (~) también pueden generar una señal eléctrica variable PWM, que puede ser útil para cosas como la creación de efectos de iluminación o el control de motores eléctricos, en secciones posteriores se tocara este tema. Figura 1-8. Pines digitales de la tarjeta Arduino UNO (www.adafruit.com ). Otros componentes dentro de la tarjeta Arduino son los diodos emisores de luz (LEDs), figura 1-9, estos diminutos dispositivos se encienden cuando una corriente pasa a través de ellos, la placa Arduino tiene cuatro LEDs: uno marcado como ON o POWER que sirve para indicar que la tarjeta tiene energía, además de dos LEDs etiquetados TX y RX que se iluminan indicando que se están transmitiendo o recibiendo datos entre el Arduino y los dispositivos conectados a través del puerto serie USB. Otro LED marcado L se conecta al pin digital número 13 y puede ser utilizado por el diseñador como testeo de funcionamiento de la tarjeta. 13 Guía Teórico Práctica Aprende ARDUINO Figura 1-9. LEDs montados en la tarjeta Arduino UNO (http://nostarch.com/). Figura 1-10. Botón de RESET de la tarjeta Arduino UNO (http://nostarch.com/).. Y, por último, dentro de toda placa Arduino se encuentra el botón RESET , Figura 1-10, que al igual que con una computadora normal, a veces las cosas pueden ir mal con el Arduino, y cuando todo lo demás falla, puede que tenga que reiniciar el sistema Arduino, pues esta es la función del botón RESET dentro de la tarjeta. Figura 1-11– Ejemplos de montajes con Arduino (http://learn.adafruit.com) 14 Guía Teórico Práctica Aprende ARDUINO Una de las grandes ventajas del sistema de Arduino es su facilidad de expansión en hardware, es fácil añadir más funciones de hardware a la capacidad básica de la tarjeta Arduino, las dos filas de pines a lo largo de cada lado de la Arduino permiten la conexión de un escudo o shield, esto es otra placa electrónica con los pines que le permiten conectarse sobre la placa Arduino. Por ejemplo, en la Figura 1-12 se muestra un escudo para Arduino que contiene una interfaz Ethernet que permite que el Arduino pueda comunicarse a través de redes e Internet, este es conocido como Escudo Ethernet, para más sobre los tipos de escudos o shields para Arduino, se recomienda visitar: http://shieldlist.org/ Figura 1-12. Dos modelos de escudos para la tarjeta Arduino (shieldlist.org). Figura 1-13. Aspecto y dimensiones de la tarjeta Arduino MEGA. (https://www.sparkfun.com) 15 Guía Teórico Práctica Aprende ARDUINO Otro de los modelos más usados es la tarjeta Arduino modelo MEGA, figura 1-13, esta placa es un poco más grande que la versión UNO en lo que a pines de entrada y salida se refiere, el Arduino MEGA dispone de 54 terminales de entrada/salida digital además de 16 entradas analógicas, además contiene trece salidas digitales tipo PWM, , además de 4 puertos seriales TTL gracias a su Microcontrolador central el ATMEGA2560, con lo cual la hace una de las placas más grandes dentro de los modelos Arduino, existen más modelos que difieren en número de terminales, pero todas se programan de igual forma , así que solo debemos de preocuparnos en elegir el modelo que más se apegue a nuestras necesidades de entras y salidas, para conocer todos los modelos disponibles pude consultar: http://arduino.cc/en/Main/Products A continuación se detallan las características técnicas y de funcionamiento más importantes de los dos modelos más populares de Arduino: UNO y MEGA, cabe recordar que existen más modelos de tarjetas Arduino y cada una solo cambia en número de entradas y salidas disponibles en la placa, y que desde el punto de vista de programación todas son iguales. Algunas características técnicas de funcionamiento de la tarjeta Arduino UNO (también válida para la tarjeta modelo NANO) se detallan a continuación: Microcontrolador ATmega328 Voltaje de Operación 5V Voltaje de Entrada 7-12 V Numero de Pines E/S Digitales 14 (21 max.) Número de Entradas Análogas 6 Corriente de Salida por pin 40 mA Memoria FLASH 32 KB SRAM 2 KB EEPROM 1 KB Velocidad de Reloj 16 MHz La tarjeta Arduino modelo MEGA es otra de las más populares, las características de esta placa se presentan a continuación, y en la figura 1-13 se puede apreciar la forma física de esta tarjeta. Microcontrolador ATmega2560 Voltaje de Operación 5V Voltaje de Entrada 7-12 V Numero de Pines E/S Digitales 54 Número de Entradas Análogas 16 Corriente de Salida por pin 40 mA Memoria FLASH 256 KB SRAM 8 KB EEPROM 4 KB Velocidad de Reloj 16 MHz Para más información sobre características técnicas de todos los modelos de tarjetas Arduino disponibles, visite: http://arduino.cc/en/Products.Compare 16 Guía Teórico Práctica Aprende ARDUINO El Software Arduino. El otro componente del sistema Arduino es el IDE o software que permite programar la tarjeta Arduino, este IDE es un Ambiente Integrado de Desarrollo donde se puede editar, copilar y programar el firmware de la aplicación Arduino, el lenguaje de programación es el “lenguaje C/C++”, en la figura 1-14 se aprecia la interface gráfica del IDE Arduino. Figura 1.14 – Interface gráfica del IDE Arduino (arduino.cc). La programación de la plataforma Arduino es sencilla, simplemente requiere un poco de conocimiento de lenguaje estructurado, el uso de librerías y objetos, y para aquellos con un poco de experiencia en programación en lenguajes estructurados será muy sencillo el desarrollar programas para Arduino, en la figura 1-15 se aprecian algunos botones que componen el interfaz IDE Arduino. Una ventaja del sistema Arduino es que su IDE es descargable completamente gratis, www.arduino.cc, además debido a que es una plataforma desarrollada baja la filosofía Open Source Hardware, existe una gran base de conocimiento sobre el uso del IDE y ejemplos de programas de aplicación para Arduino. La interface y programa IDE Arduino está desarrollado usando el lenguaje Processing, de ahí su enorme parecido con este, el IDE cuenta con todas las herramientas necesarias para codificar, compilar y descagar nuestros programas a la memoria del Microcontrolador dentro de la tarjeta Arduino, los archivos de código fuente creados por el IDE tienen la extensión .ino y son denominados sketches. A continuación se describirán aspectos funcionales de IDE Arduino, de la figura 1-15, se pueden notar que en la parte superior del IDE se tienen 6 botones principales, a continuación se describe su funcionamiento de cada botón, de izquierda a derecha: 17 Guía Teórico Práctica Aprende ARDUINO Verify (Verificar): Verifica que el código introducido sea correcto y lo compila, en caso de error nos indica la línea donde ocurrió. Upload (Cargar): Compila el programa y lo sube a la placa Arduino. New (Nuevo): Crea un nuevo sketch. Open (Abrir): Abrir un sketch existente Save (Salvar): Guarda el sketch actual. Serial Monitor: Muestra una terminal serial, esta herramienta será útil para comunicarnos con el Arduino desde el PC, comúnmente se utiliza como consola de depuración. Debajo de los botones está el área de código, donde se es escribe y edita el programa, automáticamente colorea las palabras reservadas por el compilador. Figura 1-15. Aspectos principales de la Interface gráfica del IDE Arduino (newtechandme.com). En la parte inferior está la consola de comandos, ahí es donde se informara de errores y progreso del proceso de compilación y programación de la placa; más abajo del lado izquierdo nos indica el número de línea donde se encuentra el cursor y del lado derecho nos indica la versión de placa conectada y el puerto serie a utilizar. Un programa típico en lenguaje de programación Arduino está constituido por sentencias o estamentos escritos usando instrucciones en lenguaje C de Arduino, más adelante se abordara este tema, como primer contacto con el lenguaje observe el listado del programa siguiente, el cual se denomina el “hola mundo” de los Microcontroladores y su función es encender y apagar un LED conectado a una salida de la tarjeta 18 Guía Teórico Práctica Aprende ARDUINO Arduino, también observa la figura 1-8 donde se muestra la conexión de un LED a la tarjeta Arduino. Por el momento no se explicaran las funciones y sintaxis del programa, en secciones posteriores se tocaran. /* Blink . Led Parpadeante Enciende y apaga repetidamente un LED concetado al pin 13,con un periodo de 1segundo. Este ejemplo es de Dominio Publico CC. */ // En la mayoria de tarjetas Arduino existe un LED conectado de fabrica la pin 13. int led = 13; // La rutina SETUP se ejecuta una sola vez. void setup() { pinMode(led, OUTPUT); // inicializar el pin como salida. } // la rutina LOOP se ejecutara repetidamente void loop() { digitalWrite(led, HIGH); // enciende el LED (HIGH indica 5Vdc) delay(1000); // una espera de 1seg. digitalWrite(led, LOW); // apagar el LED (LOW indica 0Vdc) delay(1000); // una espera de 1seg. } //Fin del sketch Listado 1– Programa “Blink” para Arduino (www.arduino.cc) Figura 1-8– Esquema del circuito para el programa BLINK (www.arduino.cc) En las secciones posteriores se describirán más a detalle aspectos de programación y específicamente el uso de Arduino con diversos componentes externos: sensores y actuadores, específicamente la sección siguiente trata sobre la puesta a punto y prueba inicial de nuestra tarjeta Arduino. 19 Guía Teórico Práctica Aprende ARDUINO 2. Iniciando con ARDUINO En este capítulo se explicara como iniciar en el uso de la tarjeta Arduino, se estudiara como configurar una computadora para trabajar con Arduino y además se comprobara el correcto funcionamiento de una tarjeta Arduino a través de la implementación del programa “hola mundo”. La siguiente es una guía práctica que se puede desarrollar para comprobar el funcionamiento correcto de una tarjeta Arduino y no se requiere más hardware adicional que la propia placa. Puesta a punto del Hardware Como se mencionó, en esta sección podremos configurar el Arduino para poder descargarle programas, también llamados Sketch, a través de una computadora PC o Laptop, se asume el uso de una tarjeta Arduino UNO (aunque lo siguiente también aplica a la mayoría de versiones de Arduino) y del sistema operativo Windows. Cabe aclarar que la plataforma Arduino también puede ser instalada y programada desde sistema operativo Linux y Mac, para detalles de instalación usando cualquiera de estos dos sistemas operativos se recomienda consultar http://arduino.cc/en/main/software Figura 2-1. Tarjeta Arduino mas cable USB, hardware para iniciar (newtechandme.com). 20 Guía Teórico Práctica Aprende ARDUINO Figura 2-1-1. Tarjeta Arduino mas cable USB, contactada a una PC (learn.adafruit.com). Lo primero es conseguir tu tarjeta Arduino UNO u otra versión (MEGA, NANO, LEONARDO), ya sea fabricada por el equipo oficial en Italia o por de cualquier fabricante de hardware electrónico, ya que como Arduino es una plataforma open hardware existen múltiples fabricantes basados en lo esquemas disponibles en www.arduino.cc, además de la tarjeta se necesitara un cable USB para la conexión de la PC a la tarjeta Arduino, es vía este puerto que se hará la transferencia del programa a cargar en el Microcontrolador dentro de Arduino. El próximo paso es obtener el software de aplicación ARDUINO IDE que es el entorno de desarrollo para programas destinados a toda la variedad de placas Arduino, este software se puede descargar sin costo desde http://arduino.cc/en/Main/Software , se recomienda la descarga de última versión del IDE para el sistema operativo a usar. En esta web se encontraran dos opciones de descarga: un archivo Exe o un archivo Zip conteniendo una carpeta con todos los archivos necesarios. Si se descarga el archivo .exe, la instalación solo consiste en ejecutar este archivo, y este instalara automáticamente todos los drivers y el IDE Arduino, y pase a la página 23. Si se descarga el archivo Zip se recomienda seguir el procedimiento siguiente: Cuando la descarga finalice, se debe descomprimir el archivo en una carpeta de tu preferencia, por ejemplo: dentro de la carpeta Archivos de Programas, una vez descomprimida, se obtendrá una carpeta nombrada “arduino-00XX” dentro se tendrán una serie de archivos y subcarpetas, por el momento eso es todo por el momento. Luego se deben instalar los drivers o controladores en la computadora para que esta pueda reconocer y comunicarse correctamente con nuestra tarjeta Arduino, conecta la placa Arduino a tu computadora usando el cable USB, el LED verde (rojo o amarillo) indicador de la alimentación (nombrado como PWR en la placa) 21 Guía Teórico Práctica Aprende ARDUINO debería quedar encendido a partir de ese momento. Es posible que el segundo LED de tu placa Arduino comience a parpadear es normal, y si no lo hace es normal también, no te preocupes. Para instalar los Drivers o Controladores por primera vez en una computadora bajo Windows, se deben de seguir lo siguiente pasos: 1. Conectar la Tarjeta Arduino a un puerto USB libre de la computadora y esperar a que Windows comience el proceso de instalación normal del controlador. Después de unos segundos, aparecerá un cuadro de dialogo anunciando que el proceso fallo (es normal, no hay que preocuparse). Figura 2-2. Mensaje al conectar por primera vez una Tarjeta Arduino. 2. Lo anterior simplemente indica que se deben instalar los controladores de Arduino manualmente, así que, dar clic en Inicio, y abrir el Panel de Control, y navegar hasta el menú Sistema y Seguridad, luego dentro del apartado Sistema abrir el Administrador de Dispositivos. 3. Buscar en el ítem Puertos (COM & LPT), al expandirlo se deberá ver un puerto llamado "Arduino UNO (COMxx)" o similar, por ejemplo “Comunication Port”. Hay que nota el triángulo Amarillo, este es la placa Arduino conectada, importante: Anotar el número de puerto COM al cual se ha conectado la placa Arduino Figura 2-3. Vista del Administrador de Dispositivos al conectar por primera vez Arduino. Note que se ha usado un Arduino MEGA 4. Sobre el nombre del puerto presionar click derecho y selecciona la opción “actualizar software del controlador …” 5. A continuación seleccionar la opción “Buscar software de controlador en equipo” y después navegar hasta la carpeta Drivers de la carpeta Arduino que se descargó previamente. 6. Windows terminará la instalación de los drivers para tu placa Arduino. Es de notar que este proceso generalmente solo es necesario la primera vez que conectas la placa Arduino. 22 Guía Teórico Práctica Aprende ARDUINO Figura 2-4. Tarjeta Arduino MEGA instalada. Para comprobar que los drivers de la tarjeta Arduino se han instalado correctamente, se debe abrir la carpeta del Administrador del Dispositivos, en el grupo Dispositivos del panel de control del sistema. Buscar "USB Serial Port" o "Arduino UNO” o “Arduino MEGA” o algo similar, en la sección de puertos; esa es la placa Arduino. Anotar el puerto COM en el cual está conectado el Arduino. Descargado el primer programa Arduino Luego de haber instalado correctamente los controladores de la tarjeta Arduino, ya está lista para poder recibir desde la computadora el programa que será grabado en la memoria interna del Microcontrolador para ser ejecutado por Arduino, este proceso de descarga se realiza a través del ARDUINO IDE, que es un ambiente Integrado de Desarrollo para aplicaciones Arduino. Para ejecutar el Arduino IDE navega hasta la carpeta Arduino que descargaste previamente y haz doble clic en el archivo de aplicación Arduino, se ejecutara el IDE de Arduino e iniciara en la pantalla principal. Luego se debe configurar el Arduino IDE con el modelo de tarjeta y el número de puerto COM donde esta nuestro Arduino, para seleccionar el tipo de placa de tu Arduino en el menú Herramientas > Tarjetas. Selecciona la versión de placa Arduino que tengas conectada. Ahora selecciona el número de puerto serie de la placa Arduino en el menú Selecciona el puerto COM que anotaste del Administrador de Dispositivos. Herramientas > Puertos Serie. Lo más probable es que sea COM3 o mayor (COM1 y COM2 se reservan, por regla general para puertos serie de hardware). Para asegurarte de cuál es, puedes desconectar la placa y volver a mirar el menú; el puerto de la placa habrá desaparecido de la lista. Reconecta la placa y selecciona el puerto apropiado. 23 Guía Teórico Práctica Aprende ARDUINO Figura 2-2: Pantalla principal del Arduino IDE Figura 2-3: Selección del modelo de tarjeta Arduino desde el IDE 24 Guía Teórico Práctica Aprende ARDUINO Figura 2-4: Selección del puerto COM al que se conecta la tarjeta Arduino. En este punto la tarjeta e IDE Arduino están preparados para que comiences a escribir y descargar programas a la placa, ahora para probar que la placa se instaló y funciona correctamente, Abre el programa de ejemplo para hacer parpadear un LED ("LED blink"): Archivo > Ejemplos > Basic > Digital > Blink. Figura 2-5: El programa de ejemplo BLINK 25 Guía Teórico Práctica Aprende ARDUINO Ahora simplemente pulsa sobre el botón "Descargar" en el Entorno Arduino, botón con la Flecha en el extremo superior izquierdo. Espera unos pocos segundos - deberías ver parpadear los led RX y TX de la placa. Si la descarga del código es exitosa verás aparecer el mensaje "Carga Terminada" en la barra de estado inferior. Unos pocos segundos después de finalizar la descarga del programa deberías ver cómo el led de la placa conectado al pin 13 (L) comienza a parpadear (con un color naranja, rojo o verde). Si ocurre esto ¡felicidades! Ya tienes tu Arduino listo y funcionando. Figura 2-6 Ubicación de los LEDs instalados dentro de la tarjeta Arduino UNO (oreilly.com). ¿Problemas con la descarga? Si tienes problemas con la descarga del programa puedes probar los siguientes, hay algunas cosas que podrían no estar bien. En primer lugar asegúrate de que tu placa está encendida (el LED PWR está encendido) y conectada a la computadora. A continuación, comprueba que el puerto correcto se ha seleccionado en el menú Herramientas > Puerto Serial (si el puerto no aparece, reinicia el IDE con la placa conectada al ordenador). Asegúrate de que tienes la tarjeta correcta seleccionado en el menú Herramientas > Tarjetas. Si tienes conectado a tu Arduino algún sensor o actuador, específicamente usando los pines digitales 0 y 1, desconecta estos mientras se descarga el firmware (pueden conectarse y utilizarse después de que el código se haya subido). 26 Guía Teórico Práctica Aprende ARDUINO Trata de cargar con nada más conectado a la placa (aparte del cable USB, por supuesto). Asegúrate que la placa no toca nada metálico o conductor. Comprueba que no estás ejecutando ningún programa que escanee todos los puertos serie, como aplicaciones de sincronización de PDA, Bluetooth, controladores USB (por ejemplo, BlueSoleil), Virtual Daemon Tools, etc. Asegúrate de que no tienes un software de firewall que bloquee el acceso al puerto serie (por ejemplo ZoneAlarm). Si tienes una placa que no es compatible con auto-reset (Modelo LEONARDO), asegúrate de que reinicias la placa un par de segundos antes de cargar. (Arduino UNO, Diecimila, Duemilanove, Mega, y Nano soportan auto-reset al igual que LilyPad, Pro y Pro Mini con conector de programación de 6-pines). Sin embargo, en algunos equipos, es posible que tengas que pulsar el botón de reset en la placa después de clicar el botón de descarga en el entorno Arduino. Pruebe diferentes intervalos de tiempo entre los dos, hasta 10 segundos o más. Esto sucede con computadoras antiguas o que ejecutan muchos procesos en paralelo. Si recibes este error: “ device is not responding correctly”. Intenta cargar el programa otra vez (es decir, resetea la placa y pulse el botón de descarga por segunda vez). Si recibes un error tipo “st500 no sync”, desconecta la tarjeta Arduino, cierra el IDE… reconecta la placa y reinicia el IDE, intenta la descarga nuevamente. 27 Guía Teórico Práctica Aprende ARDUINO 3. Introducción a la programación de ARDUINO Como se mencionó anteriormente Arduino es un entorno completo para desarrollo de aplicación de Computación Física, este entorno está formado por la tarjeta Arduino (Hardware) y por el IDE Arduino (Software), por lo que para el diseño de alguna aplicación específica se deben realizar el diseño de ambas partes Hardware y Software. El poder del Microcontrolador dentro de una tarjeta Arduino radica en la capacidad de programarlo para que controle estados de dispositivos conectados a sus salidas a partir de los estados de sensores conectados a sus entradas, esta capacidad se le brinda a partir del diseño del Firmware o Software de aplicación a ser grabado en la memoria interna de Arduino y que será ejecutado dentro de la tarjeta. A continuación se describirá una breve introducción al diseño del Firmware, también llamado SKETCH en jerga Arduino, dejando para las secciones posteriores el estudio específico de instrucciones destinadas a ser usadas con sensores o actuadores puntuales. Conceptos Básicos de Programación Antes de iniciar el estudio de instrucciones y de cómo realizar programas para la Arduino, vale la pena hacer un repaso a conceptos básicos sobre la programación: Programación (Programar): Acción de diseñar e implementar una solución a un problema usando un lenguaje de programación para ser ejecutado en un dispositivo digital programable: Microcontrolador (uC) o Microprocesador (uP). Algoritmo: Secuencia ordenada de pasos a seguir para resolver un problema o tarea, expresado es lenguaje natural. Lenguaje de programación: Conjunto de instrucciones con los que se pueden escribir los algoritmos para ser interpretados por un dispositivo computacional. Programa (Firmware o Sketch): Secuencia de instrucciones (comandos - código) escritas en un Lenguaje de Programación con el objetivo de ser ejecutadas en un procesador (Arduino). Lenguaje Maquina: Conjunto de instrucciones en binario que puede interpretar y ejecutar la CPU de un Up o Uc. 28 Guía Teórico Práctica Aprende ARDUINO Instrucciones: Sentencias u oraciones escritas en lenguaje de programación y que conforman un listado de programa o sketch. Sintaxis: Forma correcta de escribir las instrucciones dentro del lenguaje de programación. Estructura de control: Sentencias que permiten conjuntar instrucciones dentro de un Sketch para una mejor estructuración y lectura del Sketch. Tipo de Datos: Dentro todo lenguaje de programación a usar, los tipos de datos reconocidos son importantes ya que nos indican con que tipos de números y/o letras podemos trabajar, algunos ejemplos son: Entero, Decimal, Caracter, Cadenas de Caracteres, etc . Más adelante se estudiaran con detalle estos tipos de datos. Variable: Una variable se entiende como un espacio en memoria que se le asigna un nombre y puede almacenar un dato que puede cambiar o no dentro la ejecución del Sketch. Periféricos: Se le conoce a bloques de hardware que dispone la tarjeta Arduino y que son los dispositivos que ejecutaran las acciones indicadas por el Sketch. Función: En el lenguaje de programación de Arduino, se entiende como una instrucción ejecutable por el CPU y que al mismo tiempo es un subconjunto de instrucciones que se pueden repetir dentro de un sketch, posteriormente se tocara más acerca de las funciones propias de Arduino y como el usuario puede también crear sus propias funciones. Un Sketch es un programa diseñado para ser ejecutado por la CPU de Arduino para manipular sus entadas y salidas, el diseño de este es básicamente como realizar un programa para una computadora de escritorio, se reconocen algunos pasos o etapas a considerar en el proceso de diseño de un sistema integrado de computación física basado en Arduino, a continuación se describen: Proceso de diseño de un Sistema con Arduino Cuando se inicia un el diseño de un proyecto, es posible que se esté tentado a querer escribir el código del programa inmediatamente después de que se nos ocurre una idea, sin embargo, antes de comenzar a codificar, es necesario definir algunos aspectos de diseño previo, a modo de plan detallado como fundación para el desarrollo de un proyecto exitoso, se recomienda que cuando se inicie un proyecto nuevo, se sigan los siguientes pasos: Necesidad o Problema a resolver: es la situación real que necesita ser solventada, esta necesidad puede ser de casi cualquier naturaleza, por ejemplo: la necesidad de activación sincronizada del timbre en un colegio, el conteo automático de los pasajeros de un autobús, el aviso remoto de alguna situación de peligro en nuestro hogar, permitir la entrada a un recinto a personas autorizadas, etc. Idea de solución de una necesidad: este paso implica la decisión de aplicar una solución basada en un sistema de Computación Física basada en Arduino, además de analizar diferentes opciones de hardware electrónico a utilizar es decir realizar una factibilidad tanto económica como técnica. 29 Guía Teórico Práctica Aprende ARDUINO Diseño del hardware electrónico del sistema: en este paso nos encargamos de tomar los componentes, analizar sus hojas técnicas y datos de conexión, para diseñar el circuito electrónico completo de nuestro sistema. Implementación del hardware: basado en el diseño anterior se implementa el circuito real, ya sea en cualquiera de las formas disponibles: breadboard, tarjetas perforadas o circuito impreso (PCB), listo para recibir el programa que lo hará funcionar. Diseño del firmware o Sketch: implica la creación del código en lenguaje de programación para ser grabado en la memoria interna del Arduino, se pueden diferenciar 3 sub-etapas, la primera el Análisis que requiere el conocimiento de las necesidades de funcionamiento del sistema además de las características del lenguaje de programación a utilizar, una segunda etapa es el Diseño que implica la creación de un Algoritmo y Flujograma respectivo del programa de solución y por último la Codificación que requiere la transformación del Flujograma en código fuente en lenguaje de programación Arduino utilizando el IDE. Generalmente en aplicaciones de computación física basada en Arduino es muy común realizar la Codificación como primer paso del diseño del Sketch, pero se recomienda siempre al menos realizar un Algoritmo como guía. Compilar y descargar: En esta etapa se utiliza el IDE Arduino para compilar el código, transformarlo a código binario que entiende el CPU de Arduino, y luego descargarlo a través del puerto USB hacia el Arduino. Integración y pruebas: Se considera la etapa final que implica la puesta en funcionamiento del sistema dentro del escenario real de la aplicación, y realizar las pruebas necesarias de verificación, si algo no funciona como se espera se debe volver al diseño del Sketch para realizar las modificaciones necesarias. En resumen, todo programa (Firmware o Sketch) intenta resolver un problema (tarea o necesidad), al comenzar un programa, lo primero es definir el procedimiento general que este debe seguir, un algoritmo, el algoritmo se transforma en flujograma, y este se debe codificar en un listado escrito código en un lenguaje de programación especifico, este código debe transformase en lenguaje que interpreta la CPU, lenguaje maquina 1s y 0s, este proceso de conversión se denomina compilar. Un Sketch para Arduino debe seguir una estructura específica, además de una serie de componentes programáticos que los conforman, a continuación se describirán las diversas partes que todo Sketch debe tener y conforman su estructura funcional. Estructura básica de un Sketch Todo programa en el lenguaje de programación Arduino, se divide en varios bloques principales y dependientes el uno del otro. El primer gran bloque de programación es el lugar donde vamos a declarar los recursos utilizados en el programa principal. En este bloque declararemos todas las variables que vamos a utilizar, estableceremos el nombre que le asignamos a cada terminal de la tarjeta Arduino, constantes, etc. Luego está el bloque de configuración, Setup, y luego el bloque de instrucciones, Loop, luego de describirán estos ampliamente, en la figura siguiente se puede observar un Sketch con su estructura identificada. 30 Guía Teórico Práctica Aprende ARDUINO Figura 3-2. Bloques de un Sketch en lenguaje Arduino (ladyada.net) El segundo gran bloque de programación es el programa principal; se puede encontrar en un programa a partir de la sentencia void setup(). A partir de aquí, podemos distinguir otras dos partes, una que solo se ejecutara una sola vez al iniciar el programa y otra parte en la que se generará un bucle infinito. La parte que solo se ejecuta una vez suele ser utilizada para iniciar comunicaciones serie, i2c, isp, etc. declarar la función de las terminales de la tarjeta Arduino: entradas o salidas, y también este bloque se instrucciones puede ser utilizada para asignar valores predefinidos a variables. El bucle infinito el cual se encuentra a partir de void loop() abarca el programa que se ejecutará en el microprocesador de la tarjeta Arduino. También podemos observar que cada grupo de bloques se encuentra comprendido entre 2 llaves que los delimita, que cada sentencia acaba con punto y coma y que se pueden agregar comentarios al programa sin que afecte a este añadiendo 2 barras laterales. 31 Guía Teórico Práctica Aprende ARDUINO En conclusión todo Sketch posee tres partes bien definidas: Declaraciones, Inicializaciones (Setup) y Programa Principal (Loop). En donde setup() es la parte encargada de recoger la configuración y loop() es la que contiene el programa que se ejecutará cíclicamente (de ahí el término loop –bucle-). Ambas funciones son necesarias para que el programa trabaje. La función de configuración debe contener la declaración de las variables. Es la primera función a ejecutar en el programa, se ejecuta sólo una vez, y se utiliza para configurar o inicializar pinMode (modo de trabajo de las E/S), configuración de la comunicación en serie y otras. La función principal repetitiva infinita contiene el código que se ejecutara continuamente (lectura de entradas, activación de salidas, etc), esta función es el núcleo de todos los programas de Arduino y la que realiza la mayor parte del trabajo. Aspectos de programación del Lenguaje Arduino. Dentro de todo lenguaje de programación existen ciertos aspectos de sintaxis que todo programa debe cumplir y que son generales a cualquier Sketch sea cual sea su función, a continuación se describirán estos aspectos a considerar: Comentarios. Los comentarios son una parte importante de todo lenguaje de programación, un comentario es una línea de texto explicativo acerca de la función de una línea de código, permiten al programador llevar una secuencia informativa acerca de las instrucciones, y además permiten a un usuario externo una mejor comprensión acerca de la función de cada estamento, para indicar que una línea de programa es un comentario se precede con el símbolo // y cabe mencionar que los comentarios de un programa no ocupan espacio en memoria ya que son ignorados por el compilador, la sintaxis general de un comentario es la siguiente: // Este es un comentario Entre llaves. Las llaves {} sirven para definir el principio y el final de un bloque de instrucciones, dentro de una estructura de control y se utilizan para los bloques de programación setup(), loop(), if.., etc. Una llave de apertura “{“ siempre debe tener una llave de cierre “}”, si no es así, al momento de compilar el código este indicara errores. Punto y coma El punto y coma “;” se utiliza para separar o terminar una línea de instrucción en el lenguaje de programación de Arduino. Si olvidas poner fin a una línea con un punto y coma se producirá en un error de 32 Guía Teórico Práctica Aprende ARDUINO compilación. El texto de error puede ser obvio, y se referirá a la falta de un punto y coma, o puede que no. Si se produce un error raro y de difícil detección lo primero que debemos hacer es comprobar que los puntos y comas están colocados al final de las instrucciones. Tipos de Datos Al momento de diseñar un programa utilizando cualquier lenguaje de programación es de suma importancia el conociendo de los tipos de datos soportados, para poder hacer las declaraciones necesarios según el dato a usar, Arduino permite manejar los siguientes tipos de datos: Byte – tipo de dato Entero, almacena un valor numérico de 8 bits. Tiene un rango de 0-255. Int - almacena un valor entero de 16 bits con un rango de 32,767 a -32,768. Long - valor entero almacenado en 32 bits con un rango de 2,147,483,647 a -2,147,483,648. Float - tipo coma flotante almacenado en 32 bits con un rango de 3.4028235E+38 a - 3.4028235E+38. Char – permite almacenar un único dato alfanumérico, es decir una letra, su valor numérico es el código ASCII de ese carácter alfanumérico. String – es una variable que permite guardar una cadena de caracteres alfanuméricos Arrays - se trata de una colección de valores que pueden ser accedidos con un número de índice Variables en Lenguaje Arduino. Una variable es una manera de nombrar y almacenar un valor numérico para su uso posterior por el programa. Como su nombre indica, las variables son números que se pueden variar continuamente en contra de lo que ocurre con las constantes cuyo valor nunca cambia. Una variable debe ser declarada y, opcionalmente, asignarle un valor. El siguiente código de ejemplo declara una variable llamada variableEntrada y luego le asigna el valor de 58: int variableEntrada = 0; variableEntrada = 58; // declara una variable y le // asigna el valor 0 // se asigna el valor 58 al contenido de la variable 'variableEntrada' es el nombre de la variable en sí, la primera línea declara que será de tipo entero “int”. La segunda línea fija a la variable en un valor numérico de 58. Una vez que una variable ha sido asignada, o re-asignada, usted puede probar su valor para ver si cumple ciertas condiciones (instrucciones if..), o puede utilizar directamente su valor. Nota: Las variables deben tomar nombres descriptivos, para hacer el código más legible. Los nombres de variables pueden ser “contactoSensor” o “pulsador”, para ayudar al programador y a cualquier otra persona a leer el código y entender lo que representa la variable. Nombres de variables como “var” o “valor”, facilitan muy poco que el código sea inteligible. Una variable puede ser cualquier nombre o palabra que no sea una palabra reservada en el entorno de Arduino. 33 Guía Teórico Práctica Aprende ARDUINO Todas las variables tienen que declararse antes de que puedan ser utilizadas. Para declarar una variable se comienza por definir su tipo como int (entero), long (largo), float (coma flotante), etc, asignándoles siempre un nombre, y opcionalmente, un valor inicial. Esto sólo debe hacerse una vez en un programa, pero el valor se puede cambiar en cualquier momento usando aritmética y reasignaciones diversas. El siguiente ejemplo declara la variable 'entradaVariable' como una variable de tipo entero “int”, y asignándole un valor inicial igual a cero. int entradaVariable = 0; Una variable puede ser declarada en una serie de lugares del programa y en función del lugar en donde se lleve a cabo la definición esto determinará en que partes del programa se podrá hacer uso de ella. Una variable puede ser declarada al inicio del programa antes de la parte de configuración setup(), a nivel local dentro de las funciones, y, a veces, dentro de un bloque, como para los bucles del tipo if.. for.., etc. En función del lugar de declaración de la variable así se determinará el ámbito de aplicación, o la capacidad de ciertas partes de un programa para hacer uso de ella. Una variable global es aquella que puede ser vista y utilizada por cualquier función y estamento de un programa. Esta variable se declara al comienzo del programa, antes de la función o bloque de instrucciones setup(). Una variable local es aquella que se define dentro de una función o como parte de un bucle. Sólo es visible y sólo puede utilizarse dentro de la función en la que se declaró. Por lo tanto, es posible tener dos o más variables del mismo nombre en diferentes partes del mismo programa que pueden contener valores diferentes. La garantía de que sólo una función tiene acceso a sus variables dentro del programa simplifica y reduce el potencial de errores de programación. Partes funcionales de un Sketch en Arduino. 1. Expresiones Una expresión es una combinación de operadores y operando, también se le conoce como Instrucciones para operaciones Matemáticas, Comparación y/o Lógicas entre datos numéricos y/o variables. Ejemplos de expresiones: 5+k*2 (10*var1)/var2 Como se mencionó estas expresiones pueden ser operaciones Aritméticas, Comparaciones y/o Lógicas, a continuación un resumen de los operadores que se utilizan en el IDE Arduino. 34 Guía Teórico Práctica Aprende ARDUINO Operadores Aritméticos. En el lenguaje de programación de Arduino, se reconocen los siguientes operadores aritméticos: = (Asignación): usado para asignar algún valor numérico o alfanumérico a una variable o asignar el resultado de una operación previa a una variable. var1 = 123 + (Suma): utilizado para indicar la realización de una adición entre operandos numéricos o variables con contenidos numéricos. var2 = 123 + var1 - (Resta): este operador se aplica para realizar una sustracción entre operandos numéricos o variables con contenidos numéricos. var3 = var1 - 100 * (Multiplicación): al igual que los anteriores indica la realización de la operación multiplicación entre dos o más operandos numéricos y/o variables numéricas. var4 = var3 * 4 * var2 / (División): este operador sirve para realizar una división entre dos operandos, cabe destacar que esta operación devuelve el cociente de la división, por ejemplo en la operación siguiente la variable llamada var5 valdrá 3. var5 = 14 / 4 % (Módulo): con este operador se puede obtener el Residuo o Resto de una división, por ejemplo en la operación siguiente la variable llamada var6 valdrá 5. var6 = 14 % 4 Operadores de Comparación. En el lenguaje de programación de Arduino, se reconocen los siguientes operadores usados para realizar una Comparación, estos operadores son muy útiles en las estructuras de control decisivas en las cuales se necesita evaluar una comparación entre variables del mismo tipo, recordar que estos operadores solo devuelven uno de dos resultados: verdadero o falso. = = (Igual a): cuando se necesita verificar la igualdad entre operandos numéricos o con el contenido de alguna variable. x == y; (x es igual a y) 35 Guía Teórico Práctica Aprende ARDUINO != (Distinto de): utilizado para verificar si dos operando son diferentes entre sí, la operación será verdadera si ambos números o contenidos de variables son diferentes. x != y; (x no es igual a y) < (Menor que): este operador se aplica para realizar una comparación que será verdadera siempre que el primer operando sea menor que le segundo. x < y; (x es menor a y) > (Mayor que): al igual que la anterior, la comparación será verdadera si el primer operando es mayor al segundo. x > y; (x es mayor a y) <= (Menor o igual que): la condición será verdadera cuando el primero operando sea menor o igual al segundo operando. x <= y; (x es menor o igual a y) >= (Mayor o igual que): al igual que el anterior operador, la condición será verdadera si el primer operando es mayor o igual al segundo operando. x >= y; (x es mayor o igual a y) Operadores Lógicos Booleanos. En ocasiones es necesario la realización de operaciones lógica propias del algebra booleana, con la intención de comprobar ciertas condiciones, muy utilizadas en las estructuras de control decisivas, estas operaciones devuelven un Verdadero o Falso y son comparables con los resultados de las Compuertas Lógicas Digitales, a continuación se describen los operando reconocidos por Arduino: && (AND lógico): esté operando implica la realización de una AND lógico entre los operandos, el resultado es Verdadero sólo si ambos operadores son Verdaderos. var1 == 2 && var3 == 8 || (OR lógico): utilizado para realizar la operación OR entre operandos, el resultado de la expresión será Verdadero si alguno de los dos operadores es Verdadero. x > 0 || y > 0 36 Guía Teórico Práctica Aprende ARDUINO ! (NOT): utilizado para realizar la operación NOT con un único operando, el resultado de la expresión será Verdadero si el operando es Falso y viceversa. y = !x 2. Estamentos o instrucciones Se le llama a una línea del Sketch que es ejecutable por la CPU de Arduino, en otras palabras son comandos que se ejecutaran y realizaran acciones internas o externas sobre los periféricos. Estos estamentos están formados por Funciones o Instrucciones propias del lenguaje Arduino a las cuales se les indican parámetros de funcionamiento externo sobre los periféricos de la Tarjeta Arduino, además Arduino reconoce como estamento toda oración terminada en ; (punto y coma), si no se incluye esta puntuación al final de una línea, el compilador retorna un error. digitalWrite (13, HIGH); analogRead (A0); En los estamentos anteriores se usan dos funciones digitalWrite y analogRead , y los datos entre paréntesis se les conoce como Parámetros de la función, más adelante se estudiaran las funciones específicas para manejar dispositivos externos puntuales. 3. Estructuras de control Son bloques de estamentos o grupos de instrucciones que se ejecutan según un ciclo, los tipos de estructuras de control son Repetitivo o Decisivo, normalmente estas estructuras se utilizan cuando se desean ejecutar instrucciones una serie de veces o en dependencia de una condición verificable, a continuación se describirán los tipos de Estructuras de Control reconocidas por el lenguaje de programación Arduino. Estructura Condicional IF-THEN-ELSE Esta estructura se utiliza para probar si una determinada condición se ha alcanzado, es decir se prueba una condición y dependiendo del resultado de esta se ejecutan una serie de estamentos solo si se cumple la condición. Se pueden diferenciar 2 tipos de estructura IF más utilizadas, las estructuras Solo IF y la estructura IF Completa, En la estructura Solo IF se evalúa la condición y solo se ejecutan estamentos si la condición es verdadera, la sintaxis de la estructura Solo If es la siguiente: if (unaVariable == valor) { ejecutaInstrucciones; } 37 Guía Teórico Práctica Aprende ARDUINO Por el contrario la estructura IF Completa ejecuta bloques de estamentos para ambos resultados de la condición. El formato de sintaxis para la estructura IF Completa es el siguiente: if (inputPin == HIGH) { instruccionesA; } else { instruccionesB; } Esta estructura es muy útil cuando se trabaja con entradas analógicas o digitales provenientes de sensores externos y así poder conocer el estado de parámetros físicos dentro de los programas Arduino. Estructura Condicional SWITCH/CASE Como las sentencias if, esta estructura controla el flujo de programas permitiendo a los programadores especificar diferentes códigos que deberían ser ejecutados en función de varias condiciones. En particular, una estructura switch compara el valor de una variable con el valor especificado en las sentencias case. Cuando se encuentra una sentencia case cuyo valor coincide con dicha variable, el código de esa sentencia se ejecuta. La palabra clave break sale de la estructura switch, y es usada típicamente al final de cada case. Sin una sentencia break, la sentencia switch continuaría ejecutando las siguientes expresiones hasta encontrar un break, o hasta llegar al final de la sentencia switch. La sintaxis general de esta estructura es la siguiente: switch (var) { case valor: // sentencias a ejecutar break; case valor: // sentencias a ejecutar break; default: // sentencias a ejecutar por defecto si no se encuentra el valor } A continuación un pequeño ejemplo de uso de la estructura SWICTH/CASE, donde se evalúa el contenido de la variable VAR y se ejecutan sentencias según el caso. switch (var) { case 1: // sentencias hacer algo cuando sea igual a 1 break; case 2: // senstencias hacer algo cuando sea igual a 2 break; default: // si nada coincide, ejecuta el "default" // el "default" es opcional } 38 Guía Teórico Práctica Aprende ARDUINO Estructura Condicional WHILE Una estructura de control del tipo while es un bucle de ejecución continua mientras se cumpla la expresión colocada entre paréntesis en la cabecera del bucle. La variable de prueba tendrá que cambiar para salir del bucle. La situación podrá cambiar a expensas de una expresión dentro el código del bucle o también por el cambio de un valor en una entrada de un sensor, la sintaxis general es la siguiente: while (unaVariable ?? valor) { ejecutarSentencias; } El siguiente ejemplo testea si la variable unaVariable es inferior a 200 y si es verdad, ejecuta las declaraciones dentro de los corchetes y continuará ejecutando el bucle hasta que unaVariable no sea inferior a 200. while (unaVariable < 200) { instrucciones; unaVariable++; // testea si es menor que 200 // ejecuta las instrucciones // entre llaves // incrementa la variable en 1 } Estructura Condicional DO-WHILE El bucle o estructura do… while funciona de la misma manera que el bucle while, con la salvedad de que la condición se prueba al final del bucle, por lo que el bucle siempre se ejecutará al menos una vez, la sintaxis general es: do { Instrucciones; } while (unaVariable ?? valor); El siguiente ejemplo asigna el valor leído leeSensor() a la variable x, espera 50 milisegundos y luego continua mientras que el valor de la x sea inferior a 100. do { x = leeSensor(); delay(50); } while (x < 100); 39 Guía Teórico Práctica Aprende ARDUINO Estructura Repetitiva FOR La declaración FOR se usa para repetir un bloque de sentencias encerradas entre llaves un número determinado de veces. Cada vez que se ejecutan las instrucciones del bucle se vuelve a testear la condición. La declaración FOR tiene tres partes separadas por ';' , veamos el ejemplo de su sintaxis: for (inicialización; condición; expresión) { Instrucciones; } La inicialización de una variable local se produce una sola vez y la condición se testea cada vez que se termina la ejecución de las instrucciones dentro del bucle. Si la condición sigue cumpliéndose, las instrucciones del bucle se vuelven a ejecutar. Cuando la condición no se cumple, el bucle termina. El siguiente ejemplo inicia el entero i en el 0, y la condición es probar que el valor es inferior a 20 y si es cierto esto, i se incrementa en 1 y se vuelven a ejecutar las instrucciones que hay dentro de las llaves: for (int i=0; i<20; i++) { digitalWrite(13, HIGH); delay(250); digitalWrite(13, LOW); delay(250); } // declara i y prueba si es // menor que 20, incrementa i. // enciende el pin 13 // espera ¼ seg. // apaga el pin 13 // espera ¼ de seg. Nota: El bucle en el lenguaje C es mucho más flexible que otros bucles encontrados en algunos otros lenguajes de programación, incluyendo BASIC. Cualquiera de los tres elementos de cabecera puede omitirse, aunque el punto y coma es obligatorio. También las declaraciones de inicialización, condición y expresión puede ser cualquier estamento válido en lenguaje C sin relación con las variables declaradas. Estos tipos de estados son extraños pero permiten crear soluciones a algunos problemas de programación específicos. 4. Funciones. El último bloque funcional de un Sketch lo componen las funciones, se puede decir que una función es un bloque o conjunto de instrucciones destinadas a ejecutar una tarea específica. Normalmente en Arduino C, algunas funciones ya están predefinidas y declaradas dentro del IDE, y en el Sketch solo será necesario invocarlas. digitalWrite (pin, estado) En el estamento anterior la función digitalWrite es una función que “escribe” un estado valor de salida digital en un pin del Arduino. / Maneja una salida (periférico) digital. Sera de mucha importancia aprender a usar las FUNCIONES dependiendo del periférico que deseemos usar. Es importante notar que el usuario también puede definir funciones propias, a modo de subrutinas, con instrucciones que será necesario repetir en un sketch, segmentar el código en funciones permite al programador crear piezas modulares de código que realizan una tarea definida y vuelven a la zona del programa en la que fueron llamadas. El caso típico para crear una función es cuando uno necesita realizar la 40 Guía Teórico Práctica Aprende ARDUINO misma acción múltiples veces dentro de un mismo programa. Para programadores acostumbrados a utilizar BASIC las funciones en Arduino permiten (y extienden) la utilidad de usar subrutinas (GOSUB en BASIC). La estandarización de fragmentos de código en funciones tiene diversas ventajas: Las funciones ayudan al programador a ser organizado, además ayudan a conceptualizar el programa. Las funciones codifican una acción en un lugar, así que sólo deben ser depuradas de errores una vez. Reducen las posibilidades de error en modificaciones, si el código debe ser cambiado. Las funciones hacen el sketch pequeño y compacto por que las secciones de código se reutilizan varias veces. Hacen más fácil la reutilización de código en otros programas por hacerlo modular y, como efecto paralelo, Usando funciones se obtiene un código mas legible. Pasos funcionales de un Sketch Dentro de un Sketch es importante llevar una secuencia ordenada de los procesos a ejecutar, un buen diseño de programa debe considerar los siguiente pasos dentro de la lógica o estructura, a continuación se describieran estos cinco pasos. Paso 1 – Inicialización: En este paso o etapa deben indicarse instrucciones que tiene por objetivo realizar tareas de inicialización de variables, estados o acciones del controlador, además de la inicialización y configuración de algunos dispositivos externos a usar conectados a nuestra placa Arduino. Paso 2 – Entrada: Todo programa necesita datos o información con los que trabajar y procesar, por lo que en este paso se deben declarar las instrucciones que se deben ejecutar para adquirir la información necesaria para solventar una tarea, esta información puede ser externa proveniente de sensores o interna al Arduino. Paso 3 – Procesamiento: Con la información recabada en el paso previo, en este paso se declaran las instrucciones o estamentos que realizaran la tarea propiamente dicha, toman los datos de entrada y los procesan produciendo nuevos datos. Paso 4 – Salida: El producto del procesamiento produce nueva información que debe ser guardada y/o mostrada a un usuario, en este paso se incluyen los estamentos que toman los datos del Procesamiento y los envían a salidas dentro o fuera del Arduino. Paso 5 – Finalización: Como paso final tenemos los estamentos para finalizar el programa y apagar el sistema / poco utilizado en aplicaciones Arduino, se quiere que los sketches siempre estén «corriendo» y nunca dejen de funcionar. 41 Guía Teórico Práctica Aprende ARDUINO 4. Comunicación serial en ARDUINO Una de las ventajas de la tarjeta Arduino es la capacidad de comunicación a través del puerto USB dispuesto en ella, esta comunicación es bidireccional y de tipo Serie, y sirve para dos propósitos, el principal es permitir la descarga del Sketch desde el Arduino IDE hacia la memoria del Microcontrolador, y la segunda es la transferencia de información desde el propio Sketch hacia la computadora, ya sea para visualizar datos producidos por el Arduino o enviar información de configuración o funcionamiento hacia un Sketch. Comunicación Serie en Arduino. La comunicación o transmisión de información serial, a diferencia de la comunicación paralela, es aquella en la cual se envía bit por bit a través del canal de comunicación, es decir los bits viajan en “serie”, es decir, uno tras otro a través del medio de comunicación. Un puerto serie se entiende como los pines o terminales que dispone un dispositivo para poder realizar una comunicación serie con otros dispositivos, el caso del Microcontrolador ATMEGA328p presente en un Arduino UNO dispone de un puerto serie de tipo TTLUART (se deja al lector investigar significado) que permite comunicar la tarjeta Arduino con otros dispositivos, ya sea otro Arduino o un PC, para así poder transferir datos entre ambos, el canal físico o puerto de comunicación en el puerto USB de la tarjeta Arduino, pero también pueden ser los pines digitales 0 (Rx) y 1 (Tx) de la tarjeta. Figura 4-1. Arduino se comunica por el puerto serie USB (ladyada.net). 42 Guía Teórico Práctica Aprende ARDUINO Figura 4-2. Arduino IDE y la aplicación Monitor Serial. Para poder utilizar en los sketches de este tipo de comunicación se hace uso de un elemento del lenguaje Arduino llamado Serial, se debe conocer entonces las funciones derivadas de Serial para poder realizar con Arduino el envío o recepción de datos desde y hacia una PC. Si se desea comunicar la tarjeta Arduino con la PC, se debe ejecutar en ella un software que permita interactuar con el puerto serial de la computadora y así poder “ver” la comunicación con el Arduino, lo bueno es que el IDE de Arduino ya trae incluido una aplicación para esto, llamada “Monitor Serial” y para ejecutarlo basta con dar clic en el botón de la esquina superior. Envío de datos desde Arduino hacia la PC. Enviar datos desde nuestro Arduino a la PC es muy sencillo, no se hace uso de ninguna librería especial, y algunas de las funciones a usar son: Serial.begin(): esta instrucción abre y configura el puerto serie de Arduino para que pueda comenzar la comunicación, esta función recibe como parámetro la velocidad de transmisión, normalmente 9600, esta instrucción debe de ir dentro del bloque Setup() de nuestro Sketch. Por ejemplo: inicializamos la comunicación serial con la sentencia Serial.begin(9600). El 9600 indica el baud rate, o la cantidad de baudios por segundo que manejará el puerto serie. Se define baudio como una unidad de medida, usada en telecomunicaciones, que representa el número de símbolos por segundo en un medio de transmisión. 43 Guía Teórico Práctica Aprende ARDUINO Serial.print(): envía a través del canal o puerto serie un dato desde el Arduino hacia el computador o dispositivo conectado al puerto serie, este dato puede ser de cualquier tipo: carácter, cadena, numero entero, decimal, etc. Por ejemplo: Serial.print(“Hola”); Serial.print(var); //envía la palabra hola hacia el dispositivo //conectado al puerto serial. //envía el contenido de la variable var hacia //el dispositivo conectado al puerto serial. Serial.prinln(): hace exactamente lo mismo que Serial.print(), pero además añade automáticamente al final de los datos enviados dos caracteres extra: retorno de carro y nueva línea. Para que el IDE Monitor Serial imprima los siguientes datos en una línea nueva de la pantalla. EJEMPLO SERIAL01: Demostración de envío de datos hacia la computador, el siguiente sketch envía una serie de números y letras hacia el monitor serial usando el puerto USB del Arduino, note la diferencia entre Serial.print y Serial.println. Recordando que se debe de abrir el Monitor Serial de IDE Arduino para poder visualizar los datos enviados por nuestro Arduino. /* Sketch para demostrar el envio de datos desde Arduino Envía números en secuencia hacia el Monitor Serial del IDE Luego de descargado el sketch active el monitor serial. Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de uso libre CC */ int variable = 0; //se crea una variable void setup() { Serial.begin(9600); //activar el puerto serie del Arduino delay(2000); Serial.println(“esta es una prueba de la comunicación serie con Arduino”); } void loop() { Serial.print(“El valor de la variable es:”); Serial.println(variable); //se manda el contenido de variable delay(500); variable++; //se incrementa el valor de variable en uno } //fin del sketch 44 Guía Teórico Práctica Aprende ARDUINO Figura 4-3. Resultado en el Monitor Serial del ejemplo 1. Recibir datos desde la PC en Arduino. Al igual que se pueden enviar datos hacia una PC, el Arduino también puede recibir datos provenientes de una computadora a través de puerto serie, y así poder procesarlos y utilizarlos en nuestros sketches. Desde el Monitor Serial enviar datos a la placa Arduino es muy sencillo: no hay más que escribir lo que queramos en la caja de texto allí mostrada y pulsar el botón “Enviar”. No obstante si el sketch que se está ejecutando en la placa no está preparado para recibir y procesar estos datos, esta transmisión no llegara a ningún sitio. Por tanto, necesitamos recibir convenientemente en nuestros sketch los datos que lleguen a la placa vía comunicación serie. Las funciones a utilizar para lograr recibir datos por el puerto serie se describen a continuación. Serial.available(): devuelve el número de bytes-caracteres-disponibles para ser leído que provienen a través del canal serie (via USB o via pines Rx/Tx). Estos bytes ya han llegado al Microcontrolador y permanecen almacenados temporalmente en una pequeña memoria o buffer de 64 bytes. Si no hay bytes para leer, esta instrucción devolverá 0. Serial.read(): devuelve el primer byte aun no leído de los que estén almacenados en el buffer de entrada, para leer el siguiente byte se ha de volver a ejecutar de nuevo Serial.read(). Cabe destacar que el monitor serial “convierte” a su equivalente ASCII todo carácter eniado hacia Arduino, esto quiere decir que el Sketch Arduino deberá reconvertir o trabajar con códigos ASCII de los respectivos caracteres alfanuméricos, recordando que el lenguaje Arduino reconoce caracteres en código ASCII con la sintaxis, entre comillas simple: „x‟. EJEMPLO SERIAL02: En este ejemplo se ejecuta la comunicación con el puerto serie para recibir e interactuar con la computadora. Recuerde que se debe ejecutar el Monitor Serial, y el envió de datos se realizara con el botón Enviar. 45 Guía Teórico Práctica Aprende ARDUINO /* Programa de uso de Monitor Serial del Arduino IDE Se pide un número y el programa muestra el nombre del número en letras Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de uso libre CC */ int valor_ingresado; //se declara una variable entera void setup() { Serial.begin(9600); Serial.println("Ingrese un valor entre 0 y 9"); } void loop() { // verificar si hay un byte en el puerto serie if (Serial.available() > 0) { //si es asi, leerlo y aignarlo a la variable valor_ingresado=Serial.read(); //procesarlo if (valor_ingresado=='0') Serial.println("***Ud. if (valor_ingresado=='1') Serial.println("***Ud. if (valor_ingresado=='2') Serial.println("***Ud. if (valor_ingresado=='3') Serial.println("***Ud. if (valor_ingresado=='4') Serial.println("***Ud. if (valor_ingresado=='5') Serial.println("***Ud. if (valor_ingresado=='6') Serial.println("***Ud. if (valor_ingresado=='7') Serial.println("***Ud. if (valor_ingresado=='8') Serial.println("***Ud. if (valor_ingresado=='9') Serial.println("***Ud. delay(1000); Serial.println(""); Serial.println("Ingrese un valor entre 0 y 9"); } } //fin del sketch introdujo introdujo introdujo introdujo introdujo introdujo introdujo introdujo introdujo introdujo el el el el el el el el el el numero numero numero numero numero numero numero numero numero numero CERO"); UNO"); DOS"); TRES"); CUATRO"); CINCO"); SEIS"); SIETE"); OCHO"); NUEVE"); Figura 4-4. Resultado en el Monitor Serial del ejemplo 2. 46 Guía Teórico Práctica Aprende ARDUINO En el ejemplo anterior se recibía y procesa un solo dato o carácter enviado, pero que sucede si lo que queremos es leer toda una cadena de caracteres, por ejemplo un nombre o edad?. Esto se logra leyendo por medio de Serial.read() el carácter o letra disponible una por una de toda la frase ingresada desde el Monitor serial. EJEMPLOSERIAL03: El siguiente sketch leerá una frase o cadena de caracteres envía desde el Monitor Serial y Arduino responderá con un saludo. /* Programa que usa el Monitor Serial del IDE Arduino pide un nombre y regresa un saludo Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de uso libre CC */ char letra; // variable para el carácter recibido. String nombre; // variables para almacenar la cadena de caracteres void setup() { Serial.begin(9600); Serial.println("Cuál es tu nombre?"); } void loop() { // verificar si hay un byte en el puerto serie if (Serial.available() > 0) { //si es asi, leerlo y asignarlo a la variable letra=Serial.read(); //procesarlo, solo se leera una letra a la vez, asi //que se debe concatenar para formar todo el nombre ingresado //estudie el uso de "concat" nombre.concat(letra); delay(100); //pausa para que Arduino lea la proxima letra //verificar si ya no hay mas letras? if (Serial.available()==0) { //si es asi, imprimir el saludo Serial.print("Hola "); Serial.print(nombre); delay(1000); Serial.print(", que tengas un buen dia!"); delay(1000); Serial.println(""); Serial.print("Bye "); Serial.println(nombre); letra = 0; nombre = 0; } } } //Fin del sketch 47 Guía Teórico Práctica Aprende ARDUINO Figura 4-5. Resultado en el Monitor Serial del ejemplo 3. A partir de esto ejemplos de aplicación se recomienda el diseño de programas derivados, para la comunicación serial con la computadora, por ejemplo el diseñar una “calculadora interactiva” o “el adivinar un numero aleatorio”, más avanzado aun el desarrollar aplicación en Visual Basic que se comuniquen directamente con Arduino sin necesidad del Monitor serial 48 Guía Teórico Práctica Aprende ARDUINO APUNTES: 49 Guía Teórico Práctica Aprende ARDUINO 5. Entradas y Salidas Digitales de la tarjeta ARDUINO. Anteriormente se vio que la tarjeta Arduino, entre su hardware, posee terminales con las que puede interactuar con elementos externos de tipo digital, es decir aquellos que funcionan o brindan una salida de tipo binaria, dos estados: pagado y encendido, en este caso los pines Digitales permiten el control o conmutación de diversos elementos conectados a estas salidas y entradas, en la tarjeta Arduino UNO el número de pines digitales disponibles son 20, las numeradas en la placa como 0 a 13 y de A0 a A5, en la placa Arduino MEGA se tienen 53 salidas digitales disponibles para el usuario. En estas páginas se describirá el manejo básico de estas terminales digitales y como se configuran, para posteriormente se estudiaran estas salidas junto a dispositivos específicos Configuración de terminales Una salida digital permite proveer un estado ALTO o BAJO en cualquier pin digital de salida del Arduino, estos estados se refieren a voltaje presente en el pin, 5Vdc para el estado Alto (High) y 0Vdc para el estado Bajo (Low), el valor máximo de la corriente que puede brindar un pin de salida digital es 40mA, si se demanda más corriente se corre el riesgo de dañar dicho pin. Una terminal de Arduino puede funcionar como Salida Entrada Digital si previamente se configura como tal, para realizar esto se utiliza la instrucción pinMode, a continuación una breve descripción de su uso: pinMode(pin, configuacion): esta instrucción es utilizada en la estructura de configuración setup() y sirve para configurar el modo de trabajo de un pin pudiendo ser INPUT (entrada) u OUTPUT (salida). Como parámetros recibe el numero o referencia del Pin a configurar, y también el tipo de configuración. pinMode(13, OUTPUT); // configura el terminal 13 de Arduino como salida pinModes(pinLed, OUTPUT); //configura el terminal pasado por referencia Los terminales de Arduino, por defecto, están configurados como entradas, por lo tanto no es necesario definirlos en el caso de que vayan a trabajar como entradas. Los pines configurados como entrada quedan, bajo el punto de vista eléctrico, como entradas en alta impedancia. 50 Guía Teórico Práctica Aprende ARDUINO Estos pines tienen a nivel interno una resistencia de 20 KΩ conectada a Vcc, a las que se puede acceder mediante software. Esto con el objetivo de poder usarlas como entradas con una resistencia tipo PULL-UP (se deja al lector investigar qué significa esto), estas resistencias se acceden de la siguiente manera: pinMode(pin, INPUT); digitalWrite(pin, HIGH); // activa las resistencias internas, // configurando el pin como entrada // Pone el pin a 1 (pull-up) Las resistencias internas normalmente se utilizan para conectar las entradas a interruptores. En el ejemplo anterior no se trata de convertir un pin en entrada, es simplemente un método para activar las resistencias internas. Los pines configurado como OUTPUT (salida) se dice que están en un estado de baja impedancia y pueden proporcionar 40mA (miliamperios) de corriente a otros dispositivos y circuitos. Esta corriente es suficiente para alimentar un diodo LED (no olvidando poner una resistencia en serie), pero no es lo suficiente grande como para alimentar cargas de mayor consumo como relés, solenoides o motores. Un cortocircuito en las patillas Arduino provocará una corriente elevada que puede dañar o destruir el chip ATMEGA. Puede ser buena idea conectar un pin configurado como salida a un dispositivo externo en serie con una resistencia de 470 o de 1000 Ω. Figura 5-1 Disposición de los pines digitales del Arduino UNO Manejo de Entradas y Salidas Digitales A continuación se verán las funciones específicas para modificar el voltaje de una salida digital y como leer el estado de un pin entrada digital, cabe mencionar que en una entrada digital el estado del pin dependerá en ocasiones del tipo de sensor conectado a esta, el sensor más básico y que ejemplifica esto es el interruptor, en la figura 5-2 se observan dos formas de conectar un interruptor o pulsador a una entrada digital de la tarejeta Arduino. 51 Guía Teórico Práctica Aprende ARDUINO Figura 5-2 Formas de conexión de un interruptor a una entrada digital. Una salida digital se puede utilizar para el envío de señales de control de tipo ON-OFF hacia un actuador a manipular, por ejemplo encender o apagar un LED, un motor, una luminaria, etc. Para poder gobernar las entradas y salidas digitales de una tarjeta Arduino, es necesario conocer cuales son las instrucciones o funciones específicas para la lectura y escritura de estos pines, continuación se describirán: digitalWrite(pin, value): Envía un valor digital (0 o 5V) al pin definido como argumento, que previamente debe ser configurado como OUTPUT. El argumento PIN se puede especificar ya sea como una variable o como una constante (0-20), los pines más allá de 14 son los marcados como A0 a A5 en la placa. El segundo argumento VALOR debe indicar la salida que se desea en el pin, puede indicarse como HIGH o LOW o con indicadores numéricos 1 o 0. digitalWrite(2, HIGH); // deposita en el pin D2 un valor // HIGH (5V) digitalRead(pin): Lee el valor de un pin digital dando un resultado HIGH (alto) o LOW (bajo). El pin se puede especificar ya sea como una variable o una constante (0-13) y el resultado se puede guardar en una variable para su posterior procesamiento. valor = digitalRead(pin); 52 // hace que la variable 'valor' sea igual al // estado leído en 'pin' Guía Teórico Práctica Aprende ARDUINO EJEMPLO.DIG01: El siguiente ejemplo se manipularan una entrada y una salida digital de Arduino, el código lee el estado de un pulsador conectado a una entrada digital y lo escribe en el pin de salida LED, según la figura 5-3 int led = 13; int boton = 7; int valor = 0; // asigna a LED el valor 13 // asigna a botón el valor 7 // define el valor y le asigna el valor 0 void setup() { pinMode(led, OUTPUT); // configura el led (pin13) como salida pinMode(boton, INPUT); // configura botón (pin7) como entrada } void loop() { valor = digitalRead(boton); //lee el estado de la entrada botón digitalWrite(led, valor); // envía a la salida 'led' el valor leído } Figura 5-3 Esquema de conexión para el Ejemplo 1 En secciones posteriores se retomara el uso de las salidas digitales, específicamente para manipular dispositivos externos puntuales. 53 Guía Teórico Práctica Aprende ARDUINO 6. Manejo de LEDs con ARDUINO El diodo emisor de luz (LED) es uno de los componentes electrónicos más usados al momento de realizar una indicación visual hacia el entorno de Arduino, un LED como su nombre lo indica es un diodo que emite luz cuando se polariza en directa, el color de la luz dependerá de la construcción del LED así como el tamaño físico de este, los podemos encontrar en diámetro desde 3mm hasta 10mm o más, en la figura 6-1 se puede apreciar la estructura física, símbolo y polaridad de un LED típico. Figura 6-1 Símbolo y partes de un LED. Manejo de LED con Arduino Anteriormente se mencionó que este componente emite luz cuando se polariza en directa, entonces se puede conectar a una salida digital de nuestra tarjeta Arduino y a través de esta poder controlar en encendido y apagado de un LED, en la figura 6-2 se puede apreciar el circuito básico de conexión de un LED a un pin de Arduino, el Ánodo se conecta al pin digital de salida y el catado en serie con un resistor y a GND, el resistor en serie con el LED limita la corriente necesaria para que un encendido correcto, normalmente un LED necesita aproximadamente 20mA por lo que el resistor puede tener un valor entre 220 y 470 ohmios, cabe mencionar que el máximo de corriente que puede suplir una salida digital de Arduino es 40mA por lo que no se recomienda la conexión de más de dos LEDs manejados por un único pin de Arduino, si se desea manejar más LEDs a partir de una sola salida de Arduino se recomienda el uso de una interface amplificador de corriente o Buffer entre Arduino y los LEDs, en secciones posteriores se estudiara este tipo de circuitos. 54 Guía Teórico Práctica Aprende ARDUINO Figura 6-2. Conexión pictórica de un LED a un pin digital de Arduino. Según la conexión anterior es sencillo el encendido y apagado de un LED, desde el punto de vista del Sketch bastara con utilizar la función digitalWrite(pin, estado), donde el argumento Pin hace referencia al terminal donde se conecta el ánodo del LED y el estado es un 1 o 0 dependiendo si se desea encender o apagar el LED, esta función ya se estudió anteriormente. En este punto cabe mencionar una función muy útil en este y demás Sketch en Arduino, la ejecución de pausas, existe una función que permite detener o pausar la ejecución del Sketch un determinado periodo de tiempo, a continuación se detalla esta función llamada delay (x). delay(x): esta función permite realizar una pausa de x milisegundos en la ejecución del Sketch, recibe como único argumento el valor en milisegundos de la pausa a realizar, puede ser un numero entre 0 y 2,147,483,647, valor constante o el nombre de una variable conteniendo el número de milisegundos a pausar. EJEMPLO LED.01: En el siguiente ejemplo se usara la conexión del circuito de la figura 7-2, el Sketch a continuación hace parpadear el LED por 10 veces seguidas para luego apagarlo por 2 segundos y volver a repetir la secuencia. Note el uso de la estructura de control FOR. /* Ejemplo LED01 Manipula el parpadeo secuencial de un LED Conectado al pin 9 de una tarjeta Arduino Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio Publico - CC */ //Declaracion de una constante con el numero //del pin conectado al LED int led = 9; // funcion de configuracion void setup() { pinMode(led, OUTPUT); // inicializar el pin 9 como salida } 55 Guía Teórico Práctica Aprende ARDUINO // funcion a ejecutar infinitamente void loop() { for (int control= 1; control < 10; control++) { // encender el LED digitalWrite(led, HIGH); delay(250); // apagar el LED digitalWrite(led, LOW); delay(250); } delay(2000); // pausa de 2 segundos } //Fin del sketch EJEMPLO LED.02: A continuación se presenta un ejemplo donde se maneja más de un LED con el objetivo de formar un semáforo vial de una sola vía, se usan tres LED según el circuito que se muestra en la figura 6-3, los tiempos de encendido se pueden manipular a antojo del diseñador, los resistores pueden tener cualquier valor entre 220 y 470 ohmios. Figura 6-3. Conexión para el ejemplo 2, semáforo vial. /* Ejemplo LED02. Controla el funcionamiento de un semaforo de tres luces LEDs. Mofificado por: otoniel.flores@mail.utec.edu.sv ejemplo de dominio publico - CC */ //declaracion de constanstes con //numeros de terminales a usar int rojo = 10; 56 Guía Teórico Práctica Aprende ARDUINO int amarillo = 9; int verde = 8; //variables con los tiempos //en milisengundos por color int tRojo = 2000; int tVerde = 3000; int tAmarillo = 500; void setup() { //se configuran las salidas pinMode(rojo,OUTPUT); pinMode(amarillo,OUTPUT); pinMode(verde,OUTPUT); } void loop() { // encedido luz Verde digitalWrite(verde,HIGH); digitalWrite(amarillo,LOW); digitalWrite(rojo,LOW); delay(tVerde); // encendido luz Amarilla digitalWrite(verde,LOW); digitalWrite(amarillo,HIGH); digitalWrite(rojo,LOW); delay(tAmarillo); // encendido luz Roja digitalWrite(verde,LOW); digitalWrite(amarillo,LOW); digitalWrite(rojo,HIGH); delay(tRojo); } //FIn del Sketch EJEMPLO LED.03: El presente ejemplo muestra como manipular 8 LEDs individuales para formar un efecto luminoso, es de notar que cada LED se conecta a una salida de Arduino por medio de un resistor, la conexión a implementar se muestra en el circuito de la figura 6-4, los resistores pueden tener cualquier valor entre 220 y 470 ohmios. Figura 6-4 Conexión para el ejemplo LED03, efecto en 8 LEDs. 57 Guía Teórico Práctica Aprende ARDUINO /* Ejemplo LED03. Efecto en 8 LEDs conectados a salidas digitales de Arduino. modificado por: otoniel.flores@mail.utec.edu.sv ejemplo de dominio publico - CC */ //Defininicion de los pines a utilizar int led1 = 2; int led2 = 3; int led3 = 4; int led4 = 5; int led5 = 6; int led6 = 7; int led7 = 8; int led8 = 9; int periodo = 150; void setup(){ pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(led5, OUTPUT); pinMode(led6, OUTPUT); pinMode(led7, OUTPUT); pinMode(led8, OUTPUT); } void loop() { //Se creara un efecto del "Centro hacia afuera" //se divide en cuatro etapas, en cada una solo un par //de LEDs esta encendido. digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, HIGH); digitalWrite(led5, HIGH); digitalWrite(led6, LOW); digitalWrite(led7, LOW); digitalWrite(led8, LOW); delay(periodo); digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, HIGH); digitalWrite(led4, LOW); digitalWrite(led5, LOW); digitalWrite(led6, HIGH); digitalWrite(led7, LOW); digitalWrite(led8, LOW); delay(periodo); digitalWrite(led1, LOW); digitalWrite(led2, HIGH); digitalWrite(led3, LOW); digitalWrite(led4, LOW); digitalWrite(led5, LOW); digitalWrite(led6, LOW); digitalWrite(led7, HIGH); digitalWrite(led8, LOW); delay(periodo); digitalWrite(led1, HIGH); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); digitalWrite(led5, LOW); digitalWrite(led6, LOW); digitalWrite(led7, LOW); digitalWrite(led8, HIGH); delay(periodo); } //Fin del Sketch 58 Guía Teórico Práctica Aprende ARDUINO EJEMPLO LED.04: En este ejemplo se manipulara en encendido de uno de 8 LEDs conectados a Arduino desde el Monitor Serial de IDE, se pedirá que el usuario ingrese el número del LED (1 a 8) que se desea hacer parpadear por 10 veces. El circuito a implementar se muestra en la figura 6-4, los resistores pueden tener cualquier valor entre 220 y 470 ohmios, recordar que luego de descargar el Sketch a la tarjeta se debe abrir la comunicación vía Monitor Serial para el envío de datos a Arduino. /* Ejemplo LED04. Manejo via Monitor serial de LED. El led que se indica via Monitor Serial, se hara Parpadear 10 veces a una frecuencia constante. modificado por: otoniel.flores@mail.utec.edu.sv ejemplo de dominio publico - CC */ //Defininicion de los pines a utilizar int led1 = 2; int led2 = 3; int led3 = 4; int led4 = 5; int led5 = 6; int led6 = 7; int led7 = 8; int led8 = 9; int periodo = 250; //tiempo de parpadeo fijo int ingresoLed = 0; int numeroLed=0; void setup() { Serial.begin(9600); //se inicializa la transmision serial pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(led5, OUTPUT); pinMode(led6, OUTPUT); pinMode(led7, OUTPUT); pinMode(led8, OUTPUT); //Primero se imprime en el Monitor serial un mensaje Serial.println ("Ingrese Numero del LED a parpader "); } void loop() { //se captura el caracter ingresado if (Serial.available() > 0) { digitalWrite(led1, LOW); digitalWrite(led2, digitalWrite(led3, LOW); digitalWrite(led4, digitalWrite(led5, LOW); digitalWrite(led6, digitalWrite(led7, LOW); digitalWrite(led8, LOW); LOW); LOW); LOW); // lee el byte de entrada: ingresoLed = Serial.read(); delay(250); Serial.println (ingresoLed); if (ingresoLed > '0' && ingresoLed < '9') { //si es un valor entre 1 y 8 //generar efecto numeroLed = (ingresoLed - '0'); Serial.println (numeroLed); for (int x = 0; x < 10; x++) { digitalWrite(numeroLed + 1, HIGH); delay(periodo); digitalWrite(numeroLed + 1, LOW); 59 Guía Teórico Práctica Aprende ARDUINO delay(periodo); } delay(1000); Serial.println ("Ingrese Numero del LED a parpader "); }else { delay(1000); Serial.println ("error: ingrese un numero valido entre 1 y 8!"); } } } //FIn del Sketch //una modificacion a este Sketch es: Que además de ingresar el numero de LED , tambien el usuario ingrese //el tiempo de parpadeo en milisengundos. Diseñalo ¡ Activación de cargas de mayor potencia. Anteriormente se estudió que una salida digital de la tarjeta Arduino solo puede manejar máximo dos LEDs ya que la corriente que esta puede entregar es de máximo 40mA, si se conecta a una salida de Arduino una carga que demande más de esta corriente máxima se corre el riesgo de dañar la tarjeta. Una forma de solucionar esto es el uso de dispositivos que permitan convertir y/o amplificar la potencia de la salida de Arduino a lo necesario para esas cargar más potentes: LEDs más grandes, lámparas a 110Vac, ventiladores, motores, etc. La solución puede ser el uso de una interface entre la salida Arduino y el componente a controlar, para el caso se estudiaran dos tipos de estas interfaces: el RELE y el BUFFER (circuitos integrados amplificadores de corriente). Uso del Rele. Cuando se desea conmutar cargas de diferente voltaje y corriente que la proporcionada por una salida de Arduino se recomienda el uso de un RELE o RELEVADOR, es un dispositivo electromecánico, que funciona como un interruptor controlado por un circuito eléctrico en el que, por medio de un electroimán, se acciona un juego de uno o varios contactos que permiten abrir o cerrar otros circuitos eléctricos independientes, ver figura 7-5, de esta definición se extrae que se puede separar dos circuitos de forma que funcionen con voltajes diferentes, uno a 5Vdc@40mA (Arduino) y otro a 110Vac (por ejemplo una luminaria). La conexión del circuito de un RELE es sencilla y se aprecia en la figura 7-6 donde se puede notar que la salida de Arduino activa la bonina del RELE a través de un transistor, es importante mencionar que existen en el mercado módulos de RELE para trabajar con una salida de Arduino, estos ya incluyen la electrónica necesaria y solo requieren la conexión desde Arduino para trabajar, ver figura 7-5. Con lo anterior se deduce que la conmutación de estas cargas conectadas al RELE se hace activando y desactivando el pin de Arduino correspondiente, recordando el uso de digitalWrite(pin, estado) se hace sencillo esto. 60 Guía Teórico Práctica Aprende ARDUINO Figura 6-5. Estructura de un RELE básico y presentación modular que ya incluye los componentes listo para Arduino. Figura 6-6. Ejemplo de circuitos de conexión de una salida digital Arduino para controlar un RELE. Este circuito es el que incluyen la mayoría de módulos RELE para Arduino. Buffer ULN2803. Si se quiere controlar cargar de voltaje similar a la salida de Arduino pero qe demandan mayor corriente, una solución es utilizar el circuito integrado ULN2803, es un circuito integrado que se emplea como interfaz de potencia para circuitos con salidas de baja potencia a 5Vdc, posee 8 canales con lógica negada y en su interior posee 8 transistores NPN tipo Darlington con sus correspondientes diodos de protección que resulta ideal para controlar relés, motores, cargas inductivas, etc. Cada una de las salidas puede manejar hasta 500 mA por lo que tiene muchas aplicaciones para controlar todo tipo de cargas, en la figura 7-7 se puede apreciar físicamente este circuito integrado, por lo anterior con un solo ULN2803 se puede amplificar la corriente de 8 salidas de Arduino para poder manipular cargas que requieren mayor corriente que los 40mA de Arduino, cabe aclarar que como las salidas del ULN2803 son de lógica negada, significa que un estado BAJO en el pin Arduino corresponderá a un estado ALTO en la salida del buffer. 61 Guía Teórico Práctica Aprende ARDUINO Figura 6-7. Forma física y conexión interna del circuito integrado ULN2803 Figura 6-8. Ejemplo de conexión del circuito integrado ULN2803 Figura 6-9. Ejemplo de conexión del circuito integrado ULN2803en el manejo de más de un LED Más adelante, en la sección de “Manejo de Motores con Arduino” se retomara el uso del ULN2803, como interface que permita el accionamiento de un motor eléctrico tipo Paso a Paso desde la tarjeta Arduino. 62 Guía Teórico Práctica Aprende ARDUINO APUNTES: 63 Guía Teórico Práctica Aprende ARDUINO 7. Entradas y Salidas Analógicas de la tarjeta ARDUINO Una tarjeta Arduino también posee otro tipo de terminales de entrada y salida muy útiles, las denominadas Analógicas o Análogas, que permiten el control y manejo de diversos dispositivos externos que funcionaran con señales de tipo análogas, las entradas análogas, también conocidas como ADC (Convertidor Análogo Digital), les permiten a Arduino la interface con sensores cuya salida sea un voltaje análogo, lo cual es muy común en el mundo de los sensores, y las salidas analógicas permiten a la placa Arduino poder controlar la regulación de voltajes de salidas entre 0 y 5Vdc, algo muy útil en la regulación de brillos de lámparas y regulación de velocidad de motores, cabe mencionar que una salida analógica de Arduino también se le conoce como salidas PWM (Modulación por Ancho de Pulso) ya que el voltaje análogo de salida se logra implementando esta técnica en la propia placa Arduino. A continuación se describan funciones o instrucciones generales del uso de las terminales análogas de una placa Arduino, cabe mencionar que en una tarjeta Arduino UNO se disponen de 6 entradas análogas (ADC) y 6 salidas análogas (PWM), una tarjeta Arduino MEGA posee 16 entradas (ADC) y 15 salidas análogas (PWM). Entradas Analógicas - ADC Además de la entradas digitales previamente estudiadas, Arduino tiene disponibles entradas analógicas que le permiten la lectura de señales análogas entre 0 y 5 Vdc, es decir que a través de estas entradas el Arduino puede conocer el nivel de voltaje DC presente en un pin y obtener dentro del Sketch su respectivo valor pero en representación digital, ósea que estas entradas análogas implementan un ADC (conversor análogo digital) dentro la tarjeta Arduino. Estas entradas analógicas permiten que Arduino pueda “conocer” o “leer” señales del mundo real que son de índole continua, es decir por ejemplo el parámetro Temperatura es una señal física de tipo continua que cambia entre un rango mayor a dos estados, esta señal es captura por un sensor que la convierte a un parámetro eléctrico, por ejemplo voltaje, el cual es de tipo análogo y que debe ser convertido al mundo digital para poder ser entendido y procesado por la CPU del Microcontrolador. Esta señal analógica externa será convertida en una representación digital de 10 bits, también llamada resolución del ADC, esto significa que el rango análogo de 0 a 5 Vdc será convertido a un rango digital de 0 a 1023 valores, posibles con una resolución de 10 bits es así como una entrada de 0Vdc será convertida a un valor digital de 0 y un valor análogo de 5Vdc será convertido en 1023, ver la figura 7-1. Para conocer el valor digital al cual será convertido cualquier valor análogo se puede utilizar la ecuación de la figura 7-2. 64 Guía Teórico Práctica Aprende ARDUINO Figura 7-1. Proceso de conversión de una señal – Niveles de conversión de una señal análoga en Arduino. Figura 7-2. Ecuación para encontrar el valor ADC de 10 bits (0 a 1023) de un voltaje de entrada análogo. Figura 7-3. Pines de entrada Analógica en Arduino UNO. 65 Guía Teórico Práctica Aprende ARDUINO Generalmente estas entradas se utilizan para leer sensores de con salidas análogas DC, tales como LDR, Potenciómetros, Sensores de temperatura, Sensores de Distancia, etc. Cabe mencionar que dependerá del modelo de tarjeta Arduino el número de entradas análogas disponibles: Arduino NANO y UNO poseen 6 entradas análogas marcadas A0 a A5, el MEGA tiene disponibles 16 entradas analógicas marcadas A0 a A15. Anteriormente se estudió que el uso de las entradas análogas es obtener un valor digital representativo de un valor análogo real en el terminal del Arduino, este voltaje análogo real puede provenir de otros dispositivos con salidas análogas: sensores. Desde el punto de vista del Sketch es sencillo la lectura y conversión de una entrada análoga de nuestro Arduino, para empezar se debe configurar el pin como entrada, recordando que solo se pueden utilizar los pines A0 a A5 en Arduino UNO o NANO, y en MEGA A0 a A15. Luego la función que permite la lectura y conversión de una entrada análoga es analogRead() que ya viene incluida en la librería estándar de Arduino IDE, a continuación se verá una pequeña descripción y uso de esta función. analogRead(Ax): lee el valor análogo (0 a 5V) del pin Ax y devuelve el valor digital de la conversión realizada (0 a 1023), Ax debe ser un pin análogo valido según el modelo de Arduino usado, el dato devuelto debe guardarse en una variables tipo INT o FLOAT para su procesamiento posterior. Si el pin a leer no está conectado, es decir está en “flotante” la función devolverá valores aleatorios son significado alguno. Por ejemplo: int lectura = analogRead(A0) float lectura = analogRead(A0) //leer el valor análogo presente en el pin A0 //convertirlo a digital y guardarlo en la variable //lectura, se guardara un valor digital entero. //leer el valor análogo del pin A0 lo convierte //a su equivalente digital y lo guarda en la variable //lectura, se guarda un valor con decimal. EJEMPLO.AR01: En el siguiente ejemplo se leerá el valor de voltaje presente en el pin análogo A0 y se desplegara en el monitor serial el correspondiente valor digital, se usara como sensor un Potenciómetro lineal para manipular el voltaje en el pin A0, según la conexión del circuito de la figura 7-4 siguiente, al manipular el potenciómetro se lograra modificar el voltaje presente en la entrada análoga A0, este voltaje variara entre0 y 5 Vdc, el Sketch captura este valor y los convierte a su equivalente digital y los envía para su visualización en Monitor Serial, se puede usar cualquier valor óhmico del potenciómetro. /* Ejemplo.AR01 - lectura analoga & monitor serial Leer el valor analogo y muestra la conversión digital en el monitor serial del PC Conectar el potenciomentro asi: extremo a +5Vcd , centro a A0 , extemo a GND Modifica por otoniel.flores@mail.utec.edu.sv Distribucion Libre CC */ //Variables para guardar la lectura int lectura_int = 0; float lectura_float = 0; void setup() { //inicializar el puerto serie USB Serial.begin(9600); //configurar pin A0 66 Guía Teórico Práctica Aprende ARDUINO pinMode (A0, INPUT); // aunque no es necesario , ya que por defecto los pines A son entradas. } // leer el pin A0 y mostrar la conversión en el Serial void loop() { //leer el pinA0: lectura_int = analogRead(A0); //imprimir el valor en el Serial: Serial.print("Lectura usando variable Int = "); Serial.println(lectura_int); //leer el pinA0: lectura_float = analogRead(A0); //imprimir el valor en el Serial: Serial.print("Lectura usando variable Float = "); Serial.println(lectura_float); Serial.println("********************************************"); delay(1000); } //fin del Sketch Figura 7-4. Conexión de un potenciómetro a una entrada analógica de Arduino. EJEMPLO.AR02: En el siguiente ejemplo se realizara lo mismo que el anterior con la diferencia que se reconvertirá el valor digital a su respectivo valor análogo, así se tendrá una especie de voltímetro por el Monitor Serial, el circuito a implementar es el mismo del ejemplo anterior. /* Ejemplo.AR02 - lectura analoga & monitor serial Leer el valor analogo y mistra la conversion digital en el monitor serial del PC Conectar el potenciomentro asi: extremo a +5Vcd , centro a A0 , extemo a GND Modificado por otoniel.flores@mail.utec.edu.sv Distribucion Libre CC */ //Variables para guardar la lectura float lectura_digital = 0; float valorVoltaje = 0; 67 Guía Teórico Práctica Aprende ARDUINO void setup() { Serial.begin(9600); //inicializar el puerto serie USB } void loop() { lectura_digital = analogRead(A0); //leer el pinA0 Serial.print("Valor digital A0 es = "); Serial.println(lectura_digital); //re-convertirlo a el valor de voltaje equivalente valorVoltaje = 5.0 * lectura_digital / 1023; Serial.print("Voltaje analogo A0 es = "); Serial.print(valorVoltaje); Serial.println(" Volts"); Serial.println("********************************************"); delay(500); } //fin del sketch Aplicación del Potenciómetro: El JOYSTICK Uno de los usos más frecuentes de las entradas analógicas de Arduino es la lectura de sensores con salida análoga, uno de ellos es el Potenciómetro utilizado en los ejemplos anteriores, pero una implementación especial de estos es en los llamados JOYSTICK (palancas de control), ver figura 7-5, que en estructura son dos potenciómetros dentro de un solo modulo, de tal forma que al mover la palanca sobre el eje X se cambia un potenciómetro, y a mover la palanca en el eje Y se manipula el otro potenciómetro, además este módulo cuenta con un botón pulsador que se activa al presionar la palanca en el eje Z. De la figura siguiente se puede apreciar el modulo, en el cual se dispone de 6 terminales: GND pin de alimentación negativo, +5V pin de alimentación positivo, VRx salida análoga del potenciómetro eje X, VRy salida análoga del potenciómetro eje Y y SW salida digital del botón eje Z. Figura 7-5. Modulo JOYSTICK. Notar sus 6 pines de conexión. dos para alimentación, uno de salida digital para el botón del eje y dos de salida análoga para cada eje X y Y. 68 Guía Teórico Práctica Aprende ARDUINO El control y lectura de estos módulos JOYSTICK es sencillo, simplemente de debe leer por medio de dos entradas análogas cada uno de las salidas de los potenciómetros de cada eje X y Y, además de leer con una entrada digital el botón del eje Z, recordando que las lecturas análogas se realizan en los pines A0 a A5, y su conversión nos da un valor digital entre 0 y 1023. A continuación se demostrara con algunos ejemplos el manejo de estos módulos. EJEMPLO JS01: A continuación se demostrara el uso del Joystick, en este ejemplo simplemente se leerá el valor análogo cada Potenciómetro interno y se mostrara en el Monitor Serial el valor digital leído de cada eje. Y así se tendrá una visión que los valores obtenidos para cada posición de la palanca del módulo, además se manejara el Botón del eje Z para encender y apagar un LED. Recuerde abrir el Monitor Serial al terminar la descarga. El circuito a seguir es el mostrado en la figura 7-6. /* EjemploJS01 Lectura Analoga JOYSTICK * -----------* Se lee el poteciometro correspondiente * eje X y Y, y se muestra en el monitor serial * la conversion ADC. * por: otoniel.flores@mail.utec.edu.sv * 2013 / ejemplo de distribucion libre. */ int pinVrx = 0; //pin A0 conectar salida X del Joystick int pinVry = 1; //pin A1 conectar salida X del Joystick int valorX = 0; //variable para almacenar lectura del eje X int valorY = 0; //variable para almacenar lectura del eje Y int boton = 13; //variables de uso general int led = 11; boolean bandera; //Estructura de Configuracion void setup() { pinMode(13, INPUT); //pin 13 entrada para el pulsador del Joystick digitalWrite(13, HIGH); //se activa la resistencia PULL.UP, investigue? //se configuran el pin 11 salida para LED pinMode(11, OUTPUT); Serial.begin(9600); } //Estructura Programa Principal void loop() { //leer el valor analogo de cada eje del Joystick valorX= analogRead(pinVrx); delay(5); valorY= analogRead(pinVry); int x = digitalRead(boton); //leer estado del boton, 1 = no presionado //verificar si se presiono el ejeZ y activar o desactivar LED if (x==0) { bandera = !bandera; //que hace esta linea? digitalWrite(led, bandera); delay(100); } Serial.println(" Serial.println(" Serial.print("El valor del Eje X es: "); 69 "); "); Guía Teórico Práctica Aprende ARDUINO Serial.println(valorY); Serial.print("El valor del Eje Y es: "); Serial.println(valorX); delay(225); } //Fin del Skecth Figura 7-6. Circuito de conexión para el ejemplo JS01. EJEMPLO JS02: En este ejemplo se demostrara como manipular el botón integrado dentro del módulo Joystick, el sketch leerá el estado del botón y en el monitor serial se mostrara el número de veces que este se pulse, el circuito de conexión es similar al del ejemplo JS01. /* Ejemplo Lectura Digital JOYSTICK * -----------* El Sketch lee el boton Eje Z * e indica via Monitor Serial el numero de * , veces que se ha presionado el boton. * * por: otoniel.flores@mail.utec.edu.sv * 2013 / ejemplo de distribucion libre. */ int boton = 13; //pin donde conectar boton del Joystick boolean bandera; int contador; //Estructura de Configuracion void setup() { pinMode(13, INPUT); //pin 13 entrada para el pulsador del Joystick digitalWrite(13, HIGH); //se activa la resistencia PULL.UP, investigue? //se configuran el pin 11 salida para LED 70 Guía Teórico Práctica Aprende ARDUINO Serial.begin(9600); Serial.println("Presione el boton del Joystick!!! Serial.println(" "); "); } //Estructura Programa Principal void loop() { int x = digitalRead(boton); //leer estado del boton, 1 = no presionado //verificar si se presiono el ejeZ if (x==0) { contador++; //que hace esta linea? Serial.println(" Serial.print("El boton se ha presionado "); Serial.print(contador); Serial.println(" veces."); delay(200); } } //Fin del Skecth "); EJEMPLO JS03: Una de las aplicaciones del Joystick es el control de algún dispositivo externo a partir de posición de la palanca del módulo, en este ejemplo se usara el movimiento del eje X del joystick para manipular el encendido de un LED de 11 conectados a pines digitales de Arduino. Se debe seguir a conexión del circuito de la figura 7-7. /* Ejemplo Lectura Analoga JOYSTICK * -----------* El Sketch manipula el encendido de 1 de 11 LEDs * segun la posicion X de un Joystick * * por: otoniel.flores@mail.utec.edu.sv * 2013 / ejemplo de distribucion libre. */ int vrX = 0; //pin A0 conectar salida X del Joystick int valorX = 0; //variable para almacenar lectura del eje X int x; void setup() { // configurar pines a utulizar for(x=2; x<13; x++) { pinMode(x, OUTPUT); } } void loop() { // tomar la lectura de Eje X valorX = analogRead(vrX); delay(5); // investiga que hace la instruccion siguinte? MAP int led = map(valorX, 0, 1023, 2, 12); 71 Guía Teórico Práctica Aprende ARDUINO //apagar los 11 LEDs for(x=2; x<13; x++) { digitalWrite(x, LOW); } // encender el un LED segun la posicion del eje X digitalWrite(led, HIGH); } // Fin del Sketch Figura 7-7. Circuito de conexión para el ejemplo JS03. Note que solo se usa un resistor, PORQUE? Como se puede observar la lectura de valores análogos no es complicada, con el uso de la función analogRead() se simplifica mucho el Sketch, para conocer más al respecto: http://arduino.cc/en/Tutorial/ReadAnalogVoltage En sección posteriores se retomara el uso de las entradas analógicas de Arduino para la lectura se sensores específicos. 72 Guía Teórico Práctica Aprende ARDUINO Salidas analógicas – PWM La tarjeta Arduino cuenta con un conjunto de salidas análogas, que permiten brindar un valor de voltaje DC variable entre 0 y 5Vdc, a diferencia de las salidas digitales que solo permiten brindar DOS valores fijos 0 o 5Vdc. Estos valores de voltajes analógicos en realidad son 255 valores diferentes, es decir que es posible obtener valores de salida entre 0 y 5Vcd con incrementos de 0.02 Vdc, esto gracias a que dentro de estas terminales de Arduino se implementa la técnica PWM. El número de pines que implementa este tipo de salida PWM depende del modelo de tarjeta Arduino con el que se trabaje, en la versión UNO se disponen de 6 pines PWM: 3, 5, 6, 9, 10 y 11, reconocidos porque tienen una marca (~) impresa al lado del terminal. En la versión MEGA se tienen 12 pines PWM: desde el pin 2 al 13. Este tipo de salidas de Arduino son muy utilizadas en el control tipo Regulación, específicamente en el control de brillo de LED o más aun en el control de velocidad de motores DC (en secciones posteriores se tocara este tema más a fondo el control de Motores). ¿Qué es PWM? La Modulación por Ancho de Pulso (PWM = Pulse Width Modulation) es una técnica para simular una salida analógica con una salida digital. El control digital se usa para crear una onda cuadrada, una señal que conmuta constantemente entre encendido y apagado. Este patrón de encendido-apagado puede simular voltajes entre 0 y 5 voltios, simplemente variando la proporción de tiempo entre encendido y apagado. A la duración del tiempo de encendido (ON) se le llama Ancho de Pulso). Para variar el valor analógico cambiamos, ese ancho de pulso. Si repetimos este patrón de encendidoapagado lo suficientemente rápido el resultado será un voltaje DC “fijo” entre 0 y 5 voltios. 73 Guía Teórico Práctica Aprende ARDUINO De lo anterior se deduce que mientras más grande sea el porcentaje del periodo del PWM más cercano a 5Vdc será el voltaje de salida, en lenguaje Arduino este porcentaje del periodo de la señal se especifica usando un valor entre 0 y 255, a continuación se describirá la instrucción usada para lograr obtener una salida de voltaje en una terminal PWM o de salida analógica en Arduino: analogWrite(pin, valor) esta función produce un voltaje DC determinado en el número de salida especificado en PIN, el voltaje estará determinado por el byte VALOR, que debe ser un numero entero entre 0 a 255, el cual define el porcentaje del periodo de la señal cuadrada a producir, el efecto será un voltaje DC constante presente en el pin de salida. Recordando que solo funciona con los pines PWM de la tarjeta Arduino. Por ejemplo, al ejecutan las siguientes instrucciones usando las salidas analógicas: analogWrite(3, 126); // produce un voltaje de salida de 2.5 Vdc en el pin 3 de Arduino analogWrite(11, 255); // produce un voltaje de 5Vdc en el pin 11 de Arduino. EJEMPLO. AW01: En el siguiente Sketch se utilizara una salida analogía para modificar el brillo de un LED conectado a un pin PWM de Arduino, el circuito a conectar no tiene ningún misterio: y puede ser seguido en detalle en la figura 7-8. Figura 7-8. Conexión de un LED al pin 9. /*Ejemplo analogWrite control de brillo LED Se controla el brillo del LED conectado al pin 9 de Arduino Ejemplo de Dominio Publico Modificado por otoniel.flores@mail.utec.edu.sv */ int pinLed = 9; int brillo = 0; // pin donde conectar LED // brillantez del LED // rutina SETUP . Se ejecuta una vez 74 Guía Teórico Práctica Aprende ARDUINO void setup() { // configurar el pin 9 como salida pinMode(pinLed, OUTPUT); } // rutina LOOP . Se ejecuta por siempre void loop() { // ciclo For para aumentar gradualmente el brillo // del LED for (brillo = 0; brillo <= 255; brillo++) { analogWrite(pinLed, brillo); //se escribe el pin delay(10); } delay(750); // ciclo For para disminuir el brillo del LED for (brillo = 255; brillo > 0; brillo--) { analogWrite(pinLed, brillo); delay(10); } delay(750); } // fin del código EJEMPLO. AW02: en este ejemplo se demostrara el uso combinado de las funciones anteriores: analogRead y analogWrite para controlar por medio de un Potenciómetro el brillo del LED, el circuito de conexión es sencillo, ver figura 7-9 /*EJEMPLO. AW02 Entrada y Salida Analoga Se controla el brillo del LED por medio de un potenciomentro . Ejemplo de Dominio Publico Modificado por otoniel.flores@mail.utec.edu.sv */ // Declaracion de algunas variables&constantes int ledPin = 9; int lecturaPot = 0; void setup() { pinMode(ledPin, OUTPUT); } void loop() { lecturaPot = (analogRead(0)); // leer la entrada analogica / potenciometro // como la lectura puede ser entre 0 y 1023 // convertirla a en un rango de 0 a 255 para // aplicarsela a un PWM lecturaPot = lecturaPot/4; // modificar el brillo del led analogWrite(ledPin, lecturaPot); // una breve pausa delay(50); } // fin del código 75 Guía Teórico Práctica Aprende ARDUINO Figura 7-9. Conexión de un LED al pin 9 para ser manejado por el Potenciómetro al pinA0. EJEMPLO AW.03: Se demostrara el uso del PWM de Arduino para controlar en encendido gradual de 8 LED conectados a la placa, el circuito a implementar se aprecia en la figura 7-10, es de notar que solo se usa una salida PWM para controlar los 8 LED. Porque? /* Ejemplo AW03. Control PWM de 8 LED modificado por: otoniel.flores@mail.utec.edu.sv ejemplo de dominio publico - CC */ int pinPWM = 11; int brillo = 0; // pin donde conctar LED // brillantez del LED // rutina SETUP void setup() { // configurar los pines como salidas pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(9, OUTPUT); pinMode(11, OUTPUT); } // rutina LOOP , infinita void loop() { // un FOR que controle el brillo y este dentro de // otro FOR por cada LED 76 Guía Teórico Práctica Aprende ARDUINO for (int led=2; led < 10; led++) { // colocamos los Catodos de los LED en HIGH digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH); digitalWrite(5, HIGH); digitalWrite(6, HIGH); digitalWrite(7, HIGH); digitalWrite(8, HIGH); digitalWrite(9, HIGH); for (brillo = 0; brillo <= 255; brillo++) { digitalWrite(led, LOW); analogWrite(pinPWM, brillo); delay(2); } delay(10); // desciende for (brillo = 255; brillo >= 0; brillo--) { digitalWrite(led, LOW); analogWrite(pinPWM, brillo); delay(2); } delay(10); } delay(1000); } // fin del sketch Figura 7-10. Esquema de conexión para el Ejemplo AW03 77 Guía Teórico Práctica Aprende ARDUINO 8. Manejo de DISPLAY de 7 segmentos con ARDUINO Al momento que se desea mostrar algún resultado numérico hacia el exterior de nuestra tarjeta Arduino una de los componentes más utilizados son los DISPLAY de 7 segmentos, este componente también llamado visualizador de 7 segmentos, es un periférico que se utiliza para la representación de números en muchos dispositivos electrónicos debido en gran medida a su simplicidad. Aunque externamente su forma difiere considerablemente de un diodo LED (diodos emisores de luz) típico, internamente están constituidos por una serie de diodos LED con unas determinadas conexiones internas, estratégicamente ubicados de tal manera que forme un número 8 al activarse los 7 LEDs, a partir de esto que puedan representarse todos los símbolos numéricos y algunas letras. Los primeros siete segmentos son los encargados de formar el símbolo y con el octavo podemos encender y apagar el punto decimal. Figura 8-1, Estructura de un DISPLAY de 7 segmentos. A cada uno de los segmentos LED que forman el DISPLAY se les denomina con una letra: a, b, c, d, e, f y g y están ensamblados de forma que se permita activar cada segmento por separado consiguiendo formar cualquier dígito numérico, ver figura 8-1, y los hay de dos tipos: ánodo común y cátodo común. En los DISPLAY de tipo de ánodo común, todos los ánodos de los LED o segmentos están unidos internamente a una patilla común que debe ser conectada a potencial positivo (nivel “1”) y el encendido de cada segmento individual se realiza aplicando potencial negativo (nivel “0”) por la patilla correspondiente a través de una resistencia que limite el paso de la corriente. 78 Guía Teórico Práctica Aprende ARDUINO En los DISPLAY de tipo de cátodo común, todos los cátodos de los LED o segmentos están unidos internamente a un terminal común que debe ser conectada a potencial negativo (nivel “0”) y el encendido de cada segmento individual se realiza aplicando potencial positivo (nivel “1”) por la terminal correspondiente a través de una resistencia que limite el paso de la corriente hacia cada segmento para que no se arruine, un valor estándar entre 220 o 470 ohmios. Figura 8-2, Conexión interna de los segmentos de un DISPLAY. Los segmentos pueden ser de diversos colores, aunque el DISPLAY más comúnmente utilizado es el de color rojo, aunque se pueden encontrar en diversos colores y por su facilidad de visualización el DISPLAY de 7 segmentos sigue siendo una excelente opción en ciertas situaciones en las que se requiera mayor poder lumínico y trabajo en áreas hostiles, donde los DISPLAYs podrían verse afectado por condiciones ambientales adversas. Aún no se ha creado otro dispositivo de señalización que reúna características como este en cuanto a: Buen poder lumínico, claridad, sencillez para implementarlo, muy bajo costo, robustez. Manejo Directo con Arduino. Como cada segmento de un DISPLAY es básicamente un LED, se deduce que el manejo de estos es sencillo desde el sketch Arduino manipular el número a desplegar en el DISPLAY, como cada LED interno necesita una terminal de salida Arduino para ser conmutado, se necesitan al menos 7 salidas digitales para manipular un solo DISPLAY, a esta conexión se le denomina Manejo Directo, en esta cada pin de salida es manipulado individualmente por medio de digitalWrite(pin, estado) según el carácter que se desea formar en el DISPLAY, el siguiente ejemplo nos dejaran más claro esto. EJEMPLO.DISPLAY01. Se demostrara el Manejo Directo de un DISPLAY de 7 segmentos, siguiendo las conexiones que se muestran en las figuras 8-3 y 8-4. El Sketch a continuación muestra como desplegar caracteres numéricos en el DISPLAY, se mostraran todos los caracteres decimales a modo de conteo. /* Ejemplo.DISPLAY01 Muestra los numeros de 0 a 9 en un DISPLAY Catodo Comun Los segmentos se conectan a las salidas 2 a 8 con 79 Guía Teórico Práctica Aprende ARDUINO resistores de entre 220 y 470 ohmios, el comun a GND. Modifica por otoniel.flores@mail.utec.edu.sv Distribucion Libre CC */ //Salidas Arduino a conectar con los segmentos del DISPLAY int segA = 2; int segB = 3; int segC = 4; int segD = 5; int segE = 6; int segF = 7; int segG = 8; void setup() { //Configurar los pines como salidas pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segG, OUTPUT); } void loop() { //Se escribe el 0 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 1); digitalWrite(segE, digitalWrite(segG, 0); delay(1000); //Se escribe el 1 en el display digitalWrite(segA, 0); digitalWrite(segB, digitalWrite(segD, 0); digitalWrite(segE, digitalWrite(segG, 0); delay(1000); //Se escribe el 2 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 1); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); //Se escribe el 3 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 1); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); //Se escribe el 4 en el display digitalWrite(segA, 0); digitalWrite(segB, digitalWrite(segD, 0); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); //Se escribe el 5 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 1); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); //Se escribe el 6 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 1); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); //Se escribe el 7 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 0); digitalWrite(segE, digitalWrite(segG, 0); delay(1000); //Se escribe el 8 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 1); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); //Se escribe el 9 en el display digitalWrite(segA, 1); digitalWrite(segB, digitalWrite(segD, 0); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); //Apagamos el display digitalWrite(segA, 0); digitalWrite(segB, digitalWrite(segD, 0); digitalWrite(segE, digitalWrite(segG, 1); delay(1000); } //fin del Sketch 80 pinMode(segC, OUTPUT); pinMode(segF, OUTPUT); 1); digitalWrite(segC, 1); 1); digitalWrite(segF, 1); 1); digitalWrite(segC, 1); 0); digitalWrite(segF, 0); 1); digitalWrite(segC, 0); 1); digitalWrite(segF, 0); 1); digitalWrite(segC, 1); 0); digitalWrite(segF, 0); 1); digitalWrite(segC, 1); 0); digitalWrite(segF, 1); 0); digitalWrite(segC, 1); 0); digitalWrite(segF, 1); 0); digitalWrite(segC, 1); 1); digitalWrite(segF, 1); 1); digitalWrite(segC, 1); 0); digitalWrite(segF, 0); 1); digitalWrite(segC, 1); 1); digitalWrite(segF, 1); 1); digitalWrite(segC, 1); 0); digitalWrite(segF, 1); 0); digitalWrite(segC, 0); 0); digitalWrite(segF, 0); Guía Teórico Práctica Aprende ARDUINO Figura 8-3. Diagrama de conexiones pictórico para el manejo directo de un DISPLAY Figura 8-4. Diagrama de conexiones pictórico para el manejo directo de un DISPLAY 81 Guía Teórico Práctica Aprende ARDUINO EJEMPLO.DISPLAY02. En este ejemplo se combinara el manejo de DISPLAY con la recepción de datos vía el Monitor Serial, se recibirá un carácter por el puerto USB y se desplegara este en el DISPLAY conectado a la tarjeta Arduino, se utilizara la conexión de la figura 8-3 y 8-4. /* Ejemplo.DISPLAY02 Muestra los numeros de 0 a 9 en un DISPLAY Catodo Comun segun la recepcion del Monitor Serial Los segmentos se conectan a las salidas 2 a 8 con resistores de entre 220 y 470 ohmios, el comun a GND. Modificado por otoniel.flores@mail.utec.edu.sv Distribucion Libre CC */ //Salidas Arduino a conectar con //los segmentos del DISPLAY int int int int segA = 2; int segB = 3; int segC = 4; segD = 5; int segE = 6; int segF = 7; segG = 8; byteSerial = 0;// para los datos de entrada serie void setup() { // abre el puerto serie, establece la velocidad a 9600 bps Serial.begin(9600); //Configurar los pines como salidas pinMode(segA, OUTPUT); pinMode(segB, OUTPUT); pinMode(segC, OUTPUT); pinMode(segD, OUTPUT); pinMode(segE, OUTPUT); pinMode(segF, OUTPUT); pinMode(segG, OUTPUT); //Imprimir en el Monitor Serial Serial.println ("Introduzca un numero entre 0 y 9"); } void loop() { //Verificar si hay algun dato proveniente de la PC if (Serial.available() > 0) //si esta disponible algun dato { // lee el byte de entrada: byteSerial = Serial.read(); Serial.println(byteSerial); if (byteSerial > 57 || byteSerial < 48) { //Apagamos el display digitalWrite(segA, 0); digitalWrite(segB, 0); digitalWrite(segC, digitalWrite(segD, 0); digitalWrite(segE, 0); digitalWrite(segF, digitalWrite(segG, 1); Serial.println ("Error ! Introduzca un numero entre 0 y 9"); } //vefificar el dato ingresado if (byteSerial == '0') { //Se escribe el 0 en el display digitalWrite(segA, 1); digitalWrite(segB, 1); digitalWrite(segC, digitalWrite(segD, 1); digitalWrite(segE, 1); digitalWrite(segF, digitalWrite(segG, 0); delay(750); Serial.println ("Introduzca un numero entre 0 y 9"); } 82 0); 0); 1); 1); Guía Teórico Práctica Aprende ARDUINO if (byteSerial == '1') { //Se escribe el 0 en el display //Se escribe el 1 en el display digitalWrite(segA, 0); digitalWrite(segB, 1); digitalWrite(segD, 0); digitalWrite(segE, 0); digitalWrite(segG, 0); delay(750); Serial.println ("Introduzca un numero entre 0 } if (byteSerial == '2') { //Se escribe el 2 en el display digitalWrite(segA, 1); digitalWrite(segB, 1); digitalWrite(segD, 1); digitalWrite(segE, 1); digitalWrite(segG, 1); delay(750); Serial.println ("Introduzca un numero entre 0 } if (byteSerial == '3') { //Se escribe el 3 en el display digitalWrite(segA, 1); digitalWrite(segB, 1); digitalWrite(segD, 1); digitalWrite(segE, 0); digitalWrite(segG, 1); delay(750); Serial.println ("Introduzca un numero entre 0 } if (byteSerial == '4') { //Se escribe el 4 en el display digitalWrite(segA, 0); digitalWrite(segB, 1); digitalWrite(segD, 0); digitalWrite(segE, 0); digitalWrite(segG, 1); delay(750); Serial.println ("Introduzca un numero entre 0 } if (byteSerial == '5') { //Se escribe el 5 en el display digitalWrite(segA, 1); digitalWrite(segB, 0); digitalWrite(segD, 1); digitalWrite(segE, 0); digitalWrite(segG, 1); delay(750); Serial.println ("Introduzca un numero entre 0 } if (byteSerial == '6') { //Se escribe el 6 en el display digitalWrite(segA, 1); digitalWrite(segB, 0); digitalWrite(segD, 1); digitalWrite(segE, 1); digitalWrite(segG, 1); delay(750); Serial.println ("Introduzca un numero entre 0 } if (byteSerial == '7') { //Se escribe el 7 en el display digitalWrite(segA, 1); digitalWrite(segB, 1); digitalWrite(segD, 0); digitalWrite(segE, 0); digitalWrite(segG, 0); delay(750); Serial.println ("Introduzca un numero entre 0 } 83 digitalWrite(segC, 1); digitalWrite(segF, 0); y 9"); digitalWrite(segC, 0); digitalWrite(segF, 0); y 9"); digitalWrite(segC, 1); digitalWrite(segF, 0); y 9"); digitalWrite(segC, 1); digitalWrite(segF, 1); y 9"); digitalWrite(segC, 1); digitalWrite(segF, 1); y 9"); digitalWrite(segC, 1); digitalWrite(segF, 1); y 9"); digitalWrite(segC, 1); digitalWrite(segF, 0); y 9"); Guía Teórico Práctica Aprende ARDUINO if (byteSerial == '8') { //Se escribe el 8 en el display digitalWrite(segA, 1); digitalWrite(segB, 1); digitalWrite(segD, 1); digitalWrite(segE, 1); digitalWrite(segG, 1); delay(750); Serial.println ("Introduzca un numero entre 0 } if (byteSerial == '9') { //Se escribe el 9 en el display digitalWrite(segA, 1); digitalWrite(segB, 1); digitalWrite(segD, 0); digitalWrite(segE, 0); digitalWrite(segG, 1); delay(750); Serial.println ("Introduzca un numero entre 0 } digitalWrite(segC, 1); digitalWrite(segF, 1); y 9"); digitalWrite(segC, 1); digitalWrite(segF, 1); y 9"); } } //fin del Sketch Los ejemplos anteriores permite el manejo directo de un DISPLAY, pero si se observa bien, se nota que si se desean manejar más de un DISPLAY a la vez y mostrar datos compuestos de 3 o más cifras, los pines de una tarjeta Arduino UNO no son suficientes ya que se necesitan 7 por cada DISPLAY a controlar, además en ocasiones se necesita tener más pines para conectar otros dispositivos como sensores, es en esta situación que mejor se recomienda el uso de circuitos integrados interfaces controladores de DISPLAY, es decir un componentes diseñados para que solo necesiten un par de pines Arduino y sea este circuito integrado interface quien se encargue de las conexiones a los DISPLAY, algunos ejemplos comúnmente usados son los circuitos integrados MAX7219 y TM1640, a continuación se verán algunos ejemplos para manipular DISPLAY usando estos circuitos. Manejo de DISPLAY usando el IC MAX7219 El circuito integrado MAX7219, figura 8-5 es un estupendo chip capaz de controlar hasta 8 dígitos de 7 segmentos o 64 diodos LED independientes a partir de la comunicación desde una tarjeta Arduino con solo 3 pines, esta comunicación se realiza a través del protocolo SPI implementado en Arduino. El chip MAX7219 incorpora un decodificador BCD, realiza multiplexado para el encendido de los DISPLAY y posee memoria RAM interna de 8x8 para almacenar el valor de cada dígito. Solamente se necesita de una resistencia externa para hacerlo funcionar. Se maneja tan sólo con 3 patillas y es compatible con los protocolos de comunicación SPI™, QSPI™, y MICROWIRE™, sin embargo se verá que no es necesario conocer a detalle estos protocolos, ya que en Arduino IDE se tiene la ventajas del uso de librerías que ya incluyen funciones para manejar este circuito integrado fácilmente. 84 Guía Teórico Práctica Aprende ARDUINO Figura 8-5 Encapsulado y conexión del MAX7219 (maxim.com) El MAX7219 es ideal para controlar fácilmente una gran cantidad de diodos LED o múltiples DISPLAY de 7 segmentos. También podemos controlar una matriz de LED de 8x8 con un sólo chip (Esto se verá en secciones posteriores). Características Técnicas del MAX7219: Displays controlables: 8 (o 64 LED individuales) Tipo de display: Cátodo común Interfaz: Protocolo SPI (Interface Serial para Perifericos) Voltaje de alimentación: 4V - 5,5V Numero de Pines: 24 DIP Con Arduino la interface con un MAX7219 es sencilla, desde el punto de vista de hardware solo requiere 3 terminales y en Sketch será necesario el uso de una librería para interactuar con los DISPLAY conectados, en la figura 8-6 se puede ver un circuito de conexión típica usada para el control de hasta 8 dígitos conectados al MAX7219, en dicha figura se muestra el control de 4 dígitos, con sus terminales de segmento en paralelo y conectadas al MAX, cabe mencionar que existen módulos que ya incluyen esta conexión del MAX7219 y 8 DISPLAY, figura 8-7. 85 Guía Teórico Práctica Aprende ARDUINO Figura 8-6. Conexión típica del circuito integrado MAX7219 para el manejo de DISPLAY. (oreilly.com) Figura 8-7. Version módulo integrados MAX7219 y 8 DISPLAY. (dfrobot.net) Tomando en cuenta la conexión mostrada en la figura 8-6, desde el punto de vista del Sketch se necesita el uso de una Librería especial que incluye las funciones pre-diseñadas para un manejo sencillo de DISPLAY conectado al MAX7219, esta librería no es estándar dentro de Arduino IDE y debe ser descargada e instalada en nuestro IDE, la librería a utilizar es ledcontrol.h que puede ser descargada de https://docs.google.com/file/d/0B7SISgResP2ReUozMHVKZGpjTk0/edit?usp=sharing se recomienda descargar toda la carpeta Ledcontrol.zip desde la opción DESCARGAR en el menú Archivo. 86 Guía Teórico Práctica Aprende ARDUINO Breve nota sobre el uso e instalación de librerías externas al Arduino IDE. Una librería es un archivo de código al que se va a llamar desde un programa hecho para lenguaje Arduino, con la finalidad de que realice una tarea concreta, las librerías proporcionan funcionalidad extra para la utilización en sketches, por ejemplo para trabajar con hardware o manipular datos, en otras palabras son archivos de código que contiene las instrucciones de funciones especiales para la manipulación de algún sensor o actuador especifico. Si deseas usar librerías que no vienen junto con Arduino, necesitarás instalarlas. Para hacerlo, descarga la librería y descomprímela. Debería localizarse en una carpeta propia, y normalmente, contener dos archivos, uno con sufijo ".h" y otro con sufijo ".cpp". Abre tu carpeta de Instalacion de Arduino, si ya existe una carpeta llamada "libraries", coloca la carpeta de la librería ahí dentro. Reiniciar el IDE de Arduino para encontrar la nueva librería en el menú Sketch > Import Library. Para utilizar una librería y sus funciones en nuestro Sketch, se seleccione el menú Sketch > Import Library. Esto insertará una o más sentencias #include al principio del sketch y permitirá que se compile la librería con nuestro sketch. Debido a que las librerías se vuelcan a la placa junto con su "sketch", incrementan la ocupación del espacio disponible. Si un "sketch" no precisa de una libreria, simplemente borra su sentencia #include en la parte inicial de su código. Después de descargar, se debe instalar en el IDE la librería, siguiendo el proceso descrito anteriormente, dentro de la librería LedControl.h encontraremos algunas funciones que nos ayudaran a manipular de forma sencilla los DISPLAY conectados al MAX7219 usando Arduino, por lo que a continuación se describirán algunas de estas funciones y su uso, para luego realizar algunos ejemplos de utilización de la librería junto con el MAX7219. Funciones de Configuración LedControl miDisplay = LedControl(DIN_pin, CLK_pin, LOAD_pin, Chips): Esta función crea un “objeto” dentro del sketch llamado miDisplay, con el objetivo de ser manipulado en el programa principal, el nombre miDisplay puede cambiar a gusto del programador. Los parámetros que recibe esta función son los números de pines Arduino donde se conectaran las respectivas entradas del MAX7219: DIN, CLK y LOAD, además de un cuarto parámetro con el número de circuitos integrados MAX que se usaran en cascada, recordando que cada uno puede manipular hasta 8 DISPLAY, esta función debe incluirse al inicio del Sketch ante la función Setup(). miDisplay.shutdown(chip, false): Esta función enciende o apaga el chip MAX7219, el parámetro "false" enciende y "true" lo apaga, el parámetro chip es un nuero que denota el orden del chip a manejar si están en cascada, el numero 0 indica el primer chip. Esta función debe estar dentro de la estructura Setup(). miDisplay.setIntensity(chip, intensidad): Configura la intensidad de luz de los LED, coo parámetros recibe el número de orden del chip a manipular y un valor de intensidad entre 1 y 15. Esta función debe estar dentro de la estructura Setup(). 87 Guía Teórico Práctica Aprende ARDUINO Funciones de Manipulación miDisplay.setDigit(chip, digito, numero, punto): Esta función sirve para despegar un número entre 0 y 9 en el DISPLAY que deseemos, según los parámetros que le pasemos a la función, así: chip es el orden de MAX a controlar, 0 si solo se tiene uno conectado a Arduino, digito es el número del DISPLAY especifico conectado al MAX, 0 a 7 máximo, el parámetro punto controla e encendido o apagado del punto decimal del DISPLAY, puede ser “false” o “true”. Normalmente esta función se invoca desde la estructura Loop(). miDisplay.setChar(chip,digito,'carácter',punto): Al igual que la función anterior despliega, pero con la diferencia de que despliega un carácter alfabético en un DISPLAY, hay que recordar que solo ciertas letras pueden ser escritas en un DISPLAY de 7 segmentos. Normalmente esta función se invoca desde la estructura Loop(). En secciones posteriores se estudiara más del circuito integrado MAX7219 para el control de otro tipo de dispositivo de despliegue, la matriz de LED. EJEMPLO.MAX01: En el siguiente ejemplo se demostrara el uso las funciones de la librería LedControl.h para el manejo de 8 DISPLAY conectados aun MAX7219 vía Arduino, se recomienda el uso de modulo integrado de 8 DISPLAY como el de la figura 8-7 siguiendo las conexiones descritas en este sketch. //* Ejemplo.MAX01 – Manejo de DISPLAY con MAX7219 En este ejemplo se manipulan 8 DISPLAY conectados a un MAX7219 por medio de Arduino. Se recomienda el uso modulo integrado 8 DISPLAY y MAX7219 Modificado por: otoniel.flores@mail.utec.edu.sv Distribucion Libre CC */ //Se incluye la libreria a utilizar #include "LedControl.h" //Se configura el objeto miDisplay y los pines //de Arduino a conectar con el MAX7219 //se asume la conexion siguiente: //Arduino --- Modulo MA7219 //pin 12 conetado a DIN //pin 11 conectado a LOAD (CS) //pin 10 conectado a CLK LedControl miDisplay=LedControl(12,10,11,1); void setup() { //encender el MAX7219 miDisplay.shutdown(0,false); //setear el brillo miDisplay.setIntensity(0,8); //se "limpian" los diplays miDisplay.clearDisplay(0); } //Programa Principal 88 Guía Teórico Práctica Aprende ARDUINO void loop() { //primero se muestran todos los digitos en //los 8 displays //recordando: miDisplay.setDigit(chip, digito, numero, punto); miDisplay.setDigit(0, 0, 0, false); delay(500); miDisplay.setDigit(0, 1, 1, false); delay(500); miDisplay.setDigit(0, 2, 2, false); delay(500); miDisplay.setDigit(0, 3, 3, false); delay(500); miDisplay.setDigit(0, 4, 4, true); delay(500); miDisplay.setDigit(0, 5, 5, false); delay(500); miDisplay.setDigit(0, 6, 6, false); delay(500); miDisplay.setDigit(0, 7, 7, false); delay(2000); delay(1500); miDisplay.clearDisplay(0); delay(500); //escribir algunas letras en los displays //recordando: miDisplay.setChar(chip, digito, numero, punto); miDisplay.setChar(0,7,'a',false); delay(150); miDisplay.setChar(0,6,'b',true); delay(150); miDisplay.setChar(0,5,'c',false); delay(150); miDisplay.setChar(0,4,'d',false); delay(150); miDisplay.setChar(0,3,'E',false); delay(150); miDisplay.setChar(0,2,'F',false); delay(150); miDisplay.setChar(0,1,'H',false); delay(150); miDisplay.setChar(0,0,'L',false); delay(2000); miDisplay.clearDisplay(0); delay(250); //Efecto scroll en los display for(int i=0;i<13;i++) { miDisplay.setChar(0,i,'A',false); miDisplay.setChar(0,i+1,'L',false); miDisplay.setDigit(0,i+2,0,false); miDisplay.setChar(0,i+3,'H',false); delay(200); miDisplay.clearDisplay(0); delay(5); } miDisplay.clearDisplay(0); delay(250); //Desplegar una variable que contiene una cifra de 4 digitos. int numero = 9876; //cifra a mostrar //primero descomponer el valor en sus digitos int miles = numero / 1000; int centenas = (numero % 1000)/100; int decenas = ((numero % 1000)%100)/10; int unidades = ((numero % 1000)%100)%10; miDisplay.setDigit(0,3,miles,false); miDisplay.setDigit(0,2,centenas,false); miDisplay.setDigit(0,1,decenas,false); miDisplay.setDigit(0,0,unidades,false); delay(2000); 89 Guía Teórico Práctica Aprende ARDUINO miDisplay.clearDisplay(0); delay(250); } //Fin del sketch Manejo de DISPLAY usando el IC TM1640 El circuito integrado TM1640, figura 8-8 es un versátil chip capaz de controlar hasta 16 dígitos de 7 segmentos independientes a partir de la comunicación desde una tarjeta Arduino con solo 2 pines más dos de alimentación,. El chip TM1640 incorpora un decodificador BCD, realiza multiplexado para el encendido de los DISPLAY y posee memoria RAM interna de 8x8 para almacenar el valor de cada dígito. Y con el advenimiento de versiones modulares compatibles con Arduino, ya se dispone de una tarjeta con 16 DISPLAY conectados al TM1640 listo para ser manejado desde la tarjeta Arduino, ver figuras 8-9 y 10. Figura 8-8 Encapsulado del circuito integrado TM1640 Figura 8-9. Módulo integrado TM1640 y 16 DISPLAY listo para conexión Arduino Figura 8-10 Pines de conexión para el control del Módulo TM1640 con 16 display 90 Guía Teórico Práctica Aprende ARDUINO Nos centraremos en el uso de este módulo con Arduino, de las imágenes anteriores se aprecia que la interface es sencilla, desde el punto de vista de hardware solo requiere 2 terminales (DIN , SCLK) y en Sketch será necesario el uso de una librería para interactuar con los DISPLAY conectados en el módulo, esta librería incluye las funciones pre-diseñadas para un manejo sencillo de los DISPLAY conectado al TM1640, esta librería no es estándar dentro de Arduino IDE y debe ser descargada e instalada en nuestro IDE, la librería a utilizar es TM1640.h que puede ser descargada de https://code.google.com/p/tm1638-library/ , se recomienda descargar de la última versión disponible y debe ser instalada en nuestro IDE antes de invocarla en el Sketch. Dentro de la librería TM1640.h encontraremos algunas funciones que nos ayudaran a manipular de forma sencilla los DISPLAY dentro del módulo TM1640 usando Arduino, por lo que a continuación se describirán algunas de estas funciones y su uso, para luego realizar algunos ejemplos de utilización de la librería. Funciones de Configuración TM1640 miModulo(DINpin, SCLKpin): Esta función crea un “objeto” dentro del sketch llamado miModulo, con el objetivo de ser manipulado en el programa principal, el nombre miModulo puede cambiar a gusto del programador. Los parámetros que recibe esta función son los números de pines Arduino donde se conectaran las respectivas entradas del módulo tm1640: DIN y SCLK, esta función debe incluirse al inicio del Sketch ante la función Setup(). miModulo.setupDisplay(true, Intensidad): Configura la intensidad de luz de los LED, como parámetros recibe la palabra “true” y un valor de intensidad entre 1 y 7. Esta función debe estar dentro de la estructura Setup(). Funciones de Manipulación miModulo.clearDisplay(): Esta función “limpia” los DISPLAY y borra el contenido desplegado en ellos. miModulo.setDisplayDigit(Numero, Posición, Punto): Esta función sirve para despegar un número entre 0 y 9 en el DISPLAY que deseemos, según los parámetros que le pasemos a la función, así: Posicion es el número del DISPLAY especifico donde queremos desplegar (0 a 15), el parámetro punto controla el encendido o apagado del punto decimal del DISPLAY, puede ser “false” o “true”. Normalmente esta función se invoca desde la estructura Loop(). miModulo.setDisplayToString(String, Punto, Posición): Permite desplegar una cadena de caracteres alfanuméricos en los DISPLAY del módulo, tomando en consideración que no todas las letras pueden ser representadas correctamente, esta función recibe tres parámetros a saber: String es el nombre de la variable tipo String que contiene el mensaje alfanumérico a desplegar, recordando que este mensaje debe ser de 16 caracteres máximo, Punto es un numero en formato binario indicando que caracteres mostraran el punto decimal y cuáles no, Posicion es un número que denota la poicion de inico del mensaje dentro del Módulo. Por ejemplo, la instrucción module.setDisplayToString(name, b000000000000001, 4); despliega el contenido de la variable llamada nombre, a partir del 4 DISPLAY del módulo y solamente el primer digito enciende el punto decimal. Normalmente esta función se invoca desde la estructura Loop(). A continuación se describirá un ejemplo donde se usan las funciones anteriormente descritas y así comprobar en la práctica el funcionamiento correcto de estas. 91 Guía Teórico Práctica Aprende ARDUINO EJEMPLO TM01: En el siguiente ejemplo se conectara un Módulo 16 DISPLAY TM1640 a la tarjeta Arduino (pin 12 y 11) y se hará uso de las funciones de la librería TM1640.h para manipular los DISPLAY. /* ********************************************** Demostracion de uso del Modulo 16 DISPLAY TM1640 con la libreria TM1640.h Modificado por: otoniel.flores@mail.utec.edu.sv Basado en el trabajo de: Ricardo Batista <rjbatista at gmail dot com> Este programa es de libre distribucion bajo licencia Creative Commons ********************************************** */ //Incluir las librerias para manejo del modulo de Displays //Es necesario la inclusion de las DOS librerias #include <TM1638.h> #include <TM1640.h> //Definir los pines de conexion para el Modulo //se crea el Objeto miModulo //TM1640 miModulo(Din, SCLK); // se debe conectar asi: // Pin Modulo --- Pin Arduino // Din --11 // SCLK --12 TM1640 miModulo(11, 12); void setup() { miModulo.setupDisplay(true, 7); //configura el briilo al maximo miModulo.clearDisplay(); //limpiar displays } void loop() { //se muestran los numeros //recordando miModulo.setDisplayDigit(Numero, Posición, Punto); miModulo.setDisplayDigit(0, 0, true); delay (500); miModulo.setDisplayDigit(2, 2, true); delay (500); miModulo.setDisplayDigit(4, 4, true); delay (500); miModulo.setDisplayDigit(6, 12, true); delay (500); miModulo.setDisplayDigit(8, 14, true); delay (500); miModulo.setDisplayDigit(1, 1, false); delay (500); miModulo.setDisplayDigit(3, 3, false); delay (500); miModulo.setDisplayDigit(5, 11, false); delay (500); miModulo.setDisplayDigit(7, 13, false); delay (500); miModulo.setDisplayDigit(9, 15, false); delay (2000); miModulo.clearDisplay(); delay(1000); //Despliegue de una cadena de caracteres //primero se crea una vaiable tipo String con el texto a desplegar. String msj1 = "EL SALVAdOR . CA"; //se invoca la funcion para desplegar miModulo.setDisplayToString(msj1); delay (5000); String msj2 = "-Arduino Rule-"; miModulo.setDisplayToString(msj2); delay (5000); miModulo.clearDisplay(); delay(1000); } //Fin del Sketch 92 Guía Teórico Práctica Aprende ARDUINO APUNTES> 93 Guía Teórico Práctica Aprende ARDUINO 9. Generación de sonido con ARDUINO El transductor por excelencia usado en los sistemas embebidos para emitir sonidos simples es el BUZZER, este componente también llamado Zumbador, Piezoeléctrico o Piezobuzzer es un dispositivo que consta internamente de un disco de metal, que se deforma (debido a la piezoelectricidad) cuando se aplica corriente eléctrica. Lo interesante es que si a este disco se le aplica una secuencia de pulsos eléctricos de una frecuencia suficientemente alta, el zumbador se deformara y volverá a recuperar su forma tan rápido que vibrará, y esa vibración generara una onda de sonido audible. Figura 9-1. Forma física de diversos modelos de BUZZER. (www.buzzer-speaker.com) Cuanto mayor sea la frecuencia de los pulsos eléctricos aplicados, más agudos serán los sonidos resultantes, por lo tanto, para generar diferentes tonos con un Buzzer debemos excitarlo a distintas frecuencias de pulsos eléctricos digitales, los Buzzer admiten pulsos con un voltaje entre 3 a 5Vdc, y una salida digita de Arduino es perfecta para manejar estos dispositivos, en la figura se aprecian su forma física. Así pues para hacer sonar un Buzzer típico, simplemente se debe conectar una terminal a tierra GND y la otra a un pin digital del Arduino, respetando la polaridad del Buzzer, es común conectar un resistor (100 ohmios) en serie con el Buzzer para reducir el volumen del sonido emitido. Una conexión típica entre Arduino y un Buzzer se muestra en la figura 9-2. 94 Guía Teórico Práctica Aprende ARDUINO Afortunadamente el lenguaje Arduino incluye una función para poder manejar desde nuestros sketches esta tipo de dispositivos, para emitir “pitidos” se dispone de dos funciones especialmente pensadas para ello y facilitar la estructura de los programas. A continuación se describen estas: Figura 9-2. Conexión típica entre Arduino y un Buzzer. tone(): genera una onda cuadrada de una frecuencia determinada (especificada como parámetro de esta función) y la envía al pin digital de salida especificado también como parámetro de la función, además la duración del tono también se puede especificar. Por ejemplo tone(8,2000,500) emitirá un pulso digital de 2000 Hz por el pin 8 con una duración de 500mS. noTone(): deja de generar la onda cuadrada, si se está emitiendo alguna. Si no hay ninguna emitiéndose, la función noTone no hace nada. EJEMPLO BUZZER01: Un sketch sencillo que muestra cómo trabajan estas funciones es el siguiente, y que se puede probar siguiendo el circuito de la figura anterior, al ejecutarlo se escuchara el sonido de una sirena. /* EJEMPLO BUZZER01 Demostracion de generacion de tonos desde Arduino con un buzzer Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CreativeComons */ //variables que definen las frecuencias a generar int duracion = 250; int freq_min = 2000; int freq_max = 4000; int i; void setup() { pinMode(11, OUTPUT); //pin de conexion al buzzer 95 Guía Teórico Práctica Aprende ARDUINO } void loop() { //Se generan tonos simulando una sirena //se incrementa el tono , se hace for (int i=freq_min; i<=freq_max; { tone(11,i,duracion); } //se decrementa el tono , se hace for (int i=freq_max; i<=freq_min; { tone(11,i,duracion); } mas agudo i++) mas grave i--) } //Fin del sketch EJEMPLO BUZZER02: El siguiente sketch genera una melodía en el buzzer conectado al pin 11 del Arduino, note la forma en cómo se generan los tonos e investigue aquellas instrucciones o funciones nuevas que aparecen. El código del sketch fue tomado de: http://pastebin.com/dqdmPyhz /* Ejemplo de uso de Arduino y Buzzer para reproducir una melodia a base de tonos Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CreativeComons */ Int Melodia[] = {660,660,660,510,660,770,380,510,380,320,440,480,450,430,380,660,760,860, 700,760,660,520, 580,480,510,380,320,440,480,450,430,380,660,760,860,700,760,660,520,580,480,500,760,720, 680,620,650,380,430,500,430,500,570,500,760,720,680,620,650,1020,1020,1020,380,500,760, 720,680,620,650,380,430,500,430,500,570,585,550,500,380,500,500,500,500,760,720,680,620, 650,380,430,500,430,500,570,500,760,720,680,620,650,1020,1020,1020,380,500,760,720,680, 620,650,380,430,500,430,500,570,585,550,500,380,500,500,500,500,500,500,500,580,660,500, 430,380,500,500,500,500,580,660,870,760,500,500,500,500,580,660,500,430,380,660,660,660, 510,660,770,380}; int duracionNotas[] = {100,100,100,100,100,100,100,100,100,100,100,80,100,100,100,80,50,100,80,50,80,80,80,80, 100,100,100,100,80,100,100,100,80,50,100,80,50,80,80,80,80,100,100,100,100,150,150,100, 100,100,100,100,100,100,100,100,100,150,200,80,80,80,100,100,100,100,100,150,150,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,150,150,100,100,100,100,100, 100,100,100,100,100,150,200,80,80,80,100,100,100,100,100,150,150,100,100,100,100,100,100, 100,100,100,100,100,100,100,60,80,60,80,80,80,80,80,80,60,80,60,80,80,80,80,80,60,80,60, 80,80,80,80,80,80,100,100,100,100,100,100,100}; void setup() { for (int nota = 0; nota < 156; nota++) { int duracionNota = duracionNotas[nota]; tone(8, Melodia[nota],duracionNota); int pausaEntreNotas[] ={150,300,300,100,300,550,575,450,400,500,300,330,150,300,200,200,150,300,150,350,300, 150,150,500,450,400,500,300,330,150,300,200,200,150,300,150,350,300,150,150,500,300,100, 150,150,300,300,150,150,300,150,100,220,300,100,150,150,300,300,300,150,300,300,300,100, 150,150,300,300,150,150,300,150,100,420,450,420,360,300,300,150,300,300,100,150,150,300, 96 Guía Teórico Práctica Aprende ARDUINO 300,150,150,300,150,100,220,300,100,150,150,300,300,300,150,300,300,300,100,150,150,300, 300,150,150,300,150,100,420,450,420,360,300,300,150,300,150,300,350,150,350,150,300,150, 600,150,300,350,150,150,550,325,600,150,300,350,150,350,150,300,150,600,150,300,300,100, 300,550,575}; delay(pausaEntreNotas[nota]);} noTone(8); } void loop() { //no se hace nada mas } //Fin del sketch En los ejemplos anterior se generaron tonos en un buzzer que posee una potencia de sonido baja, pero que hacer cuando se desea un mayor volumen de los sonidos, se hace necesario el uso de un parlante o bocina y de un circuito amplificador de audio entre la salida de Arduino y el parlante, en la figura 8-4 se aprecia un circuito sencillo para la amplificación de la señal de salida del pin digital de Arduino, este circuito permite obtener una potencia de audio de hasta 500mW que está basado en un transistor BC337 y algunos pocos componentes pasivo, sin embargo si se desean niveles de amplificación mayores se recomienda el uso de circuitos integrados destinados a esta función. Figura 9-4 Circuito de amplificación para el manejo de una Bocina hasta 500mW (pighixxx.com/). 97 Guía Teórico Práctica Aprende ARDUINO 10. Uso de Matriz de LED con ARDUINO Como sabemos una forma de desplegar información: numero o/y letras, hacia un usuario externo es el uso de DISPLAY y/o LED, pero existe otro componente derivado del uso de LEDs que permite un mayor despliegue visual de mensajes alfanuméricos, los módulos matriciales de LEDs. Matriz de LEDs Este componente consiste en un arreglo matricial de varios LEDs interconectados que pueden ser encendidos y apagados individualmente desde la tarjeta Arduino, se pueden pensar en ella como una pantalla de pocos pixeles en los cuales pueden presentar gráficos y textos, tanto estáticos como en movimiento. Existen diversos modelos de matrices de LEDs, dependiendo del número de pixeles o LEDs que posea, el más común es de 8x8 (64 LEDs), pero también existen en 5x7 o 16x16, se pueden encontrar módulos de varias matrices formando una pantalla completa de mayor cantidad de LEDS, ver: http://www.sureelectronics.net/category.php?id=60, en la figura 10-1 se pueden apreciar algunos modelos matrices de diversos tamaños físicos y en número de LEDS - resolución. Como se mencionó, una matriz de LEDs es la interconexión matricial de muchos LED individuales, si la matriz es de tipo 8x8 significa que internamente posee 64 LEDs, la conexión interna de este tipo de matrices es la mostrada en la figura 10-2, sin embargo, debemos siempre mirar la hoja de características de la matriz que estemos usando, porque puede ser que difieran las conexiones internas de una marca a otra, o incluso en la misma marca, es decir, que en esta matriz, por ejemplo, la fila uno se corresponde con el pin 9, pero puede darse el caso que en otro modelo sea diferente, o que incluso las filas sean ánodos. Para desplegar caracteres alfanuméricos en una matriz, el controlador debe encargarse de encender y apagar los LEDs individuales necesarios para formar la letra o carácter a mostrar, esto se logra implementando una técnica llamada multiplexacion6, que permite el manejo de varios LEDs a partir de pocos pines de Arduino. Sin embargo, como es común en el lenguaje de programación de Arduino ya se dispone de algunas librerías que facilitan mucho la tarea de manejar una o más matrices desde Arduino, estas librerías dependerán del tipo de conexión en hardware implementada entre la matriz y Arduino. Generalmente se usan dos tipos de conexión entre Arduino y las matrices de LEDs, una es de forma directa y otra a través de un circuito integrado interface con número MAX7219, en la conexión directa el Arduino necesita utilizar al menos 16 pines digitales para una sola matriz 8x8, lo que nos pone a pensar que se nos acabaran los pines disponibles si deseamos controlar más de una matriz 8x8, en la figura 10-3 se puede apreciar esta conexión. 6 multiplexación es la combinación de dos o más canales de información en un solo medio de transmisión. 98 Guía Teórico Práctica Aprende ARDUINO Figura 10-1. Diversos modelos de matrices individuales y en módulos estilo break-out. Figura 10-2 Dimensiones y conexionado interno de una matriz 8x8 99 Guía Teórico Práctica Aprende ARDUINO Figura 10-3 Conexión directa entre Arduino y una matriz de LEDs 8x8 El otro tipo de conexión usada para manejar una matriz de LEDs es través de un circuito integrado MAX7219, este es un circuito integrado diseñado especialmente para funcionar como interface entre un Microcontrolador y una matriz de LEDs de 8x8, al utilizar esta conexión solamente se necesitan 3 pines de Arduino, ver la figura 10-4, también es posible al usar este circuito la conexión de vario MAX7219 en conexión cascada y así poder manejar hasta cuatro matrices de LEDs desde un mismo Arduino. En esta documento nos centraremos en el manejo de una matriz 8x8 usando un circuito interface MAX7219 ya que es la forma más sencilla tanto en software como en hardware, y con la popularidad de los módulos break-out, ya se dispone de pequeñas placas que incluyen una matriz 8x8 junto con un MAX7219, ver figura 10-1 imagen inferior izquierda. El manejo de una matriz desde el punto de vista del Sketch es sencillo al hacer uso de una librería especial para tal efecto “LedControl.h”, la cual puede ser descargada de: https://docs.google.com/file/d/0B7SISgResP2ReUozMHVKZGpjTk0/edit?usp=sharing, a continuación se describirán algunas funciones que incluye la librería mencionada. Funciones de Configuración LedControl ledMatrix = LedControl(DIN, CLK, CS o LOAD, CNT_DISP) : Con esta función se crea un objeto llamado ledMatrix para ser manipulado posteriormente, además recibe como parámetros los números de pines a conectar hacia el MAX7219, además de la cantidad de circuitos MAXs a conectar en cascada. Un ejemplo seria el siguiente la declaración siguiente LedControl ledMatrix = LedControl(2, 3, 4, 1) , que indicaría que se conecta el pin2 de Arduino al DIN del MAX7219, el pin 3 al CLK, el 4 al LOAD y que se conectará un único MAX7219 al Arduino. Esta función debe llamarse antes del setup(). 100 Guía Teórico Práctica Aprende ARDUINO Figura 10-4 Conexión entre un MAX7219 y una matriz de LEDs 8x8 – Circuito interno del Módulo Matriz 8x8 Figura 10-5 Conexión en Cascada de más de un MAX7219 101 Guía Teórico Práctica Aprende ARDUINO ledMatrix.shutdown(0, false): inicializa el objeto llamado ledMatrix y le indica que trabajara en modo shutdown, es decir listo para recibir instrucciones, esta función debe llamarse en la función setup(). ledMatrix.setIntensity(0, 5): configura la intensidad o brillo de los LEDs de la matriz, que puede ser entre 1 y 15, el parámetro 5 le indica intensidad media baja, el parámetro cero es obligatorio cuando una sola matriz es manejada, esta función se declara dentro del setup(). Funciones de Manipulación ledMatrix.clearDisplay(0): esta función limpia o borra cualquier dato dentro de la matriz, puede ser llamada desde cualquier parte del Sketch cuando deseemos borrar la pantalla de LEDs, como parámetro recibie el numero u orden de pantalla a borrar. ledMatrix.setRow(0, FILA, Bxxxxxxxx): enciende los LEDs de una fila de la matriz según el parámetro recibido como numero binario, los ceros indican LED apagado y los unos LED encendido, el primer parámetro 0 indica el orden de la matriz en cascada y el segundo parámetro indica el número de la fila a encender, 0 a 7. ledMatrix.setColumn(0, COL, Bxxxxxxxx): similar a la función anterior pero maneja las columnas, Enciende los LEDs de una columna de la matriz según el parámetro recibido como numero binario, los ceros indican LED apagado y los unos LED encendido, el primer parámetro 0 indica el orden de la matriz en cascada y el segundo parámetro indica el número de la columna a encender., 0 a 7. ledMatrix.setLed(0, FILA, COl, true o false): enciende un LED individual de la matriz, indicado por los parámetros de la función, FILA es la fila donde se encuentra el LED a encender, COL es el número de la columna del LED, true si se desea encender el LED o false si se apagara, el 0 indica el orden de matriz en cascada. ledMatrix.printChar(0, 0, 'A'): imprime un carácter en la matriz de LEDs, recibe como parámetros las FILA y COLUMNA donde iniciara la impresión además del carácter alfanumérico a desplegar. ledMatrix.printStringScroll(0, 0, texto, 50, '<'): imprime un mensaje de caracteres alfanuméricos en la matriz y los hace correr tipo marquesina, recibe 5 parámetros, los 2 primeros son la FILA y columna donde comenzara a desplegarse el mensaje, el tercero es el nombre de un arreglo definido previamente donde esta guardado el texto a desplegar, el cuarto parámetro es el número de milisegundos de pausa entre posiciones del mensaje, es decir la velocidad del corrimiento, y el quinto parámetro es un símbolo que indica el sentido de la animación del mensaje. A continuación se presenta un ejemplo donde se hace uso de la librería menciona y de las funciones descritas anteriormente, se manejara una sola matriz conectada al Arduino, las conexiones son sencillas ya que solo se necesitan 3 + 2 pines desde Arduino hacia el MAX7219. EJEMPLO.MATRIZ01. Se maneja una matriz de LEDs 8x8 por medio de un circuito integrado MAX7219 para el despliegue de diversos contenidos haciendo uso de las funciones de la librería LedControl.h, la conexión a implementar es la mostrara en la figura 10-4 , verifique la disposición de pines del modelo de su matriz especifico y de preferencia se recomienda el uso de modulo como el de la figura 10-6 102 Guía Teórico Práctica Aprende ARDUINO /* Demostracion uso de LedControl con Max7219 y Matrix8x8 Use de la libreria LedControl.h y sus funciones descargar e instalar la nueva version de la libreria de : https://docs.google.com/file/d/0B7SISgResP2ReUozMHVKZGpjTk0/edit?usp=sharing ver en acción: http://youtu.be/GVGLdn2YZEM Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CreativeComons */ #include "LedControl.h" //Incluir la libreria //conectar el arduino y el max7219, siguiendo: const byte DIN = 4; //pin DIN del MAX7219 a pin 4 del Arduino const byte CS = 3; //pin LOAD (CS)del MAX7219 a pin 3 del Arduino const byte CLK = 2; //pin CLK del MAX7219 a pin 2 del Arduino const byte QTD_DISP = 1; //inicializar el objeto ledMatrix LedControl ledMatrix = LedControl(DIN, CLK, CS, QTD_DISP); //variable arreglo de caracteres //con texto a desplegar char texto[] = "Hola Mundo"; //algunas variables para uso general byte i=0, col=0, row=0; void setup() { //encender el MAX7219 ledMatrix.shutdown(0, false); //modo 'shutdown' ledMatrix.setIntensity(0, 10); //intensisdad de la matriz (0~15) ledMatrix.clearDisplay(0); //limpiar la matrix } void loop() { //controlado filas ledMatrix.clearDisplay(0); for (i=0; i<8; i++) { ledMatrix.setRow(0, i, B11111111); delay(100); ledMatrix.setRow(0, i, B00000000); } //controlado columnas ledMatrix.clearDisplay(0); for (i=0; i<8; i++) { ledMatrix.setColumn(0, i, B11111111); delay(100); ledMatrix.setColumn(0, i, B00000000); } //controlando LEDs individuales ledMatrix.clearDisplay(0); for (col=0; col<8; col++) { for(row=0; row<8; row++) { ledMatrix.setLed(0, row, col, true); delay(20); } } for(row=0; row<8; row++) 103 Guía Teórico Práctica Aprende ARDUINO { for (col=0; col<8; col++) { ledMatrix.setLed(0, row, col, false); delay(20); } } /////Mostrar caracteres fijos ledMatrix.clearDisplay(0); ledMatrix.printChar(0, 0, 'A'); delay(500); ledMatrix.printChar(0, 0, 'R'); delay(500); ledMatrix.printChar(0, 0, 'D'); delay(500); ledMatrix.printChar(0, 0, 'U'); delay(500); ledMatrix.printChar(0, 0, 'I'); delay(500); ledMatrix.printChar(0, 0, 'N'); delay(500); ledMatrix.printChar(0, 0, 'O'); delay(500); /////Desplegar texto tipo marquesina ledMatrix.clearDisplay(0); //clear display '0' ledMatrix.printStringScroll(0, 0, texto, 50, '<'); delay(500); ledMatrix.printStringScroll(0, 0, texto, 50, '>'); delay(500); } //Fin del sketch Figura 10-6 Modulo MAX7219 + Matriz de leds 8x8 104 Guía Teórico Práctica Aprende ARDUINO En el ejemplo anterior se mostró el uso de las funciones del librería LedControl.h, pero una modificación a este, sería la captura dinámica de los mensajes a desplegar, en el ejemplo a continuación se implementa esta idea. EJEMPLO.MATRIZ02. En este ejemplo se desplegara un mensaje dinámico en nuestra matriz de LEDs, se captura desde el Monitor Serial la cadena de caracteres para luego ser desplegada tipo marquesina en la matriz conectada a Arduino a través de un MAX7219. /* EJEMPLO.MATRIZ02 Mensajes dinamicos desde el Monitor Serial. Demostracion uso de LedControl con Max7219 y Matrix8x8 Use de la libreria LedCOntrol.h y sus funciones descargar e instalar la nueva version de la libreria de : https://docs.google.com/file/d/0B7SISgResP2ReUozMHVKZGpjTk0/edit?usp=sharing Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CreativeComons */ #include "LedControl.h" //Incluir la libreria //conectar el arduino y el max7219, siguiendo: const byte DIN = 4; //pin DIN del MAX7219 a pin 4 del Arduino const byte CS = 3; //pin LOAD (CS)del MAX7219 a pin 3 del Arduino const byte CLK = 2; //pin CLK del MAX7219 a pin 2 del Arduino const byte QTD_DISP = 8; // indica que se pueden conectar hasta 8 max7219 en cascada //inicializar el objeto ledMatrix LedControl ledMatrix = LedControl(DIN, CLK, CS, QTD_DISP); //variable arreglo de caracteres //con texto a desplegar char mensaje[30]; char charLeido; //algunas variables para uso general byte i=0, col=0, row=0; int indice = 0; void setup() { Serial.begin(9600); //encender el MAX7219 ledMatrix.shutdown(0, false); //modo 'shutdown' ledMatrix.setIntensity(0, 10); //intensisdad de la matriz (0~15) ledMatrix.clearDisplay(0); //limpiar la matrix //pedir el mensaje desde el Monitor Serial Serial.print("Ingrese el mensaje .."); } void loop() { //verificar puerto serial por //algun dato disponible if (Serial.available() > 0) { // leer el dato: charLeido = Serial.read(); //asignarlo al arrlego que forma el mensaje: mensaje[indice] = charLeido; indice++; 105 Guía Teórico Práctica Aprende ARDUINO delay(250); if (Serial.available() == 0) //si ya se ingreso el mensaje { //desplegar mensaje Serial.println("..desplegando mensaje!"); delay(1000); ////Desplegar texto tipo marquesina ledMatrix.clearDisplay(0); ledMatrix.printStringScroll(0, 0, mensaje, 75, '<'); //borrar el arreglo, listo para otro msj. for (int x=0; x<=indice; x++) { mensaje[x] = 0; } indice = 0; Serial.println(""); Serial.print("Ingrese mensaje .."); } } } //Fin del sketch Conexión en Cascada de Matriz de LED Una ventaja del uso del MAX7219 es que permite la conexión de más de una matriz en serie o cascada, para así poder ampliar el área de despliegue para los mensajes, la conexión entre los circuitos integrados MAX7219 que controlaran cada una de las matrices en casaca de realiza de una forma sencilla por medio de 4 pines, ver figura 10-6. Para demostrar el manejo en conexión cascada se hará uso de otra librería para Arduino, llamada MaxMatrix.h y que puede ser descargada de https://arudino-maxmatrixlibrary.googlecode.com/files/MaxMatrix.zip y debe ser instalada como otra librería nueva en Arduino IDE. EJEMPLO MAX03: Se demostrara el uso de la librería MaxMatrix.h por medio de un ejemplo que despliega en 4 matrices en cascada un mensaje alfanumérico que ha sido enviado a Arduino vía el Monitor Serial del Arduino IDE. Cabe mencionar que este ejemplo está dentro de la carpeta descargable del enlace anterior. /* Sketch que manipula una Pantalla de 32x16 leds usando modulos de 8x8 con MAX7219 gobernados por un Arudino UNO, el programa muestra un mensaje personalizado enviado desde el Monitor Serial del IDE Arduino. Creado por: oscark...@gmail.com Feb 27, 2013 Modificado por: otoniel.flores@gmail.com May 2013 Creative Commons Descarga la liberia de: https://arudino-maxmatrix-library.googlecode.com/files/MaxMatrix.zip la coneccion a utilizar se muestra en la figura 10-5, con una matriz mas. 1er modulo Matrix --- Arduino DIN --- 5 CS --- 3 106 Guía Teórico Práctica Aprende ARDUINO CLK --- 4 Los otros modulos se conectan en serie uno tras otro, teniendo en cuenta que: el DOUT de una matriz se conecta con el DIN de la siguiente. */ //Incluir las librerias #include <MaxMatrix.h> //descargar #include <avr/pgmspace.h> //inluida en arduinoIDE //Delaracion de constantes para formar las letras y numeros //en una pantalla de 8x8 PROGMEM prog_uchar CH[] = { 3, 8, B0000000, B0000000, B0000000, B0000000, B0000000, // space 1, 8, B1011111, B0000000, B0000000, B0000000, B0000000, // ! 3, 8, B0000011, B0000000, B0000011, B0000000, B0000000, // " 5, 8, B0010100, B0111110, B0010100, B0111110, B0010100, // # 4, 8, B0100100, B1101010, B0101011, B0010010, B0000000, // $ 5, 8, B1100011, B0010011, B0001000, B1100100, B1100011, // % 5, 8, B0110110, B1001001, B1010110, B0100000, B1010000, // & 1, 8, B0000011, B0000000, B0000000, B0000000, B0000000, // ' 3, 8, B0011100, B0100010, B1000001, B0000000, B0000000, // ( 3, 8, B1000001, B0100010, B0011100, B0000000, B0000000, // ) 5, 8, B0101000, B0011000, B0001110, B0011000, B0101000, // * 5, 8, B0001000, B0001000, B0111110, B0001000, B0001000, // + 2, 8, B10110000, B1110000, B0000000, B0000000, B0000000, // , 4, 8, B0001000, B0001000, B0001000, B0001000, B0000000, // 2, 8, B1100000, B1100000, B0000000, B0000000, B0000000, // . 4, 8, B1100000, B0011000, B0000110, B0000001, B0000000, // / 4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // 0 3, 8, B1000010, B1111111, B1000000, B0000000, B0000000, // 1 4, 8, B1100010, B1010001, B1001001, B1000110, B0000000, // 2 4, 8, B0100010, B1000001, B1001001, B0110110, B0000000, // 3 4, 8, B0011000, B0010100, B0010010, B1111111, B0000000, // 4 4, 8, B0100111, B1000101, B1000101, B0111001, B0000000, // 5 4, 8, B0111110, B1001001, B1001001, B0110000, B0000000, // 6 4, 8, B1100001, B0010001, B0001001, B0000111, B0000000, // 7 4, 8, B0110110, B1001001, B1001001, B0110110, B0000000, // 8 4, 8, B0000110, B1001001, B1001001, B0111110, B0000000, // 9 2, 8, B01010000, B0000000, B0000000, B0000000, B0000000, // : 2, 8, B10000000, B01010000, B0000000, B0000000, B0000000, // ; 3, 8, B0010000, B0101000, B1000100, B0000000, B0000000, // < 3, 8, B0010100, B0010100, B0010100, B0000000, B0000000, // = 3, 8, B1000100, B0101000, B0010000, B0000000, B0000000, // > 4, 8, B0000010, B1011001, B0001001, B0000110, B0000000, // ? 5, 8, B0111110, B1001001, B1010101, B1011101, B0001110, // @ 4, 8, B1111110, B0010001, B0010001, B1111110, B0000000, // A 4, 8, B1111111, B1001001, B1001001, B0110110, B0000000, // B 4, 8, B0111110, B1000001, B1000001, B0100010, B0000000, // C 4, 8, B1111111, B1000001, B1000001, B0111110, B0000000, // D 4, 8, B1111111, B1001001, B1001001, B1000001, B0000000, // E 4, 8, B1111111, B0001001, B0001001, B0000001, B0000000, // F 4, 8, B0111110, B1000001, B1001001, B1111010, B0000000, // G 4, 8, B1111111, B0001000, B0001000, B1111111, B0000000, // H 3, 8, B1000001, B1111111, B1000001, B0000000, B0000000, // I 4, 8, B0110000, B1000000, B1000001, B0111111, B0000000, // J 4, 8, B1111111, B0001000, B0010100, B1100011, B0000000, // K 4, 8, B1111111, B1000000, B1000000, B1000000, B0000000, // L 5, 8, B1111111, B0000010, B0001100, B0000010, B1111111, // M 5, 8, B1111111, B0000100, B0001000, B0010000, B1111111, // N 4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // O 4, 8, B1111111, B0001001, B0001001, B0000110, B0000000, // P 4, 8, B0111110, B1000001, B1000001, B10111110, B0000000, // Q 4, 8, B1111111, B0001001, B0001001, B1110110, B0000000, // R 4, 8, B1000110, B1001001, B1001001, B0110010, B0000000, // S 107 Guía Teórico Práctica Aprende ARDUINO 5, 4, 5, 5, 5, 5, 4, 2, 4, 2, 3, 4, 2, 4, 4, 4, 4, 4, 3, 4, 4, 3, 4, 4, 3, 5, 4, 4, 4, 4, 4, 4, 3, 4, 5, 5, 5, 4, 3, 3, 1, 3, 4, }; 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, B0000001, B0000001, B1111111, B0000001, B0000001, // T B0111111, B1000000, B1000000, B0111111, B0000000, // U B0001111, B0110000, B1000000, B0110000, B0001111, // V B0111111, B1000000, B0111000, B1000000, B0111111, // W B1100011, B0010100, B0001000, B0010100, B1100011, // X B0000111, B0001000, B1110000, B0001000, B0000111, // Y B1100001, B1010001, B1001001, B1000111, B0000000, // Z B1111111, B1000001, B0000000, B0000000, B0000000, // [ B0000001, B0000110, B0011000, B1100000, B0000000, // backslash B1000001, B1111111, B0000000, B0000000, B0000000, // ] B0000010, B0000001, B0000010, B0000000, B0000000, // hat B1000000, B1000000, B1000000, B1000000, B0000000, // _ B0000001, B0000010, B0000000, B0000000, B0000000, // ` B0100000, B1010100, B1010100, B1111000, B0000000, // a B1111111, B1000100, B1000100, B0111000, B0000000, // b B0111000, B1000100, B1000100, B0101000, B0000000, // c B0111000, B1000100, B1000100, B1111111, B0000000, // d B0111000, B1010100, B1010100, B0011000, B0000000, // e B0000100, B1111110, B0000101, B0000000, B0000000, // f B10011000, B10100100, B10100100, B01111000, B0000000, // g B1111111, B0000100, B0000100, B1111000, B0000000, // h B1000100, B1111101, B1000000, B0000000, B0000000, // i B1000000, B10000000, B10000100, B1111101, B0000000, // j B1111111, B0010000, B0101000, B1000100, B0000000, // k B1000001, B1111111, B1000000, B0000000, B0000000, // l B1111100, B0000100, B1111100, B0000100, B1111000, // m B1111100, B0000100, B0000100, B1111000, B0000000, // n B0111000, B1000100, B1000100, B0111000, B0000000, // o B11111100, B0100100, B0100100, B0011000, B0000000, // p B0011000, B0100100, B0100100, B11111100, B0000000, // q B1111100, B0001000, B0000100, B0000100, B0000000, // r B1001000, B1010100, B1010100, B0100100, B0000000, // s B0000100, B0111111, B1000100, B0000000, B0000000, // t B0111100, B1000000, B1000000, B1111100, B0000000, // u B0011100, B0100000, B1000000, B0100000, B0011100, // v B0111100, B1000000, B0111100, B1000000, B0111100, // w B1000100, B0101000, B0010000, B0101000, B1000100, // x B10011100, B10100000, B10100000, B1111100, B0000000, // y B1100100, B1010100, B1001100, B0000000, B0000000, // z B0001000, B0110110, B1000001, B0000000, B0000000, // { B1111111, B0000000, B0000000, B0000000, B0000000, // | B1000001, B0110110, B0001000, B0000000, B0000000, // } B0001000, B0000100, B0001000, B0000100, B0000000, // ~ //constantes que contienen los numeros de pines //del Arduino a conectar con el primer modulo 8x8 int data = 5; int load = 3; int clock = 4; int maxInUse = 4; //se usaran 4 modulos max7219 en cascada //Se le pasan los pines y se crea el objeto m MaxMatrix m(data, load, clock, maxInUse); byte buffer[10]; void setup() { m.init(); //inicializa el objeto m m.setIntensity(8); //se setea la intensidad de los leds Serial.begin(9600); //inicializar la comunicacion via USB } 108 Guía Teórico Práctica Aprende ARDUINO //Programa Principal void loop() { //mientras exista un caracter proveniente del USB while (Serial.available() > 0) { //leerlo y asignarlo a c byte c = Serial.read(); //reeviar el equivalente decimal, solo como verificacion Serial.println(c, DEC); //inprimirlo en la matrix printCharWithShift(c, 100); } delay(100); //Scroll hacia la izquierda m.shiftLeft(false, true); } //A continuacion se declaran las funciones //que hacen el efecto SCROLL. void printCharWithShift(char c, int shift_speed) { if (c < 32) return; c -= 32; memcpy_P(buffer, CH + 7*c, 7); m.writeSprite(32, 0, buffer); m.setColumn(32 + buffer[0], 0); for (int i=0; i<buffer[0]+1; i++) { delay(shift_speed); m.shiftLeft(false, false); } } void printStringWithShift(char* s, int shift_speed) { while (*s != 0) { printCharWithShift(*s, shift_speed); s++; } } //Fin del sketch A partir de aquí el lector puede realizar cualquier modificación a su gusto y adaptar este al despliegue de mensajes de cualquier tipo provenientes fuentes como sensores. 109 Guía Teórico Práctica Aprende ARDUINO 11. Uso de display LCD con ARDUINO Una pantalla de cristal líquido o LCD (acrónimo del inglés liquid crystal display) es una pantalla delgada y plana formada por un número de píxeles en color o monocromos colocados delante de una fuente de luz o reflectora. A menudo se utiliza en dispositivos electrónicos de pilas, ya que utiliza cantidades muy pequeñas de energía eléctrica. Estas pueden desplegar caracteres alfanuméricos: números y letras. Antes de aparecer los módulos LCD, se utilizaban los DISPLAY de siete segmentos para poder mostrar la información, estos tienen una gran limitación de poder mostrar los caracteres alfa numéricos y símbolos especiales, también consumen demasiada corriente y ocupan demasiado espacio físico. Posteriormente aparecieron otros tipos de DISPLAY más complejos que podían mostrar algunos caracteres y símbolos; pero tenían de igual manera mucho consumo de corriente y espacio físico ocupaban también bastante espacio físico. Finalmente aparecieron los módulos LCD o pantallas de cristal líquido la cual tiene la capacidad de mostrar cualquier carácter alfanumérico. Estos dispositivos ya vienen con su pantalla y toda la lógica de control pre programada en la fábrica y lo mejor de todo es que el consumo de corriente es mínimo y no hace falta realizar tablas especiales como se hacía anteriormente con los DISPLAY de siete segmentos. Las aplicaciones de los módulos LCD son infinitas ya que pueden ser aplicados en la informática, comunicaciones, telefonía, instrumentación, robótica, automóviles, equipos industriales, etc. Los módulos LCD se diferencia entre por el número de caracteres que pueden desplegar, se especifican por medio el número de caracteres y líneas, es así como hay LCD 8x2, 16x1, 16x2, 20x2, 20x4, 40x2, y 40x4. Los módulos LCD más comunes son los 16x2, se pueden visualizar 2 líneas de 16 caracteres cada una, es decir, 2x16=32 caracteres. Tiene un consumo de energía de menos de 5mA y son ideales para dispositivos que requieran una visualización pequeña o media y alimentados por baterías. En hardware casi todos los LCD, independiente del fabricante, poseen los mismos terminales o pines de conexión, y están distribuidos según como se aprecia en la figura 11-2, de aquí se puede apreciar la función de cada pin del LCD. Cabe destacar que en esta sección se refiere a LCD que pueden mostrar caracteres alfanuméricos, existen LCD que pueden desplegar gráficos: GLCD, que se estudiaran en secciones posteriores. 110 Guía Teórico Práctica Aprende ARDUINO Figura 11-1. Modelos de LCD de 16 caracteres y 2 filas, 16x02 Figura 11-2. Terminales de una matriz LCD. 111 Guía Teórico Práctica Aprende ARDUINO Manejo con Arduino Manejar el despliegue de mensajes en una pantalla LCD por medio de Arduino es muy sencillo, la conexión circuito solo necesita 6 pines, en la figura 11-3 se puede apreciar una conexión típica entre un LCD conectado a Arduino, es de notar el uso de 6 pines digitales de la tarjeta. Figura 11-3. Dos tipos de conexión entre un LCD y la Tarjeta Arduino (orelly.com). Algo muy interesante es la disponibilidad de pantallas LCD en forma de Escudo o Shield Arduino listo para interactuar con la tarjeta Arduino: LCD KEYPAD SHIELD, ver figura 11-4, este escudo incorpora una pantalla LCD monocromática de 16 caracteres y 2 filas, además integra un pequeño potenciómetro para el control del contraste, y también un mini teclado formado por 5 pulsadores (se estudiara luego); este escudo se inserta en las borneras superiores de Arduino y automáticamente queda conectado a ciertos pines digitales de la tarjeta, se puede observar esta conexión en la figura 11-5, esta conexión será útil de recordad al momento de diseñar el Sketch de control. 112 Guía Teórico Práctica Aprende ARDUINO ¿Qué es un Escudo o Shield Arduino? Un shield es una placa de circuito impreso con sus components que se pueden conectar en la parte superior de la placa Arduino para ampliar sus capacidades y conectividad con otros dispositivos de entrada o salida, pudiendo ser apilada una encima de la otra. Las shields suelen ser diseños bastante simples y en general de código abierto, el diseño suelen ser publicados libremente. Existe una lista de shields con los detalles de sus conexiones y la especificación básicas aquí (http://shieldlist.org/), en la página oficial se encuentra publicada otra lista un poco menos completa (http://www.arduino.cc/en/Principal/ArduinoShields) Figura 11-4. Escudo LCD KEYPAD para Arduino. 113 Guía Teórico Práctica Aprende ARDUINO Figura 11-4. Terminales dispibles en el LCD KEYPAD para Arduino. Figura 11-4. Distribución de la conexión entre un Escudo LCD y pines digitales de Arduino . 114 Guía Teórico Práctica Aprende ARDUINO El diseño de un Sketch para manipular el despliegue de mensajes en una LCD conectada a Arduino es muy sencillo y más con la ayuda de una librería estándar: LiquidCrystal.h que incorpora algunas funciones muy útiles para manipular la LCD, a continuación se describirán algunas de estas funciones para luego poder hacer algunos ejemplos de demostraciones de uso de LCD. Funciones de Configuración LiquidCrystal lcd (rs, enable, d4, d5, d6, d7): esta función se debe incluir al inicio del Sketch antes de la función setup(), permite la creación de un objeto llamado lcd (este nombre puede ser cualquiera), para que pueda ser manipulado más adelante dentro del Sketch. Como paramentos recibe los números de pines Arduino donde se conecta la LCD a manejar, los nombres rs, enable, d4, d5, d6 y d7 hacen referencia a los pines de la pantalla. Por ejemplo si se usa el LCD KEYPAD SHIELD la instrucción seria: LiquidCrystal lcd(8, 9, 4, 5, 6, 7); lcd.begin (Ncaracteres, Nfilas): esta función inicializa el objeto llamado lcd con las dimensiones de la pantalla LCD conectada a Arduino, recibe dos parámetros: el número de caracteres y filas de la pantalla, así: lcd.begin(16,2); indica que se usara una LCD de 16 caracteres por 2 filas. Esta función se declara dentro del setup() del Sketch. Funciones de Manipulación lcd.clear():Borra la pantalla LCD conectada la tarjeta Arduino y posiciona el cursor en la esquina superiorizquierda. lcd.setCursor(col, row): Establece la posición del cursor; Esto es, la posición donde aparecerán los siguientes caracteres escritos en el LCD, recibe como parámetros las coordenadas de la posición donde se desea ubicar el cursor, por ejemplo lcd.setCursor(0,1); ubica el cursor en la esquina inferior izquierda, fila de abajo en la posición izquierda. lcd.print(var o “texto”): esta función imprime en la pantalla LCD en la posición actual del cursor ya sea un texto o el contenido de una variable, la información a desplegar se pasa como parámetro de la función, por ejemplo la instrucción lcd.print("hola mundo"); imprime el mensaje “hola mundo” en la LCD. lcd.autoscroll(): Activa el desplazamiento automático del texto en la pantalla LCD. Esto hace que cada salida de caracteres en la pantalla, "empuja" los caracteres anteriores en una posición. Si la dirección del texto actual es de izquierda a derecha (por defecto), el texto se desplaza hacia la izquierda, si la dirección actual es de derecha a izquierda, el texto se desplaza hacia la derecha. Esto tiene como efecto que la entrada de cada nuevo carácter se produce en la misma posición en la pantalla LCD. NO recibe ningún parámetro. lcd.createChar(num, data): Crea un carácter personalizado para su uso en la pantalla LCD. Hasta ocho caracteres de 5x8 píxeles son permitidos (numerados del 0 al 7). La apariencia de cada carácter personalizado se especifica mediante una serie de ocho bytes, uno para cada fila. Los cinco bits menos significativos de cada byte determinan los píxeles en esa fila. Los parámetros num es el número de orden que le asignamos al carácter creado y data es la referencia a el arreglo donde están los datos del carácter especial. Para mostrar un carácter personalizado en la pantalla, usar write() especificando su número de orden. 115 Guía Teórico Práctica Aprende ARDUINO Para más sobre las funciones de la librería estándar para pantallas monocromáticas LCD se recomienda visitar el siguiente enlace. http://arduino.cc/es/Reference/LiquidCrystal. EJEMPLO. LCD01: se demostrara el uso de las funciones de la librería LiquidCrystal.h para manipular el despliegue en una pantalla monocromática LCD de 16x02 conectada a Arduino, se asume el uso de un LCD KEYPAD SHIELD sobre el Arduino. /* EjemploLCD01. Demostrar el uso de l un LCD 16x2 conectada a Arduino, atraves de la libreria estandar LiquidCrystal.h Se asume la * LCD RS pin * LCD Enable * LCD D4 pin * LCD D5 pin * LCD D6 pin * LCD D7 pin conexion siguinte: con pin digital 8 pin con pin digital 9 con pin digital 4 con pin digital 5 con pin digital 6 con pin digital 7 Creado por Tom Igoe 8 Feb 2010 Modificado por otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CC */ // incluir la libreria estandar: #include “LiquidCrystal.h” // inicializar las conexiones del LCD LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //definir un arrgleo de datos para caracter especial byte alegre[8] = { B00000, B10001, B00000, B00000, B10001, B01110, B00000, }; void setup() { // configurar el tamaño del LCD: lcd.begin(16, 2); //crear un caracter especial lcd.createChar(4, alegre); //posicionar e cursor en la //esquina superior izquierda. lcd.setCursor(0, 0); // imprimir un mensaje. lcd.print("Hola Mundo!"); delay(2000); lcd.clear(); } void loop() { // ubicar el cursor en la esquina inferior izquierda lcd.setCursor(0, 1); // imprimir otro mensaje lcd.print("Arduino + LCD"); 116 Guía Teórico Práctica Aprende ARDUINO delay(2000); lcd.clear(); //imprimir el contenido de una variable int variable = 1234; lcd.setCursor(0, 0); lcd.print("la variable es:"); lcd.setCursor(4, 1); lcd.print(variable); delay(2000); lcd.clear(); //imprimir un caracter especial lcd.setCursor(7, 0); lcd.write(4); delay(2000); lcd.clear(); } //Fin del sketch Lectura de botones del LCD Shield. Anteriormente se estudió el uso de la pantallas de cristal líquido o LCD, y especialmente el LCD KEYPAD SHIELD, el cual es un escudo para Arduino que contiene un LCD 16x02 y además 5 botones o pulsadores, lo interesante es que estos botones no están conectados a pines de entrada digital de la tarjeta Arduino, sino que están conectados a un solo pin de entrada análoga, usando una conexión en divisor de voltaje, ver Figura 11-5 Figura 11-5. Escudo LCD KEYPAD para Arduino y como estan conectados los 5 botones. 117 Guía Teórico Práctica Aprende ARDUINO Según la conexión de los 5 botones del Escudo, se puede notar que al presionar alguno cambiara el voltaje al aplicado al pin A0 del Arduino, por lo tanto según sea el voltaje leído del ADC0 así será el botón que se ha presionado. El sketch entonces simplemente debe leer el pin A0 y verificar el valor de la conversión análoga para determinar que botón se presión, a continuación se muestra un ejemplo donde se usa una función para encontrar el botón presionado para luego ser mostrado en el propio LCD del escudo. EJEMPLO.LCD02: El siguiente ejemplo captura la tecla presionada en el escudo LCD KEYPAD y la muestra en la pantalla LCD, note que se usa la librería estándar y se crea una función especial para decodificar la tecla. /* EJEMPLO.LCD02 Demostracion de lectura de los botones del Escudo LCD KEYPAD Modificado por otoniel.flores@utec.edu.sv This example code is in the public domain. */ //incluir la libreria estandar #include <LiquidCrystal.h> // crear un objeto LiquidCrystal de acuerdo con las conexiones del escudo LCD KEYPAD RS,EN,D4,D5,D6,D7 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); void setup() { //tipo de lcd lcd.begin(16, 2); //un mensaje en la lcd. lcd.setCursor(0, 0); lcd.print("Hola Mundo!"); lcd.setCursor(0, 1); lcd.print("Prueba de Pulsadores"); delay (2000); lcd.clear(); } void loop() { lcd.setCursor(0, 0); lcd.print("Press a boton..."); int numeroBoton = leerPulsadores(); //en la variable numeroBoton queda el numero del boton presionado, si no se presiona, la variable vale 0 lcd.setCursor(0, 1); //imprimir un mesaje segun el numero boton devuelto por la funcion //usando la estrucura de control SWITCH switch (numeroBoton) { case 0: lcd.print("Ningun boton !"); delay(200); break; case 1: lcd.print("boton DERECHA !"); delay(200); break; case 2: lcd.print("boton ARRIBA ! "); delay(200); break; case 3: lcd.print("boton ABAJO ! "); delay(200); break; case 4: lcd.print("boton IZQUIERDA!"); 118 Guía Teórico Práctica Aprende ARDUINO delay(200); break; case 5: lcd.print("boton SELECT !"); delay(200); break; default: lcd.print("Ningun boton !"); delay(10); } } //fin del loop //funcion leer los botones del escudo int leerPulsadores() { int lectura_A0 = analogRead(0); //leer el pin A0 // los botones devolveran los valores digitales: 0, 144, 329, 504, 741 // aprimados if (lectura_A0 > 1000) return 0; // retornar 0 si no se prediono ningun boton if (lectura_A0 < 50) return 1; // retornar 1 si se presiono el boton DERECHA if (lectura_A0 < 195) return 2; // retornar 2 si se presiono el boton ARRIBA if (lectura_A0 < 380) return 3; // retornar 3 si se presiono el boton ABAJO if (lectura_A0 < 555) return 4; // retornar 4 si se presiono el boton IZQUIERDA if (lectura_A0 < 790) return 5; // retornar 5 si se presiono el boton SELECCION return 0; // retornar 0 si no se prediono ningun boton } //FIN DEL SKETCH 119 Guía Teórico Práctica Aprende ARDUINO 12. Manejo de teclado matricial con ARDUINO Uno de los dispositivos de entradas más utilizados para que Arduino interactúe con un usuario externo, es el Teclado matricial, figura 12-1, este tipo de componentes de entrada están compuestos por una serie de pulsadores de contacto (teclas) conectados eléctricamente en forma matricial, ver figura 12-2, lo que permite que la conexión entre este y Arduino ocupe menos pines que teclas, optimizando así el uso de los pines de nuestra tarjeta Arduino. Figura 12-1. Teclado matricial de 12 teclas y sus pines de conexión. Existen diversos tamaños de este tipo de teclados, los más comunes son de 12 y 16 teclas, en este documento nos centraremos en el uso de teclados de 12 teclas, pero los ejemplos contenidos aquí son fácilmente adaptables a teclados de 16 teclas. Antes de iniciar a utilizar un teclado, se debe conocer la distribución de sus pines de conexión, normalmente en un teclado de 12 teclas tienen una conexión como la de la figura 12-2, de aquí se puede notar que cada tecla se conecta a una fila y columna especifica. NOTA: verifique la conexión interna de su modelo de teclado especifico. 120 Guía Teórico Práctica Aprende ARDUINO Figura 12-2. Conexión interna y pines externos de un teclado de 12 teclas típico, numerados del 1 al 7 de izquierda a derecha. Teclado Matricial y Arduino. El controlar el ingreso de datos desde un teclado matricial de 12 teclas es muy sencillo con Arduino, para comenzar la conexión circuital solo requiere 7 pines digitales de la tarjeta por medio de una conexión directa con el teclado, ver figura 12-3, desde el punto de vista del sketch se hace uso de una librería llamada Keypad.h, la cual ya se incluye en la distribución estándar del IDE Arduino. El ejemplo siguiente nos deja más claro el uso de esta librería y de las funciones específicas dentro de esta, además del cómo utilizarlas en la lectura de teclas de nuestro teclado matricial. 121 Guía Teórico Práctica Aprende ARDUINO Figura 12-3. Conexión entre Arduino y un teclado matricial de 12 teclas (arduinoexamples.wordpress.com/) Figura 12-3. Conexión entre Arduino y un teclado matricial de 12 teclas (arduinoexamples.wordpress.com/) 122 Guía Teórico Práctica Aprende ARDUINO EJEMPLO. TEC01: en este ejemplo conectaremos un teclado matricial de 12 teclas a Arduino, y al presionar una tecla se desplegara el número de esta por el monitor Serial del IDE. Se usa la conexión eléctrica de la figura 12-3. Recuerde abrir el Monitor Serial luego de descargarlo a su placa. /* * * * * * * */ Ejemplo Uso del teclado matricial de 12 teclas se muestra por el Monitor Serial el numero de tecla presionada. modificado por: otoniel.flores@mail.utec.edu.sv #include "Keypad.h" //se incluye la libreria Keypad, estandar en Arduino IDE const byte FILAS = 4; //definir una constante con el numero de filas del teclado const byte COLUM = 3; // definir una constante con el numero de columnas del teclado // si tuvieramos un teclado de 16 teclas , se usarian 4 columnas // a continuacion se crea un arreglo matricial según la distribucion de las etiquetas // de las teclas del teclado a usar. char teclas[FILAS][COLUM] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'} }; // arreglo con referencia a pines de Arduino conectadas a las filas del teclado byte filPins[FILAS] = {5, 4, 3, 2}; // arreglo referencia a pines de Arduino conectadas a las columnas del teclado byte colPins[COLUM] = {8, 7, 6}; // craecion de el objeto miTeclado, con el que // se llamaran las fucniones de la librería Keypad. Keypad miTeclado = Keypad( makeKeymap(teclas), filPins, colPins, FILAS, COLUM); void setup() { Serial.begin(9600); // se inicializa la coneccion serial a 9600 baudios Serial.println ("Presione una tecla ... "); // mensaje al usuario } void loop() { // leer el teclado y asinar la lectura a la variable “tecla” char tecla = miTeclado.getKey(); // si no se presiona tecla alguna, la variable queda vacia. // verificar si se presiono una tecla if (tecla) // si no se presiona tecla alguna, la variable queda vacia. { // desplegarla por el monitor serial Serial.print("Ud. a presionado la tecla : "); Serial.println(tecla); delay(250); } } // fin del sketch // fin del sketch 123 Guía Teórico Práctica Aprende ARDUINO Figura 12-4. Salida del Monitor Serial del Ejemplo 1 A partir del ejemplo anterior es muy fácil realizar acciones en dependencia de la tecla presionada en el teclado matricial, en el siguiente ejemplo veremos esto, que es la base del proyecto “Acceso controlado por clave”. EJEMPLO. TEC02: se usara la conexión siguiente: la figura 12-3 más dos LEDS en los pines digitales 12 (rojo) y 13 (verde) de Arduino, el ejemplo realiza una especie de cerradura por código, los LED indican el estado, si se ingresa bien la clave de 4 dígitos se activa el LED verde, si no el rojo. /* Ejemplo2 Teclado matrical 12 teclas * Clave por teclado / Clave de 4 digitos * Al ingresar la clave correcta se activa led vede PIN12 por 3seg * clave incorrecta se activa led rojo pin13 * clave de 4 digitos guardada en el Sketch * * por: Simon Monk * modificado por: * otoniel.flores@mail.utec.edu.sv */ #include "Keypad.h" // se crea un arreglo que contiene la clave secreta char* clave = "1234"; int pos = 0; // definiciones para el teclado const byte FILAS = 4; // cuatro filas const byte COLUM = 3; // tres columnas // si tuvieramos un teclado de 16 teclas , se usarian 4 columnas // A continuacion se define una matriz, con las etiquetas de cada tecla char teclas[FILAS][COLUM] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'} }; // pines de Arduino conectadas a las filas del teclado byte filPins[FILAS] = {5, 4, 3, 2}; // pines de Arduino conectadas a las columnas del teclado 124 Guía Teórico Práctica Aprende ARDUINO byte colPins[COLUM] = {8, 7, 6}; int ok; //craecion de el objeto Keypad Keypad keypad = Keypad( makeKeymap(teclas), filPins, colPins, FILAS, COLUM); // doonde estaran los LEDS int rojoPin = 12; int verdePin = 13; void setup() { pinMode(rojoPin, OUTPUT); pinMode(verdePin, OUTPUT); Serial.begin(9600); // definimos una funcion propia // para activar o desactivar LEDS // llamada activarClave, se declara al final del Sketch activarClave(false); Serial.println("****************"); Serial.println("Digite su clave"); } void loop() { // se lee el teclado // y se asigna a tecla a lectura char tecla = keypad.getKey(); // si se presiono alguna tecla? if (tecla) { // procesarla Serial.print("*"); // fue una tecla de la clave¿? if (tecla == clave[pos]) { ok++; // incrementar la varible Ok } pos++; } if (pos == 4 && ok == 4) // se introdujeron los 4 digito y la clave es correcta¿ { pos=0; ok=0; activarClave(true); delay(3000); activarClave(false); Serial.println("****************"); Serial.println("Digite su clave"); } if (pos == 4 && ok != 4) // se introdujeron los 4 digito y la clave es incorrecta¿ { Serial.println("Intente de nuevo por favor ... clave incorrecta"); pos=0; ok=0; activarClave(false); Serial.println(" "); Serial.println("****************"); Serial.println("Digite su clave"); } delay(70); } // fin del Loop principal 125 Guía Teórico Práctica Aprende ARDUINO // delcaracion de la funcion // que activa los LEDS // recibe como parametro un booleano // falso o verdadero para activar o desactivar void activarClave(int activador) { if (activador) { digitalWrite(rojoPin, HIGH); digitalWrite(verdePin, LOW); Serial.println("!!! acceso correcto !!!!"); Serial.println(" "); } else { digitalWrite(rojoPin, LOW); digitalWrite(verdePin, HIGH); Serial.println("!cerradura activa!"); Serial.println(" "); } } // fin del sketch El ejemplo anterior se puede modificar para activar una cerradura eléctrica a base de pulso eléctrico por medio de un RELE en lugar del LED verde. 126 Guía Teórico Práctica Aprende ARDUINO APUNTES. 127 Guía Teórico Práctica Aprende ARDUINO 13. Uso del Reloj de Tiempo Real DS1307 con ARDUINO En ocasiones es muy necesario almacenar grandes cantidades de datos para lo cual la memoria interna de Arduino no es suficiente, además es de muy especial uso de que esta sea una memoria extraíble y brinde la posibilidad de una posterior lectura sin necesidad de desconectar nuestra tarjeta Arduino del circuito principal, pues todo esto es posible con el uso de las tarjetas de memoria SD, tarjetas de memoria que nos permiten almacenar información para una lectura de esta en un dispositivo externo como una PC o Tablet. Figura 13-1. Tarjeta modular para un DS1307 y chip individual. El circuito integrado RTC - DS1307. Un RTC (reloj de tiempo real) es básicamente un circuito como un reloj de pulsera, que nos permite conocer la hora y fecha actual; el circuito integrado DS1307 es un RTC que internamente implementa un temporizador y permite “llevar” en su memoria interna la hora y fecha actual, y con la ayuda de un cristal y una batería, estos datos no se pierden o borran al quitar la alimentación del circuito principal. Por lo anterior, el circuito DS1307 permite que Arduino pueda conocer la hora y fecha actual simplemente leyendo su memoria interna, en la figura se puede apreciar el circuito básico de conexión del DS1307 necesario para su funcionamiento, cabe señalar el uso de un cristal de cuarzo y una batería, también destacar que la comunicación con el DS1307 se logra a través de protocolo I2C (investigue!) por medio de solo dos pines de conexión SDA y SCL. La conexión del Arduino al DS1307 es sencilla y solo se necesitan dos pines para el intercambio de información entre ellos, normalmente el Arduino ya incorpora los pines SDA y SCL en sus pines, en la tarjeta 128 Guía Teórico Práctica Aprende ARDUINO UNO estos están en los pines digitales cercanos al pin AREF (UNO R3), sin embargo estos pueden ser configurados diferente desde el sketch. Figura 13-2. Conexión básica del chip DS1307 Arduino y el DS1307. El hardware o esquema de conexión entre la tarjeta Arduino y el DS1307 es sencillo, simplemente las salidas SCL y SDA del Ds1307 deben conectarse a las respectivas entradas SCL y SDA de Arduino, pero donde están ubicadas estas entradas en la tarjeta?, pues bien en el Arduino UNO está en los pines A4 y A5, pero en la versión UNO R3 están ubicadas al final de las líneas digitales se pueden diferenciar porque en esta versión estas líneas vienen identificadas, en la versión MEGA se ubican en los pines digitales 20 y21. Verifique bien la versión de su tarjeta y ubique los pines SDA y SCL. Figura 13-3. Arduino conectado a un Módulo RTC DS1307. 129 Guía Teórico Práctica Aprende ARDUINO Figura 13-4. Arduino conectado a un Módulo RTC DS1307. (miklos.blog.br) Desde el punto de vista del sketch, para que Arduino pueda comunicarse con el DS1307 es necesario el uso de funciones específicas para la comunicación I2C, sin embargo con la inclusión de librerías nuestro sketch se simplifica mucho. Una librería, de muchas existentes, es la llamada RTClib.h, descargable desde https://github.com/adafruit/RTClib y para usarla se deben declarar e incluir estas dos líneas: #include <Wire.h> #include "RTClib.h" El Arduino simplemente deberá leer el contenido de la memoria interna del DS1307 para obtener la hora y fecha actual, esta lectura se realiza utilizando las funciones específicas de la librería mencionada anteriormente, a continuación se describirán algunas de estas funciones: Funciones de Configuración RTC_DS1307 RTC: Declara y crea un objeto llamado RTC (este nombre puede ser elegido a gusto del programador) Wire.begin() y RTC.begin(): Inicializan la comunicación vía I2C y el DS1307, estos dos estamentos deben ubicarse dentro de la función Setup(). Funciones de Manipulación DateTime now = RTC.now(): Obtiene de la memoria interna del DS1307 la hora y fecha actual, para después poder leer los registro específicos de hora, minutos, segundos, dia, mes y año, se ubica dentro del Loop(). now.hour() , now.minute(),now.second(),now.year(),now.month(),now.day() : funciones de lectura del DS1307, son las funciones que devuelven el valor del registro específico para cada uno de los datos de fecha y hora, estos deben cargarse a variables individuales. 130 Guía Teórico Práctica Aprende ARDUINO adjust(DateTime(año,mes,dia,hora,minutos,segundos)) : escritura de los registros internos del DS1307, esta función recibe los seis parámetros que se desean modificar en el RTC, estos argumentos pueden ser por referencia o por valor. Básicamente estas son las funciones que se deben invocar en el sketch para ler y/o manipular los registros del DS1307, siempre que se mantenga con carga la batería interna del módulo, la hora y fecha no se borraran. EJEMPLO DS01: El siguiente sketch maneja un DS1307 conectado al Arduino, lee los registros y los muestra en el monitor serial del PC, recuerde instalar previamente la librería respectiva. /* Ejemplo de Manejo del DS1307 Lee un DS1307 conectado a Arduino Y replica su contenido por el Monitor Serial Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CC */ //incluir las librerías necesarias #include "Wire.h" #include "RTClib.h" //Se crea el objeto RTC RTC_DS1307 RTC; //Definir variables para guardar los datos //leidos del DS1307 int horas; int minutos; int segundos; int year; int month; int day; void setup () { Serial.begin(9600); // Inicializa la velocidad del puerto serie Wire.begin(); // Inicializa la comunicación I2C RTC.begin(); // Inicializa al DS1307 if (! RTC.isrunning()) //si el DS1307 está en blanco { // ajuste inicial a las 8 am del 20 de Abril del 2013 RTC.adjust(DateTime(2013,04,20,8,0,0)) ; } } //Programa Principal: leer el DS1307 y desplegar en el MS. void loop () { DateTime now = RTC.now(); // le avisa al DS1307 que se leerán valores //leer cada registro y asignarlo a una variable horas = now.hour(); minutos = now.minute(); segundos = now.second(); year_ = now.year(); month_ = now.month(); day_ = now.day(); //mostrarlos en el Monitor Serial Serial.println(“*****”); Serial.print(“la HORA actual es: ); 131 Guía Teórico Práctica Aprende ARDUINO Serial.print(horas);Serial.print(':'); Serial.print(minutos);Serial.print(':'); Serial.println(segundos); Serial.print(“la FECHA actual es: ); Serial.print(day_);Serial.print('/'); Serial.print(month_);Serial.print('/'); Serial.println(year_); Serial.println(“*****”); } //FIN del Sketch En el ejemplo anterior se vio como leer los registros internos del DS1307, en el siguiente sketch se usan las funciones para grabar una nueva hora y fecha al DS1307 a partir de una entrada del Monitor Serial. EJEMPLO DS02: El siguiente sketch maneja un DS1307 conectado al Arduino, manipula los registros internos del DS1307 vía el Monitor Serial del PC. /* Lectura y modificacion de los registros del DS1307 Via el Monitor Serial Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CC */ //incluir las librerías necesarias #include "Wire.h" #include "RTClib.h" //Se crea el objeto RTC RTC_DS1307 RTC; //Definir variables para guardar los datos //leidos del DS1307 int horas; int minutos; int segundos; int year_; int month_; int day_; void setup () { Serial.begin(9600); // Establece la velocidad de datos del puerto serie Wire.begin(); // Inicializa la comunicación I2C RTC.begin(); // Inicializa al DS1307 if (! RTC.isrunning()) //si el DS1307 esta en blanco { // ajuste inical a las 8 am del 20 de Abril del 2013 RTC.adjust(DateTime(2013,04,20,8,0,0)) ; } Serial.println("Ingerese V para ver la hora y fecha actual"); Serial.println("Para modificar la HORA ingrese + o -"); } void loop () { DateTime now = RTC.now(); // le avisa al DS1307 que se leerán valores 132 Guía Teórico Práctica Aprende ARDUINO //leer cada registro y asignarlo a una variable horas = now.hour(); minutos = now.minute(); segundos = now.second(); year_ = now.year(); month_ = now.month(); day_ = now.day(); if (Serial.available() > 0) { //si es asi, leerlo y aignarlo a la variable int valor_ingresado=Serial.read(); //procesarlo if (valor_ingresado == 'V') { Serial.println("*****"); Serial.print("la HORA actual es: "); Serial.print(horas);Serial.print(":"); Serial.print(minutos);Serial.print(":"); Serial.println(segundos); Serial.print("la FECHA actual es: " ); Serial.print(day_);Serial.print("/"); Serial.print(month_);Serial.print("/"); Serial.println(year_); Serial.println("*****"); Serial.println("Ingerese V para ver la hora y fecha actual"); Serial.println("Para modificar la HORA ingrese + o -"); } if (valor_ingresado == '+') { horas=horas++; RTC.adjust(DateTime(year_,month_,day_,horas,minutos,segundos)); Serial.println("Ud. ha AUMENTADO la hora"); delay(1000); Serial.println("Ingerese V para ver la hora y fecha actual"); Serial.println("Para modificar la HORA ingrese + o -"); Serial.println("*****"); } if (valor_ingresado == '-') { horas=horas--; RTC.adjust(DateTime(year_,month_,day_,horas,minutos,segundos)); Serial.println("Ud. ha DECREMENTADO la hora"); delay(1000); Serial.println("Ingerese V para ver la hora y fecha actual"); Serial.println("Para modificar la HORA ingrese + o -"); Serial.println("*****"); } } delay(1000); } //FIN del Sketch Compile y descargue el siguiente condigo y verifique vía el Monitor Serial su funcionamiento, observe bien como se usa la función RTC.adjust() para modificar los registros internos del DS1307. 133 Guía Teórico Práctica Aprende ARDUINO 14. Manejo de Motores Eléctricos con ARDUINO Uno de los principales componentes externos a utilizar con Arduino son los Motores Eléctricos, (que funcionan con electricidad), estos dispositivos permiten a nuestra tarjeta gobernar movimientos y acciones en el entorno físico del sistema Arduino, por ejemplo son muy usados en la robótica para generar los movimientos del mecanismo, en domótica podemos utilizar un motor para abrir o cerrar puertas y ventanas, además de que un motor puede ser adaptado a casi cualquier mecanismo que necesite un movimiento. La plataforma Arduino permite fácilmente el control de estos dispositivos, por lo que en esa sección nos centraremos en describir los tipos de motores a utilizar y como estos se pueden gobernar desde Arduino. Conceptos Básicos La definición general dice que “un motor es una máquina capaz de hacer funcionar el sistema transformando algún tipo de energía (eléctrica, de combustibles fósiles, etc.), en energía mecánica capaz de realizar un trabajo”, y específicamente un Motor Eléctrico es “aquel motor que transforma la energía eléctrica en energía mecánica, por medio de la repulsión que presenta un objeto metálico cargado eléctricamente ante un campo magnético permanente”, y es en este tipo de motor que centraremos nuestro estudio. La mayoría de los motores eléctricos funcionan gracias al principio de inducción, esto quiere decir que cuando un conductor conduce corriente eléctrica, se genera un campo magnético alrededor de él, entonces si se coloca una bobina por a que se hace circular una corriente entre dos polos magnéticos, esta bobina será atraída por un polo y repelida por el otro polo, debido al campo magnético propio, y si se coloca esta bobina sobre un eje libre, esta atracción y repulsión entre polos generara un movimiento angular en dicho eje. Existen varios datos a tener en cuenta cuando se utilizan motores en los circuito electrónicos: uno de ellos es el voltaje al que pueden funcionar eficientemente a velocidad máxima, este viene indicado por el fabricante, si de sobre pasa este valor se corre el riesgo de quemar el motor y si el voltaje es insuficiente el girara a menor velocidad o no girara. Importante es el consumo de corriente que tiene el motor, por lo que la fuente de alimentación del sistema debe ser capaz de proveer la suficiente corriente para el funcionamiento correcto del motor, si la corriente es insuficiente el motor perderá “fuerza” en su giro. Otro dato importante es el “torque” o “par” del motor, este es una medida de la fuerza de empuje o tracción que tiene el motor, es de tener en cuenta este dato dependiendo del mecanismo a mover o desplazar por el motor. 134 Guía Teórico Práctica Aprende ARDUINO Partes que componen un Motor En la estructura básica de todo motor eléctrico encontraremos tres bloques funcionales básicos: la carcasa, el rotor y el estator, cada uno con una función bien definida. Figura 14-1 Figura 14-1. Estructura interna de un motor eléctrico típico. La carcaza es la parte que contiene las partes internas del motor y le brinda protección, normalmente está hecha de metal, pero también podemos encontrar en material plástico. El estator en la parte que genera el campo magnético estático dentro del motor, está formado normalmente por boninas o imanes permanentes, como el de la figura 14-1. El rotor es la parte de motor que gira y esta compuesto por el eje y las boninas que generan un campo magnético rotatorio al interior del motor. Tipos de Motores Eléctricos. Dentro de los sistemas de computación física es común el uso de uno de estos tipos de motores eléctricos: Motor DC, Servomotor y Motor Paso a Paso, a continuación se describirá cada uno de estos y se expondrá el uso de ellos por medio de la tarjeta Arduino. Motores de Corriente Directa DC y Arduino Los motores DC (del inglés “Direct Current”) son los más simples que podemos encontrar, tienen dos terminales de alimentación, cuando se conectan a una fuente de voltaje DC, el motor gira en una dirección, y si se intercambian la conexión de las terminales, el motor gira en dirección contraria. Otra característica es que la velocidad depende del nivel de voltaje aplicado (siempre respetando los valores máximos), cuanto más grande el mayor la velocidad de giro. 135 Guía Teórico Práctica Aprende ARDUINO Figura 14-2. Diversas presentaciones de Motores DC. Algunas características de los motores DC son: Bajo costo Bajo peso Altas velocidades de giro Facil control de velocidad y sentido de giro Consumo de corriente elevada. Poco torque El control de un motor se basa en manejar sus tres características de funcionamiento, es decir: encendido, velocidad y sentido de giro, a continuación se describirá como lograr por medio de Arduino el control total de un motor DC. 136 Guía Teórico Práctica Aprende ARDUINO Como se mencionó un motor DC, es el más simple de los motores eléctricos y por lo tanto desde el punto de vista de Arduino también será fácil el control de su encendido, control de velocidad y sentido de giro. La conexión en hardware de este tipo de motores requiere que sus puntas de alimentación se conecten a una fuente de voltaje DC para comenzar a girar, es decir su control de encendido y apagado es de tipo “digital”, además su sentido de giro lo determinara la polaridad de la alimentación del motor y su velocidad estará definida por el nivel de voltaje aplicado a él. Entonces desde Arduino se pueden lograr todas estas tareas, recordando respetar las capacidades de corriente y voltaje de un pin de salida Arduino, para esto se hace uso de diferentes circuitos de interfaces o amplificador de potencia, en este documento nos centraremos en dos opciones para lograr el control de motores DC: el circuito integrado L293 (también conocido como SN754410) y el circuito integrado modular L9110, figura 14- 3. Figura 14-3. Interfaces electrónicas para manejar motores DC via Arduino, izq: L293 der: L9110 Uso del IC L293d (SN754410). El circuito integrado L293d es muy popular en los circuitos de interface entre Arduino y los motores DC, permite el control de hasta dos motores DC con un solo chip L293d, cada motor debe requerir máximo 5V@500mA, por medio de este interface podemos controlar el encendido del motor DC, su velocidad y sentido de giro, en la figura 14-4 se aprecia la conexión entre la tarjeta Arduino y un circuito L293d, se puede notar que solo necesita 3 pines Arduino por cada motor a controlar, dos de ellos pueden ser digitales y el tercero debe ser un pin PWM, en la figura los pines 7, 5 y 4, pero pueden variar, también es de notar la alimentación del motor (Motor Power) la cual es una entrada de voltaje a usar si el voltaje del motor difiere de 5Vdc, sino esta entrada se conecta a la alimentación general de Arduino. Cabe destacar que existe una versión de este circuito para motores que requieren más potencia, el L298 es un circuito que permite manejar motores de hasta 12V@1Amp. 137 Guía Teórico Práctica Aprende ARDUINO Figura 14-4. Conexión típica entre Arduino y L293 para el control de un motor DC – para motores de máximo 5V el pin 8 se conectara a pin 16 del L293d. – los capacitores son opcionales y evitan posibles ruidos eléctricos. El control desde el Sketch es sencillo y se basa en el establecimiento de señales digitales y PWM en los pines conectados al L293d - 1EN, 1A, 2A - para lograr las acciones deseadas en el motor respectivo se debe seguir la tabla de la figura 14-5. Figura 14-5. Circuito de conexión y tabla de funcionamiento del L293d 138 Guía Teórico Práctica Aprende ARDUINO Note de la tabla anterior que el pin del L293 denominado ENABLE (EN) debe conectarse a un pin PWM del Arduino, 1A y 2A son manejados por salidas digitales de Arduino. EJEMPLO.MDC01: En este ejemplo se usara la conexión eléctrica de la figura 14-4 , y se demostrara el uso de instrucciones para controlar el motor DC, el control se hace a partir del envío de señales digitales y PWM hacia el L293d. /* * Ejemplo MDC01 - Manejo de funciones Motor DC * demostraciones de las instrucciones para * manipular el funcionamiento del Motor. * usando el IC L293d * * usar el circuito de la figura 14-4 * * Michel Margolis * Modificado por: otoniel.flores@mail.ute.edu.sv */ // pines de conexion entre Arudino y L293 const int enPin = 5; // pin EN const int in1Pin = 7; // pin IN1 const int in2Pin = 4; // pin IN2 void setup() { pinMode(in1Pin, OUTPUT); pinMode(in2Pin, OUTPUT); // // // // para manipular el giro del motor de deben activar digitalmente las entradas IN1 e IN2 y la velocidad se modifica con una señal PWM al pin EN // Motor detenido digitalWrite(in1Pin, LOW); digitalWrite(in2Pin, LOW); analogWrite(enPin, 0); } void loop() { // motor girando a maxima velocidad en un sentido digitalWrite(in1Pin, HIGH); digitalWrite(in2Pin, LOW); analogWrite(enPin, 254); delay (3000); // motor girando a maxima velocidad al otro sentido digitalWrite(in1Pin, LOW); digitalWrite(in2Pin, HIGH); analogWrite(enPin, 254); delay (3000); // Motor detenido digitalWrite(in1Pin, LOW); digitalWrite(in2Pin, LOW); analogWrite(enPin, 0); delay(3000); // motor girando a media velocidad al otro sentido digitalWrite(in1Pin, HIGH); digitalWrite(in2Pin, LOW); analogWrite(enPin, 127); delay (3000); 139 Guía Teórico Práctica Aprende ARDUINO // motor girando a media velocidad al otro sentido digitalWrite(in1Pin, LOW); digitalWrite(in2Pin, HIGH); analogWrite(enPin, 127); delay (3000); // Motor detenido digitalWrite(in1Pin, LOW); digitalWrite(in2Pin, LOW); analogWrite(enPin, 0); delay(3000); // incremntar la velocidad en pasos for (int x=0; x<256; x++) { digitalWrite(in1Pin, LOW); digitalWrite(in2Pin, HIGH); analogWrite(enPin, x); delay(250); } // Motor detenido digitalWrite(in1Pin, LOW); digitalWrite(in2Pin, LOW); analogWrite(enPin, 0); delay(3000); } // fin del sketch EJEMPLO.MDC02: En el siguiente ejemplo se demostrara el manejo de un motor DC por medio de Arduino, se usara la conexión del circuito de la figura 14-4, en este Sketch se usa comandos enviados a Arduino desde el Monitor Serial para gobernar el funcionamiento – velocidad y sentido - del motor conectado al L293d. Enviar un 0 al Arduino representara detener el motor; enviar los dígitos 1 a 9 controlaran la velocidad del motor, al enviar los caracteres “+” o “-” modificara la dirección del giro del motor. Recuerde abrir el Monitor Serial del IDE después de descargar el Sketch a la tarjeta Arduino. /* * Ejemplo MDC02 - Control dede el * Monitor Serial del funcionamiento del Motor DC * Por Michel Margolis * Modificado por: otoniel.flores@mail.ute.edu.sv */ // definicion de conexiones const int enPin = 5; const int in1Pin = 7; const int in2Pin = 4; void setup() { Serial.begin(9600); pinMode(in1Pin, OUTPUT); pinMode(in2Pin, OUTPUT); Serial.println("Control Velocidad (0-9) y Direccion (- o +) :"); } void loop() { if ( Serial.available()) { // detectado un dato por el Serial // leerlo char ch = Serial.read(); // es un digito entre 0 y 9? if(isDigit(ch)) { // mapear segun el digito ingresado // investigar la funcion MAP 140 Guía Teórico Práctica Aprende ARDUINO int velocidad = map(ch, '0', '9', 0, 255); analogWrite(enPin, velocidad); Serial.println(""); Serial.print("Grirando a velocidad: "); Serial.println(velocidad); } // si el dao ingresado no es 0 a 9 else if (ch == '+') { Serial.println(""); Serial.print("Grirando en sentido Horario: "); digitalWrite(in1Pin,LOW); digitalWrite(in2Pin,HIGH); } else if (ch == '-') { Serial.println(""); Serial.print("Grirando en sentido Anti-horario: "); digitalWrite(in1Pin,HIGH); digitalWrite(in2Pin,LOW); } else { Serial.print("Caracter Inesprado, Error! "); Serial.println(ch); } } } // fin del sketch Uso del módulo controlador L9110. A continuación se estudiara el uso de otro circuito de interface para motores DC, El circuito integrado L9110 es un driver o controlador modular que permite el control de hasta dos motores DC por modulo, por medio de este interface podemos controlar el encendido del motor DC, su velocidad y sentido de giro, en la figura 14-6 se observa el modulo con sus pines de entrada, es de notar que a diferencia del L293, cada motor es controlado con solo 2 pines de entrada, en la imagen marcados como A-1A y A-1B (B-1A y B-1B) , por lo que Arduino necesitara dos pies de salida, que deben ser PWM, para manejar cada motor conectado al módulo L9110. La conexión entre Arduino y el módulo L9110 es sencilla y el control vía Sketch se realiza según la tabla a continuación. 141 Pin de entrada A-1A (B-2B) Pin de entrada A-1B (B-1B) Acción del Motor DC Señal PWM (0 a 255) 0 - LOW Gira sentido horario con velocidad según señal PWM 0 – LOW Señal PWM (0 a Gira sentido antihorario con velocidad Guía Teórico Práctica Aprende ARDUINO 255) según señal PWM Figura 14-6. Estructura, símbolo y funcionamiento de un LDR típico. http://www.scienceprog.com/ EJEMPLO.MDC03: En este ejemplo se usara la conexión siguiente: Pin Arduino --- Pin Modulo L9110 3 --- A-1A 5 --- A-1B Además de las conexiones anteriores, el motor DC debe conectarse a los terminales MOTOR-A del módulo, con este ejemplo se demostrara el uso de instrucciones para controlar el motor DC, el control se hace a partir del envío de señales PWM hacia el módulo L9110. /* * Ejemplo MDC03 - Manejo de funciones Motor DC * demostraciones de las instrucciones para * manipular el funcionamiento del Motor, por * medio del Modulo L9110 * * por: otoniel.flores@mail.ute.edu.sv */ // pines de conexion entre Arudino y L9110 const int A_1A = 3; // PWM const int A_1B = 5; // PWM void setup() { pinMode(A_1A, OUTPUT); pinMode(A_1B, OUTPUT); // para manipular el giro del // motor se actva o desactiva un pin // la velidad se manipula en el otro pin // Motor detenido, ambas senales a 0 142 Guía Teórico Práctica Aprende ARDUINO analogWrite(A_1A, 0); analogWrite (A_1B, 0); } void loop() { // motor girando a maxima velocidad en un sentido analogWrite(A_1A, 255); analogWrite (A_1B, 0); delay (3000); // Motor detenido, ambas senales a 0 analogWrite(A_1A, 0); analogWrite (A_1B, 0); delay(1000); // motor girando a maxima velocidad al otro sentido analogWrite(A_1A, 0); analogWrite (A_1B, 255); delay (3000); // Motor detenido analogWrite(A_1A, 0); analogWrite (A_1B, 0); delay(1000); // motor girando a media velocidad en un sentido analogWrite(A_1A, 126); analogWrite (A_1B, 0); delay(3000); // motor girando a media velocidad al otro sentido analogWrite(A_1A, 0); analogWrite (A_1B, 126); delay(3000); // Motor detenido analogWrite(A_1A, 0); analogWrite (A_1B, 0); delay(1000); // incremntar la velocidad en pasos for (int x=0; x<256; x++) { analogWrite(A_1A, x); analogWrite (A_1B, 0); delay(250); } // Motor detenido analogWrite(A_1A, 0); analogWrite (A_1B, 0); delay(1000); } // fin del sketch Con estos ejemplos se ha estudiado dos opciones para controlar un Motor DC, dependerá de su criterio y disponibilidad el circuito interface a utilizar en la implementación de sus proyectos. 143 Guía Teórico Práctica Aprende ARDUINO Servomotor y Arduino El servomotor es otro de los tipos de motores eléctricos más usados en sistemas de computación física, figura 14-7, básicamente este es un motor DC dentro de una caja de engranes con un controlador electrónico dentro que permiten un mejor control en la posición del eje, además se una mejora en el torque o fuerza del motor, este motor posee tres pines o terminales de entrada: 2 de alimentación 5Vdc y una tercera donde recibe una señal digital de control que le indica la posición a moverse. Figura 14-7. Servo motor típico y estructura interna. Este tipo de motores pueden moverse a una posición angular específica a velocidades rápidas, normalmente la velocidad de un servomotor esta fija a un determinado valor, dependiendo del modelo del servo a usar. A continuación una lista de características de los servomotores: Control preciso del ángulo de posición del eje. Rango movimiento angular limitado entre 0º y 180º Velocidad de posicionamiento elevada. Fuerza o torque elevado Fácil manejo por medio de una señal digital Bajo peso Una de las ventajas de los Servomotores es la no necesidad de un circuito de interface de potencia entre el controlador de Arduino y el motor, esto permite que la conexión sea directa, por ejemplo en la figura 14-8 se puede observar que solo es necesario el uso de una salida digital PWM de Arduino para controlar un servomotor. 144 Guía Teórico Práctica Aprende ARDUINO Figura 14-8. Conexión entre Arduino y un servomotor: rojo a 5V, Negro a Gnd y Blanco al pin de control. Como se mencionó, estos servomotores solo permiten el movimiento angular de su eje en un rango limitado entre 0º y 180º, dependiendo de la frecuencia (periodo de duración) de la señal de control inyectada al motor a través de la salida PWM de Arduino, ver figura 14-9. Sin embargo, en Arduino es muy sencillo el control de estos motores, ya que el IDE cuenta con una librería estándar – Servo.h - para el envío de señales de control a un servomotor conectado a nuestra tarjeta Arduino. A continuación se describirán algunas funciones a utilizar para el control de un servomotor. Figura 14-9. Detalle de los movimientos de un servomotor y su señal de control. 145 Guía Teórico Práctica Aprende ARDUINO Funciones de Configuración Servo miServo: esta función se debe incluir al inicio del Sketch antes de la función setup(), permite la creación de un objeto llamado miServo (este nombre puede ser cualquiera), para que pueda ser manipulado más adelante dentro del Sketch. No recibe ni devuelve ningún parámetro. miServo.attach(pin): esta función se debe incluir dentro del bucle setup(), le indica a Arduino cuál será el pin a usar para conectar a señal de control del Servomotor. Te debe ser un pin con capacidad PWM. Funciones de Manipulación miServo.write(Angulo): Al ejecutar esta instrucción el eje del servomotor denominado como miServo, se moverá a la posición angular definida por el valor del parámetro Angulo, cabe recordar que este valor debe estar en un rango entre 0 y 180. EJEMPLO.MSV01: En el siguiente ejemplo se demostrara el manejo de un servomotor por medio de Arduino, se usara la conexión del circuito de la figura 14-8, en este Sketch se usa comandos dentro del Sketch para manipular la posición del servomotor. /* * Ejemplo MSV0 - Manejo de la posicion de * un servo motor desde el Sketch * conectado al PIN9 de arduino * * por: otoniel.flores@mail.ute.edu.sv */ // Incluir la libreria, ya incluida en la // distribucion estandar del IDE arduino #include <Servo.h> // Defiir un objeto llamado miServo Servo miServo; void setup() { // decile donde esta coecatdo el servo miServo.attach(9); } void loop() { // posicionar el servo en 180º miServo.write(180); delay(2000); // posicionar el servo en 90º miServo.write(90); delay(2000); // posicionar el servo en 0º miServo.write(0); delay(2000); } // fin del sketch 146 Guía Teórico Práctica Aprende ARDUINO EJEMPLO.MSV02: PARA el siguiente ejemplo se usara el esquema de conexión de la figura 14-10, en este Sketch se programara el Arduino para gobernar el servomotor a partir de los movimientos sobre un potenciómetro, el programa leerá el sensor y accionara el servo según esta lectura. /* * Ejemplo MSV02 * Controlando la posición de un servo usando un potenciómetro (resistencia variable) * Por Michal Rinott * modificado por: otoniel.flores@mail.ute.edu.sv */ // Incluir la libreria, ya incluida en la // distribucion estandar del IDE arduino #include <Servo.h> Servo miServo; // Crea un objeto servo para controlar el servomotor int potPin = 0; // Pin analógico usado para conectar el potenciómetro int valorPot; // variable para leer el valor del pin analógico AO void setup() { miServo.attach(9); // asocia el servo al pin 9 } void loop() { // lee el valor del potenciómetro (valor //entre 0 y 1023) valorPot = analogRead(potPin); // escala el valor para usarlo con el // servo (valor entre 0 y 180), investigar el uso de // la fucion MAP valorPot = map(valorPot, 0, 1023, 0, 179); // accionar el servo miServo.write(valorPot); delay(25); } // fin del sketch Figura 14-10.Conexion para el control de un servomotor desde un potenciómetro. 147 Guía Teórico Práctica Aprende ARDUINO Motor Paso a Paso y Arduino Los motores paso a paso (PaP), también llamados stepper, son un tipo de motor eléctrico de voltaje DC, cuyo funcionamiento difiere en gran medida de los vistos anteriormente: DC y Servomotor, desde el punto de vista constructivo, ver figura 14-11, se diferencia por que posee 4, 5 o 6 líneas de entrada de control, dependiendo del tipo de motor paso a paso. Entre las características de funcionamiento de este tipo de motores se listan: Rango de movimiento angular 360º - rotación continua Alto valor de torque Sencillo control del ángulo, velocidad y sentido de giro Figura 14-11. Servo motor típico y estructura interna. Este tipo de motor es que es capaz de avanzar una serie de grados (paso) dependiendo del estado digital de sus entradas de control. Existen dos tipos de motores paso a paso: Bipolar y Unipolar, se diferencia en el número de conectores de entrada, el Unipolar posee 5 o 6 líneas y el Bipolar posee 4 entradas de control. Además otra característica de funcionamiento muy importante es el número de pasos de motor, es la cantidad de pasos que le toma al motor para completar un giro completo de 360º, este número de pasos varía según modelo de motor usado, por lo que debemos conocer este valor al momento de usar un motor paso a paso. Las conexiones y manejo desde Arduino son sencillas, en este caso se debe usa una interface electrónica entre Arduino y el motor, con el objetivo de amplificar la corriente de salida de los pines digitales, desde el sketch se hace fácil el manejo ya que Arduino cuenta con una librería que contiene funciones predefinidas para activar y manejar motores paso a paso de ambos tipos. En este documento nos centraremos en el uso de los motores PaP Unipolar, ya que son los de mayor disposición, uso y bajo costo, el circuito de conexión entre Arduino y un motor paso a paso Unipolar se muestra en la figuras 14-12 y 14-13 148 Guía Teórico Práctica Aprende ARDUINO Figura 14-12. Motor Unipolar y su conexión a Arduino via IC ULN2803. Figura 14-13. Motor Unipolar y su conexión a Arduino vía IC ULN2803. El control del funcionamiento del motor PaP conectado a Arduino se logra usando la librería <Stepper.h>, la cual ya está incluida dentro de la distribución estándar del IDE Arduino, y que contiene las funciones necesarias para manejar un motor PaP, a continuación se describirán algunas de las funciones incluidas en dicha librería. Funciones de Configuración Stepper miStepper (Pasos, pinA, pinB, pinC, pinD): esta función se debe incluir al inicio del Sketch antes de la función setup(), permite la creación de un objeto llamado mistepper (este nombre puede ser cualquiera), para que pueda ser manipulado más adelante dentro del Sketch. Recibe como parámetros el número de PASOS del motor usado, y los números de pines de Arduino donde se coneta el motor, estos pines puedes ser cualesquiera. miStepper.setSpeed(velocidad): esta función se debe incluir dentro del bucle setup(), le indica a Arduino la velocidad a usar para el motor llamado miStepper, donde el parámetro velocidad debe ser un valor en RPM, normalmente 30 RPM es un valor aceptable. 149 Guía Teórico Práctica Aprende ARDUINO Funciones de Manipulación miStepper.step (Npasos): Al ejecutar esta instrucción el motor paso a paso conectado a Arduino se mueve el número de pasos definido por Npasos, a partir de la posición actual y a la velocidad definida en miStepper.setSpeed. , si el parámetro Npasos es + se girara hacia un lado y si es – se girara en reversa. EJEMPLO.STP01: En el siguiente ejemplo se demostrara el manejo de un motor PaP por medio de Arduino, se usara la conexión del circuito de la figura 14-15, en este Sketch se usan comandos dentro del Sketch para manipular la posición del motor. En este ejemplo se usa el motor modelo 28BYJ-48 que es Unipolar de 5 hilos con un valor de 2048 pasos por revolución. /* * * * * * * */ Ejemplo Manejo de Stepper 28BYJ-48 con ULN2003 se hace girar el mortor una revolucion completa en ambos sentidos modificado por: otoniel.flores@mail.utec.edu.sv #include “Stepper.h” Stepper myStepper(2048,2,4,3,5); void setup() { myStepper.setSpeed(10); } void loop() { myStepper.step(2048); delay(1000); myStepper.step(-2048); delay(1000); } // fin del sketch Si se desean utilizar motores de mayor requerimiento de potencia, se recomienda el uso del circuito integrado L298, desde el punto de vista del sketch las instrucciones siguen siendo las mismas, si desea probar esta interface L298 se recomienda investigar su circuito de conexión a Arduino. 150 Guía Teórico Práctica Aprende ARDUINO Figura 14-14. Arduino controlando un motor 28BYJ-48 por medio de un módulo ULN2803. Conexión del ejemplo 1 151 Guía Teórico Práctica Aprende ARDUINO 15. Uso de Fotoresistor LDR con ARDUINO Los LDR (Ligth Depending Resistor) o Fotoresistores son sensores de luz, tal como su nombre los indica son componentes que permiten detectar la presencia de luz en el entorno, básicamente un LDR está compuesto por un resistor que cambia su valor óhmico en dependencia de la luz presente sobre el sensor, concretamente, la resistencia se reduce a medida que recibe más intensidad de luz. En la figura x.1 se puede observar la forma física y los símbolos eléctricos más usados, además podemos ver la gráfica de la función de transferencia que rige el comportamiento de estos sensores Figura 15-1. Estructura, símbolo y funcionamiento de un LDR típico. http://www.scienceprog.com/ Los LDR son sensores muy utilizados en detección de intensidad de luz ambiental, dentro de sus aplicaciones específicas se pueden nombrar circuitos que activan una salida al obscurecer o circuitos que activan una salida al amanecer, en fin, sistemas de control que activan o desactivan salidas dependiendo del grado de luminosidad del ambiente, como el caso de las lámparas del alumbrado público. 152 Guía Teórico Práctica Aprende ARDUINO Como se puede observar en la gráfica de la figura x-2 a mayor cantidad de luz menor es la resistencia entre terminales, esta resistencia llega a tener valores del orden de décimas de ohmio, dependiendo del LDR, por el contrario en total oscuridad se presenta una resistencia entre terminales del orden de las centenas de miles de ohmios, un detalle importante estos sensores reaccionan mejor a la luz blanca o amarilla. Figura 15-2. Función de transferencia de un LDR http://www.opiron.com/ Los LDR son sensores muy utilizados en detección de intensidad de luz ambiental, dentro de sus aplicaciones específicas se pueden nombrar circuitos que activan una salida al obscurecer o circuitos que activan una salida al amanecer, en fin, sistemas de control que activan o desactivan salidas dependiendo del grado de luminosidad del ambiente, como el caso de las lámparas del alumbrado público. Suelen ser pequeños, baratos y fáciles de usar; por eso aparecen mucho en juguetes y dispositivos domésticos en general. Pero son imprecisos: cada fotoresistor reacciona de forma diferente a otro, aunque hayan sido fabricados en el mismo lote, es por eso que NO son usados para determinar niveles exactos de intensidad de luz, sino más bien para determinar variaciones en ella, las cuales pueden provenir de la propia luz ambiente (“día o noche”) o bien de la presencia de algún obstáculo que bloquee la recepción de la luz incidente, o por ejemplo en un sistema de guía para un robot que siga una fuente de luz. Otro dato a tener en cuenta es que un LDR posee un tiempo de respuesta típico de alrededor de una décima de segundo, esto quiere decir que la variación de su resistencia tiene un retraso con respecto a los cambios de la luz incidente, por lo tanto en circunstancias donde la señal lumínica cambia con rapidez su uso no es recomendado. 153 Guía Teórico Práctica Aprende ARDUINO LDR y Arduino. Para comenzar con el uso de los fotoresistores debemos saber que existen dos maneras o circuitos de conexión del sensor, estos básicamente son divisores de voltaje que enviaran un nivel de voltaje a la entrada de Arduino según la luz incidente en un LDR. Figura 15-3. Circuito de conexión de un LDR http://www.arduteka.com/ Figura 15-4. Conexión hacia Arduino de los LDR http://learning.codasign.com/ 154 Guía Teórico Práctica Aprende ARDUINO De la figura 15-3, al circuito de la izquierda se le conoce como conexión “pull-up” y el de la derecha es un circuito “pull-down”, estos hacen referencia al resistor fijo, si el resistor está conectado a VCC (up) o GND(down), si se usa la resistencia “pull-up” cuanto más sea la luz incidente en el sensor más será le voltaje recibido por la entrada analógica de Arduino, en la conexión “pull-down” es lo contrario. A continuación se verán algunos ejemplos de lectura de LDR conectado a una entrada análoga de Arduino para poder detectar el nivel de luz incidente en el sensor, se usara la conexión “pull down” si no es especifica lo contrario. EJEMPLO.LDR01: El siguiente sketch asume una conexión del LDR en “pull-down” conectado al pin A0 del Arduino, se usara un LED como salida que se encenderá o apagara según el LDR se encuentre en un ambiente con luz o en obscuridad. Figura 15-5. Conexión del ejemplo LDR01 /* LED activado por Obscuridad Sketch que activa un led al detectar obscuridad sobre un LDR conectado al A0 -Se puede conctar un RELE a la salida digital para poder conmutar lamparas a 110vAc. Created by David Cuartielles Modificado por: otoniel.flores@mail.utec.edu.sv Dominio Publico CreativeCommon */ int sensorPin = A0; int ledPin = 11; int valorSensor = 0; 155 // Entrada donde se conectara el LDR // Pin donde para LED // Variable para guardar conversion del ADC0 Guía Teórico Práctica Aprende ARDUINO void setup() { // configura el pin 13 como salida pinMode(ledPin, OUTPUT); } void loop() { // leer el valor de sensor valorSensor = analogRead(sensorPin); // decidir si activar el LED if (valorSensor > 512)digitalWrite(ledPin, LOW); if (valorSensor < 512)digitalWrite(ledPin, HIGH); //si el voltaje leido del LDR es menor a 2.5v (512) //significa que esta obscurecido y el LED se apaga //de lo contrario de mantiene encendido delay(250); } //Fin del Sketh. EJEMPLO.LDR02: En este ejemplo se usara un LDR como entrada para manipular el tiempo de parpadeo de un LED conectado a una salida de Arduino. El circuito a ensamblar es el mismo del ejemplo anterior. /* Parpadeo de LED controlado por LDR La velocidad de parpadeo de LED depende del nivel de luz sobre el LDR Modificado por: otoniel.flores@mail.utec.edu.sv Dominio Publico CreativeCommon */ int pinLdr = A0; int pinLed = 11; int valorLdr = 0; // pin a conectar el LDR // pin donde se conectara el LED // variable almacenar valor ADC del LDR void setup() { pinMode(pinLed, OUTPUT); } void loop() { // tomar la lectura del sensor: valorLdr = analogRead(pinLdr); // encender el LED digitalWrite(pinLed, HIGH); // realizar una pausa segun el valor del Sensor delay(valorLdr); // apagar el led digitalWrite(pinLed, LOW); // realizar una pausa segun el valor del Sensor delay(valorLdr); } //Fin del sketch EJEMPLO.LDR03: También es posible gobernar otro tipo de componente de salida a partir de la intensidad de luz incidente en un LDR, en este ejemplo se controlara la frecuencia del tono emitido por un BUZZER dependiendo del nivel de luz. Note el uso de la instrucción map, se deja como tarea investigar su uso. /* 156 Guía Teórico Práctica Aprende ARDUINO Tono de BUZZER controlado por LDR La frecuencia del tono producido por el BUZZER depende del nivel de luz sobre el LDR Modificado por: otoniel.flores@mail.utec.edu.sv Dominio Publico CreativeCommon */ int int int int pinLdr = A0; pinBuzzer = 7; valorLdr = 0; sonido =0; // pin a conectar el LDR // pin donde se conectara el LED // variable almacenar valor ADC del LDR void setup() { pinMode(pinBuzzer, OUTPUT); } void loop() { // tomar la lectura del sensor: valorLdr = analogRead(pinLdr); // usar map, para mapear la entrada del LDR // a valores referente a Frecuencias de tono sonido = map(valorLdr, 400, 1000, 120, 1500); // emitir el tono en el buzzer tone(pinBuzzer, sonido, 10); // pausa de estabilidad delay(1); } //Fin del sketch Figura 15-6. Esquema de conexión del ejemplo 3, Buzzer y LDR. A partir de aquí se pueden realizar infinidad de aplicaciones usando LDR como entrada, se deja a imaginación y tarea del lector el estudio y realización de más circuitos y programas con dichos sensores. 157 Guía Teórico Práctica Aprende ARDUINO 16. Medición de Temperatura con ARDUINO La temperatura es una de las variables físicas de mayor interés al momento de monitorear el ambiente exterior por medio de un sistema basado en Arduino, existen una amplia gama de sensores que se pueden utilizar para dicho propósito, en esta guía nos centraremos en el uso de los dos tipos más populares de sensores para medir temperatura: el LM35, el DS18B20 y el módulo DHT11, todos ellos sensores integrados de muy buena precisión y manejo sencillo. Sensor LM35 Como se mencionó existen muchos tipos de sensores de temperatura, uno de ellos es el circuito integrado LM35, de tipo activo-análogo, este componente es un sensor de temperatura con una precisión calibrada de 1ºC y permite la toma de mediciones de temperaturas en un rango que abarca desde -55º a + 150ºC. La salida es muy lineal y cada grado centígrado en el ambiente del sensor equivale a 10 mV en la terminal de salida. El sensor se presenta en diferentes encapsulados pero el más común es el TO-92, figura 16-1, de igual forma que un típico transistor con 3 patas, dos de estas son para alimentarlo (5Vdc) y la tercera terminal del sensor nos entrega un valor de voltaje proporcional a la temperatura medida por el dispositivo. Con el LM35 sobre la mesa las patillas hacia nosotros y las letras del encapsulado hacia arriba tenemos que de izquierda a derecha los pines son: VCC - Vout - GND. Figura 16-1. Forma física y disposición de las terminales de un sensor LM35. 158 Guía Teórico Práctica Aprende ARDUINO Las características más relevantes de este sensor son: Precisión de ~1,5ºC (peor caso), 0.5ºC garantizados a 25ºC. Baja corriente de alimentación (60uA). Amplio rango de funcionamiento (desde -55º a + 150ºC). Bajo costo. Baja impedancia de salida. Su tensión de salida es proporcional a la temperatura, en la escala Celsius. No necesita calibración externa y es de bajo costo. Funciona en el rango de alimentación comprendido entre 4 y 30 voltios. Como ventaja adicional, el LM35 no requiere de circuitos adicionales para su calibración externa cuando se desea obtener una precisión del orden de ±0.25 ºC a temperatura ambiente, y ±0.75 ºC en un rango de temperatura desde 55 a 150 ºC. Figura 16-2. Modulo con sensor LM35 integrado listo para su conexión con Arduino. Este sensor dispone de tres terminales, dos para alimentación y una salida, por donde se obtiene un el voltaje análogo en proporción a la temperatura captada, la conexión de este tipo de sensor hacia la tarjeta Arduino se puede hacer directamente, sin uso de componentes adicionales, ya que la salida análoga del sensor puede ser leída por una entrada del convertidor análogo digital del Arduino, existen algunos módulos que ya traen dentro el sensor LM35 y algunos componentes estabilizadores, con conexiones directas para la placa Arduino, ver figura 16-2. Como la señal de salida del señor LM35 es de tipo análoga, esta debe ser conectada y leida por una entrada análoga del Arduino (A0 a A5 en la versión UNO) como nos indica la figura 16-3, el Sketch de aplicación para obtener la temperatura de este sensor deberá leer la entrada análoga correspondiente de Arduino y realizar las conversiones necesarias para obtener la temperatura real del sensor. Es de tomar en cuenta la ecuación de conversión que define el funcionamiento del sensor para su posterior procesamiento dentro del firmware, es decir que el sensor tendrá en su salida 10mV por cada grado Celsius detectado en el ambiente, la ecuación de la figura 16-4 es útil para obtener la temperatura a partir del voltaje leído por el ADC del Arduino. 159 Guía Teórico Práctica Aprende ARDUINO Figura 16-3 Circuito básico de conexión entre un sensor LM35 y Arduino. Figura 16-4 Ecuación de conversión para el voltaje de salida del LM35 A continuación se demostrara el uso de este sensor realizado algunos ejemplos para la lectura de la temperatura y su posterior despliegue utilizando diversos medios de salida. EJEMPLO.LM35.01 En este ejemplo se utiliza la conexión de la figura 16-3 para tomar la lectura de la temperatura del sensor y mostrarla en el Monitor Serial cada cierto periodo de tiempo, además de mensajes de alerta si la temperatura sobrepasa un valor establecido. /* Lectura de un sensor LM35 Toma la lectura de la temperatura y la muestra por el monitor serial Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CC */ int pinSensor = A0; int limiteTemp = 35; float lecAdc = 0; float tempSensor = 0; float voltSensor = 0; 160 Guía Teórico Práctica Aprende ARDUINO float promLec = 0; void setup() { Serial.begin(9600); } void loop() { //se toman 25 lecturas del A0 //y se obtiene un promedio for (int i=0; i<25; i++) { lecAdc = analogRead(pinSensor); delay(50); promLec = promLec + lecAdc; } lecAdc=promLec/25; promLec=0; //se calcula el voltaje del sensor voltSensor = (lecAdc / 1024.0) * 5000; //se calcula la temperatura del sensor tempSensor = voltSensor / 10; //ya que se tiene el valor de temperatura //se puede usar como se desee. //aqui se imprimira al Monitor Serial Serial.print("La temperatura del sensor es: "); Serial.print(tempSensor); Serial.println(" Centigrados"); Serial.print("La temperatura del sensor es: "); Serial.print((tempSensor * 9)/ 5 + 32 ); Serial.println(" Fahrenheit"); //ademas se verifica a modo de alarma si la //temperatura sobre pasa el limite establecido. if (tempSensor >= limiteTemp) Serial.println ("***ALARMA la temperatura es es mayor a 35 C****"); Serial.println (" "); Serial.println (" "); delay(1500); // breve espera } //Fin del sketch Figura 16-5 Salida vía Monitor Serial del Ejemplo con sensor LM35 161 Guía Teórico Práctica Aprende ARDUINO Sensor DS18B20 El sensor de temperatura DS18B20 es un sensor integrado de tipo digital-activo que utiliza el protocolo 1Wire para su comunicación con un Microcontrolador, es muy popular debido a su facilidad de uso y bajo costo, es capaz de tomar medidas de temperaturas en un rango de -10ºC hasta 85ºC con una precisión de +0.5ºC, se puede encontrar en su versión individual, estilo TO92, o en modulo listo para su conexión a Arduino, ver figuras 16-6 Figura 16-6 Pin-out del Sensor DS18B20 El sensor posee tres terminales, si lo observamos de frente a su cara lisa, las funciones de estas son: la terminal izquierda es la conexión a tierra o GND, la del centro es la salida digital de la señal de datos (a conectar a una entrada Arduino) y la terminal de la derecha sirve para la alimentación a VCC +5V, por lo tanto se necesitaran 1+2 conexiones desde Arduino para manejar este tipo de sensor, además el fabricante indica la conexión de un resistor de 4.7K ohmios entre la terminal de datos y VCC. Para conocer más del protocolo de comunicación 1-Wire se recomienda la lectura del tutorial en línea http://www.maximintegrated.com/products/1-wire/flash/overview/. De lo anterior, la conexión entre Arduino y el sensor DS18B20 es sencilla y solamente requiere de un pin de entrada digital de la tarjeta, en la figura 16-7 se puede observar una conexión típica, donde se puede apreciar el resistor mencionado, es de tener en cuenta que si se usa la versión de modulo break-out o modular del sensor normalmente ya se incluye este resistor dentro de dicho modulo. Figura 16-7 Conexión entre Arduino y un sensor DS18B20 162 Guía Teórico Práctica Aprende ARDUINO Para diseñar el Sketch que leerá la temperatura desde el sensor se deben utilizar funciones especiales del fabricante Dallas Semiconductor y del protocolo 1-Wire, las cuales se pueden descargar desde los enlaces siguientes: librería OneWire.h : http://www.hacktronics.com/code/OneWire.zip librería DallasTemperature.h: http://www.hacktronics.com/code/DallasTemperature.zip Estas librerías poseen algunas funciones especiales para configurar, inicializar y leer la temperatura del sensor, se mostrara un ejemplo a continuación donde se utilizan dichas funciones y se lee la temperatura de un DS18B20 para desplegarla en el Monitor Serial de la computadora. EJEMPLO.DS18B20.01 En este ejemplo se utiliza la conexión de la figura 16-7 para tomar la lectura de la temperatura del sensor y mostrarla en el Monitor Serial cada cierto periodo de tiempo. /* Lectura de un sensor DS18B20 Toma la lectura de la temperatura y la muestra por el monitor serial Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CC */ // incluir librerias necesarias – recuerde instalarlas en el IDE correctamente #include <OneWire.h> #include <DallasTemperature.h> // se le asigna una direccion al sensor dentro del bus 1-Wire, ya que pueden conectarse mas de un sensor // en el mismo bus: http://playground.arduino.cc/Learning/OneWire DeviceAddress Temperatura1; // se le asigna el sobrenombre de Temperatura1 al sensor int pinSensor = 2; // pin donde se conecatara el sensor OneWire ds(pinSensor); // se indica a la librería donde esta conectado el sensor DallasTemperature ds18b20(&ds); //crear un objeto llamado ds18b20 para manipular dentro del Sketch float tempSensor; // crear variable donde se guardara la termperatura leida void setup() { Serial.begin(9600); //iniciar el puerto serial USB ds18b20.begin(); //inicializar el objeto ds18b20 } void loop() { //las siguientes dos instrucciones son para leer la temp desde el sensor ds18b20.requestTemperatures(); //solicitar la temperatura del ds18b20 //cargar la temperatura en la variable, el 0 indica el orden de sensor dentro del bus. tempSensor = ds18b20.getTempCByIndex(0); //mostrar por el Monitor Serial la temperatura Serial.print("La temperatura es: "); Serial.print(tempSensor); Serial.println (" C"); delay (1000); //pausa entre lecturas Serial.println (" Serial.println (" "); "); } //Fin del sketch 163 Guía Teórico Práctica Aprende ARDUINO Sensor DHT11 Otro de los sensores más utilizados en medición de temperatura es el DHT11, un sensor de bajo costos y fácil manejo, además de tener la ventaja de permitir la toma de lectura de la Humedad Relativa del Aire, así como de la Temperatura del ambiente. Este sensor tiene una presentación modular, figura 16-8, que permite una rápida y fácil conexión a una placa Arduino, entre las características técnicas de este dispositivo se pueden listar las siguientes: Bajo costo Salida tipo Digital en un solo pin. Alimentación desde 3 a 5Vdc Corriente máxima de consumo 2.5mA Rango de Humedad: 20-80% con ±5% de precisión Rango de Temperatura: 0-50°C con una precisión de ±2°C. Frecuencia de muestreo 1 Hz Max. Dimensión 15.5mm x 12mm x 5.5mm Obtener la Temperatura y Humedad de ambiente usando este sensor, es muy sencillo desde Arduino, desde el punto de vista del hardware de conexión es necesario un único pin digital de Arduino, observa la conexión en la figura 16-9. Y gracias al uso de una librería especial conteniendo las funciones para leer los valores de la temperatura y humedad del sensor, el Sketch en Arduino es muy sencillo en su estructura. Figura 16-8. Modulo sensor de Temperatura y Humedad DHT11, 3 pines. Antes de iniciar con el uso de este sensor DHT11 se debe descargar e instalar la librería específica, esta puede ser obtenida de: https://github.com/adafruit/DHT-sensor-library , acceda a este enlace y descargue una carpeta comprimida desde el botón “Download ZIP” de la página del enlace, descomprímala y renombre a carpeta a “DHT”, luego instale la librería en su IDE (recuerde el procedimiento de instalación descrito en el capítulo 8). 164 Guía Teórico Práctica Aprende ARDUINO Para realizar la toma de lectura y humedad con este sensor se debe conectar a la tarjeta Arduino usando un único pin de entrada digital, según la figura 16-9, en la cual se observa la conexión a implementar. En el Sketch se utilizaran las funciones de la librería DTH que ya debe estar instalada en el IDE. A continuación se describen algunas de las funciones que incluye esta librería. Funciones de Configuración DHT sensorDht(pin, DHT11): esta función se debe incluir al inicio del Sketch antes de la función setup(), indica al compilador la creación de un objeto sensorDht conectado al pin (numero) digital de Arduino y con referencia DHT11. En esta instrucción casi todos son parámetros fijos, solo pin hace referencia a un número, por ejemplo si se usara un sensor DHT11 conectado al pin 2 de la tarjeta Arduino, se debe usar la instrucción: DHT sensorDht(2, DHT11); dht.begin(); esta función debe ser llamada dentro del bloque setup() del Sketch, le indica al compilador que se inicializara la lectura del objeto llamado sensorDht. Funciones de Manipulación nombreVariable = dht.readHumidity(); Al ejecutar esta instrucción, Arduino realiza la lectura de la Humedad Relativa captada por el sensor y devuelve un valor tipo float dentro de la variable llamada nombreVariable. nombreVariable = dht.readTemperature(); Al ejecutar esta instrucción, Arduino realiza la lectura de la Temperatura captada por el sensor y devuelve un valor tipo float dentro de la variable llamada nombreVariable. Figura 16-9. Conexión ha implementar para el ejemplo DTH.01, entre la tarjeta Arduino y el módulo DHT11. 165 Guía Teórico Práctica Aprende ARDUINO EJEMPLO.DHT11 En este ejemplo se utiliza la conexión de la figura 16-9 para tomar la lectura de la temperatura y humedad del ambiente usando el sensor DHT11 y mostrarla en el Monitor Serial cada cierto periodo de tiempo. /* Lectura de un sensor DTH11 Toma la lectura de la temperatura y humedad del ambiente y la muestra por el monitor serial del IDE. "La humedad relativa de una masa de aire es la relación entre la cantidad de vapor de agua que contiene y la que tendría si estuviera completamente saturada; así cuanto más se aproxima el valor de la humedad relativa al 100% más húmedo está. " Escrito por: LadyAda Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CC */ // incluir la liberia para el manejo del sensor DHT11 // https://github.com/adafruit/DHT-sensor-library #include <DHT.h> // definir el numero de entrada digital de arduino a usar #define DHTPIN 2 // definir el modelo de sensor a utilizar #define DHTTYPE DHT11 // DHT 11 // tambien esta libreria maneja modelos DHT22 y DHT21 //#define DHTTYPE DHT22 // DHT 22 (AM2302) //#define DHTTYPE DHT21 // DHT 21 (AM2301) // // // // // // *** Conexiones a usar Arduino - Sensor Conectar pin - del sensor a GND de Arduino Conectar pin S del sensor al pin 2 de Arduino Conecta el pin + del sensor a 5V de Arduino si utiliza el sensor individual, sin modulo, conectar un rsistor de 10k entre pin 2 y 5vd. // crear un objeto llamado miSensorDht indicando el pin y el modelo de sensor a usar. DHT miSensorDht(DHTPIN, DHTTYPE); float h=0; float t=0; // variables para almacenar lecturas void setup() { Serial.begin(9600); // inicializar la conexion del monitor Serial Serial.println("Prueba del sensor DHT11!"); // mensaje de inicio miSensorDht.begin(); // indicarle al sensor que comience a sensar } void loop() { // Tomar las lecturas de temperatura y humedad del sesnor! // tarda 250mS en responder el sensor a una peticion. // Como deficiencia de este sensor esta su baja velocidad de actualizacion // de lecturas, aprox 1 seg. h = miSensorDht.readHumidity(); // leer la humedad y asignarla a h t = miSensorDht.readTemperature(); // leer la temp y asugnarla a t // verificar si el sensor devolvio un dato valido numero 166 Guía Teórico Práctica Aprende ARDUINO // si el sensor devuelve NaN algo anda mal! if (isnan(t) || isnan(h)) { Serial.println("Fallo la lectura del DHT"); } else { Serial.print("Humedad: "); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperatura: "); Serial.print(t); Serial.println(" *C"); } } // Fin del sketch 167 Guía Teórico Práctica Aprende ARDUINO 17. Uso sensor decodificador de infrarrojo con ARDUINO Un tipo se sensor muy utilizado en la industria electrónica es el Decodificador Integrado de señales Infrarrojas, en palabras más simples, es el sensor encargado de recibir y decodificar las señales de luz infrarroja provenientes de un control remoto como el de la TV, este tipo de sensor permite que Arduino sea capaz de recibir órdenes transmitidas inalámbricamente desde un punto alejado del sensor. Es muy útil cuando queremos manipular las acciones de nuestro Arduino desde un punto no necesariamente dentro del montaje final, por ejemplo es de mucha utilidad en la Robótica y Domótica. Este tipo de sensor tiene un su interior un circuito amplificador y un oscilador, que permiten la recepción de las señales incluso en presencia de fuentes de luz intensas. Este sensor se conecta a un Arduino permitiendo recibir las señales de control de la mayoría de los mandos a distancias y hacer mediante software que el circuito ejecute diferentes instrucciones en función de las órdenes recibidas. Existen diferentes tipos de estos sensores dependiendo de la frecuencia a la cual funciona el transmisor o control remoto, Arduino puede decodificar señales para la mayoría de sensores disponibles en el mercado y que trabajen con estos protocolos de transmisión infrarroja: NEC, Sony SIRC, Philips RC5, Philips RC6. Como se mencionó, en los sistemas basados en Arduino y específicamente usando el leguaje C del Arduino IDE, se ha estandarizado el uso del sensor TSOPxx38, ver figura 17-1, este sensor dispone de tres terminales, dos para alimentación y una salida, por donde se obtiene un tren de pulsos correspondiente al número de tecla presionada en el transmisor. El circuito de acondicionamiento de señal hacia un Microcontrolador es muy sencillo, consta de un resistor y un capacitor. Bastara realizar vía software la decodificación de esta señal para saber que tecla fue presionada y tomar la acción correspondiente. Figura 17-1. Sensor de Infrarrojos y su versión modular. 168 Guía Teórico Práctica Aprende ARDUINO Figura 17-2. Indicación de pines del módulo Sensor Receptor de IR (cutedigi.com) Figura 17-3. Conexión típica entre Arduino y un Sensor Receptor IR. (laydada.com) 169 Guía Teórico Práctica Aprende ARDUINO Manejo con Arduino del Sensor Receptor de IR. Este tipo de sensor es muy sencillo de conectar a Arduino, solamente se necesita un pin digital de entrada de la tarjeta en el cual se conectara el pin de salida del sensor IR, tal como se observa en la figura 17-3, desde el lado del Sketch se necesitara la ayuda de las funciones de una librería especial, que se puede descargar de https://github.com/shirriff/Arduino-IRremote. Y luego debe ser instalada dentro del Arduino IDE. A continuación se describirán alunas de las funciones disponibles en la librería antes mencionada. Funciones de Configuración IRrecv miReceptor(receivePin): esta función se debe incluir al inicio del Sketch antes de la función setup(), permite la creación de un objeto llamado miReceptor (este nombre puede ser cualquiera), para que pueda ser manipulado más adelante dentro del Sketch. Como parámetro recibe el número de pin Arduino donde se conecta el sensor receptor IR. decode_results resultado: crea una variable llamada resultado donde se almacenará el código resultado de la captura de la señal infrarroja. Esta función se debe incluir al inicio del Sketch antes de la función setup(). miReceptor.enableIRIn(): habilita e inicia la recepción del sensor. Esta función se debe incluir dentr de la función setup(). Funciones de Manipulación miReceptor.decode(&resultado): Lee la recepción del sensor, retorna Verdadero si se recibió alguna señal o Falso si no se recibió señal alguna. Si se capturo alguna señal en la variable resultado se guarda el código de la tecla recibida. miReceptor.resume(): después de recibida, debe ser llamada esta función para resetear el sensor y prepáralo para la próxima lectura. EJEMPLO. IR01: Aquí se demostrara la recepción de códigos de teclas provenientes de un control remoto, se conecta el sensor IR al pin 2 de Arduino, y por medio del Monitor Serial del PC se observaran los códigos recibidos al presionar una tecla en el control remoto. /* Ejemplo de lectura de un sensor IR decodificador de senales. Se despliega el codigo de tecla recibido een el Monitor Serial del IDE Creado por: Ken Shirriff - http://arcfn.com Modificado por: otoniel.flores@mail.utec.edu.sv Ejemplo de dominio publico CC */ // incluir el uso de la libreria #include <IRremote.h> 170 Guía Teórico Práctica Aprende ARDUINO // indicar donde se conectara el sensor pin 2 Arduino int pinIR = 2; //se crea un objeto llamado miReceptor IRrecv miReceptor(pinIR); //variable donde se gurdaran los codigos recibidos decode_results resultado; void setup() { // configura le Monitor Serial Serial.begin(9600); // iniciar el sensor miReceptor.enableIRIn(); } void loop() { if (miReceptor.decode(&resultado)) // se ha recibido señal? { //si es asi, deplegar el valor de la variable Serial.println(resultado.value); //resetear el receptor para la proxima lectura miReceptor.resume(); delay(250); } } //Dscarga, abre le Monitor Serial y presiona las teclas en el Remoto //Fin del Sketch Después de descargar el código anterior, abre le Monitor Serial del IDE y presiona las teclas del Control Remoto, deberás observar los códigos numéricos representativos de cada una de las teclas del control remoto usado, cada una representa una tecla presionada. ¿Qué sucede si la tecla se mantiene presionada, que código se obtiene? ¿Qué sucede si se utiliza otro control remoto, son los códigos diferentes? 171 Guía Teórico Práctica Aprende ARDUINO 18. Medición de Distancia con ARDUINO La distancia es uno de los parámetros físicos más importantes dentro del campo de la Computación Física y más en la Robótica, por lo tanto aprender el uso de sensores que permitan a nuestro Arduino tener un conocimiento de este parámetro externo es muy importante. Existen diversos sensores en el mercado que nos permiten conocer la distancia de un objeto o un obstáculo frente al sensor, en esta sección estudiaremos el sensor ultrasónico HC-SR04, de bajo costo y fácil manejo, ver figura 18-1. Sensor HC-SR04 Este es un sensor medidor de distancias por señales ultrasónicas, también llamado Ranger, de tipo Digital cuya salida es un tren de pulsos con información sobre la distancia de un posible obstáculo frente a él. De la figura 18-1 se aprecia que el sensor HC-SR04 está constituido por dos dispositivos ultrasónicos, emisor y receptor, esto es porque su principio de funcionamiento se basa en la emisión de una señal ultrasónica hacia al frente del sensor, luego el rebote de la señal en un obstáculo es capturara por el receptor del sensor, y así la electrónica interna calcula la distancia a objeto por medio del tiempo que se tarda en rebotar la señal ultrasónica; al final en el pin de salida del sensor se obtiene una señal digital que contiene información sobre la distancia calculada. En la tabla siguiente se puede ver algunas características técnicas de funcionamiento de este sensor, cabe destacar que este sensor posee 4 terminales, dos de ellas para alimentación de voltaje, y las otras dos para interactuar con Arduino. Características técnicas del sensor HC-SR04 172 Voltaje: 5 VDC Corriente en reposo: < 2 mA Salida: High 5V / Low 0V Angulo: < 15º Distancia: 2 a 450 cm Resolución: 0,3 cm Guía Teórico Práctica Aprende ARDUINO Figura 18-1. Sensor Ultrasónico de Distancias HC-SR04. Figura 18-2. Conexión típica entre Arduino y un sensor HC-SR04 Manejo con Arduino. El sensor HC-SR04 es de muy fácil conexión y uso con tarjetas Arduino, además con el uso de la librería especial el firmware se hace sencillo, como primer punto veamos la conexión en hardware entre el sensor y nuestra tarjeta Arduino, de la figura 18-2 se puede apreciar que solo se requieren dos pines digitales de Arduino para la conexión con el sensor (pines Trigger y Echo), pueden usarse cualesquiera, además se debe asegurar la conexión de voltaje para el HC-SR04. El software de aplicación en Arduino para manejar este tipo de sensor es sencillo y requiere el uso de una librería especial llamada Ultrasonic.h la cual puede ser descargada de: https://github.com/elrodri/Ultrasonic-HC-SR04/archive/master.zip, además debe instalarse en el IDE Arduino antes de incluirla en nuestros Sketches. Esta librería contiene las funciones necesarias para que Arduino pueda interactuar con el sensor HC-SR04, a continuación se describirá las utilización de cada función dentro de la librería, para luego realizar algunos ejemplos de aplicación. 173 Guía Teórico Práctica Aprende ARDUINO Funciones de Configuración de librería Ultrasonic.h Ultrasonic miRanger(trigPin, echoPin): esta función se debe incluir al inicio del Sketch antes de la función setup(), permite la creación de un objeto llamado miRanger (este nombre puede ser cualquiera), para que pueda ser manipulado más adelante dentro del Sketch. Como parámetro recibe los números de pines Arduino usados para la conexión con el sensor, pin Trigger y pin Echo. Funciones de Manipulación de librería Ultrasonic.h miRanger.Ranging(CM): Activa el sensor y captura su salida, retornando como resultado el valor de la distancia a un objeto al frente, por lo tanto debe ser asignada a una variable previamente declarada. El valor retornado esta expresado en centímetros si se usa el parámetro CM y se retornara la distancia en pulgadas si se usa el parámetro INC. – La distancia máxima a leer es 5 metros, por lo que esta función devolverá 51 cm si no hay algún objeto frente a él. EJEMPLO.HC01: Con este ejemplo se demostrara el uso básico la librería Ultrasonic.h y sus funciones para capturar la distancia medida por un sensor HC-SR04 conectado a Arduino, la lectura de la distancia se enviara por Monitor Serial para su visualización. El sensor se conecta según la imagen superior de la figura 18-2. /* Ejemplo HC-SR04 Demostración del uso de un sensor HC-SR04 Conectado a Arduino asi: Pin Trigger al Pin 12 Arduino Pin Echo al Pin 11 Arduino Se usa el Monitor Serial para visualizar la distancia Leida por el sensor. Por J.Rodrigo ( www.jra.so ) Modificado: otoniel.flores@mail.utec.edu.sv Ejemplo de Distribución Libre CC */ //Se incluye la libreria #include <Ultrasonic.h> //Se configura y crea un objeto para manipular Ultrasonic ultrasonic(12,11); // (Trig PIN,Echo PIN) // variable para guardar la lectura long distancia; void setup() { //habilitar la comunicación serial Serial.begin(9600); } void loop() { //leer el sensor y asignar a la variable distancia distancia = ultrasonic.Ranging(CM); // CM o INC //enviar el contenido de la variable al Monitor Serial Serial.print("La distancia medida es: "); Serial.print(distancia); Serial.println(" cm" ); 174 Guía Teórico Práctica Aprende ARDUINO delay(500); } //Fin del sketch Figura 18-3. Salida vía Monitor Serial del Ejemplo 01 EJEMPLO.HC02: En este ejemplo se usara la pantalla LCD KEYPAD SHIELD para visualizar la distancia de un obstáculo frente al sensor, se mostrara la distancia en formato Centímetros y Pulgadas, el sensor se conecta a los pines digitales 12 y 13 de Arduino. /* Ejemplo HC-SR04 / Lcd Shield Demostración del uso de un sensor HC-SR04 Conectado a Arduino asi: Pin Trigger al Pin 9 Arduino Pin Echo al Pin 8 Arduino Se despliega en un LCD la distancia en formato Centimetros y Pulgadas. Por J.Rodrigo ( www.jra.so ) Modificado: otoniel.flores@mail.utec.edu.sv Ejemplo de Distribución Libre CC */ // Librerias a utilizar #include <Ultrasonic.h> #include <LiquidCrystal.h> //Configuracion pines LCD SHIELD LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // pines de para el sensor Ultrasonic ultrasonic(13,12); // (Trig PIN,Echo PIN) void setup() { //configura el tamaño del LCD lcd.begin(16, 2); } void loop() { //lcd.clear(); lcd.setCursor(3, 0); lcd.print("Dist = "); lcd.print(ultrasonic.Ranging(CM)); 175 Guía Teórico Práctica Aprende ARDUINO lcd.print(" cm"); delay(100); lcd.setCursor(3, 1); lcd.print("Dist = "); lcd.print(ultrasonic.Ranging(INC)); lcd.print(" pulg"); delay(250); } //Fin del sketch Figura 18-4. Salida en LCD SHIELD del Ejemplo 02 EJEMPLO.HC03: En este ejemplo se usaran 2 sensores HC-SR04 y se mostrara cada medición en el Monitor Serial del IDE, se mostrara la distancia en formato Centímetros. Un sensor se conecta en los pines digitales 13 y 12, mientras que el segundo sensor se conecta a los pines 3 y 2 de Arduino. /* Ejemplo HC-SR04 Medicion de DOS sensores HC-SR04 con visualizacion via Monitor Serial Por J.Rodrigo ( www.jra.so ) Modificado: otoniel.flores@mail.utec.edu.sv Ejemplo de Distribución Libre CC */ //Incluir la libreria #include <Ultrasonic.h> //Definicor pines para los sensores //Izquierdo y Derecho Ultrasonic sensorIzq(13,12); Ultrasonic sensorDer(3,2); // variables para obtener la lectura // de los sensores long distanciaIzq = 0; 176 Guía Teórico Práctica Aprende ARDUINO long distanciaDer = 0; void setup() { Serial.begin(9600); } void loop() { distanciaIzq = sensorIzq.Ranging(CM); distanciaDer = sensorDer.Ranging(CM); Serial.print("Izquierda: "); Serial.print(distanciaIzq); Serial.print(" cm " ); delay(50); Serial.print("Derecha: "); Serial.print(distanciaDer); Serial.println(" cm" ); delay(500); } //Fin del sketch Figura 18-5. Conexión de 2 sensores del Ejemplo 03 Figura 18-6. Salida vía Monitor Serial del Ejemplo 01 177 Guía Teórico Práctica Aprende ARDUINO 19. Manejo de tarjetas de memoria SD con ARDUINO En ocasiones es muy necesario almacenar grandes cantidades de datos para lo cual la memoria interna de Arduino no es suficiente, además es de muy especial uso de que esta sea una memoria extraíble y brinde la posibilidad de una posterior lectura sin necesidad de desconectar nuestra tarjeta Arduino del circuito principal, pues todo esto es posible con el uso de las tarjetas de memoria SD, tarjetas de memoria que nos permiten almacenar información para una lectura de esta en un dispositivo externo como una PC o Tablet. Figura 19-1. Modelos y tamaños de tarjetas de memoria SD. Secure Digital (SD) es un formato de tarjeta de memoria no volátil diseñada para ser usada en dispositivos portátiles (teléfonos móviles, cámaras digitales, computadores portátiles, tablets, etc) cuya especificación es mantenida por la SD Card Association, entidad que define estándares de fabricación del hardware. Tarjetas SD y Arduino Con Arduino podemos lograr el uso de una tarjeta de memoria SD, es decir escribir y leer el contenido de esta, la conexión entre SD y Arduino se logra a través del protocolo SPI (Serial Peripherical Interface), por medio de solamente 4 pines digitales. . 178 Guía Teórico Práctica Aprende ARDUINO Figura 19-2. Pines de una tarjeta SD y Modulo SD para Arduino Figura 19-3. Arduino conectado a un Módulo SD. Desde el punto de vista del software se hace sencillo el manejo de este tipo de memorias SD, y más aun utilizando un módulo diseñado para contener y facilitar la conexión entre la tarjeta y Arduino, y como otros dispositivos existe una librería estándar para la construcción de sketches que permite manipular un SD desde Arduino, esta librería ya viene incluida en la distribución del IDE de Arduino por lo que no es necesario la descarga adicional. Cabe mencionar que la librería SD.h asume las siguientes conexiones entre la tarjeta SD y Arduino UNO: 179 5V y GND de la tarjeta SD a los respetivos pines en la placa Arduino. CS o SS de la tarjeta SD al pin 10 del Arduino, si se usa el Ethernet Shield usar pin 4. El pin MOSI o DI de la tarjeta SD conectado al pin 11 del Arduino. MISO o DO en la tarjeta SD debe conectarse la pin 12 del Arduino. El pin SCK o CLK debe conectarse la pin 13 de Arduino. Guía Teórico Práctica Aprende ARDUINO Al usar la versión MEGA las conexiones cambian, según las siguientes: 5V y GND de la tarjeta SD a los respetivos pines en la placa Arduino. CS o SS de la tarjeta SD al pin 53 del Arduino, si se usa el Ethernet Shield usar pin 4. El pin MOSI o DI de la tarjeta SD conectado al pin 11 del Arduino. MISO o DO en la tarjeta SD debe conectarse la pin 12 del Arduino. El pin SCK o CLK debe conectarse la pin 13 de Arduino. A continuación se describirán algunas de las funciones básicas que están incluidas en la librería SD.h, estudie bien su acción y uso: Funciones de Configuración SD.begin(): inicializa la librería y la tarjeta SD. Opcionalmente admite un parámetro para especificar el número de pin de la placa Arduino que se usara para la conexión SS con la tarjeta SD. Si no se especifica nada, la librería asume el uso del pin digital 10, pero en ocasiones será necesario especificar otro según el Escudo o Shield a usar, por ejemplo al usar la SD integrada al Escudo Ethernet de Arduino, se debe especificar el pin 4 como SS para la tarjeta SD. Esta función debe incluirse dentro de la función Setup(). Funciones de Manipulación SD.mkdir(): crea una carpeta en la tarjeta SD, como único parámetro tiene el nombre de la carpeta a crear, si la carpeta ya existe, esta instrucción no hace nada. SD.open(): “abre” un archivo en la tarjeta SD, abrir significa poder empezar a leer y/o editar ek contenido del archivo abierto. Un parámetro de esta función es el nombre del archivo, si este no existe en la SD será creado automáticamente por la función. Es de importancia conocer que esta función devuelve un parámetro tipo objeto FILE, que representa al archivo abierto, y que es este objeto el que debe ser manipulado posteriormente en el sketch a través de la funciones de la librería. Así por ejemplo el estamento miArchivo = SD.open(“prueba.txt”) abre o crea un archivo llamado “prueba.txt” en el directorio raíz de la tarjeta SD, y a la vez crea un objeto llamado miArchivo para ser manipulado posteriormente. miArchivo.print(): escribe el dato pasado como parámetro dentro del archivo abierto con el objeto miArchivo, es dato puede ser un “char” o cadena o un entero, además se puede incluir opcionalmente un segundo parámetro indicando el sistema de numeración del dato entero BIN, HEX o DEC. miArchivo.println(): exactamente lo mismo que a función anterior, pero añade automáticamente un retorno de carro y nueva línea después de escribir el dato. Una observación es que estas funciones no escriben físicamente el dato en la SD, para ello debe ejecutar una de las funciones a continuación: 180 Guía Teórico Práctica Aprende ARDUINO miArchivo.close(): cierra el archivo del objeto miArchivo, antes escribe físicamente en la tarjeta cualquier dato pendiente de grabar, no necesita parámetros. miArchivo.flush(): se asegura de escribir físicamente en la tarjeta cualquier dato pendiente de grabar en el archivo del objeto llamado miArchivo. Para leer datos de la tarjeta SD la librería dispone de las siguientes funciones: miArchivo.available(): comprueba si hay algún byte todavía por leer dentro del archivo del objeto llamado miArchivo, su valor de retorno es el número de bytes aun disponibles. miArchivo.read(): lee un byte del archivo del objeto miArchivo y avanza al siguiente byte, de manera que la próxima ejecución de la función lea ese siguiente byte. Su valor de retorno es el byte leído, o es -1 si ya no hay bytes por leer. Las anteriores son algunas de las funciones de la librería SD.h , existen algunas más cuyo estudio y uso de deja como investigación, para referencia puede consultar: http://arduino.cc/en/Reference/SD o http://www.ladyada.net/products/microsd/ A continuación se presentan algunos ejemplos sobre el uso de la librería SD.h en el manejo de una memoria SD por medio de Arduino, se asume la conexión entre la tarjeta y Arduino según la explicada anteriormente, si no se especifica otra conexión. EJEMPLO.SD01: En el siguiente ejemplo se demuestra cómo escribir una cadena de caracteres en un archivo en el directorio raíz de la memoria SD. /* *Ejemplo de escritura en SD -Escribe una cadena de caracteres fija en un archivo dentro del directorio raiz de la SD -Este ejemplo asume las conexiones: * SD --- Arduino UNO --- Arduino MEGA ** MOSI (CMD/pin2) --- pin 11 --- pin 51 ** MISO (DAT0/pin7)- pin 12 --- pin 50 ** CLK (SCK/pin5)- pin 13 --- pin 52 ** CS (SS/pin1)- pin 10 --- 53 created Nov 2010 by David A. Mellis modificado por O. Otoniel Flores@2013 Distrubucion Libre CC */ //Se incluye la libreria para manipular //la memoria SD #include <SD.h> //Creamos un objeto llamado miArchivo //para manipular el archivo abierto File miArchivo; //Funcion de seteo void setup() { //Comunicacion serial USB para monitoreo Serial.begin(9600); delay(4000);//espera para abrir le monitor serial del IDE Serial.print("Inicializando la tarjeta SD..."); 181 Guía Teórico Práctica Aprende ARDUINO delay(2000); // Configurar el pin que se utilizara como CS para la SD // 10 para la tarjeta UNO, 53 en la MEGA // 4 si se usa el Escudo Ethernet pinMode(10, OUTPUT); //pinMode(53, OUTPUT); //Arduino MEGA //inicializar y comprobar la tarjeta SD if (!SD.begin(10)) { Serial.println("...inicializacion fallo!"); return; } Serial.println("...OK."); // Se abre el archivo, para escritura, si no existiera en la SD se creara miArchivo = SD.open("prueba.txt", FILE_WRITE); // si se abrio correctamnte, escribir if (miArchivo) { Serial.print("Escribiendo en prueba.txt..."); miArchivo.println("Hola Mundo ... 1,2,3"); // cerrar y grabar le archivo: miArchivo.close(); delay(1000); Serial.println("finalizado."); } else { // si no se pudo abrir el archivo.. Serial.println("error al abrir prueba.txt!"); } } void loop() { // el archivo se creó en el setup //porque solo una vez de escribira //se re-escribirá cada vez que se resete el Arduino } //Fin del Sketch EJEMPLO.SD02: En el ejemplo anterior se vio como escribir datos fijos dentro de la tarjeta SD, pero estos datos pueden ser “dinámicos”, en este ejemplo se escribirá en un archivo de la tarjeta SD los datos provenientes en tiempo real desde un sensor análogo conectado al A5, como prueba se puede conectar un potenciómetro entre `5Vdc y GND con su pin central a la entrada análoga A5. /*EJEJMPLO.SD02 *Ejemplo de escritura en SD -Escribe caracteres provenientes de la lectura de un sensor analogo conectado al pin A5, en un archivo dentro del directorio raiz de la SD ***Se creara una funcion para escribir el la SD, esta se invocara desde el LOOP, cada cierto tipo y grabara el valor capturado del A5 -Este ejemplo asume las conexiones: * SD --- Arduino UNO --- Arduino MEGA ** MOSI (CMD/pin2) --- pin 11 --- pin 51 ** MISO (DAT0/pin7)- pin 12 --- pin 50 ** CLK (SCK/pin5)- pin 13 --- pin 52 ** CS (SS/pin1)- pin 10 --- 53 created 182 Nov 2010 by David A. Mellis Guía Teórico Práctica Aprende ARDUINO modificado por O. Otoniel Flores@2013 Distrubucion Libre CC */ //Se incluye la libreria para manipular la memoria SD #include <SD.h> //Creamos un objeto llamado miArchivo //para manupular el archivo abierto File archivoSensor; //Funcion de seteo void setup() { //pin A5 como entrada pinMode(A5,INPUT); //Comunicacion serial USB para monitoreo Serial.begin(9600); delay(4000);//espera para abrir el monitor serial del IDE Serial.print("Inicializando la tarjeta SD..."); delay(2000); // Configurar el pin que se utilizara como CS para la SD // 10 para la tarjeta UNO, 53 en la MEGA // 4 si se usa el Escudo Ethernet pinMode(10, OUTPUT); //Arduino UNO //pinMode(53, OUTPUT); //Arduino MEGA //inicializar y comprobar la tarjeta SD if (!SD.begin(53)) { Serial.println("...inicializacion fallo!"); return; } Serial.println("...OK."); } void loop() { //se captura el valor analogo (entre 0 y 1023) //del canal analogo A0 int lectura = analogRead(A0); grabarSD(lectura); // invoca la fucnion grabarSD delay(4000); //esribir un nuevo dato cada 4seg. } void grabarSD(int x) { // Se abre el archivo, para escritura, si no existiera en la SD se creara archivoSensor = SD.open("lecA0.txt", FILE_WRITE); // si se abrio correctamnte, escribir if (archivoSensor) { Serial.print("Escribiendo en lecA5.txt..."); archivoSensor.println(x); // cerrar y grabar le archivo: archivoSensor.close(); delay(100); Serial.print(x); Serial.println("...hecho."); } else { // si no se pudo abrir el archivo.. Serial.println("error al abrir el leca5.txt!"); } } //Fin del Sketch 183 Guía Teórico Práctica Aprende ARDUINO EJEMPLO.SD03: En este ejemplo se verá cómo podemos leer los datos guardados en una tarjeta, en este Sketch primero se guardaran 5 lecturas de una entrada analógica y luego el Arduino leerá el archivo en la SD y replica el contenido de este en el monitor serial. /*EJEJMPLO.SD03 *Ejemplo de escritura y lectura en SD -Escribe 5 lecturas provenientes de un sensor analogo conectado al pin A5, en un archivo dentro del directorio raiz de la SD, para despues leerles y mostrarlos en el MonitorSerial ***Se creara una funcion para escribir el la SD, esta se invocara desde el LOOP, cada cierto tipo y grabara el valor capturado del A5 -Este ejemplo asume las conexiones: * SD --- Arduino UNO --- Arduino MEGA ** MOSI (CMD/pin2) --- pin 11 --- pin 51 ** MISO (DAT0/pin7)- pin 12 --- pin 50 ** CLK (SCK/pin5)- pin 13 --- pin 52 ** CS (SS/pin1)- pin 10 --- 53 created Nov 2010 by David A. Mellis modificado por O. Otoniel Flores@2013 Distrubucion Libre CC */ //Se incluye la libreria para manipular //la memoria SD #include <SD.h> //Creamos un objeto llamado lecturas //para manipular el archivo abierto File lecturas; //Funcion de seteo void setup() { //pin A5 como entrada pinMode(A5,INPUT); //Comunicacion serial USB para monitoreo Serial.begin(9600); delay(4000);//espera para abrir le monitor serial del IDE Serial.print("Inicializando la tarjeta SD..."); delay(2000); // Configurar el pin que se utilizara como CS para la SD // 10 para la tarjeta UNO, 53 en la MEGA // 4 si se usa el Escudo Ethernet pinMode(10, OUTPUT); //pinMode(53, OUTPUT); //Arduino MEGA //inicializar y comprobar la tarjeta SD if (!SD.begin(10)) { Serial.println("...inicializacion fallo!"); return; } Serial.println("...OK."); } void loop() { grabarSD('*'); //grabar separador entre lecturas - note lo grabado en la SD for (int i=1; i <= 5; i++) 184 Guía Teórico Práctica Aprende ARDUINO { //se captura el valor analogo (entre 0 y 1023) //del canal analogo A5 int lectura = analogRead(A5); grabarSD(lectura); delay(4000); //escribir un nuevo dato cada 4seg. } ///***Los estamentos a continuacion son necesarios par leer //caracteres desde un archivo en la SD, directorio raiz. Serial.println("Abriendo el archivo para lectura:"); // re-open the file for reading: lecturas = SD.open("lecturas.txt"); if (lecturas) { Serial.println("los valores son="); //leer dato por dato desde el archivo y //escribirlos en el Monitor Serial. //hasta que ya no hayan datos disponibles: while (lecturas.available()) { Serial.write(lecturas.read()); delay(500); } // close the file: lecturas.close(); } else { // si no se pudo abrir el archivo: Serial.println("error aperturando lecturas.txt"); }//volver a capturar valores analogos ////*** }//Fin del programa principal ///Funcion para grabar un dato en un archivo //en la SD, directorio raiz void grabarSD(int x) { // Se abre el archivo, para escritura, si no existiera en la SD se creara lecturas = SD.open("lecturas.txt", FILE_WRITE); // si se abrio correctamnte, escribir if (lecturas) { Serial.print("Escribiendo en lecturas.txt..."); lecturas.println(x); // cerrar y grabar le archivo: lecturas.close(); delay(500); Serial.print(x); Serial.println("...hecho."); } else { // si no se pudo abrir el archivo.. Serial.println("error al abrir el lecturas.txt!"); } } //Fin del Sketch 185 Guía Teórico Práctica Aprende ARDUINO 20. Comunicación Ethernet con ARDUINO. La tarjeta Arduino es capaz de transferir información a través de las redes Ethernet, esto se logra por medio de un adaptador o Escudo Ethernet para Arduino, que está provisto de un Jack RJ45 y se comunica con Arduino vía protocolo SPI (se deja al lector investigar), en la figura podemos ver este Ethernet Shield. Figura 21-1. Escudo Ethernet y montado sobre el Arduino UNO. Al dotar a nuestro Arduino de un escudo Ethernet podemos diseñar sketches que intercambien información con otros terminales conectados a la misma red Ethernet y por ende al Internet, a continuación se describirán el uso de este tipo de comunicación, y se verán ejemplos de cómo Arduino se puede comunicar en red. Conceptos básicos de redes de datos. En una comunicación a través de una red Ethernet es necesario disponer se ciertas configuraciones en los equipos a comunicarse por medio de este tipo de redes de datos. A continuación se describen algunos conceptos que debemos conocer y que debemos setear en nuestra placa Arduino para que pueda acceder a redes Ethernet. Dirección IP: todo terminal conectado a una red Ethernet debe estar provisto por una dirección IP, esta es una etiqueta numérica formada por cuatro cifras, de valores entre 0 y 255, que identifica a la tarjeta de red un dispositivo (una computadora, una impresora, un Arduino Ethernet) dentro de y una red de tipo TCP/IP. Cada 186 Guía Teórico Práctica Aprende ARDUINO dispositivo debe poseer una dirección IP exclusiva para poder identificarse, un ejemplo de dirección IP podría ser: 66.249.92.10. IP privada y pública: Al momento de asignar la dirección IP a nuestro Arduino, nos surge la duda de si cualquier combinación de números es válida, la respuesta es no, debe ser una combinación de números valida según la red a la que queramos tener acceso. Así, si nuestra red es privada, es decir solo es accesible dentro de un grupo selecto de terminales, e deben usar IPs de tipo “privada”, ya que esta dirección no será accesibles desde una red pública: internet. Las IP privadas pueden ser iguales en diferentes redes privadas, pero cuando se desea conectar nuestra terminal a una red pública como Internet, se necesita asignarle una dirección pública y única, esta se denominara IP Publica. Un dato importante es que las IP Públicas son limitadas, todas las combinaciones posibles de los 4 campos numéricos IP de una IP. Por ejemplo el servidor de Google tiene la IP Publica http://173.194.67.103/ , ¿Cuál es la IP publica del sitio Web de tu institución? Dirección MAC: es una etiqueta numérica de 48 bits, que identifica a la tarjeta de red utilizada, que también es única en el mundo, esta dirección física es puesta por defecto por el fabricante de la tarjeta d red utilizada. Servidor DNS: Es un computador de acceso público que hace posible que los usuarios de la red Internet usemos nombres de dominio en lugar de las direcciones numéricas IP para acceder a un terminal. Configuración de la placa/shield Ethernet. Como se mencionó para poder brindarle acceso a nuestra tarjeta Arduino a una red Ethernet, se debe conectar una placa o escudo que permita esto. En los sketches se debe iniciar configurando los parámetros de esta tarjeta de red para Arduino, entre otras se debe asignar un IP y configurar el tipo de terminal que se utilizara: Servidor o Cliente. Cabe destacar que estas funciones son parte de la librería Ethernet.h incluida dentro de la distribución base del IDE Arduino Ethernet.begin(mac, ip, servdns, Gateway, subnet): esta función inicializa la tarjeta o escudo de red para nuestro Arduino, recibe los parámetros especificados como la IP que tendrá el Arduno, la dirección MAC, la dirección del servidor DNS, la dirección del Gateway o puerta de enlace y la máscara de subred a utilizar, todos estos parámetros se pasan a la función como arreglos numéricos . Normalmente no es necesario especificar todos los parámetros, sino que solo la IP y la MAC a usar, el Arduino asume los demás valores por defecto. Arduino como Servidor Ethernet La tarjeta Arduino puede trabajar como un servidor para redes Ethernet, ya sea un servidor FTP, TELNET, WEB, etc. Configurar el Arduino para brindar estos servicios es sencillo y la comunicación se realiza utilizando instrucciones muy similares a las usadas en la comunicación serial USB, a continuación se describen algunas funciones propias de la comunicación vía Ethernet. EthernetServer miServidor (Npuerto): esta función inicializa un objeto (variable) llamado “miServidor” dentro del Sketch para ser manipulado luego, y a través de este poder hacer todas las operaciones de escritura 187 Guía Teórico Práctica Aprende ARDUINO y lectura del servidor a crear en Arduino. El parámetro Npuerto se refiere a el número de puerto a usar para a conexión del servidor, por ejemplo 80 en servidores tipo WEB. Una vez ya credo el objeto “miServidor” usando la declaración anterior, se debe poner en marcha mediante la siguiente función: miServidor.begin(): hace que “miServidor” comience a escuchar las peticiones provenientes vía Ethernet y específicamente el puerto definido en su declaración. Esta instrucción se debe incluir dentro de la función setup(), no tiene parámetros ni valor de retorno. A partir de aquí, ya se pueden hacer cosas en el Sketch, por ejemplo enviar datos a todos los clientes conectados a nuestro servidor, usando estas funciones: miServidor.print() y miServidor.println: envía el dato especificado como parámetro a todos los clientes en ese momento a la placa Arduino Ethernet, el dato puede ser de cualquier tipo. Si se usa la versión println se añade automáticamente un retorno de carro y nueva línea al envió. Pero lo más interesante es tratar individualmente a cada una de las conexiones a nuestro servidor, recordando que un servidor en Arduino puede atender hasta 4 clientes simultáneos), y para esto se usa la función: miServidor.available(): devuelve (crea) un objeto del tipo “EthernetClient” cuando “miServidor” detecta una entrada de datos provenientes de algún cliente exterior. Este objeto representa la conexión establecida con este cliente. Pero antes este objeto debe ser declarado mediante la sintaxis EthernetClient miCliente (suponiendo el nombre miCliente). Una vez creado el objeto “miCliente” podremos comunicarnos con ese cliente particular, usando las funciones a continuación: miCliente.read(): devuelve un byte proveniente de la conexión “miCliente”, cada vez que se ejecute esta funcion, devolverá el siguiente byte proveniente de dicha conexión. Si ya no hay más byte disponibles, la función devolverá -1. Y para enviar datos específicos entre “miServidor” a “miCliente” se usan las siguientes funciones: miCliente.print(), miCliente.pirintln(): envían el byte especificado como parámetro hacia la conexión específica, se envía solo a este cliente y no a todos como las funciones anteriores. A continuación algunos ejemplos que ponen en demostración el uso de las funciones anteriormente descritas, recordando que se debe tener un Escudo Ethernet para Arduino y conectado a una red Ethernet local, además de otros terminales PCs o Arduinos. 188 Guía Teórico Práctica Aprende ARDUINO Arduino como Servidor Web El escudo Ethernet también permite que la tarjeta Arduino funcione como un servidor de páginas Web, específicamente para ser consultada desde un navegador desde cualquier computador conectada a la misma red de nuestro Arduino. Esto con el objetivo de, a través de la página WEB en Arduino, poder consultar estados de la tarjeta desde una computadora remota, también es posible controlar el estado de salidas de Arduino desde una página web accedida desde una computadora conectada a la red Ethernet. EJEMPLO ET01: Monitoreo de Arduino como Servidor WEB, el siguiente sketch configura el uso de Arduino como un servidor de páginas Web, permitiendo monitorear desde el navegador de una computadora conectada a la misma red Ethernet que Arduino, en este ejemplo se demuestra como monitorear el estado de pines análogos y digitales, que en realidad pueden ser sensores de temperatura, presencia, luz, sonido, etc. En este ejemplo se “verán” los estados del pin analógico A0, y del pin digital 2 de Arduino, los cuales se desplegaran en una página web consultada por el navegador desde una PC dentro de la misma red LAN (o internet). Se recomienda la conexión de un potenciómetro o LDR a la entrada A0 para una mejor lectura de las variaciones de la entrada A0, así como conectar al pin digital un pulsador o interruptor. Descargue y conecte su Arduino a la red Ethernet, luego acceda desde otro dispositivo (PC, Tablet o Teléfono Inteligente) a la IP de Arduino por medio de un navegador, observe el comportamiento de los pines. /* Ejemplo Ethernet 1 – Estacion de Monitoreo WEB Desde un navegador de una PC podemos acceder a ver el estado de pines analogicos y digitales de Arduino created 18 Dec 2009 by David A. Mellis, modified 9 Apr 2012 by Tom Igoe modified 20 Mar 2013 by John Boxall modificado por: otoniel.flores@mail.utec.edu.sv Julio2013 */ #include <SPI.h> #include <Ethernet.h> IPAddress ip(192,168,1,177);// ip de la placa Arduino, debe ser unica en la red LAN o Internet byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // debe ser unica en la red LAN o Internet EthernetServer server(80); //decile a Arduino que funcionara como Servidor Web (puerto 80) int sensorAna = 0; int sensorDig = 2; void setup() { // Iniciar la conecion del escudo y el servidor Ethernet.begin(mac, ip); server.begin(); pinMode(sensorDig, INPUT); // pin digital como entrada } 189 Guía Teórico Práctica Aprende ARDUINO void loop() { // escuchar por clientes nuevos (requerimiento web desde un terminal) EthernetClient client = server.available(); if (client) // ¿existe alguna peticion WEB? { // requerimiento http? boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n' && currentLineIsBlank) { // a continuacion se genara la pagina WEB en HTML, note que // esta “inscrutado” dentro del Sketch // para mas sobre HTML se recomienda http://www.w3schools.com/html/default.asp client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); // adicionar una etiqueta, para refrescar pagina cada 1 seg client.println("<meta http-equiv=\"refresh\" content=\"1\">"); // enviar el valor de los sensores analogo y digital int lecturaAna = analogRead(0); client.print("Entrada Analoga A0 = "); client.print(lecturaAna); client.println("<br />"); boolean estadoDig = digitalRead(sensorDig); client.print("Entrada Digital 2 = "); client.print(estadoDig); client.println("<br />"); client.println("</html>"); break; } if (c == '\n') { // comienza una nueva linea currentLineIsBlank = true; } else if (c != '\r') { // se recibe un caracter nuevo currentLineIsBlank = false; } } } // dar tiempo al navegador de recibir el dato delay(1); // cerrar la coneccion client.stop(); } } // fin del sketch 190 Guía Teórico Práctica Aprende ARDUINO EJEMPLO ET02: Control de actuadores de salidas de Arduino por medio de página WEB, el siguiente sketch configura el uso de Arduino como un servidor de páginas Web, permitiendo activar o desactivar entradas digitales desde el navegador de una computadora conectada a la misma red Ethernet que Arduino, en este ejemplo se demuestra como conmutar un LED conectado al pin 8 de la tarjeta. Recordando que este ejemplo es expandible a más salidas y otros dispositivos actuadores como Lámparas, Timbre, Válvulas, etc. Descargue y conecte su Arduino + Escudo Ethernet a una red Ethernet (LAN o Internet), luego acceda desde otro dispositivo a la IP de Arduino por medio de un navegador, active y desactivé el botón de la pagina /* * EJEMPLO ARDUINO como WEB SERVER * Control web de pines digitales * en este ejemplo LED conectado al PIN 8 * a través de botones web. * optimizado por: ooflores@mail.utec.edu.sv * cc-distribucion libre */ //incluir las librerías para el Escudo Ethernet #include <SPI.h> #include <Ethernet.h> //definir la MAC y la IP del Arduino, debe ser unica dentro de la misma red para cada Arduino byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 192,168,1,177 }; //definir un objeto servidor y un objeto cliente EthernetServer miservidor(80); //80 puerto servicios WEB EthernetClient micliente; // Objeto para el cliente WEB //Algunas variables boolean lineaActualEstaVacia = true; char caracter; String peticion=""; void setup() { pinMode(8, OUTPUT); //pin a usar como salida Ethernet.begin(mac, ip); //inicializar el escudo ethernet miservidor.begin(); //iniciar el servidor Arduino } //programa principal-ejecución cíclica infinita void loop() { int i; micliente = miservidor.available(); //capturar peticion del cliente if (micliente == true) //si hay una peticion del cliente { while (micliente.connected()==true) //mientras el cliente siga conectado { if (micliente.available()>0) //leer los datos provenientes del cliente { caracter = micliente.read(); //leer dato a dato if (peticion.length() < 30) //concatenar en una sola frase { peticion.concat(caracter); } if (caracter == '\n' && lineaActualEstaVacia == true) //termino de llegar la peticion { // responder con el encabezado html estandar // a continuacion se genara la pagina WEB en HTML, note que // esta “inscrutado” dentro del Sketch 191 Guía Teórico Práctica Aprende ARDUINO // para mas sobre HTML se recomienda http://www.w3schools.com/html/default.asp micliente.println("HTTP/1.1 200 OK"); micliente.println("Content-Type: text/html"); micliente.println("Connnection: close"); micliente.println(""); micliente.println("<!DOCTYPE HTML>"); //a continuacion la pagina html de respuesta micliente.println("<html>"); //titulo de la pagina micliente.println("<font color='blue'><h1>Control Domotica via WEB</font></h1>"); micliente.println("</title><body>"); //a continuación se forman los botones micliente.println("<br/>"); micliente.println("<form>");//inicia el formulario //aqui se declaran los botones y los valores que retornaran //un boton con el nombre OFF y que retornara la sentencia pin8=0 micliente.println("<button type='submit' name='pin8' value='0'>OFF</button>"); //un boton con el nombre ON y que retornara la sentencia pin8=1 micliente.println("<button type='submit' name='pin8' value='1'>ON</button>"); //si deseamos mas botones u otro tipo de ingreso de datos //aqui lo declaramos micliente.println("</form>"); //termina el formulario //A continuación se verifica la petición realizada //por el cliente, es decir si a presionado el boton //ejecutar una accion en los pines de Arduino if (peticion.indexOf("pin8=0")>0) //verifica si el boton OFF se presiono { micliente.println("El led conectado al Pin8 está Apagado !! <br/>"); digitalWrite(8,LOW); } if (peticion.indexOf("pin8=1")>0) //verifica si el boton ON se presiono { micliente.println("El led conectado al Pin8 esta Encendido !! <br/>"); digitalWrite(8,HIGH); } //fin del verificación de los botones ///////////////////////////// //finalizar la pagina html micliente.println("<br/>"); micliente.println("<br/>"); micliente.println("<font size='2' face='georgia' color='maroon'>copyleft@UTEC2013</font>"); micliente.println("</html>"); //termina la pagina htlm break; } if (caracter == '\n') //si termino la peticion del cliente { lineaActualEstaVacia = true; }else if (caracter != '\r'){ lineaActualEstaVacia = false; } } } peticion=""; micliente.stop(); //cerrar la conexion del cliente } } //fin del SKETCH – cc 192 Guía Teórico Práctica Aprende ARDUINO 21. Comunicación Bluetooth con ARDUINO. En esta sección se explicara cómo por medio de la tarjeta Arduino podemos comunicarnos a través del protocolo Bluetooth con otras tarjetas y dispositivos que disponga de una interface de este tipo. Se revisara el concepto de operación de esta forma de comunicación y de como de envían y reciben datos desde Arduino. Que es Bluetooth? Es una forma de comunicación inalámbrica usando en dispositivos móviles o de escritorio para e intercambio de información digital, específicamente el nombre “Bluetooth” hace referencia a una especificación industrial, también conocido como estándar IEEE 802.15.1, que define características de técnicas y de funcionamiento de redes inalámbricas de corto alcance. Su principal uso es brindar un protocolo de comunicación entre dispositivos electrónicos de consumo, específicamente para intercambio de información sin necesidad de realizar compleja configuraciones, además de ser enlaces próximos de máximo una decena de metros. Hoy en día es común encontrar conectividad Bluetooth en casi cualquier dispositivo electrónico móvil, es por eso que aquí estudiaremos como Arduino puede también hacer uso de este tipo de comunicación, para muchas aplicaciones desde el control remoto hasta el envió de reportes periódicos de sensores a una PC. En esta obra no nos centraremos en el intricado estudio del protocolo, detalles técnicos de electrónica y software, sino que explicaremos como configurar nuestro Arduino por medio del Sketch para poder intercambiar información por medio de interfaces Bluetooth. Figura 22-1. La conectividad Bluetooth 193 Guía Teórico Práctica Aprende ARDUINO Arduino y Bluetooth. Dotar a la tarjeta Arduino de conectividad Bluetooth, implica conectar un módulo periférico a esta, y así poder enviar y recibir información con otros dispositivos que tengan disponible este tipo de conexión. En el mercado ya se disponen de muchos periféricos que brindan una interface Bluetooth a nuestro Arduino, estos módulos se comunican con Arduino por medio de su puerto Serie (Tx, Rx), por lo que es muy sencillo el envío y recepción de datos, es decir que estos módulos se encargan de manejar la conversión y protocolo de forma trasparente para Arduino, en la figura 21-2 podemos apreciar el modulo modelo HC-05 muy popular, de bajo costo y sencillo de usar con Arduino, además se pueden apreciar también las terminales de conexión del módulo HC-05, además se identifica la descripción de cada una de estas, debemos notar que los pines Tx, Rx son los que brindaran la conexión Arduino, los demás son pines de alimentación del módulo, a partir de esta información se deduce que desde el punto de vista del Sketch, la transferencia de información se realiza a través de las funciones e instrucciones que se usan para el manejo de la comunicación Serial de Arduino. Figura 22-2. Módulo Bluetooth para Arduino, modelo HC-05 194 Guía Teórico Práctica Aprende ARDUINO Según lo anterior, la conexión electrónica de un módulo Bluetooth y la tarjeta Arduino es sencilla, ver la figura 22-3, solo necesita dos pines digitales: Tx y Rx, y desde el Sketch el intercambio de información es sencillo, y se ocuparan las mismas funciones que en la comunicación serial, con la diferencia de que si deseamos usar pines diferentes a los que ya en predefinidos en Arduino como Tx y Rx, debemos crear un puerto serie virtual con otros pines de conexión, usando la función: SoftwareSerial miSerial(rxpin, txpin): esta instrucción abre y configura un puerto serie de Arduino en los pines especificados como parámetros, rxpin y txpin son los números de pines digitales que se convertirán en Rx y Tx del nuevo puerto serial, y que servirán para conectar el modulo Bluetooth. La etiqueta miSerial es el nombre que se le asignara a ese nuevo puerto creado. Figura 22-3. Conexión entre Arduino y el Modulo Bluetooth HC-05 Otro dato importante es que la trasferencia de datos debe seguir cierto procedimiento, tal como cuando se emparejan los Bluetooth de dos teléfonos móviles, por lo tanto este proceso se debe hacer desde el dispositivo a conectar con el Bluetooth Arduino, además la transmisión de paquete de datos hacia el Arduino se puede manejar desde una aplicación para este tarea desde la PC, Tablet o Teléfono Móvil, bajo dispositivos con SO Androide se recomienda el uso de la aplicaciones como: ArduDroid o el BTRelCtrl que son aplicativos disponibles gratuitamente en el Play Store de Google. EJEMPLO BT01: Demostración del envío y recepción de datos entre Arduino y un dispositivo electrónico con Bluetooth, (teléfono móvil, Tablet o computador) se usa la conexión de la figura 22-3 donde los pines Tx y Rx del módulo Bluetooth se conectan al pin 2 y 3 de Arduino donde se crea vía Sketch un puerto serial virtual. Este Sketch replica los datos recibidos desde el Bluetooth en el Monitor Serial de la computadora y desde el dispositivo externo se deben enviar datos a Arduino vía una aplicación para esta función, en SO Android se recomienda la aplicacion BTRelCtrl. – disponible en el Google Play. /* * Ejemplo de Demostracion * de envio y recepcion de datos * via Bluetooth, los datos recibidos y * a enviar via Monitor Serial del PC * ..clave de pariamiento BT: 1234 * … se recomeinda el uso de App BT Rel Ctrl en SO Androide */ 195 Guía Teórico Práctica Aprende ARDUINO // incluir la libreria para emular una coneccion serial // donde conectar el Modlo BT #include “SoftwareSerial.h” const int rxpin = 2; // pin usado para Recibir RX const int txpin = 3; // pin usado para Transmitir TX SoftwareSerial bluetooth(rxpin, txpin); // configurar una nueva coneccion serial llamada bluetooth void setup() { Serial.begin(9600); // inicializar el serial USB bluetooth.begin(9600); // inicializar el serial Bluetooth Serial.println("USB listo!"); Serial.println("Bluetooth listo!"); } void loop() { // se verificara si se recibe un caracter por la conexion serial // del Bluetooth if (bluetooth.available()) { // si hay algun dato, llerlo y asigarlo a la variable dato char dato = (char)bluetooth.read(); Serial.write(c); // imprimir en el Monitor Serial del IDE, el caracter recibido } } //Recuerde abrir el Monitor Serial del PC, y haber realizado el pareamiento //del bluetooth en su dispositivo movil o tablet. //Fin del Sketch Al ejecutar el ejemplo anterior, debe abrir la aplicación en Androide y presionar los botones de la APP y verifique en el Monitor Serial los comandos enviados por cada uno de dichos botones. Este ejemplo es la base para la trasmisión de información vía Bluetooth, el resto es dedicar tiempo a la implementación específica del control de acciones de la tarjeta Arduino desde un dispositivo. 196 Guía Teórico Práctica Aprende ARDUINO Los ejemplos vistos en las secciones anteriores solo deben ser el inicio de su estudio de conectividad Arduino, se recomienda continuar indagando en el amplio mundo de Arduino y el desarrollo de circuitos aplicados en las áreas de Computación Física, Robótica y Domótica. El autor recomienda dar un vistazo al material de estudio referenciado en la bibliografía, y que esto solo sea el inicio de una gran aventura por el mundo Arduino ¡ ¡Nunca dejes de Aprender! 197 Guía Teórico Práctica Aprende ARDUINO Bibliografía Cairo, O. (2011). Metodologia de la Programacion. Mexico: Alfaomega. Commons, C. (1 de Octubre de 2004). Creative Commons España. Recuperado el 1 de Abril de 2013, de http://es.creativecommons.org/blog/licencias/ Equipo Arduino. (1 de mayo de 2013). Arduino. Recuperado el 12 de Diciembre de 2012, de www.arduino.cc Evans, B. (2011). Beginning Arduino Programming. New York: Apress. Galeano, G. (2009). Sistemas Embebidos. Mexico: Alfaomega. Karvinen, K. (2012). Make: Arduino Bots. USA: O'reilly. Margolis, M. (2013). Arduino Cookbook. Los Angeles: O'reilly. Mikeln, J. (2012). Bascom AVR. Ljubljana: Ax Electronica. Monk, S. (2012). Arduino + Android. New York: Mac Graw Hill education. Monk, S. (2013). 30 Arduino Projects. New York: Mc Graw Hill Education. Premeaux, E. (2012). Arduino projects to save the world. New York: Apress. Purdum, J. (2012). Beginning C. New York: Apress. Technologies, A. L. (1 de 1 de 2005). Lear Adafruit. Recuperado el 15 de Enero de 2013, de http://learn.adafruit.com/ Torrente, O. (2013). Curso Practico de Formacion. Madrid: Libros RC. Warren, J. D. (2011). Arduino Robotics. USA: Apress. Wheat, D. (2011). Arduino Internals. New York: Apress. 198 Guía Teórico Práctica