Академический Документы
Профессиональный Документы
Культура Документы
PROGRAMACIN INTERMEDIA 30
2
TABLA DE CONTENIDO DEL HARDWARE EXTERNO
3
COMENZANDO CON ARDUINO
Para la instalacin de los drivers y del software puede visitarse la pagina oficial:
http://arduino.cc/es/Guide/HomePage
Para comenzar se realizar el ejercicio de encender un Led. La tarjeta del Arduino Uno
cuenta con un Led en el pin 13 por lo cual este ser el pin a usar.
voidloop(){
http://arduino.cc/en/Reference/HomePage
http://arduino.cc/es/Reference/HomePage
4
COMENZANDO CON ARDUINO
constintledPin = 13;
voidsetup(){
//Apaga el led
digitalWrite(ledPin, LOW);
//Espera medio segundo
delay(500);
//Apaga el led
digitalWrite(ledPin, LOW);
voidloop(){
5
// EJEMPLO 003 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende y apaga un led en un ciclo infinito
constintledPin = 13;
voidsetup(){
pinMode(ledPin, OUTPUT);
}
Esquema 1
Conectando un Led
6
En el siguiente ejemplo usaremos un suitche para encender o apagar un led. En este
caso el pin que asignemos como entrada debe ir conectado de este modo.
Esquema 2
Suitche y Led
Cada vez que usemos una protoboard para utilizar elementos externos debemos
compartir la polarizacin del Arduino, por lo tanto cada que se use un circuito externo
deben agregarse los cables negros y rojos que se ven en el dibujo.
voidsetup(){
7
//Se lee la entrada del pin
intswitcheEstado = digitalRead(switchePin);
8
// EJEMPLO 005 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende una secuencia de leds
voidsetup(){
voidloop(){
9
// EJEMPLO 006 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende una secuencia de leds utilizando
// el ciclo for
constintswitchePin = 2;
voidsetup(){
voidloop(){
10
// EJEMPLO 007 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Creacion de funciones
voidsetup(){
asignarSalidas(2,3);
}
voidloop(){
alternarLeds();
}
pinMode(pPin1, OUTPUT);
pinMode(pPin2, OUTPUT);
}
digitalWrite(pPin1, HIGH);
delay(500);
digitalWrite(pPin1, LOW);
digitalWrite(pPin2, HIGH);
delay(500);
digitalWrite(pPin2, LOW);
}
Las funciones permiten que el cdigo sea ms organizado, legible, reutilizable y que
pueda trabajarse en equipos, debido a que cada persona puede encargarse de una
funcin diferente y luego unirlas para conseguir desarrollar un programa complejo en
poco tiempo.
11
Pueden utilizarse otros elementos externos al Arduino por ejemplo un Display 7
segmentos o un Display doble 7 segmentos, con el fin de realizar una interfaz que
permita observar variables (temperatura, presin, luminosidad) o contadores.
Esquema 3
Decodificador y Display doble 7 segmentos
Tabla 1
Binario a decimal y salidas del integrado
12
// EJEMPLO 008 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Permite utilizar un display siete segmentos conectado
// a un decodificador para display
voidsetup(){
voidloop(){
//Se llama la funciondisplay y se le envia un numero entero llamado
//valor
miDisplay(valor);
}
//Se crea una funcion llamada miDisplay() que recibe un valor entero
voidmiDisplay(intpValor){
13
break;
//En el caso '2' la salida debe ser 0010
case 2:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, HIGH);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, LOW);
break;
//En el caso '3' la salida debe ser 0011
case 3:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, HIGH);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, LOW);
break;
//En el caso '4' la salida debe ser 0100
case 4:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, HIGH);
digitalWrite(pinA3, LOW);
break;
//En el caso '5' la salida debe ser 0101
case 5:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, HIGH);
digitalWrite(pinA3, LOW);
break;
//En el caso '6' la salida debe ser 0110
case 6:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, HIGH);
digitalWrite(pinA2, HIGH);
digitalWrite(pinA3, LOW);
break;
//En el caso '5' la salida debe ser 0111
case 7:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, HIGH);
digitalWrite(pinA2, HIGH);
digitalWrite(pinA3, LOW);
break;
//En el caso '5' la salida debe ser 1000
case 8:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, HIGH);
break;
//En el caso '5' la salida debe ser 1001
case 9:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, HIGH);
break;
}
}
14
Cuando se necesita usar ambos Displays se puede utilizar una tcnica llamada
multiplexacin que consiste en apagar y encender constantemente los Displays, para
conseguir esto debe llevarse a ambos Displays las decenas sin embargo solo dejamos el
Display izquierdo encendido, se espera un momento y luego se envan las unidades
pero en este caso solo se enciende el Display derecho, esto se hace durante un ciclo
infinito. Debido a la velocidad a la que se hace este cambio no se nota cuando se apaga
cada uno de los Displays, una ventaja adicional de este mtodo es que al solo estar un
Display encendido a la vez se consume menos corriente de la que sera necesaria si se
encendieran ambos Displays.
constint pinB1 = 2;
constint pinB2 = 3;
voidsetup(){
pinMode(pinB1, OUTPUT);
pinMode(pinB2, OUTPUT);
}
voidloop(){
voidmiDisplayCompleto(intpValorCompleto){
15
digitalWrite(pinB1,HIGH);
digitalWrite(pinB2,LOW);
//Se muestran las decenas
miDisplay(decenas);
//Se espera 1 milisegundo
delay(1)
//Se crea una funcion llamada miDisplay() que recibe un valor entero
voidmiDisplay(intpValor){
16
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, HIGH);
digitalWrite(pinA3, LOW);
break;
//En el caso '6' la salida debe ser 0110
case 6:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, HIGH);
digitalWrite(pinA2, HIGH);
digitalWrite(pinA3, LOW);
break;
//En el caso '5' la salida debe ser 0111
case 7:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, HIGH);
digitalWrite(pinA2, HIGH);
digitalWrite(pinA3, LOW);
break;
//En el caso '5' la salida debe ser 1000
case 8:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, HIGH);
break;
//En el caso '5' la salida debe ser 1001
case 9:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, HIGH);
break;
17
COMENZANDO CON ARDUINO
PROGRAMACIN BASICA: CAPTURAS ANALOGAS
El Arduino nos permite manejar entradas anlogas que van desde la A0 a A6 y son
trabajadas por defecto con una resolucin de 1024. Para entender mejor estos
conceptos puede revisarse la clase 6 del semillero.
constintrelePin=13;
voidsetup() {
//Se asigna un pin como salida
pinMode(relePin, OUTPUT);
}
//
if(voltaje< 1.5){
digitalWrite(relePin,HIGH);
delay(50);
}
else{
digitalWrite(relePin,LOW);
}
18
Esquema 4
Sensor de luz
Esquema 5
Conexin de un Relay
Es posible crear libreras con las funciones que se han creado antes por ejemplo es
posible crear una librera para el uso del Display doble 7 segmentos y enlazarlo a un
programa para ver en tiempo real la temperatura de un lugar.
19
// EJEMPLO 011 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende un ventilador cuando la temperatura
// Supera cierto umbral. En este ejemplo se usa una librera para
// observar la temperatura en un display
#include <displayCompleto.h>
constintrelePin=13;
DisplayCompleto displayLuz(7,6,5,4,9,8);
voidsetup() {
pinMode(relePin, OUTPUT);
}
voidloop() {
// Se convierte a voltaje
float voltaje = valorSensor * (5.0 / 1024.0);
20
// Ejemplo 012 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende una cantidad de luz proporcional
// A la cantidad de luz que recibe el sensor. Para este ejemplo se
// Conectan los pines digitales del 2 al 6 a LEDs
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
}
voidloop(){
//Si el valor del sensor esta entre 600 (incluyendo 600) y 750
if( valorSensor>= 600 &&valorSensor< 750){
digitalWrite(2,HIGH);
21
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,HIGH);
digitalWrite(6,LOW);
}
//Si el valor del sensor es mayor o igual a 750
if( valorSensor>= 750){
digitalWrite(2,HIGH);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
}
22
COMENZANDO CON ARDUINO
PROGRAMACIN BASICA: COMUNICACIN SERIAL
voidsetup(){
voidloop(){
Para hacer pruebas puede utilizarse una aplicacin llamada Docklight. Al enviarse un
dato utilizando esta aplicacin se obtiene el valor en ASCII correspondiente por
ejemplo para la a se obtiene un 97, al observar los nmero vemos que el ASCII de
cada nmero es equivalente al nmero + 48.
http://www.docklight.de/download_en.htm
23
La comunicacin serial puede utilizarse para hacer pruebas o para conocer el valor de
alguna variable del programa. En este ejemplo se utiliza para conocer el valor de un
sensor.
voidsetup(){
//Se inicializa la comunicacion serial
Serial.begin(9600);
}
voidloop(){
24
// Ejemplo 015 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Envia por serial el dato recibido utilizando
// Interrupciones. En este caso el programa se queda en el ciclo
// Infinito (loop) hasta recibir algun dato por el puerto serial.
voidsetup() {
//Se inicializa la comunicacion serial
Serial.begin(9600);
}
voidloop() {
intrelePin = 13;
intvalorLeido = 0;
voidsetup() {
//Se inicializa la comunicacion serial
Serial.begin(9600);
//Se asigna una salida
pinMode(relePin, OUTPUT);
}
voidloop() {
if(valorLeido == 1){
digitalWrite(relePin,HIGH);
}else{
digitalWrite(relePin,LOW);
}
25
voidserialEvent(){
Permite seleccionar el puerto, mostrar datos en los Displays de la interfaz, cuenta con
10 botones numricos y con un Dial.
26
Finalmente cuenta con indicadores que fueron diseados para mostrar un valor entre
0 y 100 de la temperatura, la luminosidad y la presin.
Debido a que la interfaz cuenta con varias entradas y salidas debe crearse un protocolo
que indique que se ha utilizado de la interfaz y que dato se ha enviado. El protocolo se
ha definido de este modo:
27
Desde la interfaz hacia el Arduino
Interfaz Dato de Inicio Tipo de Dato Valor de Dato Dato de Fin
Botn 0 I B 0 F
Botn 1 I B 1 F
Botn 2 I B 2 F
Botn 3 I B 3 F
Botn 4 I B 4 F
Botn 5 I B 5 F
Botn 6 I B 6 F
Botn 7 I B 7 F
Botn 8 I B 8 F
Botn 9 I B 9 F
Dial I D 0-9 F
Alarma I A 0-1 F
// Datos de interes
inttipoDato = 0;
intvalorDato = 0;
28
voidsetup(){
Serial.begin(9600);
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
voidloop(){
voidobtenerDatos(){
29
if(vectorSerial[0]=='I'&&vectorSerial[3]=='F'){
tipoDato=vectorSerial[1];
valorDato=vectorSerial[2]-48;
}
contadorSerial=0;
intcontadorSerial=0;
intvectorSerial[4];
inttipoDato = 0;
intvalorDato = 0;
boolean temporal=false;
voidsetup(){
Serial.begin(9600);
pinMode(13,OUTPUT);
pinMode(12,OUTPUT);
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
voidloop(){
30
voidserialEvent(){
vectorSerial[contadorSerial] = Serial.read();
if(vectorSerial[0] == 'I'){
contadorSerial++;
}
if(contadorSerial> 3){
obtenerDatos();
}
voidobtenerDatos(){
if(vectorSerial[0]=='I'&&vectorSerial[3]=='F'){
tipoDato=vectorSerial[1];
valorDato=vectorSerial[2]-48;
}
contadorSerial=0;
31
COMENZANDO CON ARDUINO
PROGRAMACIN INTERMEDIA
En ocasiones es necesario tener una variable que cuente el tiempo sin hacer uso de la
funcin Delay( ) debido a la gran cantidad de inconvenientes que representa tener un
retraso de tiempo, esto se soluciona creando una base de tiempo de la cantidad de
tiempo que sea necesaria, el siguiente ejemplo ilustra como debe crearse la base de
tiempo.
#include <displayCompleto.h>
voidsetup(){
pinMode(8 ,OUTPUT);
pinMode(9 ,OUTPUT);
pinMode(10,OUTPUT);
voidloop(){
tiempo = millis();
32
segundos = 0;
minutos = minutos+1;
}
miDisplay.mostrar(segundos);
33
Con lo que se ha visto en las memorias del semillero no se ha visto como trabajar con
eventos que tengan una duracin corta en el tiempo o que no permanecen en un
estado, por ejemplo: un pulsador o un aplauso. En el cdigo que se presenta a
continuacin se utilizan datos lgicos (booleanos) conocidos como banderas que nos
permiten manejar este tipo de eventos.
Esquema 5
Micrfono amplificado
constintledPin=13;
//Se crea un tipo de dato booleano, este tipo de datos
//solo puede tomar dos valores: Falso o Verdadero
booleanaplauso = false;
voidsetup() {
pinMode(ledPin, OUTPUT);
}
voidloop() {
34
//Se convierte a voltaje
float voltaje = valorSensor * (5.0 / 1023.0);
Se pueden utilizar banderas y bases de tiempo para crear un programa que encienda
una bombilla cuando se aplaudan dos veces en menos de 2 segundos y que se apague
con un aplauso.
constintrelePin=13;
int aplausos = 0;
booleanaplausoActivo = false;
booleanencenderBombillo = false;
unsignedlongtiempo=0;
unsignedlongtiempoAnterior=0;
unsignedlongmedioSegundo=0;
35
intvalorSensor = analogRead(A0);
float voltaje = valorSensor * (5.0 / 1023.0);
tiempo = millis();
}
//De lo contrario se desactiva
else{
digitalWrite(relePin,LOW);
36
COMENZANDO CON ARDUINO
CAPTURA DE SEALES DIGITALES
Es importante hablar de las seales digitales debido a que no todas las seales son
anlogas, algunos sensores entregan seales digitales, como ejemplo: los sensores de
velocidad (sensor de Efecto Hall) y el sensor de IR (Infrarrojo). Es importante recordar
que las seales digitales cuentan con un tiempo en alto y con un tiempo en bajo a
travs del cual pueden enviar informacin.
Esquema 6
Conexin del sensor de IR
En el caso de los controles Sony y Panasonic la informacin viaja en el tiempo que dura
en alto o en bajo, para averiguar estos tiempos utilizamos una librera desarrollada por
el grupo de investigacin GEPAR utilizando la funcin encontrar tiempo.
37
// EJEMPLO 022 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacion GEPAR
// Giovanny Espinal Ramirez
// Descrpicion: Permite capturar los tiempos del control
#include <controlTV.h>
voidsetup(){
//Es necesario inicializar el serial
Serial.begin(9600);
}
voidloop(){
//EncontrarTiempo nos permite capturar el tiempo del
//Control, el '0' indica que va a capturarse el tiempo
//En bajo, y el '7' indica cual es el pin de captura
encontrarTiempo(0,7);
}
En el caso de un control Sony VTR los tiempos obtenidos son todos similares, lo que
significa que el tiempo en bajo NO lleva informacin, en la captura de pantalla que se
presenta a continuacin se tiene un cero cuando no se presiona ningn botn y
cuando se presiona cualquier botn se obtienen tiempos similares (entre 300 500).
Para ver los resultados se debe abrir el monitor serial incluido en el Arduino, esto se
hace a travs de Herramientas / Monitor Serial o Ctrl + Shift + M
38
Como el tiempo en bajo no contiene informacin podemos probar capturar los
tiempos en alto modificando la funcin encontrar tiempo.
voidloop(){
//Si se remplaza el '0' por un '1' se captura el tiempo
//En alto
encontrarTiempo(1,7);
}
39
Al modificar esta lnea obtenemos tiempos diferentes ya que ahora estamos
capturando el tiempo en alto de la seal, en este caso es evidente que el tiempo
presenta cambios notables.
De acuerdo a estos datos podemos determinar que los tiempos en alto que presentan
una mayor duracin tienen un valor entre 1400 y 2700, aunque para evitar problemas
podemos decir que se encuentran entre 1000 y 3000, y sern los valores que
tomaremos como un 1 lgico, siendo as los pulsos que tengan una duracin de ms
de 0 pero de menos de 1000 sern los 0s lgicos. Esta nueva informacin la utilizamos
en el programa con la funcin calcular Protocolo incluida en la librera controlTv.h
40
// EJEMPLO 022 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacion GEPAR
// Giovanny Espinal Ramirez
// Descrpicion: Permite obtener un protocolo estimado
#include <controlTV.h>
voidsetup(){
voidloop(){
41
Este proceso realizado corresponde a un mapeo del control, con este mapeo podemos
encontrar el protocolo de tantos botones como deseemos, en el ejemplo a
continuacin utilizamos el mapeo anterior para tomar decisiones.
#include <controlTV.h>
42
voidsetup(){
Serial.begin(9600);
pinMode(13,OUTPUT);
}
voidloop(){
if(datosDisponibles() == true){
43
COMENZANDO CON ARDUINO
ENLACES DE INTERES
44