Para que sea todo más fácil de entender, sobretodo para quien no haya programado nunca nada, explicaré como programar todo por separado, con sus respectivos códigos.
Luego abordaré la programación del robot y subiré el código con un enlace externo para que lo podáis descargarlo y modificarlo a vuestro gusto. ¡Empezamos!
Antes de nada, para poder programar Arduino necesitarás descargarte su entorno de programación totalmente gratuito que puedes encontrar en http://arduino.cc/en/Main/Software
LO BÁSICO
Entorno de programación Arduino. Compilador. Estructura de un programa. Declaración de variables.
A continuación, la teoria:
Mediante la programación puedes hacer escritura digital, escritura analógica digital, lectura
tanto analógica como digital, comunicación serial Arduino-PC y viceversa, y
realización de pulsos por modulación a través de los pin PWM.
En la práctica se puede traducir a encender y apagar un led, variar la intensidad de éste, crear botones
con estado, realizar operaciones aritméticas obtener valores de los sensores,
comunicarse con Arduino a través de un puerto serie, mover los motores en ambos sentidos, etc.
Antes
de explicar algunas de las prácticas, es importante conocer el entorno de
programación de Arduino, que consigue hacer fácil la escritura del código y
además es el encargado de cargar el programa a la placa mediante la conexión
USB.
Como
se puede observar ,
consta de una serie de botones, que uno tiene que conocer, y un cuerpo central
vacío donde se escribirá el código que se enviará a la placa. Ejemplos son los
botones que se muestran a continuación.
El
código que se escribirá en el compilador es un lenguaje y como todo lenguaje
tiene su vocabulario, sintaxis, normas y una estructura que hay que respetar. Podeís encontrar más sobre la sintaxis en: http://arduino.cc/en/Reference/HomePage
Para
la programación se utiliza el lenguaje Wiring. El lenguaje Wiring, es muy parecido a C, ya que
es un subconjunto de éste. Tiene unas peculiaridades destacables, se dice que
son Case Sensitive, es decir sensible
a las mayúsculas. No es lo mismo escribir “analogWrite” que “analogwrite”. Otra peculiaridad es que cada vez que se acaba una instrucción se ha de separar
por “;” (punto y coma).
La
estructura principal está dividida en dos apartados:
La
función setup(), establece cuando se
inicia un programa. Se utiliza para iniciar variables, establecer estados de
los pins, o establecer cualquier
configuración inicial. Esta función se ejecuta una única vez después de
conectar la alimentación a Arduino o cuando se pulsa el botón reset.
La
función loop() que se escribe justo debajo
debajo del setup(). Inicializa y hace justo lo que su propio nombre sugiere, se
ejecuta consecutivamente, permitiendo al programa variar y responder, es decir
actúa como un bucle. Una vez llamadas las funciones, el código que se escriba
debe ir entre llaves “{}”.
Por
encima del setup(), se declararán las variables globales, que en programación
son estructuras de datos, como su nombre indica, pueden cambiar de contenido a
lo largo de la ejecución de un programa. Dependiendo del tipo de dato que se
tenga que almacenar en la variable lo indicaremos con una palabra u otra.
¿Cómo se declara una variable? Al principio
escribiremos el tipo de dato, dejaremos un espacio en blanco, escribiremos el
nombre que le queramos asignar a la variable y finalizaremos con un punto y
coma. En el caso que la variable se refiera a un pin determinado de arduino,
después de asignar un nombre a la variable, escribiremos un igual, el número de
pin y cerraremos con el punto y coma.
Ejemplo:
int /*tipo de dato entero*/ led /*nombre de la variable*/ =13 /*asignación del pin nº 13*/;
Muchas
veces se crean pequeños programas dentro del programa que se está creando para
hacer más sencilla la escritura del código. Éstos se crearan justo debajo del
loop().
Resumen estructura
de programación en el entorno de programación arduino usando el lenguaje
Wiring:
En la segunda entrada del foro podréis encontrar un archivo en formato .zip con los códigos de todos los ejercicios y la programación del robot. También lo podréis encontrar en este enlace externo y al final de cada apartado.
Recordad que para abrir estos archivos necesitareis el entorno de programación Arduino que podéis encontrar en http://arduino.cc/en/Main/Software y cualquier duda que tengáis sobre el proyecto, ya sea programación o no, lo podéis hacer aquí en el foro.
Ejercicios de programación básica:
-Ejercicio 1
Objetivos:
encender y apagar un led, variar la intensidad del led.
Conectaremos
un led en el pin numero 11 de la siguiente manera , lo
he conectado en un pin PWM para después explicar cómo variar la intensidad del
led utilizando el mismo pin.
Encender y apagar un led: para hacer más comoda la escritura del código
declararemos una variable de nombre
“led” que asignaremos al pin donde lo hayamos conectado en este caso el número
11.
En la configuración incial hemos de declarar el estado del pin que puede ser
de entrada (INPUT) o salida (OUTPUT). En este caso es de salida.
En el loop()
escribiremos la función digitalWrite, que espera recibir dos datos, el numero
de pin(escribiremos “led”), y el valor de éste puede recibir dos valores que
son de carácter constantes, HIGH o LOW.
Escribir un HIGH significa que arduino recibirá un 1, y lo traducirá enviando
5V al pin numero 11 y nosotros lo interpretaremos como un ON (Encendido).
Dejaremos un espacio de tiempo de un segundo escribiendo delayed(1000)
(1000milisegundos=1segundo), y repetiremos la escritura digital pero
escribiendo esta vez un LOW.
Cuando se ejecute el loop() encenderá y apagará el led
cada segundo.
- Variar la intensidad del LED
Para conseguir variar la intensidad del led mediante
la programación hemos de conseguir que la diferencia de potencial que se le suministre
al LED sea por debajo de 5V y superior a 0V.
Esto se consigue mediante la
escritura analógica, llamando a la función analogWrite(), solo funciona en los
pin PWM, de la misma forma que la escritura digital nos pide el numero del pin
y un valor.
Esta vez el valor será un número comprendido entre el 0 y el 255
que como expresa la tabla que hay a continuación, cuando enviamos 255, se traducirá a 5V y cuando el
valor analógico sea 0 el voltaje será 0. De esta forma el led emitirá distintas
intensidades.
- Ejercicio 2
Objetivo: obtener lecturas de un sensor infrarrojo, a
través del serial monitor.
Realizaremos las conexiones como aparecen en la imagen. El sensor lo colocamos en
un pin analógico.
Para conseguir una lectura analógica, primero hemos de
leer y luego imprimirlo en la pantalla.
Empezaremos configurando el setup(), indicando que el sensor es un elemento de entrada (INPUT) y
la velocidad de comunicación con el serial monitor, escribiendo:
Serial.begin(115200) (115200 baudios).
La lectura del sensor la haremos
llamando a la función analogRead(),
entre paréntesis escribiremos la variable a leer por ejemplo:
analogRead(sensor).
Ahora crearemos otra variable dónde será almacenado el
valor que leerá el sensor y asignaremos a la nueva variable la lectura del
sensor y la imprimiremos en el monitor serial, llamando a la funcion
Serial.print(), indicando entre paréntesis la variable que tiene que imprimir. Serial.print(dato).
Al abrir el
serial monitor recibiremos datos comprendidos entre el 0 y el 1023. El dato
recibido por el sensor habrá que interpretarlo en voltios, de la misma forma
que en el proceso de escritura analógica, 1023 equivaldrá a 5V y 0 a 0V.
- Ejercicio 3
Objetivo: mover los servomotores en ambos sentidos.
Conectaremos los motores en pins PWM para la
realización de este ejercicio.
El servomotor de rotación continua se controla a
través de la modulación por ancho de
pulso donde la velocidad y el sentido de rotación están determinados por la
duración del pulso. Para que la rotación sea uniforme, el servomotor necesita
una pausa de 20 milisegundos entre cada pulso.
Y viceversa, cuando el pulso sea superior a los 1500
microsegundos, el servo motor girara en el sentido contrario a las agujas del
reloj.
Los valores del espaciado de tiempo para realizar el
pulso variaran según el modelo y el fabricante del servomotor, los valores
utilizados son del servomotor parallax de rotación continua.
¿Como intercalar dos pulsos para mover dos motores a
la vez?
El objetivo es conseguir es realizar 2 pulsos (uno en
cada motor) cada 20 ms (como indica el periodo).
Para ello, vamos a contar el tiempo en que los motores
estan a 0 (20 ms) en vez de parar durante 20 ms, como haciamos en el ejemplo
anterior con el delay
if (instanteTiempoActual > ultimoInstanteTiempo + 20)
{/*Explicación: han pasado 20 ms desde la última vez que realice un pulso en este motor. Puedo hacer un nuevo pulso porque ha pasado tanto tiempo como indica el periodo*/ultimoInstanteTiempo=instanteTiempoActual;}
DESCARGAR CÓDIGO EJERCICIO SERVOMOTORES
- PROGRAMACIÓN DEL ROBOT
He creado un diagrama de flujo para tener una guía a la hora de programar. Así que vamos a ello.
Lo que haré será explicar como se ha programado y os dejaré el código para descargar en el foro y también podéis preguntar cualquier duda.
DESCARGAR CÓDIGO ROBOT EVITA-OBSTACULOS
No olvidéis comentar lo que queráis y si tenéis dudas, no dudes en dejar algún comentario en el foro y si habéis realizado el proyecto subir una foto o un vídeo.- PROGRAMACIÓN DEL ROBOT
He creado un diagrama de flujo para tener una guía a la hora de programar. Así que vamos a ello.
Lo que haré será explicar como se ha programado y os dejaré el código para descargar en el foro y también podéis preguntar cualquier duda.
Siguiendo las instrucciones del diagrama el loop() solo cumplirá dos funciones detectar() y adelante().
La función detectar()
realizara la acción de hacer 5 lecturas de cada sensor, eliminar la lectura más
alta y más baja, por si se trataran de subidas, bajadas de tension o algún
error del sensor, y despúes realizará la media aritmetica de éstas y cada
sensor en una variable distinta, guardará en dicha variable si existe o no
existe obstaculo.
La función adelante(), comprobará las variables para averiguar si hay obstáculo.
En caso de existir obstáculo, girará en dirección contraria al obstaculo y en
el caso de que ninguna variable comunique obstáculo seguira hacia adelante.
Existen más funciones para que esta programación que
he explicado funcione correctamente, como la realización de los pulsos, que he
situado fuera del loop() al igual
que muchas otras funciones.
El setup() lo
he configurado, para que una vez cargado todos los datos se encienda el led
durante dos segundos. ¿Por qué? Es una manera muy sencilla de comprobar que el setup() se ha cargado de forma
correctamente, puede parecer una tonteria pero si no se encendiera el led,
sabria que si ocurre algun problema, el error probablemente procederá del
setup().
Una vez
que se apague el led, el loop() se
iniciará y tan solo se volverá a iluminar el led cuando el sensor detecte algún obstáculo.DESCARGAR CÓDIGO ROBOT EVITA-OBSTACULOS
Arduindroid.
GRACIASSSSSSS. Si lo llego a hacer cosa que queda muy poco tiempo para hacerlo como proyecto final de curso os lo enseño. SALu2
ResponderEliminarMuy buenas, excelente tutorial, estamos en clases desarrollando el proyecto y está casi todo listo, tenemos que terminar la alimentación y sobre todo el código fuente, ya que hemos optado por utilizar los servos más sencillos de 60º, que tenían que trucarse, tenemos también el texto del fuente para controlar el motor trucado, pero no me termina de ejecutar, también comentar que estamos haciendo un cambio en el tema de los sensores, estamos utilizando unos pulsadores, ya veré la forma de haceros llegar fotos, cambiamos también el chasis, es en base a un case de disco duro.
ResponderEliminarMuchas gracias por el aporte, espero me pudierais aconsejar con respecto a los 2 temas, tanto de los servos trucados como de los sensores (que parámetros debería cambiar, creo será necesario simplemente utilizar pines digitales ya que cuando se tope contra algo es cuando activará el giro.
Hola, muchas gracias por visitar nuestro blog.
ResponderEliminarReferente a tus dudas:
Si no he entendido mal los servos trucados no se te mueven al subir el código a la placa, eso puede ser porque los anchos de pulso que mandas a los servos no sean los adecuados, ya que yo utilizaba los propios que recomendaba el fabricante para ese modelo concreto de servos, ese puede ser un caso, o el otro que no lo hayas conectado a pines PWM.
Y respecto a los sensores que pretendes utilizar si son tipo "switch" son fáciles de programar.
Tienes que guardar en una variable le lectura del sensor p.ej
lectura=digitalRead(numero pin);
if lectura==true
{
aqui programas lo que quieras que haga el robot al toparse contra el obstaculo
}
Si no te referias a este tipo de sensor, deja un comentario con un link y veremos que podemos hacer por ayudarte.
Espero que te haya servido de ayuda.
Un saludo