Вы находитесь на странице: 1из 44

MEMORIAS SEMILLERO DE AUTOMATIZACIN

COMENZANDO CON ARDUINO

Giovanny Espinal Ramrez


Giovanny.espinal@gmail.com

Desarrollo del Hardware:


Sebastin Guzmn Obando
German Dez Valencia

Grupo de investigacin GEPAR


Universidad de Antioquia
TABLA DE CONTENIDO

PROGRAMACIN BASICA: APRENDIENDO LO BASICO DIGITAL 4

PROGRAMACIN BASICA: CAPTURAS ANALOGAS 17

PROGRAMACIN BASICA: COMUNICACIN SERIAL 21

PROGRAMACIN INTERMEDIA 30

CAPTURA DE SEALES DIGITALES 35

ENLACES PARA DESCARGAS DEL CURSO 44

2
TABLA DE CONTENIDO DEL HARDWARE EXTERNO

CONEXIN DE UN SUITCHE Y UN LED 7

CONEXIN DE UN DISPLAY DOBLE UTILIZANDO UN DECODIFICADOR 12

USO DEL RELAY PARA MANEJAR ELEMENTOS DE POTENCIA 19

CONEXIN DEL SENSOR DE LUZ 19

AMPLIFICACIN DE LA SEAL DEL MICROFONO 34

CONEXIN PARA USO DEL CONTROL DE TELEVISIN 37

3
COMENZANDO CON ARDUINO

El Arduino es una plataforma de prototipado basado en un sistema flexible de uso


sencillo del hardware y el software, esta orientado para artistas, diseadores y
cualquier persona interesada en crear un entorno interactivo.

Para conocer un poco sobre la historia del Arduino:


http://archive.org/details/Arduino.TheDocumentary.Spanish

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.

// EJEMPLO 001 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende un led

// Se crea una variable llamada ledPin y se le asigna un valor de 13:


constintledPin = 13;

// Todo lo que se encuentre dentro de esta funcin es llamado solo


// una vez
voidsetup(){

// Asigna el pin ledPin como salida:


pinMode(ledPin, OUTPUT);
// Otra forma de hacerlo es:
pinMode(13, OUTPUT);
// Escribe un '1' logico en la salida:
digitalWrite(ledPin, HIGH);
// Otra forma de hacerlo es:
digitalWrite(13, HIGH);
}

voidloop(){

En general la programacin de un Arduino no requiere un conocimiento profundo del


funcionamiento del microcontrolador, los nombres de las funciones son intuitivos y
cuenta con una referencia que puede encontrarse tanto en ingles como en espaol en
la pgina oficial.

http://arduino.cc/en/Reference/HomePage
http://arduino.cc/es/Reference/HomePage

4
COMENZANDO CON ARDUINO

COMENZANDO CON ARDUINO


PROGRAMACIN BASICA: APRENDIENDO LO BASICO DIGITAL

// EJEMPLO 002 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende un led 3 veces

constintledPin = 13;

voidsetup(){

//Asigna el pin ledPin (13) como salida


pinMode(ledPin, OUTPUT);
//Escribe un '1' logico en la salida
digitalWrite(ledPin, HIGH);
//Espera medio segundo
delay(500);

//Apaga el led
digitalWrite(ledPin, LOW);
//Espera medio segundo
delay(500);

//Escribe un '1' logico en la salida


digitalWrite(ledPin, HIGH);
//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);
}

// Esta funcin es un ciclo infinito, es decir todo lo que se


// encuentre dentro de la funcin se llamara constantemente
voidloop(){

//Escribe un '1' logico en la salida


digitalWrite(ledPin, HIGH);
//Espera 1000 milisegundos (1 segundo)
delay(1000);
//Escribe un '0' logico en la salida
digitalWrite(ledPin, LOW);
//Espera 1 segundo
delay(1000);
}

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.

// EJEMPLO 004 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende un led cuando una seal digital
// esta en alto '1'

//Se le asigna un nombre a los pines


constintledPin = 13;
constintswitchePin = 2;

voidsetup(){

//Se asigna un pin como salida y otro como entrada


pinMode(ledPin, OUTPUT);
pinMode(switchePin, INPUT);
}

//Se pregunta por el suitche en el ciclo infinito de modo


//Que se pueda hacerce en cualquier instante
voidloop(){

7
//Se lee la entrada del pin
intswitcheEstado = digitalRead(switchePin);

//Si la entrada esta en '1'


if( switcheEstado == HIGH){
//Se activa el pin llamado ledPin
digitalWrite(ledPin, HIGH);
}
//De lo contrario
else{
//Se desactiva el pin
digitalWrite(ledPin, LOW);
}

El condicional IF nos permite tomar decisiones de acuerdo a ciertas condiciones y ser


utilizado cada vez que se requiera tomar una decisin.

8
// EJEMPLO 005 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende una secuencia de leds

//Informacion acerca de los pines


constint ledPin4 = 4;
constint ledPin5 = 5;
constint ledPin6 = 6;
constint ledPin7 = 7;
constint ledPin8 = 8;

voidsetup(){

//Asigna todos los pines como salidas


pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(ledPin7, OUTPUT);
pinMode(ledPin8, OUTPUT);

voidloop(){

//Encience el led y luego de medio segundo lo apaga


//Esto lo hace para cada pin desde el 4 hasta el 8

digitalWrite(ledPin4, HIGH); // enciende el LED


delay(500);
digitalWrite(ledPin4, LOW); // apaga el LED
delay(500);
digitalWrite(ledPin5, HIGH); // enciende el LED
delay(500);
digitalWrite(ledPin5, LOW); // apaga el LED
delay(500);
digitalWrite(ledPin6, HIGH); // enciende el LED
delay(500);
digitalWrite(ledPin6, LOW); // apaga el LED
delay(500);
digitalWrite(ledPin7, HIGH); // enciende el LED
delay(500);
digitalWrite(ledPin7, LOW); // apaga el LED
delay(500);
digitalWrite(ledPin8, HIGH); // enciende el LED
delay(500);
digitalWrite(ledPin8, LOW); // apaga el LED
delay(500);

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(){

// Asigna los pines desde el 4 hasta el 9 como salida


for(inti=4; i<9; i++){
pinMode(i, OUTPUT);
}

// Se asigna el pin 2 como entrada


pinMode(switchePin, INPUT);
}

voidloop(){

// Se lee la entrada del pin 2


intswitcheEstado = digitalRead(switchePin);

// Si el pin 2 esta en alto


if( switcheEstado == HIGH){

// Entonces activa los pines desde el 4 hasta el 9


for(inti=4; i<9; i++){
digitalWrite(i, HIGH); // Enciende el LED
delay(500);
digitalWrite(i, LOW); // Apaga el LED
}
}

10
// EJEMPLO 007 SEMILERO DE AUTOMATIZACION
// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Creacion de funciones

voidsetup(){

asignarSalidas(2,3);
}

voidloop(){

alternarLeds();
}

//Se crea una funcion llamada asignarSalidas() que recibe dos


//parmetros.

//los numeros que se lleven como parametros se asignan como salidas.


voidasignarSalidas(int pPin1, int pPin2){

pinMode(pPin1, OUTPUT);
pinMode(pPin2, OUTPUT);
}

//Se crea una funcion llamada alternarLeds() que alterna la


//activacionentre dos pines
voidalternarLeds(){

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

En la imagen anterior se observa como puede conectarse un Display doble siete


segmentos a un Arduino a travs de un decodificador BCD, esto con el fin de ahorrar
pines y hacer ms intuitivo el manejo del display.

DECIMAL BINARIO SALIDA DEL DOCODIFICADOR


74Ls47
A B C D a b c d e f g
0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 1 1 0 0 1 1 1 1
2 0 0 1 0 0 0 1 0 0 1 0
3 0 0 1 1 0 0 0 0 1 1 0
4 0 1 0 0 1 0 0 1 1 0 0
5 0 1 0 1 0 1 0 0 1 0 0
6 0 1 1 0 1 1 0 0 0 0 0
7 0 1 1 1 0 0 0 1 1 1 1
8 0 0 0 0 0 0 0 0 0 0 0
9 1 0 0 1 0 0 0 1 1 0 0

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

//Se asignan pines para la salida


constint pinA0 = 4;
constint pinA1 = 5;
constint pinA2 = 6;
constint pinA3 = 7;

//Se crea una variable que llevara el numero del display


int valor = 0;

voidsetup(){

//Se asignan los pines de salida


pinMode(pinA0, OUTPUT);
pinMode(pinA1, OUTPUT);
pinMode(pinA2, OUTPUT);
pinMode(pinA3, OUTPUT);
}

voidloop(){
//Se llama la funciondisplay y se le envia un numero entero llamado
//valor
miDisplay(valor);

//Esparamos 500ms (medio segundo)


delay(500);

//Incrementamos el valor para ver todos los numeros


//Solo incrementamos si no hemos llegado al 10
if(valor<10){
valor++;
}
//Cuando lleguemos al 10 reiniciamos el valor
else{
valor=0;
}

}
//Se crea una funcion llamada miDisplay() que recibe un valor entero
voidmiDisplay(intpValor){

//Se crean casos para cada numero


switch(pValor){
//En el caso '0' la salida debe ser 0000
case 0:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, LOW);
break;
//En el caso '1' la salida debe ser 0001
case 1:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, LOW);

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.

// EJEMPLO 009 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Permite utilizar un display doble siete segmentos
// conectado a un decodificador para display

//Se asignan pines para la salida


constint pinA0 = 4;
constint pinA1 = 5;
constint pinA2 = 6;
constint pinA3 = 7;

constint pinB1 = 2;
constint pinB2 = 3;

//Se crea una variable que llevara el numero del display


int valor = 0;

voidsetup(){

//Se asignan los pines de salida


pinMode(pinA0, OUTPUT);
pinMode(pinA1, OUTPUT);
pinMode(pinA2, OUTPUT);
pinMode(pinA3, OUTPUT);

pinMode(pinB1, OUTPUT);
pinMode(pinB2, OUTPUT);
}

voidloop(){

//Se llama la funcionmiDisplayCompleto y se muestra un 18


miDisplayCompleto(18);

voidmiDisplayCompleto(intpValorCompleto){

//Se obtienen las decenas:


int decenas = pValorCompleto/10;
//Se obienen las unidades:
int unidades = pValorCompleto - decenas*10;

//Se enciende un display y se apaga el otro

15
digitalWrite(pinB1,HIGH);
digitalWrite(pinB2,LOW);
//Se muestran las decenas
miDisplay(decenas);
//Se espera 1 milisegundo
delay(1)

//Se enciende un display y se apaga el otro


digitalWrite(pinB2,HIGH);
digitalWrite(pinB1,LOW);
//Se muestran las unidades
miDisplay(unidades);
//Se espera 1 milisegundo
delay(1)

//Se crea una funcion llamada miDisplay() que recibe un valor entero
voidmiDisplay(intpValor){

//Se crean casos para cada numero


switch(pValor){
//En el caso '0' la salida debe ser 0000
case 0:
digitalWrite(pinA0, LOW);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, LOW);
break;
//En el caso '1' la salida debe ser 0001
case 1:
digitalWrite(pinA0, HIGH);
digitalWrite(pinA1, LOW);
digitalWrite(pinA2, LOW);
digitalWrite(pinA3, LOW);
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:

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.

// EJEMPLO 010 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Enciende una bombilla cuando no hay luz suficiente

constintrelePin=13;

voidsetup() {
//Se asigna un pin como salida
pinMode(relePin, OUTPUT);
}

//Se crea un ciclo infinito


voidloop() {

//Se lee la entrada analoga A0


intvalorSensor = analogRead(A0);
//Se conviete a voltaje multiplicando el valor leido
//por 5/1023
floatvoltaje = valorSensor * (5.0 / 1023.0);

//
if(voltaje< 1.5){
digitalWrite(relePin,HIGH);
delay(50);
}
else{
digitalWrite(relePin,LOW);
}

En la descripcin se especifica que va a encenderse una lmpara en lugar de un LED,


esto es debido a que cualquier seal digital puede ser utilizada para encender un
elemento de potencia si se utiliza un Rel. Se observa algo del tema en la clase 4 del
semillero.

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 lee el valor de la entrada analoga A0


intvalorSensor = analogRead(A0);

// Se convierte a voltaje
float voltaje = valorSensor * (5.0 / 1024.0);

// Los calculosestan hechos para el sensor LM35


int temperatura = (voltaje*100);
displayLuz.mostrar(temperatura);

// Si la temperatura supera los 35 grados centgrados se activa


// El pin relePin
if(temperatura> 35){
digitalWrite(relePin,HIGH);
}
else{
digitalWrite(relePin,LOW);
}

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

//Inicializamos los pines como pines de salida


voidsetup(){

pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
}

voidloop(){

//Se conecta el sensor a la entrada A5 y se lee su valor


intvalorSensor = analogRead(A5);

//El valor del sensor va desde 0 hasta 1023. As que podemos


//encender un led cada 150, de este modo:

//Si el valor del sensor es menor 150


if(valorSensor< 150){
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
}
//Si el valor del sensor esta entre 150 (incluyendo 150) y 300
if( valorSensor>= 150 &&valorSensor< 300){
digitalWrite(2,HIGH);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
}
//Si el valor del sensor esta entre 300 (incluyendo 300) y 450
if( valorSensor>= 300 &&valorSensor< 450){
digitalWrite(2,HIGH);
digitalWrite(3,HIGH);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
}
//Si el valor del sensor esta entre 450 (incluyendo 450) y 600
if( valorSensor>= 450 &&valorSensor< 600){
digitalWrite(2,HIGH);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
}

//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

La comunicacin serial es un tipo de comunicacin utilizada para comunicar


ordenadores y ordenadores con perifricos, debido a que es altamente utilizada, el
Arduino cuenta con funciones que nos permiten hacer una comunicacin de manera
sencilla.

// Ejemplo 013 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Renvia por serial el dato recibido

voidsetup(){

//Se inicializa la comunicacion serial


Serial.begin(9600);
}

voidloop(){

//Se pregunta si existen datos para leer


if(Serial.available() > 0){
//Se imprimen los datos leidos
Serial.println(Serial.read());
}
}

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.

Puede descargarse el Docklight del siguiente link:

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.

// Ejemplo 014 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Envia por serial el dato que se lee del sensor

voidsetup(){
//Se inicializa la comunicacion serial
Serial.begin(9600);
}

voidloop(){

//Se lee el valor del sensor


int sensor = analogRead(A0);
//Se envia por el puerto serial
Serial.println(sensor);
//Opcional: Se espera un tiempo para facilitar la lectura
delay(100);
}

En la programacin de los microcontroladores pueden utilizarse interrupciones, estas


interrupciones se refieren a eventos que sacan al programa de su comportamiento
normal para atender un evento de alta prioridad.

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() {

//Se crea una interrupcin para atender el evento serial


voidserialEvent(){

//Se lee lo recibido


intmiSerial = Serial.read();
//Se imprime lo leido
Serial.println(miSerial,DEC);
delay(1);
}

Es posible utilizar la comunicacin serial como interfaz entre el ordenador y el Arduino,


es decir es posible hacer cosas como encender una bombilla desde el ordenador.

// Ejemplo 016 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Se leen los datos recibidos por el puerto serial
// Utilizando interrupciones, el dato ledo se convierte de ASCII
// A decimal y si es un 1 se activa un pin de los contrario se
// Apaga.

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);
}

//Se crea una interrupcin para atender el evento serial

25
voidserialEvent(){

//Se lee lo recibido y se convierte a decimal


valorLeido = Serial.read()-48;
Serial.print(valorLeido);
}
Con el fin de hacer la comunicacin entre el ordenador y el Arduino ms sencilla e
intuitiva se puede disear una interfaz grafica, esto puede hacerse utilizando QT
creator, Visual Studio, Matlab, entre otros. La interfaz diseada para este semillero ha
sido diseada en QT Creator y se presenta a continuacin:

Permite seleccionar el puerto, mostrar datos en los Displays de la interfaz, cuenta con
10 botones numricos y con un Dial.

Permite utilizar la cmara como un sistema de seguridad. Para esto se ajusta la


tolerancia de modo que la alarma se encienda cuando detecte una cantidad de
movimiento apropiada.

26
Finalmente cuenta con indicadores que fueron diseados para mostrar un valor entre
0 y 100 de la temperatura, la luminosidad y la presin.

La interfaz puede descargarse desde el siguiente link:


http://dl.dropbox.com/u/73742692/SemilleroAutomatizacion/Ejecutable/SemilleroAutomatizacion
.zip

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

Desde el Arduino hasta la interfaz


Interfaz Dato de Inicio Tipo de Dato Valor de Dato Dato de Fin
Display 1 I D 0-9999 F
Display 2 I D 0-9999 F
Luminosidad I L 0-99 F
Temperatura I T 0-99 F
Presin I P 0-99 F

Teniendo este protocolo podemos utilizar la interfaz, si se desea mostrar un 60 en el


indicador de temperatura debemos entonces enviar una I, una L, un 60, y una F.
Cuando la interfaz recibe estos datos sabe que se refiere al indicador de temperatura.
En el caso contrario se utiliza el protocolo de la interfaz al Arduino, por ejemplo si se
enciende la alarma el Arduino recibir: IA1F y en el momento en que se apague
recibir: IA0F.

// Ejemplo 017 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Se activa un pin al recibir la alarma
// Y otro cuando se presiona el boton 5.

// Datos para almacenar el protocolo


intcontadorSerial=0;
intvectorSerial[4];

// Datos de interes
inttipoDato = 0;
intvalorDato = 0;

28
voidsetup(){

Serial.begin(9600);

pinMode(11,OUTPUT);
pinMode(10,OUTPUT);

voidloop(){

//Si se recibe una alarma


if(tipoDato == 'A'){
//Si la alarma esta activa
if(valorDato == 1){
digitalWrite(10,HIGH);
}
//Si la alarma no esta activa
else{
digitalWrite(10,LOW);
}
}

//Si se recibe un boton


if(tipoDato == 'B'){
//Si el boton recibido es el 5
if(valorDato == 5){
digitalWrite(11,HIGH);
}else{
//Si el boton recibido no es un 5
digitalWrite(11,LOW);
}

//Interrupciones por serial


voidserialEvent(){

//Se almacenan los datos recibidos en un vector


vectorSerial[contadorSerial] = Serial.read();

//Solo se almacenan si el primer dato es una I


//Debido a que la 'I' indica que se enviara informacion
if(vectorSerial[0] == 'I'){
contadorSerial++;
}

//Cuando se hayan recibido todos los datos se revisa


//Que tipo de dato se ha enviado
if(contadorSerial> 3){
obtenerDatos();
}

voidobtenerDatos(){

//Si los datos recibidos cumplen el protocolo se almacenan

29
if(vectorSerial[0]=='I'&&vectorSerial[3]=='F'){
tipoDato=vectorSerial[1];
valorDato=vectorSerial[2]-48;
}
contadorSerial=0;

// Ejemplo 018 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descripcion: Se activa un pin con una intensidad proporcional
// A la seleccionada en el Dial de la interfaz (se puede probar
// En un led), se envia la cantidad de luz recibida por la entrada
// Analoga A0 al indicador de luz de la interfaz

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(){

// Si el dato es enviado por el Dial


if(tipoDato == 'D'){
// El valor recibido esta entre 0 y 9. Este se convierte
// En un valor de 0 a 255 y se le lleva al LED.
intvalorPWM = (valorDato*255)/9;
analogWrite(10,valorPWM);
}

//Se enva la Luz recibida por el sensor conectado a la entrada


//Analoga A0
int luz = analogRead(A0);
Serial.print('I');
Serial.print('L');
Serial.print(luz);
Serial.print('F');

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.

// EJEMPLO 019 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descrpicion: Utiliza dos displays 7 segmentos para implementar
// un cronometro que permite contar hasta 3 minutos

#include <displayCompleto.h>

//Se crea un objeto tipo display


DisplayCompleto miDisplay;

//Se utilizan dos variables de tiempo

//El tipo de variable no tiene signo debido a que el tiempo nunca


//es negativo
unsignedlong tiempo = 0;
unsignedlongtiempoAnterior = 0;

//Estas variables cuentan cuantos segundos y cuantos minutos


//han transcurrido
unsignedint segundos = 0;
unsignedintminutos = 0;

voidsetup(){

//Se inicializa el display


miDisplay.inicializar(5,4,3,2,7,6);

pinMode(8 ,OUTPUT);
pinMode(9 ,OUTPUT);
pinMode(10,OUTPUT);

voidloop(){

tiempo = millis();

//Se crea una base de tiempo de un segundo. El programa


//solo entra a este condicional cuando ha transcurrido un segundo
if(tiempo - tiempoAnterior>= 1000){
tiempoAnterior = tiempo;
//Se incrementa la variable segundos
segundos = segundos + 1;
}

//Cuando han transcurrido 60 segundos, el contador debe iniciar


//nuevamente, y los minutos incrementan
if(segundos >= 60){

32
segundos = 0;
minutos = minutos+1;
}

//Se encienden leds dependiendo de la cantidad de minutos que


//han transcurrido
if( minutos == 0){
digitalWrite(8 ,LOW);
digitalWrite(9 ,LOW);
digitalWrite(10,LOW);
}
if( minutos == 1){
digitalWrite(8 ,HIGH);
digitalWrite(9 ,LOW);
digitalWrite(10,LOW);
}
if( minutos == 2){
digitalWrite(8 ,HIGH);
digitalWrite(9 ,HIGH);
digitalWrite(10,LOW);
}
if( minutos == 3){
digitalWrite(8 ,HIGH);
digitalWrite(9 ,HIGH);
digitalWrite(10,HIGH);
}

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

// EJEMPLO 020 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descrpicion: Enciende una bombilla con un aplauso

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() {

//Se lee la entrada analoga que debe estar conectada a un


//Microfono amplificado
intvalorSensor = analogRead(A0);

34
//Se convierte a voltaje
float voltaje = valorSensor * (5.0 / 1023.0);

//Si el voltaje supera cierto umbral se considera que ha


//Ocurrido un aplauso
if(voltaje > 0.8){

//La bandera aplauso niega su valor actual. Por lo tanto:


//Si estaba en falto cambia a verdadero y viceversa
aplauso = !aplauso;
delay(50);
}

//Si la bandera esta en cierto se activa el pin


if( aplauso == true){
digitalWrite(ledPin,HIGH);
}
//Si la bandera esta en falso se desactiva el pin
else{
digitalWrite(ledPin,LOW);
}

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.

// EJEMPLO 021 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacin GEPAR
// Giovanny Espinal Ramirez
// Descrpicion: Enciende una bombilla cuando se aplaude dos
// Veces en menos de medio segundo. Se apaga con un aplauso

constintrelePin=13;

int aplausos = 0;
booleanaplausoActivo = false;
booleanencenderBombillo = false;

unsignedlongtiempo=0;
unsignedlongtiempoAnterior=0;
unsignedlongmedioSegundo=0;

// the setup routine runs once when you press reset:


voidsetup() {
pinMode(relePin, OUTPUT);
}

// the loop routine runs over and over again forever:


voidloop() {

35
intvalorSensor = analogRead(A0);
float voltaje = valorSensor * (5.0 / 1023.0);

tiempo = millis();

//Crea una base de tiempo de medio segundo


if(tiempo - tiempoAnterior> 500){
tiempoAnterior = tiempo;
medioSegundo++;
}

//Si detecta un sonido fuerte se activa la bandera


//aplausoActivo y se lleva el contador de tiempo a cero
if(voltaje > 0.5){
medioSegundo=0;
aplausoActivo= true;
delay(50);
}

//Si ya existe un aplauso y ha pasado menos de medio segundo


//o medio segundo se aumenta la cantidad de aplausos
if(aplausoActivo == true&&medioSegundo<= 1){
aplausoActivo = false;
aplausos = aplausos + 1;

//Si ha pasado ms de medio segundo se resetea el contador


//de aplausos
if(medioSegundo> 1){
aplausos=0;
}

//Si han ocurrido dos aplausos se activa la bandera


//Encender Bombillo
if( aplausos == 2){
encenderBombillo= true;
//Tambien se resetea el contador de aplausos
aplausos=0;
}

//Para apagar la bombilla se debe recibir un aplauso


//Y la bombilla debe estar encendida
if(aplausos == 1 &&encenderBombillo == true){
encenderBombillo = false;
aplausos=0;
}

//Si la bandera encender bombilla esta activa


if(encenderBombillo == true){
//Se activa un pin
digitalWrite(relePin,HIGH);

}
//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(){

//Es necesario inicializar la comunicacion serial


Serial.begin(9600);
}

voidloop(){

//De acuerdo a los tiempos obtenidos anteriormente


//Se considera que es un '1' cuando el tiempo en alto
//Esta entre 1000 y 3000, el tercer parametro indica
//Que la informacion esta en el tiempo en alto y que
//El pin de captura es el pin 7
calcularProtocolo(1000,3000,1,7);

//Si existen datos disponibles


if(datosDisponibles() == true){
//Se reinician
reiniciarDatos();
}
}

Al utilizar este programa y revisar el monitor serial podemos obtener un protocolo


estimado de cada botn, es bueno presionar cada botn varias veces con el fin de
verificar que el protocolo no vari cuando no se cambia de botn, es importante
tambin presionar cada botn pero no sostenerlo para no obtener un protocolo ms
largo de lo que realmente es.

La captura de pantalla resultado de este programa es una captura utilizando un control


Sony VTR, se presion el botn nmero 1 en tres ocasiones (recuadro rojo) y se realizo
el mismo procedimiento con el botn nmero 2 y 3, si se revisa con cuidado el
protocolo pueden verse las diferencias de cada uno.

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.

// EJEMPLO 022 SEMILERO DE AUTOMATIZACION


// Autor: Grupo de investigacion GEPAR
// Giovanny Espinal Ramirez
// Descrpicion: Permite encender un led cuando se presiona
// El boton '1' de un control Sony VTR y apagarlo con otro
// boton

#include <controlTV.h>

//Ejemplo con control sony VTR:


//Boton 1:
int bSony1[] =
{1,0,0,0,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,
1,1,0,1,0};
//Boton 2:
int bSony2[] =
{1,1,0,0,0,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,0,
1,1,0,1,0};

42
voidsetup(){

Serial.begin(9600);
pinMode(13,OUTPUT);
}

voidloop(){

//Se obtienen los datos


calcularProtocolo(1000,3000,1,7);

if(datosDisponibles() == true){

//Se comparan los datos con los datos almacenados como


//bSony1, y se comparan los 30 primeros datos.

//Si los datos son iguales se enciende el led


if(compararDatos(bSony1,30) == true){
digitalWrite(13,HIGH);
}else{
digitalWrite(13,LOW);
}

//Finalmente tienen que reiniciarse los datos para las


//nuevas capturas
reiniciarDatos();
}
}

43
COMENZANDO CON ARDUINO
ENLACES DE INTERES

Presentaciones del curso:


http://dl.dropbox.com/u/73742692/SemilleroAutomatizacion/Clases/Clases.zip

Interfaz del curso:


http://dl.dropbox.com/u/73742692/SemilleroAutomatizacion/Ejecutable/SemilleroAut
omatizacion.zip

Libreras del curso:


http://dl.dropbox.com/u/73742692/SemilleroAutomatizacion/Librerias/SemilleroAuto
matizacion.zip

Para pruebas de comunicacin serial: Docklight


http://www.docklight.de/download_en.htm

44

Вам также может понравиться