Taller Arduino
Taller Arduino
Introducción
En los últimos años se han producido grandes cambios culturales, atravesados por las
tecnologías de la información y la comunicación, que transformaron sustancialmente las
formas en las cuales el conocimiento se produce, circula y se distribuye. A partir de los
desarrollos tecnológicos, aparecen nuevas formas o fenómenos u objetos culturales que se
constituyen en tendencias y a través de los cuales se interpreta, comprende y apropia el
mundo. En este sentido, proponemos trabajar con Arduino, una placa electrónica que se
puede programar.
Sobre la propuesta
A partir de un abordaje interdisciplinar esta propuesta busca aprender a programar y utilizar
la placa Arduino para el desarrollo de proyectos de robótica y control, mediante el uso de
distintos sensores y actuadores.
En ésta primera etapa se hará uso solamente de las entradas y salidas digitales.
ENCUENTRO 1
Actividades
Momento 4: Variables
Una variable es una manera de nombrar y almacenar un valor numérico para su uso
posterior por el programa. Como su nombre indica, las variables son números que se
pueden variar continuamente en contra de lo que ocurre con las constantes cuyo valor
nunca cambia. Una variable debe ser declarada y, opcionalmente, asignarle un valor.
Como ejemplo, declaramos una variable en el programa anterior.
Vamos a declarar la variable “led” como un entero, y le asignaremos el valor 13. De ésta
manera, cada vez que escribamos “led”, el programa lo entiende como 13.
Volvemos a ejecutar los pasos para transferir el programa y observamos los resultados.
Las variables deben tomar nombres descriptivos, es decir, nombres que ayuden a
identificar lo que representan, para hacer el código más legible.
Declaración de variables
Todas las variables tienen que declararse antes de que puedan ser utilizadas. Para declarar
una variable se comienza por definir su tipo como int (entero), long (largo), float (coma
flotante), etc, asignándoles siempre un nombre, y, opcionalmente, un valor inicial. Esto
sólo debe hacerse una vez en un programa, pero el valor se puede cambiar en cualquier
momento usando aritmética y reasignaciones diversas.
Utilización de una variable
Una variable puede ser declarada al inicio del programa antes de la parte de configuración
setup(), a nivel local dentro de las funciones, y, a veces, dentro de un bloque.
En función del lugar de declaración de la variable así se determinara el ámbito de
aplicación, o la capacidad de ciertas partes de un programa para hacer uso de ella. Una
variable global es aquella que puede ser vista y utilizada por cualquier función y
estamento de un programa. Esta variable se declara al comienzo del programa, antes de
setup(). Una variable local es aquella que se define dentro de una función o como parte de
un bucle. Sólo es visible y sólo puede utilizarse dentro de la función en la que se declaró.
Por lo tanto, es posible tener dos o más variables del mismo nombre en diferentes partes
del mismo programa que pueden contener valores diferentes. La garantía de que sólo una
función tiene acceso a sus variables dentro del programa simplifica y reduce el potencial
de errores de programación.
Los tipos de variables se pueden declarar como:
byte: almacena un valor numérico de 8 bits sin decimales. Tienen un rango entre 0 y 255.
int: enteros, son un tipo de datos primarios que almacenan valores numéricos de 16 bits
sin decimales comprendidos en el rango 32.767 a -32.768.
long: el formato de variable numérica de tipo extendido “long” se refiere a números
enteros (tipo 32 bits) sin decimales que se encuentran dentro del rango -2147483648 a
2147483647.
float: el formato de dato del tipo “punto flotante” “float” se aplica a los números con
decimales. Los números de punto flotante tienen una mayor resolución que los de 32 bits
con un rango comprendido 3,4028235 10 +38 a -3.4028235 10+38
array: es un conjunto de valores a los que se accede con un número índice. Cualquier
valor puede ser recogido haciendo uso del nombre de la matriz y el número del índice. El
primer valor de la matriz es el que está indicado con el índice 0, es decir el primer valor
del conjunto es el de la posición 0. Un array tiene que ser declarado y opcionalmente
asignados valores a cada posición antes de ser utilizado
int miArray[] = {valor0, valor1, valor2...}
Momento 5: constantes
El lenguaje de programación de Arduino tiene unos valores predeterminados, que son
llamados constantes. Se utilizan para hacer los programas más fáciles de leer. Las
constantes se clasifican en grupos.
Cierto/falso (TRUE/FALSE): Estas son constantes booleanas que definen los niveles HIGH
(alto) y LOW (bajo) cuando estos se refieren al estado de las salidas digitales. FALSE se
asocia con 0 (cero), mientras que TRUE se asocia con 1, pero TRUE también puede ser
cualquier otra cosa excepto cero. Por lo tanto, en sentido booleano, -1, 2 y -200 todos
también se definen como TRUE. (esto es importante tenerlo en cuenta).
HIGH/LOW: Estas constantes definen los niveles de salida altos o bajos y se utilizan para la
lectura o la escritura digital para las patillas. ALTO se define como en la lógica de nivel 1,
ON, ó 5 voltios, mientras que BAJO es lógica nivel 0, OFF, o 0 voltios.
INPUT/OUTPUT: Estas constantes son utilizadas para definir, al comienzo del programa, el
modo de funcionamiento de los pines mediante la instrucción pinMode de tal manera que
el pin puede ser una entrada INPUT o una salida OUTPUT.
ENCUENTRO 3
Actividades
Momento 1: Repaso de lo visto el día anterior. Conexión de elementos externos a la
placa Arduino.
Después de repasar la estructura de un sketch y de las instrucciones vistas, procedemos a
conectar un led con su respectiva resistencia a la placa Arduino.
El esquemático de conexión es el siguiente:
El programa a utilizar es igual al anterior (parpadeo del led), solo que ahora utilizamos un
led conectado a otra salida de Arduino. Aquí podemos ver la ventaja de utilizar la variable
led, que permite conectar al led a distintas salidas, modificando solamente el número de
pin.
Ejecutamos el programa, lo transferimos al microcontrolador y observamos sus
resultados.
Cambiamos los valores de tiempo de encendido y apagado y cambiamos el pin de salida,
haciendo las respectivas modificaciones en el sketch.
El esquema de conexión es el siguiente:
ENCUENTRO 4
Actividades
Momento 1: Conexión de una placa de 5 leds a Arduino
Se procederá a conectar la placa con 5 leds, de acuerdo a la siguiente figura:
void setup() {
pinMode(led1,OUTPUT); //definimos cada pin como salida
pinMode(led2,OUTPUT);
pinMode(led3,OUTPUT);
pinMode(led4,OUTPUT);
pinMode(led5,OUTPUT);
}
void loop() {
digitalWrite(led1,HIGH); //encendemos el led1
delay(400); //esperamos 400 ms
digitalWrite(led2,HIGH); //encendemos el led2
delay(400); //esperamos 400 ms
digitalWrite(led3,HIGH); //encendemos el led3
delay(400); //esperamos 400 ms
digitalWrite(led4,HIGH); //encendemos el led4
delay(400); //esperamos 400 ms
digitalWrite(led5,HIGH); //encendemos el led5
delay(400); //esperamos 400 ms
digitalWrite(led1,LOW); //apagamos led1
digitalWrite(led1,LOW); //apagamos led2
digitalWrite(led1,LOW); //apagamos led3
digitalWrite(led1,LOW); //apagamos led4
digitalWrite(led1,LOW); //apagamos led5
}
Momento 3: Modificamos el sketch para que enciendan los leds, de a uno por vez, desde
el led 1 al led 5 y luego en sentido contrario. El tiempo de encendido de cada led será de
500 ms y el tiempo de espera para que encienda el próximo led será de 200 ms.
El sketch será el siguiente:
int led1=2; //nombramos cada salida como led y un número
int led2=4;
int led3=6;
int led4=8;
int led5=10;
void setup() {
pinMode(led1,OUTPUT); //definimos cada pin como salida
pinMode(led2,OUTPUT);
pinMode(led3,OUTPUT);
pinMode(led4,OUTPUT);
pinMode(led5,OUTPUT);
}
void loop() {
digitalWrite(led1,HIGH); //encendemos el led1
delay(500); //esperamos 500 ms
digitalWrite(led1,LOW); //apagamos el led1
delay(200); //esperamos 200 ms
digitalWrite(led2,HIGH); //encendemos el led2
delay(500); //esperamos 500 ms
digitalWrite(led2,LOW); //apagamos el led2
delay(200); //esperamos 200 ms
digitalWrite(led3,HIGH); //encendemos el led3
delay(500); //esperamos 500 ms
digitalWrite(led3,LOW); //apagamos el led3
delay(200); //esperamos 200 ms
digitalWrite(led4,HIGH); //encendemos el led4
delay(500); //esperamos 500 ms
digitalWrite(led4,LOW); //apagamos el led4
delay(200); //esperamos 200 ms
digitalWrite(led5,HIGH); //encendemos el led5
delay(500); //esperamos 500 ms
digitalWrite(led5,LOW); //apagamos el led5
delay(200); //esperamos 200 ms
digitalWrite(led4,HIGH); //encendemos el led4
delay(500); //esperamos 500 ms
digitalWrite(led4,LOW); //apagamos el led4
delay(200); //esperamos 200 ms
digitalWrite(led3,HIGH); //encendemos el led3
delay(500); //esperamos 500 ms
digitalWrite(led3,LOW); //apagamos el led3
delay(200); //esperamos 200 ms
digitalWrite(led2,HIGH); //encendemos el led2
delay(500); //esperamos 500 ms
digitalWrite(led2,LOW); //apagamos el led2
delay(200); //esperamos 200 ms
}
Momento 4: Modificación del sketch anterior utilizando arreglos y la función for
Funciones
Una función es un bloque de código que tiene un nombre y un conjunto de estamentos
que son ejecutados cuando se llama a la función. Son funciones setup() y loop() de las que
ya se ha hablado. Las funciones de usuario pueden ser escritas para realizar tareas
repetitivas y para reducir el tamaño de un programa. 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 escribirán, si es necesario, los
parámetros que se deben pasar a la función para que se ejecute.
tipo nombreFunción(parámetros)
{
estamentos;
}
for: La declaración for se usa para repetir un bloque de sentencias encerradas entre
llaves un número determinado de veces. Cada vez que se ejecutan las instrucciones del
bucle se vuelve a testear la condición. La declaración for tiene tres partes separadas por (;)
vemos el ejemplo de su sintaxis:
for (inicialización; condición; expresión)
{
Instrucciones;
}
La inicialización de una variable local se produce una sola vez y la condición se testea cada
vez que se termina la ejecución de las instrucciones dentro del bucle. Si la condición sigue
cumpliéndose, las instrucciones del bucle se vuelven a ejecutar.
Cuando la condición no se cumple, el bucle termina. El siguiente ejemplo inicia el entero i
en 0, y la condición es probar que el valor es inferior a 20 y si es cierto i se incrementa en
1 y se vuelven a ejecutar las instrucciones que hay dentro de las llaves:
for (int i=0; i<20; i++) //declara i, prueba que es menor que 20, incrementa i en 1
{
digitalWrite(13, HIGH); // envía un 1 al pin 13
delay(250); // espera 1⁄4 seg.
digitalWrite(13, LOW); // envía un 0 al pin 13
delay(250); // espera 1⁄4 de seg.
}
Si en el sketch anterior, utilizamos variables, arreglos y la función for, nuestro sketch se
simplifica y queda de la siguiente manera:
int led[]={2,4,6,8,10,}; //nombramos cada salida como led y un número
int tencendido=500;
int tapagado=200;
void setup() {
for(int i=0;i<5;i++) {
pinMode(led[i],OUTPUT); //definimos cada pin como salida
}
}
void loop() {
for(int i=0;i<5;i++) {
digitalWrite(led[i],HIGH); //encendemos el led
delay(tencendido); //esperamos medio segundo
digitalWrite(led[i],LOW); //apagamos el led
delay(tapagado);
}
for(int i=3;i>=1;i--) {
digitalWrite(led[i],HIGH); //encendemos el led
delay(tencendido); //esperamos medio segundo
digitalWrite(led[i],LOW); //apagamos el led
delay(tapagado);
}
}
ENCUENTRO 5
Actividades
Momento 1: Utilización de pulsador y display 7 segmentos.Conexiones.
La conexión de un pulsador o interruptor a una entrada digital se realiza como indica el
esquemático:
La resistencia es necesaria para que el pin de entrada tenga un valor de 0 Volts cuando se
abre el pulsador o interruptor. Si se requiere 5 Volts cuando el pulsador o interruptor se
abre, se intercambia la conexión entre el pulsador y la resistencia.
Realizaremos un sketch que muestre en el display el conteo de las veces que se pulsa el
pulsador, hasta llegar a 9.
Por medio de otro pulsador, se reiniciará el conteo a partir de cero, independientemente
del estado de la cuenta.
Además un buzzer, indicará cuando la cuenta pasa nuevamente a cero.
El diagrama de conexiones es el siguiente:
void loop() {
estado = digitalRead(pulsador); //se lee el valor del pulsador y se guarda en estado
while(estado == HIGH){ //mientras estado esté en alto, se ejecuta lo siguiente
delay(150); //retardo para evitar rebotes
estado = digitalRead(pulsador); //se lee nuevamente el estado del pulsador
if(estado == 0){ //si el estado es cero
contador++; //se incrementa el contador
if(contador >9){ //si contador es mayor a 9
contador = 0; //se pone encero contador
tone(buzzer,1500,500); //se produce un tono de 1500 Hz durante medio segundo
cero(); //se llama a la función cero
}
}
}
int reinicio; //declaración de la variable reinicio
reinicio= digitalRead (0); //lectura del valor del pulsador de reinicio
if(reinicio == HIGH){ //si se oprimió el pulsador
cero(); //reiniciar el conteo (puesta a cero)
contador=0; //poner en cero la variable contador
}
if(contador==1){ //preguntar por contador y llamar a la función del número
uno ();
}
if(contador==2){
dos ();
}
if(contador==3){
tres ();
}
if(contador==4){
cuatro ();
}
if(contador==5){
cinco ();
}
if(contador==6){
seis ();
}
if(contador==7){
siete ();
}
if(contador==8){
ocho ();
}
if(contador==9){
nueve ();
}
}
Si se envía HIGH al pin, el motor funciona. Por el contrario si se envía LOW al pin, el motor
deja de funcionar.
void loop() {
for(i=0; i<6; i++){ //repetimos 5 veces
digitalWrite(motor,HIGH); //encendemos motor
delay(1000); //esperamos 1 segundo
digitalWrite(motor,LOW); //apagamos motor
delay(1000); //esperamos 1 segundo
}
Un móvil sigue líneas, sigue una línea negra trazada sobre fondo claro, por medio de dos
sensores CNY 70 separados por el ancho de la línea y colocados en la parte frontal del
mismo. El móvil cuenta con dos motores (izquierdo y derecho), que permiten controlar su
movimiento.
Cada vez que un sensor detecta la zona clara, produce la detención del motor contrario al
sensor. Es decir, el sensor derecho detiene al motor izquierdo y el sensor izquierdo
detiene al motor derecho. Este comportamiento permite que el móvil pueda seguir la
trayectoria de la línea negra, ya que de estar ambos sensores detectando a la misma, los
dos motores continuarán funcionando.
ENCUENTRO 7
Actividades
Momento 1: Construcción de un móvil sigue líneas
Se entregará a cada participante una plataforma con los dos motores ya colocados, un
portapilas, un convertidor de tensión y una placa Arduino UNO.
Además se hará entrega de un experimentor, resistencias, transistores, diodos y un
conjunto de cables de conexión.
ENCUENTRO 8
Actividades
Momento 1: Programación del móvil sigue línea
Antes de realizar la programación, hay que tener en cuenta que los valores que recibe el
pin donde se conecta el sensor infrarrojo, están comprendidos entre 0 y 1024,
dependiendo de la cantidad de luz infrarroja que llegue al fototransistor. Es por ésto que
conectamos las salidas de los sensores a entradas analógicas de Arduino.
Cuando el sensor recibe el reflejo del haz infrarrojo, el valor que llega al pin de Arduino es
un valor alto, de lo contrario recibe un valor bajo, en éste caso está detectando la línea. La
idea es que cuando ambos sensores (derecha e izquierda) detecten la línea, pongan en
funcionamiento ambos motores. Cuando algún sensor no detecte la línea, detenga el
movimiento del motor opuesto al mismo, de tal manera que el auto retome su camino por
la línea.
Por lo tanto tendremos que determinar un umbral, para establecer cuando detecta la
línea y cuando no. Este umbral dependerá de la altura a la que se encuentran los sensores,
de la cantidad de luz sobre la pista y del contraste entre la línea negra y sus alrededores.
El programa a realizar es el siguiente:
int umbral= 500; //umbral para determinar cuando está sobre la línea
int Sderecha = 3; //Salida para activar el motor derecho, pin 3
int Sizquierda = 11; //Salida para activar el motor izquierdo, pin 11
int valorSD; //valor del sensor derecho
int valorSI; //valor del sensor izquierdo
void setup() {
pinMode(Sderecha, OUTPUT); //Configuramos los pines 3 y 11 como salidas
pinMode(Sizquierda,OUTPUT);
}
//El sensor infrarrojo entrega un valor bajo si detecta la linea y un valor alto si no detecta
void loop() {
valorSD=analogRead(A5); //Leemos el sensor infrarrojo derecho y guardamos su valor
valorSI=analogRead(A0); //Leemos el sensor infrarrojo izquierdo y guardamos su valor
if(valorSD >= umbral){ //Si señal sensor derecho es mayor o igual a umbral
digitalWrite(Sizquierda,LOW); //Paramos motor izquierdo
}
else { //Si detecta línea
digitalWrite(Sizquierda,HIGH);//Encendemos motor izquierdo
}
if(valorSI >= umbral){ //Si señal sensor izquierdo es mayor o igual a umbral
digitalWrite(Sderecha,LOW); //Paramos motor derecho
}
else { //Si detecta línea
digitalWrite(Sderecha,HIGH); //Encendemos motor derecho
}
}
Se procede a cargar el programa a la placa Arduino y se verifica su funcionamiento.
ENCUENTRO 9
Actividades
Momento 1: Puesta a punto
Los participantes buscarán optimizar el programa y el móvil para que funcione
correctamente.
Momento 2: Competencia
Los participantes competirán entre sí, buscando que el móvil no se desvíe de la línea y que
lo haga en el menor tiempo posible.
Para ello ajustarán las variables necesarias para el correcto funcionamiento del móvil
sigue línea.