Kitabı oku: «Taller de Arduino. Experimentando con Arduino MKR 1010»

Yazı tipi:



Taller de Arduino

Experimentando con Arduino MKR 1010

Segunda edición, 2021

© 2021 Germán Tojeiro Calaza y Gerardo Reino Bértoa

© 2021 MARCOMBO, S. L.

www.marcombo.com

Diseño de cubierta: ENEDENÚ DISEÑO GRÁFICO

Maquetación: Giancarlo Salinas

Correctora: Nuria Barroso

Directora de producción: M.a Rosa Castillo Producció del ebook: booqlab

«Cualquier forma de reproducción, distribución, comunicación publica o transformación de esta obra solo puede ser realizada con la autorización de sus titulares, salvo excepción prevista por la ley. Diríjase a CEDRO (Centro Español de Derechos Reprográficos, www.cedro.org) si necesita fotocopiar o escanear algún fragmento de esta obra».

ISBN: 978-84-267-3235-4

A todas las personas afectadas directa o indirectamente por la COVID-19.

A Marga Abeal, por su sonrisa.

Índice

Prólogo

Agradecimientos

1. Empezando con Arduino MKR

1.1 ¿Qué es Arduino y para qué sirve?

1.2 Configuración e instalación

1.2.1 Instalación del entorno de desarrollo

1.2.2 Instalación de controladores para el MKR 1010

1.3 Una primera práctica: parpadeo de un LED

1.4 La familia Arduino MKR

2. El lenguaje de programación de Arduino

2.1 Introducción al concepto de programación

2.2 Cuerpo de un programa en Arduino

2.2.1 Estructuras

2.2.2 Variables

2.2.3 Operadores aritméticos, lógicos y booleanos

2.2.4 Estructuras de control: condicionales y ciclos

2.3 Funciones

2.4 Librerías

3. Transmisión en serie. Pines analógicos y digitales

3.1 Monitor serie

3.2 Pines digitales

3.2.1 Funcionamiento de los interruptores, pulsadores y potenciómetros

3.2.2 Memoria FlashStorage

3.2.3 Modulación por amplitud de pulsos PWM

3.2.4 Funcionamiento de un pequeño altavoz

3.2.5 Introducción a las interrupciones en Arduino

3.3 Entradas analógicas

4. Sensores y actuadores

4.1 Sensor de temperatura DS18B20

4.2 Relé para controlar dispositivos de corriente alterna

4.3 Sensor ultrasonidos HC-SR04

4.4 Servomotor

4.5 Termómetro de infrarrojos MLX90614

4.6 Sensor micrófono

4.7 Control remoto y receptor IR

4.8 Sensor de luz LDR

4.9 Detector de obstáculos con IR

4.10 Pantallas gráficas TFT

5. Comunicaciones inalámbricas Bluetooth

5.1 Comunicaciones inalámbricas Bluetooth

5.1.1 Tipos de módulos Bluetooth

5.1.2 Comandos AT

5.1.3 Conexión y configuración de Bluetooth HC-05 a MKR 1000

5.2 Control de un led con BlueTerm

5.3 App Inventor 2 y MKR 1010

5.3.1 Funcionamiento básico de App Inventor 2

5.3.2 Encendido y apagado de un led

6. Extender Arduino MKR con shields

6.1 Arduino MKR env shield

6.2 Arduino MKR relay proto shield

6.2.1 EL RTC interno del MKR

6.2.2 Aplicación completa con RTC y Shield Relay

6.3 Arduino MKR motor shield

6.3.1 Servomotores

6.3.2 Motores DC

7. El sistema grove y sus módulos básicos

7.1 El sistema grove

7.2 Práctica 7.1: Funcionamiento de un led grove

7.3 Práctica 7.2: Funcionamiento de un pulsador grove con zumbador

7.4 Práctica 7.3: Funcionamiento de un potenciómetro grove

7.5 Práctica 7.4: Funcionamiento de un micrófono grove

7.6 Práctica 7.5: Funcionamiento de un sensor de contacto

7.7 Práctica 7.6: funcionamiento de la LDR grove

7.8 Práctica 7.7: Funcionamiento del sensor de temperatura

7.9 Práctica 7.8: Funcionamiento del LCD grove

7.10 Práctica 7.9: El módulo relé grove

7.11 Práctica 7.10: El RTC (reloj en tiempo real)

7.12 Práctica 7.11: El módulo PIR grove

7.13 Práctica 7.12: El módulo DHT grove

7.14 Práctica 13: El módulo humedad grove

7.15 Práctica 14: El módulo display Oled 1.12”

7.16 Práctica 7.15: el módulo display triple color E-INK 1.54”

8. IoT Internet de las cosas

8.1 Introducción al internet de las cosas

8.2 El origen del internet de las cosas

8.3 ¿Qué es el internet de las cosas?

8.4 Comunicación IoT

8.4.1 Comunicaciones “dispositivo a dispositivo”

8.4.2 Comunicaciones “dispositivo a la nube”

8.4.3 Comunicaciones “dispositivo a puerta de enlace”

8.4.4 Comunicaciones “intercambio de datos a través del back-end”

8.5 El mercado

8.6 Aplicaciones del IoT

8.7 Protocolos de comunicación

8.7.1 Entorno doméstico

8.7.2 Entorno industrial

8.8 Plataformas IoT

8.8.1 Thingspeak

8.8.2 IFTTT

8.8.3 THINGER.IO

8.8.4 ADAFRUIT.IO

8.8.5 Blynk

9. Arduino MKR 1010 e IOT

9.1 Características wifi del 1010

9.1.1 La librería WiFiNINA

9.1.2 Escanear redes inalámbricas wifi

9.1.3 Implementar un simple control de ledes por wifi

9.2 Monitor continuo de casos de Covid-19 en España

9.3 ADAFRUIT.IO

9.3.1 Feeds

9.3.2 Dashboard

9.3.3 Control de un led inalámbricamente

9.3.4 Visualización remota de variables ambientales

9.4 Automatización con IFTTT

9.5 Trabajar con ThingSpeak

10. Arduino MKR 1010 + Blynk

10.1 ¿Cómo funciona Blynk?

10.2 Cómo controlar varias placas en un mismo proyecto

10.3 Cómo configurar placas diferentes en un mismo proyecto

10.4 Comunicación entre placas

11. Lorawan y Arduino MKR 1300

11.1 Arduino MKR 1300

11.2 Comunicación entre dos Arduino MKR 1300

11.3 RAK 7258. GATEWAY LORAWAN.TTN

11.4 Envío de datos de temperatura a TTN

12. Los Bricks y Arduino 1010

12.1 Bricks

12.2 Bricks y Arduino MKR 1010

12.3 Bricks, Arduino MKR 1010 y la nube

12.4. Visualización de valores del DHT11 en el puerto Serie.

Prólogo

Después de muchas ideas, proyectos, tareas inacabadas, idas y vueltas y embrollos que fueron constantes a lo largo de 2019, Gerardo y el presente que redacta estas líneas, decidimos darle una vuelta definitiva a esa idea embrionaria de realizar un nuevo libro de Arduino. En la feria de SIMO Educación 2019, durante la primera semana de noviembre, nos pusimos serios y con el ceño fruncido comenzamos a darle forma a este libro. ¿Alee, otro libro de Arduino? Como si no hubiera cientos de ellos en las librerías técnicas, además de miles de tutoriales por YouTube.

Si nos ponemos a ello, deberíamos darle un acento propio e innovador. ¡Qué bien suena la frase! Gerardo y yo estábamos inmersos en una de esas discusiones tontas sobre la nueva familia de Arduino MKR y si esta, realmente, iba a sustituir al clásico Arduino UNO. Tomando lo que, si mal no recuerdo, era la segunda caña de cerveza en el bar del hotel, cuando empezamos a darle vueltas a la idea de realizar una segunda edición del libro anterior, y en un verdadero ataque de ilusión nos preguntamos: ¿y por qué no nos arriesgamos y empezamos a exponer este tema de Arduino desde cero, pero abordándolo desde una nueva perspectiva más ambiciosa? ¿Por qué no empezamos a escribir prácticas y proyectos utilizando el Arduino 1010 de la familia MKR? Los fundamentos básicos son los mismos que en Arduino UNO, el precio de Arduino MKR 1010 es similar, pero su potencia infinitamente mayor. Y ya puestos, por qué no diseñar algún proyecto sencillo con Arduino MKR 1300 y exponer conceptos nuevos sobre LoRaWAN. Además, y ya que estamos, por qué no hacerlo todo con tecnología de componentes Groove, que nos va a evitar el cableado engorroso y, sobre todo, esos gráficos de fritzing tan liosos. En ese punto de la conversación, Gerardo esbozó una amplia sonrisa, ya que sería el encargado de realizar los gráficos del libro. Finalmente, y tras dos horas de palique y cuatro cañas, apostamos por dedicar un capítulo a los bricks con Arduino y IoT, sumamente didáctico y triunfando en las escuelas alemanas como un sistema tipo Lego de aprendizaje de la electrónica. Hasta ahora, no existe ningún libro parecido con estas novedades. El propósito fundamental del futuro libro sería el de mostrar al lector otras cosas, otras vías, otras plataformas relacionadas con Arduino que simplifiquen la tarea de diseñar y proyectar electrónica. Crucemos los dedos y empecemos.

Germán Tojeiro Calaza

Gerardo Reino

Profesores de electrónica (Carballo, La Coruña)

Julio de 2020

Agradecimientos

En primer lugar, agradecer a Ana y Abel de Maker Store by ALLNET, en Carballo, el apoyo técnico y la aportación de material educativo de bricks cuyo contenido se expone en el capítulo 12.

Y como viene siendo habitual en todas mis publicaciones a lo largo de estos últimos años, agradecer nuevamente el apoyo técnico incondicional de José Abelenda García. En este libro, concretamente, la redacción y revisión del capítulo 11.

CAPÍTULO 1
Empezando con Arduino MKR

En el primer capítulo vamos a acercarnos a Arduino MKR y a la instalación de su entorno de desarrollo (a partir de ahora: IDE). Se explicará el Arduino más básico desde nuestro punto de vista: El modelo MKR 1010. Más adelante, se describirá a toda su familia, por así decirlo. Primeramente, se trabajará con el más versátil y se examinarán sus características principales y se llevará a cabo una primera práctica sencilla. Con posterioridad, podrá comprobar que el modelo 1010 tiene hermanos mayores y menores. Por último, se recomendarán algunas herramientas, tanto de software como de hardware, para que puedan hacer realidad sus proyectos electrónicos.

1.1 ¿Qué es Arduino y para qué sirve?

Arduino es una plataforma de electrónica abierta (open hardware) para la creación de prototipos basada en software y hardware libre. Se creó para artistas, diseñadores, aficionados y cualquier interesado en crear entornos u objetos interactivos.

Arduino puede tomar información y datos del entorno a través de sus pines de entrada por medio de toda la gama de sensores que existen en el mercado. En base a ello, puede usarse para controlar y actuar sobre todo cuanto le rodea; como, por ejemplo, luces, motores y otro tipo de actuadores. El microcontrolador de la placa Arduino se programa mediante un sencillo lenguaje de programación basado en C/C++ y un entorno de desarrollo (IDE) que responde a las especificaciones de open software. Los proyectos hechos con Arduino pueden ejecutarse sin necesidad de conectarlo a un ordenador, si bien tienen la posibilidad de hacerlo y comunicarse con diferentes tipos de software (p. ej., Flash, Processing, MaxMSP, etc.).

Se llama open hardware a los dispositivos de hardware cuyas especificaciones y diagramas esquemáticos son de acceso público, ya sea bajo algún tipo de pago o de forma gratuita. Se debe recordar en todo momento que libre no es sinónimo de gratis. El hardware libre forma parte de la cultura libre.

Se llama open software al tipo del software que respeta la libertad de los usuarios sobre su producto adquirido y, por tanto, una vez obtenido puede ser usado, copiado, estudiado, modificado y redistribuido libremente.

Un microcontrolador (abreviado μC, UC o MCU) es un circuito integrado programable, capaz de ejecutar las órdenes grabadas en su memoria. Está compuesto de varios bloques funcionales, los cuales cumplen una tarea específica. Un microcontrolador incluye en su interior las tres principales unidades funcionales de un ordenador: unidad central de procesamiento, memoria y periféricos de entrada/salida.

Arduino sirve para implementar cualquier idea que se proponga realizar. Por ejemplo, puede pensar en automatizar el control de su terrario, o en construir un pequeño robot, tipo auto, que evite objetos y que suba las escaleras de su casa. Este último caso, revoloteó por mi cabeza hace algunos meses; pero cuando miré su precio en Internet, me pareció excesivo. Así que me propuse realizar sin ayuda (DIY, o “hágalo usted mismo”) las carcasas de los robots. ¿Y cómo? Pues adquiriendo un kit para mi impresora 3D delta Anycubic (figura 1.1), tras lo que me di cuenta de que su placa controladora está basada en un tipo de Arduino, por lo que su entorno de programación me resultaba familiar.

Le recomiendo que visite la página http://proyectosconarduino.com/robots/otto-diy/. Trata sobre el robot OTTO (figura 1.2), que es un robot pensado para ser armado de forma muy fácil e intuitiva y es ideal para dar los primeros pasos con sus hijos en la programación con Arduino y la robótica educativa, ya que requiere pocas piezas, no necesita soldadura y se puede programar en un entorno gráfico como “mBlock” (busque esta palabra en Google y descubrirá un mundo nuevo). Las piezas del robot (cuerpo y piernas) se pueden imprimir con una impresora 3D. Realmente, el cerebro de este robot es un tipo de Arduino denominado NANO, de tal manera que aprendiendo lo expuesto en este libro se puede adentrar sin miedo en el terreno de la robótica.

En definitiva, las posibilidades de Arduino son inmensas y, además, todos los días aparecen en la red aplicaciones de lo más insospechado y curioso. Además, si se cansa del terrario o del robot, puede reutilizar la placa reprogramable para otros nuevos proyectos.

En la figura 1.3 se puede observar la apariencia de un Arduino MKR 1010. Es la placa competidora del clásico Arduino UNO (siempre desde nuestro punto de vista y perfectamente opinable según otros). Cabe en la palma de la mano y cuesta alrededor de 34 euros (la empresa Allnet Ibérica [www.allnet.es] tiene un convenio con el sector educativo, de tal manera que si lo adquiere para un centro educativo podrá beneficiarse económicamente). Con este modelo 1010 se realizarán la mayoría de proyectos de este libro.

Está equipado con un módulo ESP32 hecho por u-blox. Esta placa tiene como objetivo acelerar y simplificar la creación de prototipos de aplicaciones de IoT basadas en wifi gracias a la flexibilidad del módulo ESP32 y su bajo consumo de energía. La placa está compuesta por tres bloques principales:

* SAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits.

* Wifi IEEE® 802.11 b/g/n u-blox serie NINA-W10 de baja potencia de 2.4 GHz.

* ECC508 Crypto Authentication.

El MKR 1010 incluye potencia de cómputo de 32 bits, un rico conjunto usual de interfaces de E/S y wifi de baja potencia con un Cryptochip para una comunicación segura mediante el cifrado SHA-256. Además, ofrece la facilidad de uso del software Arduino (IDE) para el desarrollo y la programación de código. Todas estas características hacen de esta placa la opción preferida para los proyectos de IoT en una forma compacta sin necesidad de añadir ningún tipo de shield como en el caso del Arduino UNO. Su puerto USB se puede utilizar para suministrar alimentación (5 V) a la placa. Tiene un circuito de carga Li-Po que permite que funcione con energía de la batería o con una fuente externa de 5 voltios, cargando la batería Li-Po mientras funciona con energía externa. El cambio de una fuente a otra se hace automáticamente. A diferencia de la mayoría de las placas Arduino, el MKR 1010 funciona a 3.3 V. El voltaje máximo que pueden tolerar los pines de E S es 3.3 V. La aplicación de voltajes superiores a 3.3 V a cualquier pin de E/S podría dañar la placa. Si bien la salida a dispositivos digitales de 5 V es posible, la comunicación bidireccional con dispositivos de 5 V necesita un cambio de nivel de voltaje adecuado.

En la figura 1.4 se observa el pineado completo del Arduino MKR 1010. Dispone de 15 entradas/salidas digitales. También dispone de 6 pines de entrada analógicos que trasladan las señales a un conversor analógico/digital de 10 bits. Además, dispone (y esto es novedoso en el mundo clásico de Arduino) de una salida digital/analógica (DAC) localizada en el pin AO. Si tiene nociones de electrónica, le adelanto que, además, posee los siguientes pines especiales:

* RX y TX: Se usan para transmisiones serie de señales TTL.

* Número amplio de interrupciones externas.

* PWM: Dispone de 12 salidas destinadas a la generación de señales PWM de hasta 8 bits.

* SPI: Posibilidad de comunicarse mediante el protocolo SPI (útil para pantallas TFT u OLED).

* I2C: Posibilidad de utilizar este protocolo I2C (útil para sensórica o interface Grove).

Por otra parte, el 1010 tiene un RTC (reloj en tiempo real) incluido en la propia placa. Esta característica simplifica muchos proyectos en los que precise tener en cuenta el tiempo.

Por último y no menos importante, hay que señalar la potencia intrínseca de este modelo en cuanto a conexión wifi se refiere. Pero de ello se hablará con detenimiento en capítulos posteriores.

El “hágalo usted mismo” (DIY, del inglés: do it yourself) es la práctica de la fabricación o reparación de cosas por uno mismo, de modo que ahorre dinero y aprenda al mismo tiempo. Es una forma de autoproducción, sin esperar la voluntad de otros, para realizar proyectos propios. La ética del do it yourself está generalmente asociada a varios movimientos anticapitalistas, ya que rechaza la idea de tener que comprar siempre a otros las cosas que uno desea o necesita. Se trata de un movimiento contracultural trasladable a cualquier ámbito de la vida cotidiana. Hay muchos ejemplos del uso de esta filosofía. El primero puede ser las reparaciones que suelen hacer algunas personas en sus hogares, sin la necesidad de tener que recurrir a profesionales como fontaneros, electricistas, etc.

1.2 Configuración e instalación

En estos momentos seguramente ya disponga de un flamante y potente Arduino MKR 1010 entre las manos. Ahora ya podrá empezar a configurar e instalar su entorno de trabajo para desarrollar sus proyectos. Además, conectará el MKR al ordenador e instalará el paquete necesario para que reconozca su 1010 y que ambos se puedan comunicar.

1.2.1 Instalación del entorno de desarrollo

Lo primero que hay que hacer es descargar el entorno de desarrollo (IDE) de la página web oficial de Arduino: http://arduino.cc/en/Main/Software. Dependiendo del sistema operativo de su equipo, deberá bajarse una versión u otra. La apariencia y funcionamiento del entorno de desarrollo es igual para todos los sistemas operativos. Se trata de un software que le permitirá escribir, depurar y desarrollar el código de programa asociado a sus proyectos. Después de instalarlo, lo ejecuta y se abrirá en pantalla una ventana con el aspecto de la figura 1.5. En Linux, el proceso depende de la distribución que utilice. Le sugiero consultar la página http://www.arduino.cc/playground/Learning/Linux. De todas maneras, no suele presentar inconvenientes en las distribuciones más extendidas como Ubuntu. Más fácil, imposible.

El IDE proporciona una interfaz gráfica en la que se puede escribir el código, depurarlo, compilarlo y cargarlo o subirlo a Arduino. En un primer vistazo, se observa que, en la parte superior, hay seis iconos en la barra de botones que utilizará muy a menudo (figura 1.6). Además, si despliega el menú de opciones de la barra superior, observará que cada elemento del menú ofrece más opciones que irá descubriendo progresivamente a lo largo de este libro. Aunque ahora es necesario que se fije en el submenú de Herramientas (figura 1.7), ya que presenta dos opciones imprescindibles para que todo funcione desde el principio:

* Placa: Determina el tipo de Arduino con el que trabaja.

* Puerto: Indica el puerto serie del ordenador al cual tiene conectado Arduino.

Estos dos datos están presentes bajo la ventana de mensajes tal y como se muestra en la figura 1.7.

1.2.2 Instalación de controladores para el MKR 1010

En un principio, la placa por defecto seleccionada al iniciar por primera vez el IDE (entorno de desarrollo) es la de Arduino UNO/Genuino. Si busca en la barra de desplazamiento el modelo 1010, no lo encontrará. Es necesario conectarse a Internet y abrir el menú Herramientas y, dentro del mismo, acudir a la opción: “Gestor de tarjetas”. Introduzca la palabra SAMD en la caja de búsqueda, tal como se observa en la figura 1.8.

Proceda a instalar este controlador (driver) o paquete adicional, que le proporcionará casi todos los modelos Arduino de la nueva familia MKR.

Ahora ya tiene disponible en la selección de placas Arduino MKR 1010, que debe seleccionar para realizar una primera práctica de iniciación y verificación del correcto funcionamiento del mismo (figura 1.9).

Un controlador de dispositivo (llamado normalmente controlador, en inglés, driver) es un programa informático que permite al sistema operativo interaccionar con un periférico, haciendo una abstracción del hardware y proporcionando una interfaz para usarlo. Se puede esquematizar como un manual de instrucciones que le indica cómo se debe controlar y comunicarse con un dispositivo en particular. Por tanto, es una pieza esencial, sin la cual no se podría usar el hardware.

Se recuerda a aquellos lectores que han trabajado hace tiempo con Arduino que con los sistemas operativos Windows 7 y 10 la instalación de los drivers se hace de forma automática cuando instala el software de desarrollo IDE. Tan solo pregunta de vez en cuando, durante el proceso de instalación, si confía en la empresa para proceder a instalar los drivers de Arduino y nada más. Es decir, lo que antes había que realizar por separado, ahora se simplifica y se hace en una sola vez. En la mayoría de los casos, el usuario no tiene por qué preocuparse de este asunto.

Más adelante, cuando trabaje con los populares nodeMCU tendrá que volver a la opción de gestión de tarjetas para instalar los drivers correspondientes.

1.3 Una primera práctica: parpadeo de un LED

Llegó la hora de realizar la primera práctica. Va a hacer parpadear un diodo led conectado a una patilla digital de MKR 1010. La tarea es sencilla, pero no trivial. Aprenderá el procedimiento general de realización de proyectos con Arduino. Se aplicará este método a todos los diseños que se lleven a cabo a lo largo de todo el libro.

Lo primero que hay que hacer es abrir el IDE y comprobar que ha seleccionado el tipo de Arduino MKR 1010 y el puerto al que está conectado. Un truco que empleo a menudo cuando no me acuerdo del número del puerto serie al que está conectado Arduino, es desconectarlo del PC y observar la lista de puertos series en el IDE. A continuación, vuelvo a conectar Arduino y veo de nuevo la lista de los mismos. Aparecerá un nuevo puerto al final de esa lista. Ahí es donde está Arduino (figuras 1.10 y 1.11).

La palabra española “led” proviene del acrónimo inglés: LED (light-emitting diode: diodo emisor de luz). Los ledes se usan como indicadores y en iluminación. Existe una forma básica de conocer la polaridad de un led. La pata más larga siempre va a ser el ánodo y la más corta, el cátodo.

El 1010 incorpora de serie un led que puede utilizar en esta primera práctica para realizar un parpadeo continuo del mismo. Esta luz está conectada internamente al pin 6 de la placa (figura 1.12).

El siguiente paso es escribir el código que subirá a Arduino y hará parpadear el led interno. Para ello, o bien abre el sketch (programa) llamado blink.pde (los programas de Arduino tienen la extensión pde) desde la opción Archivo->Ejemplos bajo el menú de opciones (figura 1.13) o bien escribiendo el código mostrado en la figura 1.14. Recomiendo llevar a cabo esto último para que se acostumbre a utilizar el lenguaje de programación de Arduino. Para ello debe abrir un fichero nuevo en blanco desde la opción Archivo->Nuevo.

Un programa para ejecutarse en Arduino se conoce como sketch. Podría traducirse como “boceto” o “borrador”. Un sketch siempre tiene la misma estructura. Lo que se escriba entre las llaves que acompañan al nombre setup, se ejecuta una única vez siempre que se encienda o resetee la placa. Lo que se escriba dentro de las llaves que acompañan al nombre loop se ejecutará constantemente hasta que se apague Arduino.

Como se aprecia en la figura 1.15, la estructura básica de un programa consta de en cuatro bloques. El primero es opcional y contiene una barra inclinada seguida de un asterisco: “/*” para abrir el bloque y una segunda barra y asterisco para cerrarlo: “*/”. Contiene texto en el que puede escribir una referencia al autor (puede que sea usted mismo), la fecha de creación, a quién va dedicado, etc. En el siguiente bloque, definirá las variables que utilizará en el sketch. Más adelante, se explica lo que es una variable. El tercer bloque es importante porque en él se define la configuración del hardware de la placa. En este caso, el pin 6 funcionará como salida, ya está conectado el led. El cuarto bloque repetirá continuamente, y en bucle, las instrucciones que contiene entre las llaves (de ahí el nombre de loop).

Práctica 1.1 Parpadeo de un led (encabezado)

/* Parpadeo. Encienda y apague un led con intervalos de 1 segundo */

El encabezado contiene solo información y no se ejecuta. En este caso, informa de lo que hace el programa.

Práctica 1.1a Parpadeo de un led (inicialización)


En este bloque setup() (inicialización) se establecen las variables que utilizará durante todo el programa. Se define una variable llamada led de tipo entero int y le asigna el número 6. De ahora en adelante, cada vez que aparezca la palabra “led”, se hará referencia al número 6. Debe de fijarse que todas las sentencias o instrucciones que contenga su programa acaban en un punto y coma. Esto es una regla del lenguaje de programación C obligatoria. Observará también un comentario de texto: “// El led está conectado al pin 6”. Aclara que el led está conectado a dicho pin o patilla de Arduino. Es recomendable añadir de vez en cuando comentarios al programa para clarificar el código.

Las instrucciones o funciones que van entre llaves solo se ejecutan una sola vez y configuran el hardware de Arduino. En este caso, se tiene solo una: pin-Mode (número de pin, entrada o salida).

.-.pinMode es una función que configura uno de los pines digitales de Arduino como entrada o salida. En el caso de Arduino MKR 1010 se disponen de ocho pines digitales. Pues bien, pinMode establece que “tal pin” sea entrada o salida. La palabra INPUT establece entrada y la palabra OUTPUT inicializa el pin como salida. Así que para configurar el pin 6 como salida tendrá que escribir:

pinMode(6, OUTPUT);

Si lo quisiera configurar como entrada tendría que escribir:

pinMode(6, INPUT);

De esta forma tan sencilla se pueden configurar todos los pines digitales de Arduino para que actúen como entradas o salidas, dependiendo de lo que tenga conectados a los mismos.

Práctica 1.1b Parpadeo de un led (bloque repetitivo)

Dentro de la estructura loop() (repetitivo) y también entre llaves, aparece el fragmento de programa que se va a repetir continuamente. Ahora se dispone de una nueva función llamada digitalWrite (número de pin, estado alto o bajo).

Esto guarda relación con las señales digitales. Como sabe, las señales digitales binarias representan dos estados: un estado bajo, conocido como 0, apagado u OFF; y un estado alto conocido como 1, encendido u ON. El estado alto o HIGH se representa con 5 V y el estado bajo o LOW se representa con 0 V.

.-.digitalWrite es una función que necesita dos parámetros: el primero, una vez más, es el número de pin digital y el siguiente es el estado lógico que queremos mantener en ese pin, por lo tanto, si quiero enviar un valor alto al pin 6 tendrá que escribir:

digitalWrite(6, HIGH);

Si quiero tener 0 V en el pin 6 escribirá:


Delay es una función muy sencilla. Hace que toda la ejecución de Arduino pare o se detenga durante los milisegundos que le indique como parámetro.

Por lo tanto, si quiere esperar medio segundo escribirá:

delay(500);

Si desea esperar diez segundos escribirá:

deLay(10000);

Por tanto, echando un nuevo vistazo al bloque loop(), observará que el diodo LED conectado a la patilla 6 se va a encender (estado HIGH) durante 1 segundo y se va a apagar (estado LOW) durante otro segundo, consiguiendo el ansiado efecto de parpadeo.

Lo que resta por hacer es subir el código a la placa Arduino y comprobar si funciona. Para ello, presione el botón de compilación y subida de código indicado en la figura 1.16. Si todo va bien verá una lucecita (el diodo led) en la placa que parpadea durante un momento. Esto indica que el programa está cargándose en el microcontrolador de Arduino. Este breve parpadeo es un importante aviso de que las cosas van por buen camino. La placa está conectada correctamente al puerto serie y el código del sketch no tiene errores de sintaxis. Si algo de esto fuera mal observaría errores en la ventana de mensajes del entorno de desarrollo IDE (figura 1.17).

Observará que el error cometido se muestra con una barra de color amarillo a continuación de la línea de programa responsable del mismo.

Por otra parte, si quiere en algún momento comprobar o verificar si el código está bien escrito porque se ha olvidado algún punto y coma o si, por ejemplo, ha escrito digitalwrite en vez digitalWrite, puede recurrir al botón de verificación de programa que le avisará si todo va bien (figuras 1.18 y 1.19).


Realice el mismo montaje anterior, pero utilizando el pin 5 para conectar un diodo led externo.

Con el montaje anterior haga que el led esté encendido 1 segundo y apagado 2.

1.4 La familia Arduino MKR

Dado el éxito de Arduino, la compañía reconoció la necesidad de una versión estándar más pequeña que el modelo UNO. Además, se estaban imponiendo en el mercado una serie de placas competidoras que brindaban excelentes capacidades para el desarrollo de aplicaciones en el terreno del internet de las cosas (IoT). Por ello, se apresuraron a diseñar la serie MKR de Arduino con un objetivo en mente: el IoT. La compañía empezó a plantearse seriamente dejar de fabricar modelos “experimentales” por así decirlo, como Arduino YUN y shields como wifi o Ethernet, que no podían competir en precio con otros fabricantes más baratos como Raspberry Pi o Banana Pi.

Dada la naturaleza más pequeña de las aplicaciones de IoT más simples, donde la potencia y el tamaño del hardware son siempre una preocupación, Arduino diseñó la serie MKR, que aún empaqueta 28 pines en menos de la mitad del área total. Por otra parte, la conectividad inalámbrica era una barrera conocida para Arduino UNO, por lo que, naturalmente, la serie MKR se tomó la libertad de integrar todas las opciones de conectividad de IoT a través de los diferentes miembros de esta familia. En la figura 1.20 se observa dónde la compañía encuadra la familia MKR.

Algunos de los tipos de MKR que contiene la figura anterior son experimentales y posiblemente desaparezcan con el paso del tiempo o incluso sean reemplazados por nuevas revisiones, como es el caso de Arduino YUN revisión 2, que mejora considerablemente al anterior. Sin embargo, se verán los que a mi juicio son claramente ganadores en esta nueva familia. Además, se desarrollarán algunas prácticas para incitar al lector a adquirir alguno de estos modelos y darse cuenta de que realmente la empresa ha apostado fuerte en este sentido.

Arduino MKR1000 WiFi

El 9 de diciembre de 2015 se presentó Arduino MKR1000 y el 2 de abril de 2016 salió a la venta para todo el público. ¿Qué tiene de especial esta placa? Lo más llamativo es que viene integrada con un wifi abriendo las puertas de la comunicación a todo el mundo. No hay que olvidar que, gracias a Arduino, la robótica, la electrónica y la programación son accesibles a todo el mundo, principalmente por tres razones. La primera, el bajo coste que supone en la actualidad competir claramente con otras placas del mercado. La segunda es su facilidad de uso y programación. Se continúa utilizando el mismo entorno IDE de programación, de tal manera que los clásicos usuarios del UNO no tengan que adaptarse a nuevos ambientes de trabajo. Y la tercera, y la más importante, la gran comunidad que existe detrás de esta nueva placa.

Características de Arduino MKR1000

Como toda placa de prototipado o desarrollo, es necesario conocer las características más importantes. En este caso verá las que incluye Arduino MKR1000. En la figura 1.21 se observa su apariencia física y su aspecto virtual para el diseño de proyectos utilizando el fritzing.

Arduino MKR1000 se ha diseñado para ofrecer una solución práctica y rentable para los fabricantes que buscan agregar conectividad wifi a sus proyectos con una experiencia previa mínima en redes. Está basado en el Atmel ATSAMW25 SoC (system on chip), que forma parte de la familia SmartConnect de dispositivos inalámbricos Atmel, diseñada específicamente para proyectos y dispositivos IoT. El ATSAMW25 se compone de tres bloques principales:

SAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits

WINC1500 de baja potencia; 2.4 GHz IEEE® 802.11 b/g/n WiFi

ECC508 Crypto Authentication

El ATSAMW25 incluye también una sola antena de PCB de flujo 1×1. El diseño incluye un circuito de carga Li-Po que permite que el MKR1000 funcione con batería o con 5 V externos, cargando la batería Li-Po mientras funciona con energía externa. El cambio de una fuente a otra se realiza de forma automática. Una buena potencia de cómputo de 32 bits, el amplio conjunto habitual de interfaces de E S, wifi de baja potencia con un Cryptochip para una comunicación segura. Exactamente igual que su hermano el MKR 1010, con el que desarrollará la mayoría de los proyectos de este libro, es posible suministrar energía de tres maneras. Se puede hacer a través del puerto microUSB o alimentarlo a través del pin VIN. En los dos casos se requiere de una diferencia de potencial de 5 V. Si desea crear un dispositivo autónomo puede hacer uso de una batería, dispone de pines de conexión para baterías. La recomendación del fabricante es que utilice una batería de 3.7 V y, como mínimo, 700 mAh (miliamperio hora). Es sencillo calcular la duración en horas de su batería si conoce el con-sumo máximo de corriente (mA) y la capacidad de la batería (mAh).


La multiplicación por el factor 0.7 se lleva a cabo debido a los factores externos que pueden afectar a la duración de la batería. Algo a muy a tener en cuenta y con la que debe tener mucha precaución es la diferencia de potencial que suministra a las entradas. Funcionan con 3.7 V y la recomendación es que no debe de suministrar el valor típico de 5 V a ninguna entrada. Esto puede dañar la placa. En la figura 1.22 se observa un ejemplo de alimentación con una Li-Po.


MicrocontroladorSAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits
Fuente de alimentación de la placa (USB/VIN)5 V
Batería soportada (*)Li-Po de una celda, 3.7 V, 700 mAh mínimo
Voltaje de funcionamiento del circuito3.3V
Pernos digitales de E/S8
PWM pines12 (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, A3 - o 18 -, A4 - o 19)
UART1
SPI1
I2C1
Clavijas de entrada analógica7 (ADC 8/10/12 bits)
Pernos de salida analógica1 (DAC 10 bits)
Interrupciones externas8 (0, 1, 4, 5, 6, 7, 8, A1 -o 16-, A2 - o 17)
Corriente DC por pin de E/S7 mA
Memoria flash256 kB
SRAM32 kB
EEPROMno
Velocidad de reloj32.768 kHz (RTC), 48 MHz
Led_BUILTIN6
Dispositivo USB de velocidad completa y host integrado
Longitud61.5 mm
Anchura25 mm
Peso32 g

Arduino MKR WiFi 1010

El MKR WiFi 1010 es una mejora significativa en el MKR1000 WiFi. Está equipado con un módulo ESP32 hecho por u-blox. Esta placa tiene como objetivo acelerar y simplificar la creación de prototipos de aplicaciones de IoT basadas en wifi gracias a la flexibilidad del módulo ESP32 y su bajo consumo de energía. En la figura 1.23 se observa su apariencia física y su aspecto virtual para el diseño de proyectos utilizando el fritzing.

Características del Arduino MKR 1010

La placa está compuesta por tres bloques principales:

* SAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits;

* u-blox Serie NINA-W10 de baja potencia de 2.4 GHz IEEE® 802.11 b/g/n wifi, y

* ECC508 Crypto Authentication.

El MKR WiFi 1010 incluye potencia de cómputo de 32 bits, el rico conjunto usual de interfaces de E/S y wifi de baja potencia con un Cryptochip para una comunicación segura mediante el cifrado SHA-256. Además, ofrece la facilidad de uso del software de Arduino (IDE) para el desarrollo de código y programación. Su puerto USB se puede utilizar para suministrar alimentación (5 V) a la placa.

Tiene un circuito de carga Li-Po que permite que el Arduino MKR WiFi 1010 funcione con energía de la batería o con una fuente externa de 5 V, cargando la batería Li-Po mientras funciona con energía externa. El cambio de una fuente a otra se hace automáticamente.

Su puerto USB se puede utilizar para suministrar alimentación (5 V) a la placa. Tiene un circuito de carga Li-Po que permite que Arduino MKR WiFi 1010 funcione con energía de la batería o con una fuente externa de 5 V, cargando la batería Li-Po mientras funciona con energía externa. El cambio de una fuente a otra se hace automáticamente.


MicrocontroladorSAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits
Fuente de alimentación de la placa (USB/VIN)5V
Batería soportada (*)Li-Po Single Cell, 3.7V, 700 mAh mínimo
Voltaje de funcionamiento del circuito3.3 V
Pines digitales de E/S8
PWM pines12 (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, A3 - o 18 -, A4 - o 19)
UART1
SPI1
I2C1
I2S1
ConectividadWifi
Pines de entrada analógica7 (ADC 8/10/12 bits)
Pines de salida analógica1 (DAC 10 bits)
Interrupciones externas8 (0, 1, 4, 5, 6, 7, 8, A1 -o 16-, A2 - o 17)
Corriente DC por pin de E/S7 mA
Memoria flash256 kB
SRAM32 kB
EEPROMNo
Velocidad de reloj32.768 kHz (RTC), 48 MHz
LED_BUILTIN6
Dispositivo USB de velocidad completa y host integradoIncluido
LED_BUILTIN6
Longitud61.5 mm
Anchura25 mm
Peso32 g

Arduino MKR1200 WIFI

Arduino MKRFOX1200 (figura 1.24) ha sido diseñado para ofrecer una solución práctica y rentable a los fabricantes que buscan agregar conectividad Sigfox en sus proyectos con una mínima experiencia previa en redes. Está basado en el módulo Atmel SAMD21 y ATA8520 Sigfox. La placa Arduino MKRFOX1200 es una de las placas de prototipado más dotadas para el internet de las cosas o IoT. Con capacidad para conectarse a la red de Sigfox, pone a su alcance el poder de las redes LPWAN para conectarse a grandes distancias y muy bajo consumo.

Existen placas más económicas, como el ESP8266 o el ESP32. Incluso el Arduino MKR1000 explicado anteriormente puede ser un gran rival. Sin embargo, utilizan tecnologías diferentes de comunicación. Y aunque estas placas son muy versátiles, su función no tiene nada que ver con despliegues masivos de dispositivos del IoT. No cumplen las premisas de bajo consumo y un amplio alcance de cobertura. Sin embargo, placas compatibles con LoRaWan o Sigfox, cumplen con creces estas premisas.

Arduino MKRFOX1200 es una potente placa que combina la funcionalidad del Arduino Zero y la conectividad de Sigfox. Es la solución ideal para crear dispositivos de IoT de forma fácil y sencilla. La placa incluye 2 años de suscripción gratuita a Sigfox (con un máximo de 140 mensajes al día) y acceso gratuito a Spot’it, un servicio de geolocalización para ubicar la placa sin GPS extra. El Arduino MKRFOX1200 se ha diseñado para ofrecer una solución eficiente y de bajo coste para realizar proyectos con la conectividad Sigfox. Se basa en un potente microcontrolador Atmel SAMD21 y un módulo Sigfox ATA8520. Se puede alimentar con 2 pilas AA de 1.5 V, con baterías AAA o con una alimentación externa de 5 V. A diferencia de otras placas Arduino y Genuino, el MKRFOX1200 funciona con 3.3 V. El máximo voltaje aplicable a los pines I/O es de 3.3 V. Si se aplican voltajes superiores a 3.3 V a cualquiera de los pines se puede dañar la placa y anular la garantía. El plan de datos de Sigfox incluido se activa automáticamente al enviar el cuarto mensaje en la red. Se pueden enviar hasta 140 mensajes por día durante un año. La placa necesita una antena GSM 868 MHz (no incluida por defecto) para poder funcionar correctamente. Se recomienda un modelo que incluya el conector UFL.

Características de Arduino MKRFOX1200

* Microcontrolador: SAMD21 Cortex-M0+ 32bit low power ARM MCU

* Alimentación (USB/VIN): 5 V

* Baterías soportadas: 2× AA o AAA

* Voltaje de operación: 3.3 V

* Pines digitales I/O: 8

* Pines PWM: 12 (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, A3 o 18 -, A4 o 19)

* UART 1

* SPI 1

* I2C 1

* Entradas analógicas: 7 (ADC 8/10/12 bits)

* Salidas analógicas: 1 (DAC 10 bits)

* Interrupciones externas: 8 (0, 1, 4, 5, 6, 7, 8, A1 o 16, A2 o 17)

* Corriente DC por pin: 7 mA

* Memoria Flash: 256 kB

* Memoria SRAM: 32 kB

* No dispone de EEPROM

* Reloj RTC: 32.768 kHz (RTC), Micro: 48 MHz

* LED_BUILTIN 6

* Full-Speed USB Device and embedded Host

* LED_BUILTIN 6

* Antenna: 2 dB

* Frecuencia: 868 MHz

* Apto para Europa (Consultar cobertura actual en página de Sigfox)

* Largo: 67.64 mm

* Ancho: 25 mm

* Peso: 32 g

El pineado completo se muestra en la figura 1.25.

Arduino MKR1300 WIFI

MKR WAN 1300 es una placa potente que combina la funcionalidad de la conectividad MKR ZERO y LoRa/LoRaWAN TM. Es la solución ideal para los fabricantes que desean diseñar proyectos de IoT con una experiencia previa mínima en redes que tengan un dispositivo de bajo consumo.

Arduino MKR WAN 1300 ha sido diseñado para ofrecer una solución práctica y rentable para los fabricantes que buscan agregar conectividad LoRa a sus proyectos con una experiencia previa mínima en redes. Se basa en el Atmel SAMD21 y un módulo Murata CMWX1ZZABZ LoRa (figura 1.26).

El diseño incluye la capacidad de alimentar la placa con dos baterías AA o AAA de 1.5 V o 5 V externos. El cambio de una fuente a otra se hace automáticamente. Una buena potencia de cómputo de 32 bits similar a la placa MKR ZERO, el rico conjunto habitual de interfaces de E/S, comunicación LoRa de baja potencia y la facilidad de uso del software Arduino (IDE) para el desarrollo y la programación de códigos. Todas estas características hacen de esta placa la opción preferida para los proyectos emergentes impulsados por batería de IoT en un factor de forma compacta. El puerto USB se puede utilizar para suministrar alimentación (5 V) a la placa. Arduino MKR WAN 1300 puede funcionar con o sin las baterías conectadas y tiene un consumo de energía limitado.

Características de Arduino MKR WAN 1300


MicrocontroladorSAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits
Módulo de radioCMWX1ZZABZ (hoja de datos)
Fuente de alimentación de la placa (USB/VIN)5 V
Baterías compatibles (*)2 × AA o AAA
Voltaje de funcionamiento del circuito3.3 V
Pernos digitales de E/S8
PWM pines12 (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, A3 - o 18 -, A4 - o 19)
UART1
SPI1
I2C1
Clavijas de entrada analógica7 (ADC 8/10/12 bits)
Pernos de salida analógica1 (DAC 10 bits)
Interrupciones externas8 (0, 1, 4, 5, 6, 7, 8, A1 -o 16-, A2 - o 17)
Corriente DC por pin de E/S7 mA
Memoria flash256 kB
SRAM32 kB
EEPROMno
Velocidad de reloj32.768 kHz (RTC), 48 MHz
LED_BUILTIN6
Dispositivo USB de velocidad completa y host integrado
Poder de la antena2 dB
Frecuencia de carga433/868/915 MHz
Región de trabajoEU/US
Longitud67.64 mm
Anchura25 mm
Peso32 g

Arduino MKR GSM 1400

Arduino MKR GSM 1400: conectividad global 3G GSM con el potente módulo ATSAMD21 de Microchip ATSAMD21 y u-blox SARA-U201. El consumo de energía ultra bajo y el elemento criptográfico seguro combinados con el módulo SARA-U201 lo hacen ideal para la conexión de automóviles, transporte y ciudades inteligentes.

Arduino MKR GSM 1400 (figura 1.27) se ha diseñado para ofrecer una solución práctica y rentable para los fabricantes que buscan agregar conectividad GSM global a sus proyectos con una experiencia previa mínima en redes. Se basa en el Atmel SAMD21 y un módulo GSM SARA-U201. El diseño incluye la capacidad de alimentar la placa con una batería Li-Po o una fuente de alimentación externa de 5 V. El cambio de una fuente a otra se hace automáticamente. Una buena potencia de cómputo de 32 bits similar a la placa Zero, el amplio conjunto habitual de interfaces de E/S, la comunicación GSM global y la facilidad de uso del software Arduino (IDE) para el desarrollo y la programación de códigos. Todas estas características hacen de esta placa la opción preferida para los proyectos emergentes impulsados por batería de IoT en un factor de forma compacta. El puerto USB se puede utilizar para suministrar alimentación (5 V) a la placa.

Características de Arduino MKR GSM 1400


MicrocontroladorSAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits
Fuente de alimentación de la placa (USB/VIN)5 V
Batería soportada (*)3.7 V Li-Po
Voltaje de funcionamiento del circuito3.3 V
Pernos digitales de E/S8
PWM pines12 (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, A3 - o 18 -, A4 - o 19)
UART1
SPI1
I2C1
Clavijas de entrada analógica7 (ADC 8/10/12 bits)
Pernos de salida analógica1 (DAC 10 bits)
Interrupciones externas8 (0, 1, 4, 5, 6, 7, 8, A1 -o 16-, A2 - o 17)
Corriente DC por pin de E/S7 mA
Memoria flash256 kB
SRAM32 kB
EEPROMNo
Velocidad de reloj32.768 kHz (RTC), 48 MHz
LED_BUILTIN6
Dispositivo USB de velocidad completa y host integrado
Poder de la antena2 dB
Frecuencia de cargaGSM 850 MHz, E-GSM 1900 MHz, DCS 1800 MHz, PCS 1900 MHz
Región de trabajoGlobal
Longitud67.64 mm
Anchura25 mm
Peso32 g
Tamaño de SIMMicro

Arduino MKR ZERO

El MKR ZERO tiene un conector SD incorporado con interfaces SPI dedicadas (SPI1) que le permite jugar con archivos de audio sin hardware adicional e incluye dos bibliotecas para su utilización:

* Biblioteca de sonidos de Arduino : una forma sencilla de reproducir y analizar datos de audio utilizando Arduino en tableros basados en SAM D21.

* Biblioteca I2S : para usar el protocolo I2S en placas basadas en SAMD21. I2S (Inter-IC Sound) es un estándar de interfaz de bus serie eléctrico para conectar dispositivos de audio digital.

El MKR ZERO le ofrece la potencia de un Cero en el formato más pequeño establecido por el factor de forma MKR. La placa MKR ZERO actúa como una gran herramienta educativa para aprender sobre el desarrollo de aplicaciones de 32 bits. Tiene un conector SD incorporado con interfaces SPI dedicadas (SPI1) que permite jugar con archivos de audio sin hardware adicional. La placa está alimentada por la MCU SAMD21 de Atmel, que cuenta con un núcleo ARM Cortex® M0 + de 32 bits (figura1.28).


Características del Arduino MKR ZERO


MicrocontroladorSAMD21 Cortex-M0 + MCU de bajo consumo de 32 bits
Fuente de alimentación de la placa (USB/VIN)5 V
Batería soportada (*)Li-Po de una celda, 3.7 V, 700 mAh mínimo
Corriente DC para 3.3 V pin600 mA
Corriente DC para 5 V pin600 mA
Voltaje de funcionamiento del circuito3.3 V
Pernos digitales de E/S22
PWM pines12 (0, 1, 2, 3, 4, 5, 6, 7, 8, 10, A3 - o 18 -, A4 - o 19)
UART1
SPI1
I2C1
Clavijas de entrada analógica7 (ADC 8/10/12 bits)
Pernos de salida analógica1 (DAC 10 bits)
Interrupciones externas8 (0, 1, 4, 5, 6, 7, 8, A1 -o 16-, A2 - o 17)
Corriente DC por pin de E/S7 mA
Memoria flash256 kB
Memoria Flash para Bootloader8 kB
SRAM32 kB
EEPROMno
Velocidad de reloj32.768 kHz (RTC), 48 MHz
LED_BUILTIN32
Dispositivo USB de velocidad completa y host integrado

CAPÍTULO 2
El lenguaje de programación de Arduino

En este segundo capítulo se abordará la tarea de comprender los aspectos básicos del lenguaje de programación de Arduino y se entrará detalladamente en el funcionamiento de las instrucciones básicas para programarlo. En esta sección aprenderá a elaborar secuencias de órdenes para enviar a Arduino MKR y que actúe como usted le ordene. A este tipo de acción se le llama “programar”.

2.1 Introducción al concepto de programación

Buscando una similitud o parecido entre Arduino y el ordenador; programar es el proceso de diseñar, escribir, probar, depurar y mantener el código fuente de programas. El código fuente se escribe en un lenguaje de programación. El propósito de la programación es crear programas que presenten un comportamiento deseado. Para crear un programa que el ordenador o Arduino interpreten y ejecuten las instrucciones escritas para ellos debe usarse un lenguaje de programación. En sus inicios, los ordenadores interpretaban solo instrucciones en un lenguaje específico del más bajo nivel, conocido como código máquina, siendo excesivamente complicado para programar. De hecho, consiste en cadenas de números 1 y 0 (sistema binario). Para facilitar el trabajo de programación, los primeros técnicos que trabajaban en esa área decidieron reemplazar las instrucciones, secuencias de unos y ceros, por palabras o letras provenientes del inglés, codificándolas y creando un lenguaje de mayor nivel que se conoce como Assembly o lenguaje ensamblador. Por ejemplo: para sumar se usa la letra A de la palabra inglesa add (sumar). En realidad, escribir en lenguaje ensamblador es básicamente lo mismo que hacerlo en lenguaje máquina, pero las letras y palabras son bastante más fáciles de recordar y entender que secuencias de números binarios.

A medida que creció la complejidad de las tareas que realizaban los ordenadores, se hizo necesario disponer de un método sencillo para programar. Entonces, se crearon los lenguajes de alto nivel. Mientras que una tarea tan trivial como multiplicar dos números puede necesitar un conjunto de instrucciones en lenguaje ensamblador, en un lenguaje de alto nivel bastará con solo una.

Un lenguaje de programación es un idioma artificial diseñado para expresar operaciones que pueden ser llevadas a cabo por máquinas como los ordenadores o, como en este caso, Arduino MKR. Puede usarse para crear programas que controlen el comportamiento físico y lógico de una máquina, para expresar algoritmos con precisión, o como modo de comunicación humana. Está formado por un conjunto de símbolos y reglas sintácticas y semánticas que definen su estructura y el significado de sus elementos y expresiones. Al proceso por el cual se escribe, se prueba, se depura, se compila y se mantiene el código fuente de un programa informático se le denomina programación.

El lenguaje de máquina es el sistema de códigos directamente interpretable por un circuito microprogramable, como el microprocesador de un ordenador o el microcontrolador que lleva dentro Arduino MKR. Este lenguaje está compuesto por un conjunto de instrucciones que determinan acciones que serán tomadas por la máquina. Estas instrucciones normalmente se ejecutan en secuencia, con eventuales cambios de flujo causados por el propio programa o eventos externos. El lenguaje máquina trabaja con dos niveles de voltaje. Dichos niveles se simbolizan con el cero (0) y el uno (1), por eso el lenguaje de máquina solo utiliza dichos signos. En cambio, el lenguaje ensamblador es un lenguaje de programación de bajo nivel para los ordenadores, microcontroladores y otros circuitos integrados programables. Implementa una representación simbólica de los códigos de máquina. Esta representación es usualmente definida por el fabricante de hardware. Está basada en códigos mnemotécnicos que simbolizan los pasos de procesamiento (las instrucciones). Un lenguaje ensamblador es, por lo tanto, específico a cierta arquitectura de ordenador física (o virtual). Esto está en contraste con la mayoría de los lenguajes de programación de alto nivel que idealmente son portables. En la cúspide de esta pirámide reina los lenguajes de programación de alto nivel que se caracterizan por expresar los algoritmos de una manera muy cercana al lenguaje humano. Para los lenguajes de alto nivel se requiere de ciertos conocimientos de programación necesarios para escribir las secuencias de instrucciones lógicas. Los lenguajes de alto nivel se crearon para que el usuario común pudiese solucionar un problema de procesamiento de datos de una manera más fácil y rápida.

Cuando se disponga a realizar un programa en lenguaje de alto nivel como C, lo primero que tendrá que hacer es diseñar un algoritmo gráfico de la tarea que vaya a emprender. Por ejemplo, si retoma el primer programa o práctica de parpadeo de un led que se explicó en el capítulo anterior, podría dibujar un algoritmo parecido al que se muestra en la figura 2.1. Está representando una secuencia de pasos que deberá ejecutar más tarde MKR. En primer lugar, aparece un bloque llamado Cabecera que contendrá todos los comentarios relativos al propósito del programa, autor, fecha, lugar donde se ideó, etc. Después dispone de un bloque que hace referencia a la configuración de Arduino, es decir, en este caso definir que la patilla 6 de la placa se comporte como salida, ya que a esta va conectada el led. Después ha de entrar en varios bloques que realizan las tareas de encender un led, esperar un tiempo, apagarlo, esperar otro tiempo y volver al principio, es decir, encenderlo de nuevo.

De una forma visual se representa lo que desea hacer. De esta manera sencilla es posible corregir o depurar cómodamente los pasos de su proyecto.

Además, cualquiera que le eche un vistazo al gráfico se dará cuenta rápidamente de lo que intenta hacer.

Más adelante se traducirán estas acciones escritas dentro de los bloques en instrucciones o sentencias del lenguaje de programación de Arduino MKR. Al principio, lo importante es tener claros los pasos que debe seguir. No es cuestión de escribir código de programación sin tener un objetivo en mente. Se trata de programar, pero con un lenguaje muy cercano a su forma natural de entender las cosas.

En todo caso, programará en un lenguaje de ultra alto nivel. Es de vital importancia construir este tipo de bocetos, esquemas, gráficos, organigramas o como desee llamarlo, siempre que aborde un proyecto nuevo con Arduino.

A continuación, se describe cómo traducir todo esto al lenguaje propio de Arduino. Pero antes, hay que examinar la estructura básica de que consta un programa en Arduino y los elementos con los que jugar.

2.2 Cuerpo de un programa en Arduino

Un programa diseñado para ejecutarse en Arduino se conoce como sketch, que podríamos traducir como “boceto” o “borrador”. Un sketch siempre tiene la misma estructura general y consta de dos estructuras: setup() y loop(). Estas constituyen el cuerpo general e imprescindible de un programa. Esto quiere decir, ni más ni menos que cuando cree un programa o sketch nuevo desde el IDE de Arduino, nos van a aparecer siempre, y por defecto, estas dos estructuras en nuestra plantilla vacía.

2.2.1 Estructuras

En primer lugar, tenemos la estructura setup(). Lo que se escriba entre las llaves que acompañan a su nombre se ejecuta una única vez siempre que se encienda o resetee la placa. El bloque o estructura setup() contendrá toda la configuración hardware de Arduino, es decir, cómo quiere que funcionen determinados pines de MKR como entrada o como salida. A medida que conozca sus posibilidades aumentará el tamaño de la configuración de este bloque.

En segundo lugar, todo programa en Arduino tiene que poseer también la estructura loop(). Todo lo que se escriba dentro de las llaves que acompañan a su nombre, se ejecutará constantemente hasta que se apague o resetee la máquina. El bloque o estructura loop() incluirá su programa propiamente dicho y este se ejecutará ininterrumpidamente y en bucle.

En resumen, la primera estructura engloba la propia configuración hardware de Arduino y la segunda estructura define su propio programa o las acciones que desea realizar continuamente:


Por otra parte, Arduino se programa en el lenguaje de alto nivel C/C++. Generalmente, posee los siguientes componentes para elaborar el sketch o programa:

* Variables

* Operadores matemáticos, lógicos y booleanos

* Estructuras de control (condicionales y ciclos)

* Funciones

A continuación, se describen someramente los elementos que componen un programa típico en Arduino. No es mi intención aburrirles con una larga, teórica y tediosa exposición de toda la sintaxis y referencia del lenguaje de programación de Arduino. El planteamiento que le propongo es conocer lo mínimo para empezar a programar y, a medida que lo necesite, abordar cada uno de los nuevos tipos de variables, operadores, funciones o características nuevas de este lenguaje. Creo que es la mejor manera de aprender, sin que programar se vuelva una tarea demasiado ardua y memorística. Es el método que habitualmente empleo en mis clases de electrónica. Los nuevos componentes electrónicos aparecen a medida que se plantean nuevos proyectos, retos o ideas. La idea principal es: “Si no lo necesito para qué voy a conocerlo”. Si no fuera por este método estoy seguro de que la mitad de mis alumnos hubieran abandonado al mes de empezar el curso. De hecho, una de las ventajas de aprender a programar Arduino es que se conoce un lenguaje de alto nivel como es C/ C++, que servirá, sin duda, si decide abordar en un futuro otras plataformas hardware. Un amigo que estudió la carrera de ingeniería informática se quejaba siempre que, en primero, cuando recibía clases de Pascal (otro lenguaje de programación de alto nivel) los resultados de la ejecución de sus programas solo los veía en la pantalla del ordenador. Usted tiene la ventaja de que, al trabajar con hardware y software a la vez, puede observar los resultados malos o buenos sobre un diseño real en Arduino con leds, motores, sensores, etc., lo que lo convierte en adictivo y lúdico.

2.2.2 Variables

Una variable es una manera de nombrar y almacenar un valor numérico para su uso posterior en el programa. Como su nombre indica, las variables son números o caracteres que se pueden variar continuamente en contra de lo que ocurre con las constantes, cuyo valor nunca cambia. Todas las variables tienen que declararse antes de que puedan utilizarse. Para declarar una variable se comienza por definir su tipo, asignándoles siempre un nombre y, opcionalmente, un valor inicial. Esto solo debe hacerse una vez en un programa, pero su valor se puede cambiar en cualquier momento. Una variable puede ser declarada en cualquier lugar del programa y, en función de donde se lleve a cabo su definición, se determinará en qué partes del programa se podrá hacer uso de ella.

Una variable puede ser declarada al inicio del programa, a nivel local dentro de las funciones y a veces dentro de un bloque. En función del lugar de declaración de la variable así se determinará su ámbito de aplicación y 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 sentencia de un programa. Esta variable se declara al comienzo del programa, antes de la estructura setup(). Una variable local es aquella que se define dentro de una función o como parte de un bucle. Solo es visible y solo puede utilizarse dentro de la función en la que se declaró. El ámbito de utilización de las variables se entenderá mejor cuando conozca un poco mejor los fundamentos de la programación.

Existen diferentes tipos de variables en concordancia con el tipo de dato que almacenen. Las variables que utilizará más a menudo en sus programas son:

* Tipo entero: int

* Tipo carácter: char

* Tipo booleano: Boolean

El tipo entero denominado “int” almacena valores numéricos de 16 bits sin decimales comprendidos en el rango 32,767 a -32,768. La siguiente sentencia define una variable de tipo entero con el nombre Ventrada. Además, le asigna un valor inicial y numérico de 200.

int Ventrada = 200; // declara una variable de tipo entero.

El tipo carácter llamado “char” de un tamaño de 1 byte que almacena valores tipo carácter. Es decir, que solo puede contener un carácter tipo ASCII. La siguiente sentencia define una variable de tipo carácter con el nombre Ventrada y, además, le asigna un valor inicial con la letra ´a´.

char Ventrada = ’a’; // declara una variable de tipo carácter.

El tipo booleano (Boolean) solo puede contener dos valores: TRUE (verdadero) o FALSE (falso). De esta manera, cada una de estas condiciones ocupa 1 byte de memoria. La siguiente sentencia define una variable de tipo booleano con el nombre Ventrada y, además, le asigna un valor inicial verdadero o TRUE.

boolean Ventrada = true; // declara una variable de tipo booleano.

En cuanto al tipo matriz (array), a diferencia del tipo de variables vistas anteriormente que solo podían almacenar un valor único a la vez, los arrays son un caso especial de variables que pueden almacenar un conjunto de valores, y modificar solo uno, o algunos, o incluso todos los valores contenidos en el mismo en cualquier momento y según nuestra conveniencia. También sería posible evitar el uso de arrays y en vez de ello crear “muchas” variables con distintos nombres. Sin embargo, esto no resultará cómodo de utilizar. La traducción de array es literalmente “colección”, ya que se utiliza para “juntar” varios objetos de un mismo tipo. En otras materias, como matemáticas, se conoce con el nombre de matriz y, generalmente, se usan las de 2 dimensiones, por su facilidad para representarlas en un plano, ya que tienen ancho y alto. Cada elemento de la matriz se identifica por un par de números que indican la fila y la columna en que se ubica el elemento. También podría tener una matriz de 3 dimensiones (cubo). En ese caso, cada elemento de la matriz se identificará con 3 valores ordenados (que indicarán la posición relativa del elemento dentro de la matriz), por ejemplo: el elemento A(1,8,76) habría que encontrarlo dentro de la matriz A, en la fila 1, columna 8, “nivel” o “capa” 76.

En el caso de Arduino es todavía más simple. Utilizará un tipo de matriz de una sola dimensión. Por ejemplo, se podría declarar un array de las siguientes formas:

int minume[6];

//se define un array que tendrá 6 elementos de tipo entero (int).

int minume[] = {2, 4, 8, 3, 6};

//se define el array y se le rellena con valores numéricos.

char mensaje[6] = “hola”;

//ahora almacena caracteres individuales.

Los arrays son “zero indexed”, lo que significa que, al referirse a una matriz, el primer elemento de la matriz está en el índice 0. Por lo tanto:

minume[0] == 2, minume[1] == 4, y sucesivamente.

Esto también quiere decir que en una matriz con 10 elementos el índice 9 es el último elemento. Por lo tanto:

int myArray[10]={9,3,2,4,3,2,7,8,9,11};

// myArray[9] = 11.

// myArray[10] es inválido y contiene información aleatoria.

Las variables de tipo string (‘s’ minúscula) se representan como un tipo particular de arrays de caracteres (tipo char) que terminan con el carácter NULL. Por ejemplo:

char Str1[15];

// Declara un array de caracteres sin inicializarlo.

char Str2[8] = {‘a’, ‘r’, ‘d’, ‘u’, ‘i’, ‘n’, ‘o’};

// Declara un array de caracteres (con un carácter extra) y el compilador añadirá el carácter NULL requerido.

char Str3[8] = {‘a’, ‘r’, ‘d’, ‘u’, ‘i’, ‘n’, ‘o’, ‘\0’};

// Explicita el carácter NULL.

char Str4[ ] = “Arduino”;

// Inicializa con un string constante entre comillas dobles; el compilador medirá el tamaño del array para ajustar el string constante y carácter NULL para finalizar,

char Str5[8] = “Arduino”;

// Inicializa el array con un tamaño explícito y un string constante,

char Str6[15] = “Arduino”;

//Inicializar el array, dejando un espacio extra para un string más largo,

Generalmente, los string se finalizan con un carácter NULL (código ASCII: 0). Esto permite a funciones como Serial.print(), establecer dónde está el final del string. De otra forma, seguiría leyendo los siguientes bytes de la memoria que no forman parte del string. Los string siempre se definen entre comillas dobles (“Abc”) y los caracteres siempre se definen dentro de comillas simples (‘A’). A menudo es conveniente, al trabajar con grandes cantidades de texto, como proyectos con displays o LCD, configurar un array de string, es decir: una matriz de cadenas de textos.

El tipo String (‘S’ mayúscula) merece una explicación, ya que es un poco más que un tipo de variable. De hecho, es un objeto (en el sentido de la programación orientada a objetos). Los objetos cuentan con propiedades y funciones especiales. Propiedades y funciones son disponibles de forma nativa en el núcleo de Arduino y se pueden ver como una entidad preexistente, incluso si su IDE no contiene ninguna línea. Una vez más, el núcleo de Arduino proporciona funciones de gran alcance ya preparadas para utilizar directamente.

El tipo de datos String es diferente que el tipo de datos de cadena (nótese la mayúscula S para este tipo de datos en comparación con el anterior). Este tipo de datos es en realidad una construcción a partir del tipo de datos de cadena, pero se trata como un objeto o instancia en lugar de una sencilla matriz de caracteres. Lo que esto significa es que tiene una gran cantidad de funcionalidad integrada con el tipo de datos String. Se ha establecido con anterioridad la definición de las variables, pero los objetos tienen un concepto similar llamado: “construcción”. Para objetos String, se hace referencia a la construcción en términos similares a la declaración de una variable. Declarar un tipo String en el núcleo de Arduino incluye un constructor de objeto, que es un concepto de programación orientada a objetos que se pueden obviar, ya que el núcleo de Arduino lo hace por usted, de tal manera que es mucho más fácil.

Por ejemplo, suponga que tiene una secuencia de caracteres que se leen de un sensor en una variable de cadena denominada miDato. Además, suponga que necesita convertir todos los caracteres en letras mayúsculas. Con el tipo de datos de cadena string, tendría que escribir el código para hacer la conversión.

Si define miDato como un objeto String, entonces podría escribir la conversión simplemente como:

miDato = miDato.ToUpperCase ();

Y ya está. La razón por la que esto funciona es porque dentro del objeto String existe una función (también denominada método) que contiene el código para hacer la conversión por usted. Solo tiene que definir la variable como:

miDato = String (100);

Así define una cadena denominada miDato con espacio suficiente para 99 caracteres. Para utilizar una función integrada de este tipo, escriba el nombre de la variable seguida de un punto (llamado el operador de punto), seguida por la función que desea llamar.

Por ejemplo:

miDato = miDato.ToLowerCase ();

Dicha funcionalidad es común con los lenguajes de programación como C++, C # y Java (programación orientada a objetos). Aunque Arduino C no es exactamente un lenguaje de programación orientada a objetos, contiene algunas de las características. En la tabla 2.1 se muestran algunas de las funciones incorporadas que están disponibles cuando se utilizan objetos String (puede consultar la tabla completa en la web oficial de Arduino).

Existen más tipos de variables que irá conociendo a medida que avance en la programación de Arduino MKR. Si desea consultarlos ahora puede visitar la página: http://Arduino.cc/en/Reference/HomePage.

Las variables deberán tomar nombres descriptivos para hacer el código más legible. Nombres de variables pueden ser contactoSensor o pulsador. Sirven 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.


FunciónDescripción
compareTo(String two)Comprueba si dos cadenas son iguales
concat(String two)Combina dos cadenas en una nueva cadena
equals(String two)Realiza la comparación entre mayúsculas y minúsculas entre dos cadenas
replace(String one, String two)Reemplaza todas las apariciones de un carácter o de una subcadena por otra
toLowerCase()Devuelve una copia de la cadena original con todos los caracteres en minúsculas
length()Devuelve la longitud en caracteres de la cadena
Trim()Devuelve una copia de la cadena original con todos los espacios en blanco, antes y después de la cadena, eliminados

Tabla 2.1

2.2.3 Operadores aritméticos, lógicos y booleanos

Los operadores aritméticos que se incluyen en el entorno de programación de Arduino son: la suma, la resta, la multiplicación y la división. Estos devuelven la suma, diferencia, producto o cociente de dos operandos. Esto es lo que normalmente se denominan matemáticas de andar por casa.

y = y + 3; // Sume 3 a la variable y

x = x - 7; // Reste 7 a la variable x

i = j * 6; // Realice el producto de 6 y de la variable j

r = r / 5; // Divida la variable r entre 5

Los operadores de comparación de una variable se utilizan con frecuencia en las sentencias condicionales del tipo IF (las veremos más adelante) para comprobar si una condición es verdadera o falsa; es decir, para tomar decisiones en el programa. Los símbolos de los operadores de comparación se muestran a continuación.

x == y // x es igual a y

x != y // x no es igual a y

x < y // x es menor que y

x > y // x es mayor que y

x <= y // x es menor o igual que y

x >= y // x es mayor o igual que y

Los operadores booleanos son una forma de comparar dos expresiones y devolver un TRUE o FALSE dependiendo del operador. Existen tres operadores lógicos:

&& Operador AND

|| Operador OR

! Operador NOT

Desde nuestro punto de vista es más productivo memorizar los diferentes tipos de operadores que los diferentes y variados tipos de variables. La razón se asienta en la experiencia que afirma que los operadores constituyen la toma de decisiones fundamental en los programas y elegir un operador u otro puede determinar el funcionamiento correcto o no de su proyecto. En cambio, la elección de una variable u otra no tiene por qué ser determinante.

2.2.4 Estructuras de control: condicionales y ciclos

Son instrucciones que permiten tomar decisiones durante la ejecución del programa y hacer diversas repeticiones de acuerdo a unos parámetros, cuyos conceptos son de gran importancia a la hora de empezar a programar y que no dejo de repetir a mis alumnos, aunque mis palabras acostumbran a caer en saco roto, lo que se refleja en el fracaso de sus proyectos. Los cuatro jinetes del apocalipsis son los siguientes:

* If

* Switch/case

* For

* While

Estructuras condicionales. Sirven para tomar decisiones después de evaluar condiciones lógicas. Tenemos dos principales: If y Switch/case.

* If. Es una estructura (figura 2.2) simple que se utiliza para evaluar si una determinada condición se ha alcanzado, como, por ejemplo, determinar si un valor analógico es igual a un valor de referencia preestablecido y ejecutar una serie de operaciones que se escriben dentro de llaves si es cierta la condición. Si es falsa (la condición no se cumple), el programa salta y no ejecuta las operaciones que están dentro de las llaves. Un ejemplo de uso de la misma es el siguiente:


Se evalúa si la variable x es igual a 15. Si se cumple la condición se le suma el valor 30 y después le suma 1000. Entonces la variable x contendrá el valor 1045. Si no es igual, solo le suma 1000, ya que se salta las posibles operaciones que hubiera dentro de las llaves (en este caso, la suma del valor 30). Hay que tener cuenta el uso especial del símbolo ‘=’ dentro de if: x = 15 podría parecer que es válido, pero, sin embargo, no lo es; ya que esa expresión asigna el valor 15 a la variable x. Por eso, dentro de la estructura if, se utiliza x==15, que, en este caso, lo que hace el programa es comprobar si el valor de x es 15. Ambas cosas son distintas. Dentro de las estructuras if, cuando se pregunte por un valor se debe poner el signo doble de igual “==”. Una variedad muy utilizada y más completa de la estructura anterior es la denominada if/else que responde la idea “si esto no se cumple se hace esto otro”. Variando el ejemplo anterior se puede evaluar, en un nuevo ejemplo, si la variable x es igual a 15; si no es así, se le suma un valor de 1000 (opción “else”). Pero ahora, en el caso de que fuera igual a 15, se le suma el valor de 30 como en el sketch anterior. Sin embargo, no se le suma después el valor de 1000 (figura 2.3).


* Switch/case. 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 suele usarse 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. Volviendo al ejemplo anterior, se podría comparar el valor de la variable x con distintos valores y, en función de si es igual a alguno de ellos, ejecutar las operaciones o expresiones a partir de ese case o caso particular (figura 2.4).


En el programa se comprueba si x vale 15 (de ser así, le suma el valor de 30) o si vale 67 (en este caso multiplica por dos su valor). Si x posee cualquier otro valor distinto se le añade el valor 1000.

Estructuras de bucle o de ciclo. Sirven para ejecutar continuamente un conjunto de operaciones o sentencias hasta que se cumplan ciertas condiciones lógicas, aritméticas o booleanas. Las dos más importantes son: For y While.

* For. Esta estructura 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 evaluar la condición y, si deja de cumplir, se sale de este bucle continuo. La estructura for tiene tres partes separadas por (;). Su formato es el siguiente:

for (inicialización; condición; expresión)

La inicialización de una variable local se produce una sola vez y la condición se comprueba 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. A continuación, se muestra un sketch para clarificar su uso (figura 2.5):


El sketch (figura 2.5) hace parpadear veinte veces, y solo veinte, la patilla 13 de Arduino con un intervalo de medio segundo. En este caso, la variable de inicialización i se pone a cero. A continuación, se comprueba (condición) el valor de i en cada ejecución de todo lo que va entre llaves, si esta variable es menor que el valor 20. Si es así, sigue realizando el bucle, si no es así, se sale de la estructura for. Por último, apreciar que cada vez que se ejecuta un bucle la variable i se incrementa en uno (expresión).

* While. Una estructura de tipo (figura 2.6) 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. Se presenta un ejemplo para aclarar su utilización. while (x < 200)


En este caso se evalúa si la variable x es menor que 200. Si es así, se suma 500 a otra variable llamada z y además se autoincrementa la variable x. Cuando esta variable sea igual a 200, se sale del bucle while. Existe una variedad de esta última estructura que es la llamada: 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. El bucle siempre se ejecutará al menos una vez. A lo largo del libro se utilizará más de una vez.

2.3 Funciones

Una función es un conjunto de líneas de código que realizan una tarea específica. Las funciones pueden tomar parámetros que modifiquen su funcionamiento. Las funciones son utilizadas para descomponer grandes problemas en tareas simples, y para implementar operaciones que son comúnmente utilizadas durante un programa y, de esta manera, reducir la cantidad de código. Cuando se invoca una función se le pasa el control a la misma; una vez que esta finalizó con su tarea, el control se devuelve al punto desde el cual la función fue llamada. Una función puede llamarse múltiples veces e incluso llamarse a sí misma (función recurrente). Las funciones pueden recibir datos desde fuera al ser llamadas a través de los parámetros y puede entregar un resultado.

Las funciones se declaran asociadas a un tipo de valor. Este valor será el que devolverá la función, por ejemplo, ‘int’ se utilizará cuando la función devuelva un dato numérico de tipo entero. Si la función no devuelve ningún valor entonces se colocará delante la palabra void, que significa “función vacía”.

Para llamar a una función, simplemente:

nombredelafunción(parámetros)

En una función que devuelve un valor siempre debe tener la instrucción: “return”, este termina una función y devuelve un valor a quien ha llamado a la función. Si se define una función y no pone return el valor devuelto es cero. No da error de compilación. Generalmente, los nombres de las funciones deben ser en minúscula, con las palabras separadas por un guion bajo, aplicándose estos tanto como sea necesario para mejorar la legibilidad.

La forma en que se ha declarado y pasado los parámetros de las funciones hasta ahora es la que normalmente se conoce como “por valor”. Esto quiere decir que cuando el control pasa a la función, los valores de los parámetros en la llamada se copian a “objetos” locales de la función, estos “objetos” son de hecho los propios parámetros. Esto se observa claramente en el siguiente sketch:


Empezará haciendo a = 10 y b = 20, después llamará a la función “función_ pepe” con los objetos a y b como parámetros. Dentro de “función_pepe” esos parámetros se llaman n y m, y sus valores son modificados. Sin embargo, al retornar al programa que lo llama, a y b conservan sus valores originales. Lo que pasa no son los objetos a y b, sino que copia sus valores a los objetos n y m. Es lo mismo que hacer funcion(10,20), cuando llama a la función con parámetros constantes. Si los parámetros por valor no funcionasen así, no sería posible llamar a una función con valores constantes o literales.

Si quisiera que los cambios realizados en los parámetros dentro de la función se conservasen al retornar de la llamada, deberá pasarlos por referencia. Este punto es un poco más complejo y, como no lo necesita, de momento no se va a abordar. Es necesario recordar que su ruta de trabajo en este libro es: “Si no lo necesita, no lo aprenda”.

2.4 Librerías

En el mundo de Arduino, una librería es un trozo de código que incluye en su sketch y que proporciona funciones determinadas que, simplemente, llama cuando le interesa. Por ejemplo, si va a utilizar un determinado sensor, puede buscar si existe una librería asociada. En caso de que la encuentre, puede añadirla a su programa y utilizar las funciones que ofrece para manejar dicho sensor. No tiene que conocer como está hecha o programada, simplemente debe saber qué funciones le ofrece y cómo utilizarlas. Es lo mismo que saber conducir un coche, no está obligado a entender el funcionamiento del motor o cómo es capaz de moverse. Algunas librerías funcionan por sí mismas, es decir, incluyéndolas directamente en su programa; otras precisan de un hardware adicional para ser utilizadas. Normalmente, cuando adquiere una shield nueva, para, por ejemplo, controlar un servomotor, descarga la librería asociada que se ocupa de manejar este hardware, facilitándole mucho el trabajo, ya que se despreocupa de la comunicación entre dicha shield y Arduino.

Es importante señalar que no debe confundir el concepto de función con el de librería. De hecho, una librería es un conjunto de funciones con un objetivo específico. La declaración de librerías, tanto en C como en C++, se debe hacer al principio de todo su código; antes de la declaración de cualquier función o línea de código, debe indicarle al compilador qué librerías usar, para saber qué términos están correctos en la escritura de su código y cuáles no. La sintaxis es la siguiente: #include <nombre de la librería> o alternativamente #include “nombre de la librería”. En su código puede declarar todas las librerías que quiera, aunque en realidad no tienen sentido declarar una librería que no va a usar en su programa; sin embargo, no existe límite para ello. La directiva de preprocesador #include se usa en los lenguajes C y C++ para “incluir” las declaraciones de otro fichero en la compilación. Esta directiva no tiene más misterio para proyectos pequeños. En cambio, puede ayudar aprovechar bien esta directiva en proyectos con un gran número de subdirectorios.

Por otra parte, las librerías propias de Arduino se catalogan en tres tipos:

* Librería core.

* Librerías estándar.

* Librerías añadidas o contributivas.

La librería principal o core se proporciona con el IDE de Arduino y es fundamental para los usuarios principiantes y para los más experimentados. Oculta gran parte de la complejidad que tradicionalmente supone trabajar con un microcontrolador. Los miembros del equipo de desarrollo de Arduino que participaron en enseñar a los estudiantes a usar microcontroladores en sus proyectos, reconocieron que el poco uso de muchos microcontroladores tradicionales, por parte de la mayoría principiantes y neófitos en el campo de la electrónica, era la dificultad de su programación. Estudiaron cuáles eran la acciones o proyectos que muchos de sus estudiantes querían llevar a cabo con un microcontrolador y, basándose en esto, diseñaron una biblioteca central que evitara la complejidad de las tareas más engorrosas e hiciera la programación más fácil. La mayoría de los proyectos leen datos en los pines de entrada y escriben datos en los pines de salida. La librería core hace que estas tareas comunes sean sencillas de utilizar. Por ejemplo, para leer el valor de una patilla digital, solo tiene que utilizar la función digitalRead(). Lo mismo pasa con la función serial(), que permitía interactuar con el programa monitor sin excesiva dificultad.

Cuando haya descargado e instalado el IDE de Arduino observará que algunas librerías llamadas estándar se incluyeron con la instalación. Las bibliotecas estándar son las que el equipo de desarrollo Arduino pensó que eran necesarias por muchas personas en sus propios proyectos. Estas librerías no se incluyen por defecto, como la librería core, debido a que Arduino ha limitado incluirlas automáticamente, ya que sería una pérdida de recursos (sobre todo, en memoria del propio microcontrolador) dejando poco espacio para su propio código. Para utilizar las librerías estándar, tiene que incluirlas explícitamente en sus sketch. Para ello, es necesario agregar una sentencia #include en la parte superior del programa. Por ejemplo, si quiere incluir la librería LiquidCrystal, que se utiliza para mostrar datos sobre una pantalla LCD, hay que añadir lo siguiente al principio del sketch:

#include <LiquidCrystal.h>

El nombre de la librería está delimitado por paréntesis angulares y, además, la línea no termina con un punto y coma (;) como es usual. Se dará cuenta de que todas las librerías que forman parte del core de Arduino llevan la h.

En la figura 2.7 se pueden observar dos librerías estándar que vienen incluidas “de serie” con el IDE de Arduino.

Finalmente, denominamos librerías añadidas o contributivas (figura 2.7) a aquellas aportadas por algunos usuarios o aficionados altruistas o por empresas que han desarrollado hardware y que proporcionan estas librerías para compatibilizarlo con Arduino. Aunque hoy en día, la empresa Arduino está ofreciendo poco a poco y con cada nueva versión de su IDE, nuevas librerías del hardware que va apareciendo en el mercado. De hecho, no hay más que observar el propio buscador e instalador (figura 2.8) que trae integrado por defecto el IDE, para examinar los cientos de posibles librerías que se pueden instalar y utilizar en sus proyectos.

CAPÍTULO 3
Transmisión en serie Pines analógicos y digitales
3.1 Monitor serie

La placa Arduino MKR puede establecer comunicación con el ordenador a través de una conexión por un cable USB para recibir los programas y que queden grabados en el microcontrolador. Solo es necesario indicar el número de puerto USB (figura 3.1) donde está conectado el MKR y, desde el IDE visible en el PC, presionar el botón de enviar o subir.

Además, dentro de la interfaz IDE dispone de la opción monitor serie que posibilita la visualización de datos procedentes de Arduino. Es decir, que la comunicación serie es en los dos sentidos. Puede, por tanto, monitorizar lo que pudiera enviar Arduino y verlo en una ventana del IDE. Si su placa está captando datos de temperatura o de humedad o de lo que sea del entorno ambiental, estos datos se pueden observar en tiempo real en el PC. Pero ojo, no puede guardarlos, solo ir visualizándolos a medida que los adquiere por Arduino.

Para ilustrar de forma práctica esta característica examinará un sketch que envíe desde Arduino un mensaje de texto. El contenido del mismo lo verá en la ventana del monitor serie del IDE.

En el programa mostrado en la figura 3.2 se observan dos líneas nuevas:

Serial.begin(9600);

Esta sentencia debe colocarse dentro de la estructura de configuración setup() y establece la velocidad en bits por segundo (baudios) entre la placa de Arduino y el PC. Debe ser igual en ambos dispositivos. La segunda sentencia envía al PC el texto (entre paréntesis y comillas) añadiendo un salto de línea.

Serial.println(“Esto del arduino es para frikis”);

Al estar dentro de la estructura loop() se ejecutará indefinidamente; de ahí que se escriba la dichosa frase un montón de veces dentro de la ventana del programa monitor (figura 3.3). Pero, además, podría utilizar el programa monitor para enviarle órdenes a Arduino a través de texto o códigos ASCII. Es decir, se puede gobernar Arduino desde el ordenador.

El campo que abre está lleno de posibilidades, tanto en la visualización de datos como la del propio control Arduino. Así que, a partir de aquí, se utilizará este recurso para la ejecución de proyectos.

3.2 Pines digitales

Ha llegado el momento de empezar a poner a trabajar su Arduino. Y lo va a hacer con los pines de la placa que sirven para manejar señales digitales. Las patillas digitales Arduino MKR 1010 están numeradas del 0 al 14, ambas incluidas. Sin embargo, como se observa en la figura 3.4, solo hay que utilizar los pines del 0 al 12, ya que los pines 13 y 14 están reservados para la comunicación serie entre el PC y el propio Arduino. De hecho, al lado de dichos números están serigrafiados en la placa, las etiquetas TX y RX, que son las abreviaturas de transmisión y recepción serie, respectivamente. El estudio de las patillas analógicas se pospone para más adelante. Por ahora nos vamos a centrar en lo más básico y sencillo: escribir y leer unos y ceros. No obstante, antes de empezar hay que conocer cómo funcionan esos dispositivos que normalmente están asociados a los pines digitales. Usará los diodos led como salidas para mostrar un uno o un cero (encendido/apagado). Los interruptores o pulsadores se utilizarán para proporcionar información digital de entrada a Arduino, lo que se abordará en el siguiente punto.

Una señal analógica (figura 3.5) es continua y puede tomar infinitos valores. Una señal digital es discontinua y solo puede tomar dos valores o estados: 0 y 1. Estos dos valores pueden ser impulsos eléctricos de baja y alta tensión, interruptores abiertos o cerrados, pulsadores, etc.

3.2.1 Funcionamiento de los interruptores, pulsadores y potenciómetros

El diodo led. Es un componente muy común, infinitamente útil, que convierte en luz la intensidad eléctrica que circula por él. Los ledes vienen en diferentes formas, tamaños y colores. La conexión de un led en un circuito está “polarizada”, es decir, la corriente puede entrar y salir del mismo en una sola dirección. Entra por el lado de la patilla llamada ánodo (positivo) y sale por la patilla denominada cátodo (negativo). No puede circular en sentido contrario. Para identificar cuáles son las patillas descritas, eche un vistazo a la figura 3.6.

Al añadir un led a un proyecto se deben tener en cuenta los valores de voltaje y corriente. Por ejemplo, los ledes rojos comunes requieren alrededor de 1.7 a 5 voltios de tensión entre ánodo y cátodo y una corriente mínima de 20 mA para encenderse normalmente. En el extremo contrario del valor máximo de corriente, todo diodo led tiene que llevar asociado en serie una resistencia para limitar la corriente que pase por él (figura 3.7). Sin esta resistencia, el diodo led podría quemarse. Por ello, el problema que se presenta es calcular la resistencia adecuada para su led. Esto es algo muy sencillo, y se aplicará la ley de Ohm:


donde:

R es la resistencia limitadora;

VCC es la tensión de alimentación (valor de la batería);

Vf es la caída típica de voltaje en el led, e

If es la corriente típica que debe pasar para que se encienda el led.

Por ejemplo, tiene una alimentación de 9 V y desea poner un diodo led rojo con Vf = 1.2 voltios e If = 20 mA. Su resistencia limitadora R será de 390 ohmios. Aunque este valor siempre es estimativo, ya que si escoge un valor comercial de la resistencia un poco más bajo, no pasará nada, circulará una corriente más alta y el led se encenderá un poco más. Claro está, sin pasarse demasiado, porque si elige por “avaricia de luminosidad” una resistencia muy baja que permita una intensidad muy alta (por encima de los 100 mA), destruiría el led.

El interruptor, como su nombre indica, es un dispositivo que permite o no el paso de corriente eléctrica. En el mercado existen muchos tipos. Los que utilizará para insertarlos en la protoboard son los llamados de tipo DIP (dual in-line package).

En las figuras 3.8 y 3.9 se observan un conjunto de interruptores de tipo DIP con dos posiciones de funcionamiento: ON/OFF.

El pulsador. Los pulsadores son de diversas formas y tamaño y se encuentran en todo tipo de dispositivos, aunque principalmente en aparatos eléctricos y electrónicos. En general, los pulsadores se activan al presionarlos con un dedo. Permiten el flujo de corriente mientras son accionados. Consta del botón pulsador, una lámina conductora que establece contacto con los dos terminales al oprimir el botón y un muelle que hace recobrar a la lámina su posición primitiva al cesar la presión sobre el pulsador. Cuando ya no se presiona sobre él, vuelve a su posición de reposo. Puede ser un contacto normalmente abierto en reposo NA (NO en inglés: normally open), o con un contacto normalmente cerrado en reposo NC.

El tipo de pulsadores que usará con Arduino son los de tipo mini, tal como se aprecia en la figura 3.10. Llevan cuatro contactos unidos dos a dos, de tal manera que cuando pulsa, se establece conexión eléctrica entre un lado y otro del pulsador.

El potenciómetro. La mayoría de la gente no lo sabe, pero la mayoría utiliza un potenciómetro casi todos los días. Puede encontrarlos en los automóviles, equipos de música, interruptores de luz y muchos otros dispositivos. Sin ellos, tendría serias dificultades para accionar la mayoría de los aparatos electrónicos. Sin embargo, ¿qué son exactamente los potenciómetros y qué funciones tienen? Los potenciómetros (figura 3.11) son resistencias que constan de tres terminales (A, B, C). Estas resistencias tienen divisores de tensión (circuitos lineales) que proporcionan una salida de tensión (terminal B), que es menor que el voltaje de entrada. Los potenciómetros proporcionan transiciones suaves de los niveles de tensión y pueden ser rotativos o lineales. Uno de los principales usos de los potenciómetros son las perillas de control de audio. Al girar el dial del potenciómetro hacia un lado o el otro, controla el volumen del dispositivo de audio. Se pueden encontrar otros potenciómetros en las perillas de audio de los graves, los agudos y las perillas de las pistas que permiten seleccionar el grado de frecuencias altas y bajas. Los productores de un estudio tienen docenas de potenciómetros en su equipo de sonido para conseguir el sonido adecuado y el equilibrio en una grabación.

Los potenciómetros también se encuentran habitualmente en los reguladores de intensidad de las luces. Los reguladores de intensidad operan de forma lineal, pero trabajan de la misma forma que los potenciómetros del tipo circular o a perilla.

Cuando una persona ajusta un potenciómetro afecta la corriente que está tomando parte en la iluminación y, por lo tanto, puede hacer que las luces se atenúen o sean más brillantes, de acuerdo con la cantidad de electricidad que deje llegar a la bombilla. En los proyectos con Arduino utilizará un tipo de potenciómetro denominado trimmer que es adecuado para los montajes en la protoboard.

En esta primera práctica se va a simular el juego de luces del famoso coche fantástico de la serie de televisión que se hizo popular en los años ochenta.

El algoritmo que implementará es el que se muestra en la figura 3.12.

Se trata de apagar y encender ledes con esperas de tiempo intercaladas para producir un efecto de movimiento de la luz que recorre estos diodos.

Ahora va a construir el circuito (figura 3.13). Le recomiendo que primero lo realice con el software Fritzing. Es una buena forma de aprender a documentar proyectos y, sobre todo, impactar a los amigos con una excelente presentación.

En cuanto al hardware, necesitará:

* Cinco diodos led

* Cinco resistencias de 220 W

* Una protoboard

* Cablecitos de conexión

* Un Arduino MKR 1010 y un cable USB

Conecte los cinco diodos led a los pines digitales (1 al 5) a través de las cinco resistencias limitadoras. Examine el sketch que debe escribir, guardar y subir a Arduino para comprobar su funcionamiento.

Práctica 3.1 Empezar a programar. El coche fantástico



En este programa aparecen tres funciones que hacen todo el trabajo. Las estudiamos con detalle a continuación. ¡Prepárese porque empieza a programar!

pinMode (pin, mode). Esta instrucción es utilizada en la parte de configuración setup() y sirve para configurar el modo de trabajo de un pin, pudiendo ser el parámetro mode como INPUT (entrada) u OUTPUT (salida). 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 estado de alta impedancia.

Estos pines tienen a nivel interno una resistencia de 20 kΩ a la que se puede acceder mediante software. A estas resistencias se accede de la siguiente manera:


Las resistencias internas normalmente se utilizan para conectar las entradas a interruptores. En el ejemplo anterior no se trata de convertir un pin en salida, es simplemente un método para activar las resistencias interiores. Los pines configurados como OUTPUT (salida) se dice que están en un estado de baja impedancia y pueden proporcionar 40 mA de corriente a otros dispositivos. Esta corriente es suficiente para alimentar un diodo led, pero no es lo suficientemente grande para alimentar cargas de mayor consumo como relés, solenoides o motores.

digitalWrite(pin,mode). Envía al pin definido previamente como OUTPUT el valor HIGH o LOW (poniendo en 1 o 0 la salida). Por ejemplo:


delay(milisegundos). Detiene la ejecución del programa la cantidad de tiempo en milisegundos que se indica en la propia función, de tal manera que 1000 equivale a 1 segundo.

delay(2000); // espera 2 segundos

Cuando reviso el sketch anterior me doy cuenta que tanto el algoritmo como el programa propiamente dicho tienen partes que se repiten continuamente y, aunque utilice la opción “Copiar y pegar” dentro del IDE, la verdad es que no es muy flexible. Por ello voy a cambiar un par de cosas.

Primero introduciré una variable de tipo “int” para poder variar el tiempo de espera en la función delay(ms). Después reemplazaré el código principal por otro más corto que use la potencia de la estructura “for” que vio anteriormente. A esto, los programadores experimentados lo llaman optimizar el código.

Práctica 3.2 Optimizar el código


El primero de los bucles “for” repetirá el código dentro de las llaves siempre y cuando la condición sea verdadera. En este caso se ha utilizado una variable de tipo entero a que comienza con el valor 1. Cada vez que se ejecuta el código, se le sumará 1 a dicha variable. El bucle continuará de esta manera mientras que “a” sea menor de 6. Una vez que sea igual o mayor que 6 se sale del bucle for y vuelve al principio de la estructura void loop(), es decir, vuelve a iniciarse otro bucle for desde el principio. El segundo bucle for inicializa la variable a con el valor 5 que es el penúltimo led. Ahora se va reduciendo esta variable hasta llegar al valor 1 que se corresponde con el primer led. De esta manera invierte la secuencia de encendido. Puede probar otros valores de la variable a para comprobar si he cometido una errata de código.

Además, dentro de la función delay(ms); se ha introducido una variable de tipo entero d que permite cambiar de manera sencilla el intervalo de espera.

Práctica 3.3 Encendido de un led con un pulsador

El propósito de esta práctica es encender un led mediante un pulsador. El led permanecerá prendido durante 2 segundos tras los cuales se apagará hasta que vuelva a presionar el pulsador.

El algoritmo, por otra parte, muy simple, es el que se muestra en la figura 3.14.

En cuanto al hardware, necesitará:

* Un diodo led

* Una resistencia de 220 Ω

* Una resistencia de 10 kΩ

* Un pulsador tipo mini

* Una protoboard

* Cablecitos de conexión

* Un Arduino MKR y un cable USB

Conectará el pulsador al pin digital 6 a través de una resistencia de 10 kΩ. Esta resistencia se lleva por el otro terminal a 5 voltios. El diodo led se conecta al pin 12 a través de una resistencia de 220 Ω. En la figura 3.15 se observa el circuito diseñado con Fritzing.

Las resistencias pull up y pull down no son más que resistencias dispuestas en una configuración determinada. Dicha configuración (figura 3.16) determina si la resistencia es de pull up o pull down. Este tipo de configuración establece un estado lógico a la entrada de un circuito lógico cuando dicho circuito está en reposo, siendo para pull up un estado lógico alto y para pull down, bajo. De esta forma, se evita falsos estados producidos por ruido eléctrico si dejara una entrada con un valor indeterminado.

En la configuración pull up, cuando el pulsador está en reposo, Vout será prácticamente Vcc, pudiéndose considerar como nivel lógico alto. Ahora bien, cuando se pulsa S1, se deriva toda la corriente a masa, por tanto, Vout será 0. Esto mismo ocurre con la configuración pull down, pero a la inversa. Cuando el circuito está en reposo, la caída de tensión en R1 es prácticamente 0 que es la misma tensión de Vout. En ese momento tendremos un nivel lógico bajo. Al pulsar S1, la caída de tensión en R1 ahora será Vcc, Vout será un nivel lógico alto. Generalmente, se suele usar un valor de 10 kΩ para estas resistencias.

A continuación se examina el sketch que debe escribir, guardar y subir a Arduino para comprobar su funcionamiento, encendiendo un led durante dos segundos con un pulsador.



La dinámica del programa es simple. Se comprueba continuamente el estado del pulsador cuyo estado en reposo produce un 0 en el pin de entrada 6 de Arduino MKR 1010. Si no activa el pulsador se comprueba el “if” de forma indefinida. En cuanto pulse, el estado de la patilla 6 cambia a voltaje positivo y entonces se ejecutan las acciones que van comprendidas entre llaves, es decir, el encendido del led, la espera de 2 segundos y el apagado del diodo. Tras esto, vuelve al principio del void loop(), ejecutando de nuevo la comprobación del pulsador con la estructura “if”.

Descubrirá algunas cosas nuevas:

#define. Es un comando del lenguaje C muy útil que permite al programador dar un nombre a un valor constante antes de que se compile el programa. Las constantes definidas en Arduino no aumentan el tamaño que el programa ocupa en el chip. El compilador reemplaza las referencias a estas constantes con el valor definido en tiempo de compilación. Básicamente utilizará #define para etiquetar los pines digitales y, de esta manera, cada vez que en el programa se haga referencia a esa etiqueta se apuntará a su valor. Por ejemplo, en nuestro sketch cada vez que utiliza la palabra led hace referencia al pin 12 de Arduino.

digitalRead(pin). Lee el valor de un pin (definido como digital) dando un resultado HIGH (alto) o LOW (bajo) y pudiendo depositar este valor en una variable. Por ejemplo:

valor = digitalRead(4);

En esta sentencia se lee el estado del pin 4 y se deposita su estado alto o bajo en la variable valor, que se supone que se ha definido previamente como de tipo booleano o entero. Evidentemente, esto es útil para evaluar el estado abierto o cerrado de un pulsador o interruptor. Por ello, cuando en el sketch anterior tiene la expresión: “if (digitalRead(BUTTON) == HIGH)” lo que está haciendo es evaluar si el pin 6 definido con el nombre BUTTON está HIGH o LOW. Es decir, se comprueba el estado del pulsador y, en función de su estado, ejecuta o no lo que está dentro de las llaves del if.

Práctica 3.4 Control de dos semáforos

Imagine un túnel estrecho donde sería imposible circular a la vez en ambos sentidos. Desde luego necesitaría un sistema de regulación para que no entraran dos vehículos al mismo tiempo en sentido contrario. En uno de los extremos del túnel, al que llamará “ENTRADA DEL TÚNEL” tiene un semáforo, “SEMÁFORO 1”, que dará acceso al mismo, mientras que en otro extremo tiene “SALIDA DEL TÚNEL”, donde, a su vez, dispone de un segundo semáforo, “SEMÁFORO 2”, que permanecerá en estado contrario al primero para los vehículos que quieran regresar y no hacer coincidir el tráfico en ambos sentidos (figura 3.17).

Va a resolver el diseño considerando la sincronización de los dos semáforos: el de entrada al túnel y el de salida. De usted depende que no se encuentren dos coches en medio del mismo, ya que, como se observan en las fotos, el túnel solo tiene un carril. Para simular los dos semáforos utilizará 6 diodos led: 2 de color rojo, 2 de color verde y 2 de color amarillo (a falta del color ámbar) (figura 3.18). Observe el diagrama de flujo (figura 3.19) en el que se observan cómo se cumple la secuencia típica de un cruce de semáforos normal. Mientras que un semáforo está en rojo, el otro está en verde, y viceversa. Los cambios de un color a otro se producen tras una espera determinada, que, en este caso, supone de varios segundos. El tiempo de cambio de cada semáforo puede establecerlo en 2 minutos, ya que por esta carretera no existe demasiado tráfico. En cuanto al hardware, necesitará:

* 6 diodos led de varios colores

* 6 resistencias de 220 Ω

* Una protoboard

* Cablecitos de conexión

* Un Arduino y un cable USB

Un vistazo al esquema de semáforos siguiente le permitirá entender mejor el diagrama de flujo anterior y el listado de programa que se muestra.





Ahora tiene un nuevo concepto que es el de función. Como se expusoanteriormente, una función es un trozo de código que se va a utilizar varias vecesdentro del mismo programa. Una función es, por tanto, un bloque de código que tiene un nombre y un conjunto de sentencias. Las funciones se declaran asociadas a un tipo de valor: type. Este valor será el que devolverá la función, por ejemplo int se utilizará cuando la función devuelva un dato numérico de tipo entero. Si la función no devuelve ningún valor, entonces se colocará delante la palabra void, que significa “función vacía”. Después de declarar el tipo de dato que devuelve la función se debe escribir el nombre de la función y entre paréntesis se pondrán, si es necesario, los parámetros que se deben pasar a la función para que se ejecute. Su formato específico es el siguiente:


En el ejemplo anterior se expresan dos funciones diferenciadas: la función semaforo_1() y la función semaforo_2(). Son de tipo void porque no devuelven nada; solo ejecutan una serie de acciones para gobernar las luces de las que consta cada semáforo. Además, como ve, se han definido antes de la estructura loop().

Imagine que está en un supermercado esperando turno en una larga cola. Normalmente tendría un contador de turnos que sería visible desde cualquier zona del local. Si quisiera fabricar un contador similar con Arduino sería bastante sencillo.

El programa que va a crear va a simular uno de esos contadores. Deberá mostrar en nuestro monitor serie el número de veces que un pulsador ha sido presionado. Además, hará un proceso que, de acuerdo al número de pulsaciones, encienda o apague un led. Para hacerse una idea le muestro el esquema en la figura 3.20, donde he conectado el pulsador al pin digital 6 a través de una resistencia pull up de 10 kΩ.

En cuanto al hardware, necesitará:

* 1 diodo led de cualquier color.

* 1 resistencia1 de 220 Ω

* 1 pulsador tipo mini

* Una protoboard

* Cablecitos de conexión

* Un Arduino y un cable USB

Práctica 3.5 Contador de pulsaciones



En el código ha creado la variable Turno que se incrementará a medida que se presiona el pulsador “Turno++”, pero también ha establecido un rango de números para el contador que va de 1 a 10. Si desea incrementar ese rango solo debe editar la siguiente línea:

if (Turno > 10) Turno = 1;

Además, ha añadido un led que parpadeará una vez con cada cambio de turno.

El resultado en su monitor serie es el siguiente (figura 3.21):

Como novedad en este sketch, dispone de dos nuevas funciones relacionadas con la trasmisión serie entre Arduino y PC, y también se juega con los if anidados.

3.2.2 Memoria FlashStorage

¿Sabe que su Arduino MKR tiene una memoria no volátil? Es decir, tiene una memoria en la cual no se borran ni se pierden datos cuando deja de alimentarlo, por lo que podría usarla para almacenar y más tarde recuperar información importante: recuperar la configuraciones, tales como calibraciones de sensores (una vez calibrado un sensor no es necesario volver a hacerlo puesto que los límites están guardados en la Flash), contadores de tiempo de uso, de modo que cuando Arduino MKR deje de estar alimentado no pierda la cuenta de tiempo de funcionamiento, etc.

En Arduino UNO tenía una memoria EEPROM que era realmente fácil de programar. El MKR carece de esta memoria, pero eso no es un problema ya que puede usar la memoria Flash para el mismo uso y disfrute.

La memoria Flash, debido a sus propiedades, generalmente se usa para almacenar el código del firmware, pero también se puede usar para almacenar los datos del usuario. Tiene una cantidad limitada de ciclos de escritura. La memoria Flash típica puede realizar aproximadamente 10 000 ciclos de escritura en el mismo bloque Flash antes de comenzar a “desgastarse” y comenzar a perder la capacidad de retener datos.

Así que cuidado: el uso incorrecto de esta biblioteca puede destruir rápida y permanentemente la memoria flash de su micro, en particular, debe evitar llamar a la función write() con demasiada frecuencia y asegurarse de que durante toda la vida del micro el número de llamadas a la escritura se mantiene muy por debajo del límite anterior de 10 000 (es una buena regla general tener en cuenta ese número incluso si el fabricante del micro garantiza un mayor número de ciclos).

No recomiendo utilizar la memoria Flash si su micro proporciona una EEPROM. Casi siempre es mejor usar la EEPROM porque es un tipo de memoria diseñada con el propósito específico de almacenar datos del usuario (tiene una vida útil más larga, número de ciclos de escritura, etc.). Pero en ausencia de una EEPROM, puede usar esta biblioteca para usar una parte de la memoria Flash como alternativa a la EEPROM. Sin embargo, siempre debe tener en cuenta sus límites.

Puede almacenar datos complejos declarando una estructura con más campos y crear un objeto FlashStorage para almacenar toda la estructura. Es una información que no se borra, aunque desconecte su placa de la alimentación o la reinicie. Pero el contenido memorizado sí se borrará cada vez que se carga un nuevo sketch.

Para usar la memoria Flash en sus proyectos es necesario disponer de la biblioteca FlashStorage (figura 3.22). Esta tiene como objetivo proporcionar una forma conveniente de almacenar y recuperar datos del usuario utilizando la memoria Flash no volátil de los microcontroladores.

Para esta práctica se retomará el contador de supermercado. Va a implementarle una función de recuperación en el caso que se vaya la corriente y quiera seguir el turno donde lo dejó.

Ücretsiz ön izlemeyi tamamladınız.

Türler ve etiketler

Yaş sınırı:
0+
Hacim:
671 s. 670 illüstrasyon
ISBN:
9788426732354
Yayıncı:
Telif hakkı:
Bookwire
İndirme biçimi:

Benzer kitaplar