Professional Documents
Culture Documents
1
Índice
Introducción 3
Estructuras de control de flujo repetitivas 3
while 4
do while 8
for 11
break y continue 13
go to 14
Comunicación serie 15
Monitor serie 17
Enviar datos del Arduino al IDE 21
Saltos de línea y tabulaciones 31
Variables 34
Recibir datos 42
Comunicación serie entre Arduinos 57
Funciones 68
Funciones con valor de retorno 73
Pasar parámetros a una función 76
Interrupciones 81
Interrupciones por señal 81
Interrupciones por tiempo 85
Fritzing 87
Simuladores 90
2
Introducción
Este ejemplar es la continuación del libro Arduino. Entendiendo el
mundo. Tomo I. Por lo tanto, si no has leído el Tomo I, te recomiendo
que lo hagas antes de continuar con la lectura de este. La finalidad de
este libro es compartir nuevos conocimientos relacionados con los
vistos en el libro anterior.
3
while
while(condición)
{
//Instrucciones que se ejecutan mientras se cumpla la condición
}
Imagen 1.
Imagen 2.
4
Imagen 3.
Imagen 4.
5
Imagen 5.
Imagen 6.
Ejercicio propuesto:
6
1. Conectar un led, un botón y un potenciómetro. Regular el led
mientras el botón esté pulsado.
7
do while
do
{
//Instrucciones que se ejecutan al menos una vez y
mientras se cumpla la condición
}while(condición);
Imagen 7.
8
Imagen 8.
Imagen 9.
Ejercicios propuestos:
9
2.Conectar un led y un potenciómetro. El led siempre se
tiene que encender durante al menos 1 segundo y, si la
entrada analógica (conectada al potenciómetro) recibe una
señal entre 1 y 4 V, permanecerá encendido al menos 1
segundo más. Cuando no se cumpla esta condición, el led
deberá apagarse durante al menos 4 segundos .
10
for
11
Imagen 10.
Imagen 11.
Imagen 12.
12
break y continue
Imagen 13.
Imagen 14.
13
Imagen 15.
go to
go to nombre_etiqueta;
-
.
.
.
nombre_etiqueta:;
Imagen 16.
14
Imagen 17
Comunicación serie
Para transmitir datos al exterior, un Arduino dispone de varios
protocolos de comunicación: atendiendo a si es una comunicación
síncrona o asíncrona, disponemos de varios protocolos de
comunicación. En este capítulo, trabajaremos con la comunicación
serie (UART).
15
USB. Para ello, el Arduino UNO dispone de un segundo MCU
(ATmega16U2), que realiza la traducción.
Imagen 18.
Todos los MCU de los Arduinos disponen entonces del hardware para
establecer una comunicación UART (transmisor receptor asíncrono
universal). No necesitamos profundizar en esta tecnología, lo que nos
interesa saber es que, para que dos dispositivos se comuniquen
mediante UART, se necesitan tres cables: TX, que es por el que se
transmite, RX, por el que se recibe y GND, conexión en común entre
ambos dispositivos. Al disponer de dos líneas diferentes para recibir y
enviar datos, la comunicación es full duplex (información en ambos
sentidos).
16
Imagen 19.
Monitor serie
Imagen 20.
Si hacemos clic sobre la lupa, se abre una pestaña, además del IDE
de Arduino, lo que se conoce como «monitor serie».
17
Imagen 21. Monitor serie
Imagen 23.
18
Imagen 24.
Imagen 25.
Al lado del conector USB del hardware del Arduino UNO, disponemos
de un botón que sirve para restear el Arduino. Si continuamos con el
mismo programa y circuito anteriores y pulsamos el botón, vemos
que ocurre lo mismo que al abrir el puerto serie.
19
Imagen 26.
Serial.begin(parámetro);
• 300
• 1200
• 2400
• 4800
• 9600
• 19200
• 38400
• 57600
• 74880
• 115200
• 230400
• 250000
20
Imagen 27.
Serial.println();
Imagen 28.
21
Imagen 29.
Serial.print();
Imagen 30.
Imagen 31.
22
Imagen 32. Conexión Pull-Down externa
Imagen 33.
Imagen 34.
23
Imagen 35.
Imagen 36
Imagen 37.
24
Imagen 38.
Imagen 39.
Imagen 40.
25
Imagen 41.
Imagen 42.
Imagen 43.
26
¿Por qué? Un byte está formado por 8 bits, esto significa que
tenemos 256 (28) posibles combinaciones de ceros y unos. Si esto lo
traducimos a números reales, comprendería números entre 0 y 255.
Como la variable es de tipo byte, al llegar a 255 y tratar de
incrementar el valor del contador, este se resetea y vuelve a empezar
desde 0.
Imagen 44.
Imagen 45.
27
Con todos estos conceptos más claros, vamos a sacarle un poco más
de partido a la monitorización de un Arduino.
Imagen 46.
Imagen 47.
28
Imagen 48.
Con todo esto, podemos monitorizar el estado del led a través del
IDE. Puede darse la circunstancia de que, al cambiar de estado, nos
envíe dos veces el mensaje de encendido y apagado. Esto es debido
al mecanismo de un interruptor, que introduce interferencias en la
señal; veremos en próximos tomos cómo eliminar esto.
Imagen 49.
Lo que hace esto es que la señal pase varias veces por el margen que
delimita los dos estados posibles: encendido o apagado, 0 o 1...
Entonces, cabe la posibilidad de tomar lecturas incorrectas. Veremos
cómo solucionar esta cuestión en el próximo tomo, profundizando en
un componente nuevo: el condensador.
29
Imagen 50.
Imagen 51.
Imagen 52.
Imagen 53.
30
Tenemos conectado el potenciómetro, por un lado, a la entrada
analógica y, por otro, a una entrada digital. Lo que se pretende
demostrar es que los márgenes para cada estado son: de 0 a 2,5 V,
estado = 0, y de 2,5 a 5 V, estado = 1. Si analizamos el
comportamiento, vemos que, entre 2,4 y 2,6, los cambios se pueden
volver difíciles de predecir; es un factor que hay que tener en cuenta
a la hora de diseñar los circuitos con los que trabajemos.
Salto de línea: \n
Imagen 54.
Imagen 55.
31
Imagen 56.
Imagen 57.
Imagen 58.
32
Imagen 59.
Tabulación: \t
Al igual que ocurría con \n, que incluye un salto de línea, con los
caracteres \t se incluye una tabulación.
Imagen 60.
Imagen 61.
33
En resumen, el funcionamiento es igual que \n, pero haciendo una
tabulación y, por supuesto, se pueden usar en un mismo mensaje
varios saltos de líneas y tabulaciones.
Variables
Hasta ahora, hemos visto casi todos los tipos de datos numéricos,
salvo los datos tipo float y double, que permiten almacenar datos con
decimales. En estas variables, se pueden almacenar datos entre
3.4028235x1038 a 3.4028235x1038 y se escriben con punto y no con
coma.
34
Código Código Código
numérico Carácter numérico Carácter numérico Carácter
33 ! 65 A 97 a
34 " 66 B 98 b
35 # 67 C 99 c
36 $ 68 D 100 d
37 % 69 E 101 e
38 & 70 F 102 f
39 ´ 71 G 103 g
40 ( 72 H 104 h
41 ) 73 I 105 i
42 * 74 J 106 j
43 + 75 K 107 k
44 , 76 L 108 l
45 - 77 M 109 m
46 . 78 N 110 n
47 / 79 O 111 o
48 0 80 P 112 p
49 1 81 Q 113 q
50 2 82 R 114 r
51 3 83 S 115 s
52 4 84 T 116 t
53 5 85 U 117 u
54 6 86 V 118 v
55 7 87 W 119 w
56 8 88 X 120 x
57 9 89 Y 121 y
58 : 90 Z 122 z
59 ; 91 [ 123 {
60 < 92 \ 124 |
61 = 93 ] 125 }
62 > 94 ^ 126 ~
63 ? 95 _ 127 DEL
64 @ 96
35
Imagen 62.
Imagen 63.
Imagen 64.
36
Imagen 65.
Imagen 66.
Imagen 67.
37
Imagen 68.
Imagen 69.
Imagen 70.
Imagen 71.
38
Imagen 72.
Imagen 73.
Imagen 74.
39
Imagen 75.
Serial.write();
40
Imagen 76.
Imagen 77.
41
Hasta aquí quizás sea fácil de entender, lo que puede resultar un
poco más complicado es el envío de números. Cuando se envía un
número, lo que se hace es traducir cada dígito con la tabla ASCII y,
luego, se envía cada dígito traducido.
Código
numérico Carácter
48 0
49 1
50 2
51 3
52 4
53 5
54 6
55 7
56 8
Es importante tener esta cuestión en cuenta a la hora de recibir
valores del IDE, puesto que, si son números, antes de operar con
ellos, debemos realizar la conversión correcta.
Recibir datos
Serial.availble();
Imagen 78.
42
Una vez que sepamos si hay datos o no, debemos leerlos y
almacenarlos en una variable, para que se eliminen del buffer de
entrada y dejen espacio a otros datos que se puedan recibir. Si no lo
hacemos, una vez que se llene el buffer de entrada (con 64 datos),
cada carácter que nos envíen se perdería.
Serial.read();
Imagen 79.
43
Imagen 80.
Si enviamos:
Imagen 81.
Ilustración 82
44
byte o, lo que es lo mismo, entre carácter y carácter, ponemos un
guion para diferenciar cuándo empieza y acaba uno. En la
comunicación serie pasa algo similar: cada byte viene precedido por
un bit de «inicio» y un bit de «fin», que delimitan cada carácter.
Imagen 83.
Imagen 84.
45
Antes de enviar un mensaje por el puerto serie y probar si, al enviar
«encender», se enciende y, con «apagar» se apaga, debemos
configurar el monitor serie.
Imagen 85.
Equivalente número
Codificación binario natural
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 1 0 2
0 0 0 0 0 0 1 1 3
0 0 0 0 0 1 0 0 4
0 0 0 0 0 1 0 1 5
Código
numérico Carácter
48 0
49 1
50 2
51 3
52 4
53 5
54 6
55 7
56 8
46
Imagen 86.
toInt();
Imagen 87.
47
Ejercicios propuestos:
48
3. Conectar un led, un botón y un pulsador a un Arduino.
Configurar tres modos de funcionamiento que se puedan
controlar desde el IDE: modo 1, el led parpadea cada
segundo; modo 2, el led se puede encender o apagar con el
botón; modo 3, el led se puede regular con el
potenciómetro.
49
Continúaà
50
4. Dos Arduinos: el Arduino A recibe órdenes de encendido y
apagado de un led por el puerto serie y el Arduino B tiene
conectado el led. Si el A recibe el mensaje de encender, el B
debe encender el led; si el A recibe el mensaje de apagar, el B
debe apagar el led.
A B
51
B
52
5. Dos Arduinos: el Arduino A recibe el valor de regulación de
un led y el B tiene conectado el led. El Arduino B debe regular
el led en función del valor que se envíe por el puerto serie al
Arduino A.
A B
53
6. Dos Arduinos: el Arduino A se comunica por el puerto serie
con el IDE y el Arduino B tiene conectado un botón. En el
momento en el que se pulse o se deje de pulsar el botón del B,
el A debe enviar el mensaje correspondiente del evento que
acaba de ocurrir. (Solo ante un cambio de estado).
A B
54
7-Dos Arduinos: el Arduino A se comunica por el puerto serie
con el IDE y tiene conectado un potenciómetro; por otro lado,
el Arduino B tiene conectado un botón. Cada vez que se pulse
el botón del Arduino B, el A debe enviar al IDE el valor actual
del potenciómetro. Solo una vez por cada pulsación.
B
A
55
8Traductor de caracteres. Enviar un carácter y que el Arduino
nos devuelva su posición en la tabla ASCII y su codificación en
binario.
56
Comunicación serie entre Arduinos
A B
Imagen 88.
A B
Imagen 89.
57
A
Imagen 90.
Imagen 91.
A
B
Imagen 92.
58
Para esto, lo primero que tenemos que hacer es cargar el programa a
cada Arduino por separado y, luego, conectarlos. Hay que tener en
cuenta que el monitor serie utiliza el mismo canal y, si hay una
comunicación por los pines RX y TX proveniente de otro Arduino, no
vamos a poder cargar el programa.
Imagen 93.
Imagen 94.
59
A B
Imagen 95.
Imagen 96.
60
B
Imagen 97.
En los dos últimos casos, debido a que el Arduino UNO solo dispone
de un puerto serie, tenemos que cargar primero los programas y,
después, conectar los circuitos. Si, por ejemplo, queremos establecer
un chat entre dos ordenadores a través del IDE de Arduino, no
podríamos hacerlo; en cambio, si dispusiéramos de otro Arduino,
como el Arduino Mega 2560, que dispone de varios puertos, esto ya
sería posible.
Imagen 98.
61
Como el Arduino Mega 2560 dispone de hasta cuatro puertos serie,
podemos utilizar uno para comunicar el Arduino con el IDE de su PC
y, otro, para la comunicación con el otro Arduino.
Imagen 99.
Imagen 100.
62
buscar una librería en concreto; si hemos encontrado algún caso
práctico en una web y vemos que necesitamos una librería, podemos
probar a buscarla en este apartado.
Imagen 101.
Imagen 102.
Por último, nos aparece un listado con todas las librerías instaladas;
muchas de ellas ya vienen instaladas al descargar el IDE de Arduino,
son las que se conocen como librerías oficiales de Arduino.
63
Las librerías que instalemos por nuestra cuenta se incluirán en esta
lista de librerías, pero con un encabezado diferente. Ahora que
sabemos cómo instalar librerías, tenemos que saber utilizarlas para
tener acceso a sus funciones.
Para ello, debemos declarar qué librería o librerías vamos a utilizar;
una forma sencilla de hacerlo es seleccionarla de la lista. Para el caso
que nos ocupa, necesitamos la librería «SoftwareSerial».
Imagen 103.
Imagen 104.
64
Cada librería implementa sus propias funciones o instrucciones, por lo
que cada librería «es un mundo». Como al principio puede resultar
complejo entender cada librería, disponemos de ejemplos para
asimilar su funcionamiento.
Imagen 105.
Imagen 106.
65
de utilizar un puerto del Arduino UNO para la comunicación con el IDE
y, otro, para la comunicación con otro Arduino.
Imagen 107.
Con este paso, ya podemos trabajar con este puerto igual que hemos
hecho con el Serial; la diferencia es que el prefijo es mySerial:
mySerial.print();, mySerial.println();, mySerial.available();.
66
A
B
Imagen 108.
Imagen 109.
67
Cargamos el programa anterior a cada Arduino, conectamos entre sí
los Arduinos y cada uno a un PC. Abrimos en cada PC el IDE de
Arduino y empezamos a enviar mensajes. Al enviar mensajes,
comprobamos que, los que nosotros enviamos, se visualizan en
nuestro monitor en el margen derecho y, los que nos envía el otro
PC, en el margen izquierdo; se ha programado cada Arduino para
simular el funcionamiento de un chat.
Funciones
Una función no es más que un trozo de código que se identifica con
un nombre y que, para que se ejecute, debe ser «llamado». Por lo
tanto, podemos escribir líneas de código fuera del void setup y void
loop, que deben estar identificadas por un nombre y que se
ejecutarán si se las «llama» desde otra parte del programa.
Imagen 110.
68
Imagen 111.
Imagen 112.
69
incluye el nombre de la función y, la de cierre, el nombre de retorno.
En cuanto al nombre de una función, debemos seguir las mismas
normas que en la declaración de funciones.
Ejercicios propuestos:
70
7. Crear una función para que un led parpadee cada segundo.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
71
8. Con una función, encender un led si se ha pulsado un botón.
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
72
Funciones con valor de retorno
La función tipo void loop ejecutaba el código que había entre sus
llaves y, al finalizar, volvía a la línea desde donde había sido
«llamada». Las funciones permiten devolver un valor (tipo string,
int...) en la línea en la que son «llamadas».
Para ello, las funciones no deben ser declaradas tipo void, sino que
deben ser declaradas como algún tipo de variable, es decir: tipo int,
string, etc.
Al declarar así una función, el valor que devuelve es del tipo que sea
la función, es decir: una función tipo int devuelve un valor tipo int. Es
«obligación» de la persona que programa almacenar el valor que
devuelve la función.
Imagen 113.
73
Imagen 114.
Ejercicios propuestos:
74
9. Crear una función que, al recibir un mensaje por el
monitor serie, lo almacene y, al finalizar, devuelva ese
mensaje al programa principal para visualizarlo en el
monitor serie.
75
Pasar parámetros a una función
Una función no solo puede devolver datos, sino que, al ser llamada,
se le pueden pasar datos. Para ello, debe haber una concordancia
entre el valor que se envía y la variable en la que se almacena, es
decir, ambos deben ser del mismo tipo.
Imagen 115.
Imagen 116.
76
Podemos pasar a una función el número de parámetros que
necesitemos y todos los datos pueden ser, o no, del mismo tipo.
Mantenemos el mismo circuito y cargamos el siguiente programa.
Imagen 117.
Ejercicios propuestos:
77
10 Pasar como parámetros el valor de una entrada analógica
y de un pulsador, para que la función regule el led si el
pulsador está pulsado y lo apague si no está pulsado.
78
11. Crear funciones para establecer un chat mediante el puerto
serie con otro Arduino.
79
El IDE de Arduino dispone de una herramienta que permite escribir
funciones en otras «ventanas» y así dejar la «hoja» en la que
escribimos el programa principal para: declarar librerías, variables y
las partes básicas del programa (loop y setup).
Imagen 118.
Imagen 119.
Imagen 120.
80
Imagen 121.
Interrupciones
Este tipo de «mecanismo» interrumpe la ejecución normal de un
programa por la atención de un evento. Los eventos que puede
atender un Arduino son:
attachInterrupt(Pin_interrupción,nombre_función,tipo_evento);
81
No se pueden atender eventos en todos los pines: en el caso del
Arduino UNO, disponemos de dos eventos por interrupción en los
pines 2 y 3, que se configuran como interrupción 0 e interrupción 1,
respectivamente.
Los eventos que puede atender una interrupción son los que
presentamos a continuación; vamos a suponer que el evento
sucederá en el pin 2, es decir, la interrupción 0 y la función que se
tiene que ejecutar tiene el nombre de «funcion_evento»:
82
Vamos a realizar un ejemplo para entender cómo funciona una de
ellas, ya que el resto funciona exactamente igual; la diferencia reside
en el evento que se atiende.
Imagen 122.
Imagen 123.
83
Imagen 124.
detachInterrupt ( interrupción )
84
Interrupciones por tiempo
Imagen 125.
Imagen 126.
Imagen 127.
Ejercicios propuestos:
85
del botón; si se da este caso, se regulará el tiempo de interrupción
con el valor del potenciómetro entre un valor de 0,2 y 2 segundos
proporcional a la medida del potenciómetro.
86
Fritzing
Fritzing es una herramienta que nos permite graficar los circuitos que
realizamos mediante un entorno sencillo e intuitivo. Todas las
imágenes de circuitos que se muestran en esta serie de ejemplares
fueron creadas en esta herramienta.
Imagen 128.
87
Imagen 129.
Imagen 130.
88
Imagen 131.
Imagen 132.
89
Imagen 133.
Simuladores
Los simuladores son ideales para cuando no disponemos de un
Arduino, pero necesitamos realizar pruebas o, incluso, queremos
desarrollar un proyecto, pero, por seguridad y antes de cargarlo al
Arduino, queremos probarlo si peligro.
90
Imagen 134.
Imagen 135.
Imagen 136.
91
Imagen 137.
92