Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Todo Sobre Arduino

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 222

¿Qué es un encoder rotativo?

Un encoder rotativo es un dispositivo genérico que permite determinar la posición y velocidad


angular de un accionamiento, y registrar la medición desde un procesador o autómata como
Arduino.
No es la primera vez que hablamos de encoders y su utilidad. Previamente hemos visto encoders
ópticos y encoders magnéticos, así como su importancia a la hora de aplicar criterios de selección
de motores y accionamientos.
Existen múltiples tipos de encoders rotativos, pero en el ámbito de Arduino y
los proyectos de electrónica caseros es muy frecuente encontrar encoders rotativos
electromecanicos.
Externamente estos encoders pueden ser parecidos a ciertos tipos modelos de potenciómetros, lo
cual puede ser una ventaja porque hace que ciertos accesorios sean similares, e incluso sea posible

sustituir uno por otro.


Sin embargo, no hay que confundir un encoder rotativo con un potenciómetro ya que tanto su
electrónica como comportamiento son totalmente diferentes.
Este tipo de encoder rotativo es un dispositivo incremental que proporciona un pulso digital cada vez
que el encoder gira un determinado ángulo. El número de pulsos por vuelta depende del encoder
empleado, siendo habitual 256 pulsos/vuelta.
Frecuentemente, también incorporan un pulsador que actual al apretar la palanca del encoder.
Curiosamente, este tipo de encoders no son demasiado útiles para actuar como
encoders propiamente dichos, es decir, para registrar el giro de un elemento (por ejemplo, la rueda
de un robot) de un debido a la dificultad de acoplarlo al eje y la baja resolución del encoder.
Su uso principal es como mando o dispositivo de control o en sustitución de potenciómetros. Por
ejemplo, pueden emplearse para regular el brillo de una pantalla LCD, el volumen de un dispositivo,
o el ángulo de un motor paso a paso o servo.

¿Cómo funciona un encoder rotativo?


Internamente el encoder está formado por dos escobillas que deslizan sobre una pista de metálica
con divisiones. Al girar el eje, una pequeña bola metálica cierra el contacto, actuando como un
pulsador.
Normalmente disponen de dos salidas formando un sistema equivalente a disponer dos
pulsadores (Canal A y B). Estos pulsadores están desplazados uno respecto al otro, formando lo que
se denomina un encoder en cuadratura.
En un encoder en cuadratura existe un desfase entre ambos sensores de forma que la señal que
producen está desplazada 90º eléctricos. Gráficamente, la señal de ambos canales respecto al
ángulo girado sería la siguiente.

La ventaja de los encoder en cuadratura es que, además de detectar la posición y la


velocidad, permiten determinar el sentido de giro.
Para visualizarlo, consideremos que tomamos como origen de eventos los flancos de subida o bajada
del Canal A. Si giramos en el sentido CW, se producirán los eventos t0, t1, t2, t3… tn.
Si en estos eventos miramos el Canal B, vemos que la señal A es siempre inversa al Canal B.
.Si invertimos el sentido de giro, e igualmente tomamos como referencia los flancos de bajada o
subida del Canal A, vemos que en los instantes (t0, t1, t2, t3… tn) la señal del Canal A y B son
siempre idénticas.

En realidad, que el sentido de giro sea CW o CCW dependerá de la construcción interna del
sensor, de la conexión, y del canal que tomemos como referencia.
Pero, en cualquier caso, vemos que es posible diferenciar el sentido de giro simplemente
comparando las señales obtenidas en el encoder en cuadratura, y asignar un significado físico CW
o CCW es inmediato, simplemente probando el montaje una vez.
Respecto a la precisión, tenemos más de una opción.

 Precisión simple, registrando un único flanco (subida o bajada) en un único canal.


 Precisión doble, registrando ambos flancos en un único canal.
 Precisión cuádruple, registrando ambos flancos en ambos canales.

Esquema de montaje
Para conectar el encoder a Arduino, necesitamos tres entradas digitales, dos para la detección del
encoder y una adicional si queremos registrar la pulsación de la palanca.
Idealmente, deberíamos emplear interrupciones para registrar el movimiento del encoder.
Lamentablemente, la mayoría de placas de Arduino sólo tienen dos pines asociados a interrupciones.
En el caso de querer precisión cuádruple esto supone emplear los dos pines con interrupciones.
En este caso, la conexión del encoder sería la siguiente.
Mientras que la conexión vista desde Arduino sería la siguiente.

No obstante, es posible emplear el encoder sin emplear interrupciones, lo que permite emplear
entradas digitales. Sin embargo, tendremos que preguntar por pool el estado de la entrada, lo que
supone un peor rendimiento.

Ejemplos de código
Precisión simple o doble por pool
En este primer ejemplo realizamos la lectura del encoder por pool, sin emplear interrpciones. Para
ello podemos usar dos entradas digitales cualquiera, en el ejemplo D9 y D10. La precisión puede ser
doble o simple, para lo cuál tendréis que cambiar la linea comentada en el condicional (aunque no
se me ocurre una razón para preferir precisión simple a doble)
1 const int channelPinA = 9;
2 const int channelPinB = 10;
3
4 unsigned char stateChannelA;
5 unsigned char stateChannelB;
6 unsigned char prevStateChannelA = 0;
7
8 const int maxSteps = 255;
9 int prevValue;
10 int value;
11
12 const int timeThreshold = 5;
13 unsigned long currentTime;
14 unsigned long loopTime;
15
16 bool IsCW = true;
17
18 void setup() {
19 Serial.begin(9600);
20 pinMode(channelPinA, INPUT);
21 pinMode(channelPinB, INPUT);
22 currentTime = millis();
23 loopTime = currentTime;
24 value = 0;
25 prevValue = 0;
26 }
27
28 void loop() {
29 currentTime = millis();
30 if (currentTime >= (loopTime + timeThreshold))
31 {
32 stateChannelA = digitalRead(channelPinA);
33 stateChannelB = digitalRead(channelPinB);
34 if (stateChannelA != prevStateChannelA) // Para precision simple
35 if((!stateChannelA) && (prevStateChannelA))
36 {
37 if (stateChannelB) // B es HIGH, es CW
38 {
39 bool IsCW = true;
40 if (value + 1 <= maxSteps) value++; // Asegurar que no sobrepasamos maxSteps
41 }
42 else // B es LOW, es CWW
43 {
44 bool IsCW = false;
45 if (value - 1 >= 0) value = value--; // Asegurar que no tenemos negativos
46 }
47
48 }
49 prevStateChannelA = stateChannelA; // Guardar valores para siguiente
50
51 // Si ha cambiado el valor, mostrarlo
52 if (prevValue != value)
53 {
54 prevValue = value;
55 Serial.print(value);
56
57 }
58
59 loopTime = currentTime; // Actualizar tiempo
60 }
61
62 // Otras tareas
}

Precisión doble con una interrupción


En este ejemplo cambiamos una de las entradas digitales por una interrupción, registrando flancos
de subida y bajada, por lo que tenemos precisión doble.

1 const int channelPinA = 2;


2 const int channelPinB = 10;
3
4 const int timeThreshold = 5;
5 long timeCounter = 0;
6
7 const int maxSteps = 255;
8 volatile int ISRCounter = 0;
9 int counter = 0;
10
11 bool IsCW = true;
12
13 void setup()
14 {
15 pinMode(channelPinA, INPUT_PULLUP);
16 Serial.begin(9600);
17 attachInterrupt(digitalPinToInterrupt(channelPinA), doEncode, CHANGE);
18 }
19
20 void loop()
21 {
22 if (counter != ISRCounter)
23 {
24 counter = ISRCounter;
25 Serial.println(counter);
26 }
27 delay(100);
28 }
29
30 void doEncode()
31 {
32 if (millis() > timeCounter + timeThreshold)
33 {
34 if (digitalRead(channelPinA) == digitalRead(channelPinB))
35 {
36 IsCW = true;
37 if (ISRCounter + 1 <= maxSteps) ISRCounter++;
38 }
39 else
40 {
41 IsCW = false;
42 if (ISRCounter - 1 > 0) ISRCounter--;
43 }
44 timeCounter = millis();
45 }
46 }

Precisión cuádruple con dos interrupciones


En este último ejemplo, empleamos interrupciones para ambos canales, y en ambos flancos.
Obtenemos precisión cuádruple, pero a cambio dejamos sin más pines con interrupciones a la
mayoría de modelos de Arduino.

1 const int channelPinA = 2;


2 const int channelPinB = 3;
3
4 const int timeThreshold = 5;
5 long timeCounter = 0;
6
7 const int maxSteps = 255;
8 volatile int ISRCounter = 0;
9 int counter = 0;
10
11 bool IsCW = true;
12
13 void setup()
14 {
15 pinMode(channelPinA, INPUT_PULLUP);
16 Serial.begin(9600);
17 attachInterrupt(digitalPinToInterrupt(channelPinA), doEncodeA, CHANGE);
18 attachInterrupt(digitalPinToInterrupt(channelPinB), doEncodeB, CHANGE);
19 }
20
21 void loop()
22 {
23 if (counter != ISRCounter)
24 {
25 counter = ISRCounter;
26 Serial.println(counter);
27 }
28 delay(100);
29 }
30
31 void doEncodeA()
32 {
33 if (millis() > timeCounter + timeThreshold)
34 {
35 if (digitalRead(channelPinA) == digitalRead(channelPinB))
36 {
37 IsCW = true;
38 if (ISRCounter + 1 <= maxSteps) ISRCounter++;
39 }
40 else
41 {
42 IsCW = false;
43 if (ISRCounter - 1 > 0) ISRCounter--;
44 }
45 timeCounter = millis();
46 }
47 }
48
49 void doEncodeB()
50 {
51 if (millis() > timeCounter + timeThreshold)
52 {
53 if (digitalRead(channelPinA) != digitalRead(channelPinB))
54 {
55 IsCW = true;
56 if (ISRCounter + 1 <= maxSteps) ISRCounter++;
57 }
58 else
59 {
60 IsCW = false;
61 if (ISRCounter - 1 > 0) ISRCounter--;
62 }
63 timeCounter = millis();
64 }
65 }

PCF8574. Expansor I2C de puertos GPIO digitales de entrada y salida.


Arduino
Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 05 Enero 2018
Visto: 1026

Voto 5 Votar
Por favor, vote

Cuando un proyecto crece en complejidad no es raro encontrarse con que hacen falta más puertos
de entrada-salida de los que hay disponibles en el microcontrolador seleccionado inicialmente. La
solución puede ser optar por otro modelo de MCU de la misma familia pero que disponga de más
patillas o añadir al proyecto un integrado, como el PCF8574, que aporte los GPIO que falten y se
comunique con el µC con un bus I2C (que el bus que utiliza el PCF8574) o un bus SPI, con los que
se puede conectar al microcontrolador varios dispositivos de manera simultánea.
El PCF8574 es muy popular porque, además de ser
barato, es sencillo tanto incluirlo en un circuito como usarlo desde un programa. Se presenta en
varios encapsulados, incluyendo DIP, por lo que es ideal para hacer prototipos y pruebas antes de

implementar el integrado en el proyecto definitivo.


La conexión del PCF8574 es muy sencilla. Por el lado del microcontrolador se conecta al bus I2C y
a un pin que soporte una interrupción. Las tres líneas, las dos del bus y la de la interrupción, deben
contar con las correspondientes resistencias pull-up.
La parte fija de la dirección IC del PCF8574 es 0b0100AAA (0x32 | AAA) y la del PCF8574A es
0b0100AAA0 (0x64 | AAA). Los tres dígitos representados con AAA se configuran con las patillas A0
a A2.
. Conectándolas a masa (a nivel bajo), como en el esquema de conexión del ejemplo de abajo, se
consigue la dirección base 0b0100000 (0x32), o 0b0100AAA0 (0x64) en el caso del PCF8574A.

El PCF8574 dispone de resistencias pull-up internas en los pin de entrada y salida P0 a P7 por lo
que al inicio de su funcionamiento (al alimentarlo) están a nivel alto.
La alimentación del PCF8574 está en el intervalo de 2,5 V a 6 V, así que puede usarse con un rango
muy amplio de µC. Como no ofrece a la salida una corriente muy alta, es conveniente conectar las
salidas del integrado con un driver (un simple transistor en corte o saturación puede servir) o, por
ejemplo para usar LED, activarlos a nivel bajo y no alimentarlos con la salida del PCF8574.
Aunque es muy sencillo incorporar la versión DIP a un prototipo o usarla para pruebas, también
existen módulos, como el de la imagen de abajo, que incluyen el PCF8574A, las resistencias del bus
I2C (aunque normalmente no la de la interrupción) y recursos para configurar la dirección del
dispositivo y encadenar módulos al estilo daisy chain.

El PCF8574 puede manejarse desde una placa Arduino usando la librería Wire en el programa con
el que se explote. Para usarlo en modo escritura basta con enviar el valor del estado de los 8 bits
que representan el puerto. La lectura puede hacerse de dos modos: que el programa tome la
iniciativa para realizar el muestreo (por ejemplo cada cierto intervalo de tiempo) o que se realice la
lectura del estado sólo cuando se produzca un cambio, del que el integrado avisa al microcontrolador
con la interrupción.
En el siguiente código se muestra un ejemplo de cómo usar la salida del PCF8574. El funcionamiento
consiste, básicamente, en enviar el código que representa el nivel de las patillas a la dirección I2C
del integrado. Para hacer esta operación con la librería Wire de Arduino hay que activar las
comunicaciones con Wire.begin() (que no será necesario invocar más que una vez), acceder a la
dirección del PCF8574 o del PCF8574A con Wire.beginTransmission(), enviar el valor con
Wire.write() y liberar el bus I2C con Wire.endTransmission().

#define ESPERA_ENTRE_CAMBIOS 1000


#define DIRECCION_PCF8574 32 // 0B0100000
#define DIRECCION_PCF8574A 64 // 0B01000000
#include <Wire.h>
long cronometro_cambio=0;
long tiempo_transcurrido;
byte codigo=0;
void setup()
{
Wire.begin();
}
void loop()
{
tiempo_transcurrido=millis()-cronometro_cambio;
if(tiempo_transcurrido>ESPERA_ENTRE_CAMBIOS)
{
cronometro_cambio=millis();
Wire.beginTransmission(DIRECCION_PCF8574);
Wire.write(codigo++);
Wire.endTransmission();
}
}
El ejemplo de abajo es el caso más sencillo de lectura del PCF8574, simplemente se consulta el
estado cada cierto intervalo de tiempo y se envía a la consola serie (como ejemplo de uso). Las
principales diferencias con el código del ejemplo anterior consisten en que se solicitan los datos con
Wire.requestFrom() y se cargan del bus con Wire.read().

#define ESPERA_ENTRE_CAMBIOS 1000


#define DIRECCION_PCF8574 32 // 0B0100000
#define DIRECCION_PCF8574A 64 // 0B01000000
#include <Wire.h>
long cronometro_cambio=0;
long tiempo_transcurrido;
byte lectura=0;
void setup()
{
Serial.begin(9600);
Wire.begin();
}
void loop()
{
tiempo_transcurrido=millis()-cronometro_cambio;
if(tiempo_transcurrido>ESPERA_ENTRE_CAMBIOS)
{
cronometro_cambio=millis();
Wire.requestFrom(DIRECCION_PCF8574,1); // Pedir a la dirección DIRECCION_PCF8574 1 byte
lectura=Wire.read();
Serial.println(lectura);
}
}
La parte menos ortodoxa del código anterior consiste en leer el bus I2C sin saber si se habrán
recibido ya los datos o no. Para hacerlo de forma más correcta se puede usar Wire.available() para
saber cuántos bytes de datos se han recibido en la última consulta.
El formato más básico, que suele ser suficiente, consiste en consultar los datos recibidos y operar
con ellos desde una estructura if() para evitar leerlos si no están disponibles.
#define ESPERA_ENTRE_CAMBIOS 1000
#define DIRECCION_PCF8574 32 // 0B0100000
#define DIRECCION_PCF8574A 64 // 0B01000000
#include <Wire.h>
long cronometro_cambio=0;
long tiempo_transcurrido;
byte lectura=0;
void setup()
{
Serial.begin(9600);
Wire.begin();
}
void loop()
{
tiempo_transcurrido=millis()-cronometro_cambio;
if(tiempo_transcurrido>ESPERA_ENTRE_CAMBIOS)
{
cronometro_cambio=millis();
Wire.requestFrom(DIRECCION_PCF8574,1);
if(Wire.available())
{
lectura=Wire.read();
Serial.println(lectura);
}
}
}
Aunque, en principio, el método anterior funciona, ya que el tiempo que tarda en ejecutarse la
consulta es suficiente para que los datos hayan podido transmitirse, lo más correcto sería esperar
hasta que lleguen los datos solicitados o hasta que pase un intervalo de tiempo prefijado (timeout)
después del cual se podría suponer que se ha producido algún tipo de error y no llegarán esos datos.
#define ESPERA_ENTRE_CAMBIOS 1000
#define DIRECCION_PCF8574 32 // 0B0100000
#define DIRECCION_PCF8574A 64 // 0B01000000
#define TIMEOUT_I2C 10 // 10 milisegundos de espera antes de renunciar a leer el bus I2C
#include <Wire.h>
long cronometro_timeout_i2c;
long cronometro_cambio=0;
long tiempo_transcurrido;
byte lectura=0;
void setup()
{
Serial.begin(9600);
Wire.begin();
}
void loop()
{
tiempo_transcurrido=millis()-cronometro_cambio;
if(tiempo_transcurrido>ESPERA_ENTRE_CAMBIOS)
{
cronometro_cambio=millis();
Wire.requestFrom(DIRECCION_PCF8574,1);
cronometro_timeout_i2c=millis();
do
{
tiempo_transcurrido=millis()-cronometro_timeout_i2c;
}
while(!Wire.available()&&tiempo_transcurrido<TIMEOUT_I2C);
if(Wire.available())
{
lectura=Wire.read();
Serial.println(lectura);
}
}
}
Muestrear el estado del puerto del PCF8574 cada cierto periodo de tiempo o cuando lo determinen
ciertas condiciones del estado del sistema (por ejemplo, la lectura de otras entradas) es
perfectamente funcional, pero en algunas situaciones hay que responder a determinada lectura,
cuando lleguen nuevos datos, lo antes posible, no cuando el intervalo de muestreo lo determine.
Para esos casos lo más eficaz es utilizar una interrupción hardware, que en el PCF8574 se activa
con cada cambio en el estado del puerto, es decir, con cada nueva lectura.
Las diferentes placas Arduino tienen asignaciones de patillas asociadas a interrupciones por
hardware un poco diferentes.

• Los basados en el ATmega 328, como Arduino Uno, Arduino Nano o Arduino Mini usan las patillas
2 y 3.
• Arduino Mega, Arduino Mega 2560 y Arduino Mega ADK es capaz de detectar interrupciones
hardware en las patillas 2, 3, 18, 19, 20 y 21.
• Los basados en el ATmega 32U4 como Arduino Micro o Arduino Leonardo detectan interrupciones
en las patillas 0, 1, 2, 3, 7.
• Arduino Due puede usar todas las patillas para las interrupciones hardware.
• Arduino Zero (Genuino Zero fuera de USA) puede atender interrupciones hardware en todas las
patillas excepto en la número 4.
• Arduino MKR1000 (Genuino MKR1000 fuera de USA) utiliza para las interrupciones hardware las
patillas 0, 1, 4, 5, 6, 7, 8, 9, A1 y A2.
Para asignar las interrupciones se usa attachInterrupt() y para desactivarlas detachInterrupt(). La
asignación de la interrupción necesita que se indique:
• el número de interrupción, que se puede obtener con digitalPinToInterrupt() indicándole el número
del pin (en lugar del número de interrupción, que podría dar lugar a confusión por el modelo de placa),
• la función que se invoca cuando se genera la interrupción y
• el estado que se detecta, que puede ser LOW, CHANGE, RISING o FALLING según se considere
el nivel bajo, un cambio en el pin de la interrupción, el flanco de ascenso o el flanco de descenso,
respectivamente.
Conforme a lo anterior, el código de lectura del PCF8574 que lee su estado solamente cuando se
genera una interrupción podría quedar como el del siguiente ejemplo:
#define PIN_INTERRUPCION 7
#define DIRECCION_PCF8574 32 // 0B0100000
#define DIRECCION_PCF8574A 64 // 0B01000000
#define TIMEOUT_I2C 10 // 10 milisegundos de espera antes de renunciar a leer el bus I2C
#include <Wire.h>
byte lectura=0;
boolean lectura_pendiente=true;
long cronometro_timeout_i2c;
long tiempo_transcurrido;
void setup()
{
Serial.begin(9600);
Wire.begin();
pinMode(PIN_INTERRUPCION,INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPCION),recibir_PCF8574,FALLING);
}
void loop()
{
if(lectura_pendiente)
{
Wire.requestFrom(DIRECCION_PCF8574,1);
cronometro_timeout_i2c=millis();
do
{
tiempo_transcurrido=millis()-cronometro_timeout_i2c;
}
while(!Wire.available()&&tiempo_transcurrido<TIMEOUT_I2C);
if(Wire.available())
{
lectura=Wire.read();
Serial.println(lectura);
}
lectura_pendiente=false;
}
}
void recibir_PCF8574()
{
detachInterrupt(digitalPinToInterrupt(PIN_INTERRUPCION));
lectura_pendiente=true;
attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPCION),recibir_PCF8574,FALLING);
}
En el ejemplo anterior se usa la variable global lectura_pendiente como un indicador de que se ha
producido un cambio en el puerto. La función que gestiona la interrupción se encarga del mínimo
proceso necesario y el código de lectura queda dentro del bucle de forma análoga a los anteriores
ejemplos.
Al utilizar interrupciones, en lugar de muestrear «manualmente» el estado del puerto, será muy
importante atender a las condiciones en las que se lanza la interrupción, para evitar efectos como
los rebotes en contactos. La solución puede ser hardware (con un condensador o con una puerta
lógica) o software, modificando el código para no actuar si el periodo entre cambios de estado del
puerto no se produce en determinado intervalo.

Como crear una librería para arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 19 Diciembre 2017
Visto: 1821
Voto 5 Votar
Por favor, vote

Este documento explica cómo crear una librería para Arduino. Se comienza con un programa que
realiza, mediante encendido y apagado de un led, el código morse y se explica cómo convertir este
en una función de librería. Esto permite a otras personas utilizar fácilmente el código que has escrito
cargándolo de
una forma sencilla.
Se comienza con el programa de un sencillo código Morse: La palabra a generar es SOS (. . . - - - .
. . ).

// Genera SOS en código Morse luminoso

int pin = 13;

void setup()

pinMode(pin, OUTPUT);

void loop() //Programa principal que genera '. . .', '- - -' y '. . .'

dot(); dot(); dot(); //Genera la S (. . .)

dash(); dash(); dash(); // Genera la O (- - -)

dot(); dot(); dot(); // Genera la S (. . .)

delay(3000); //Espera un tiempo

void dot() //Procedimiento para generar un punto


{

digitalWrite(pin, HIGH);

delay(250);

digitalWrite(pin, LOW);

delay(250);

void dash() //Procedimiento para generar una raya

digitalWrite(pin, HIGH);

delay(1000);

digitalWrite(pin, LOW);

delay(250);

Si se ejecuta este programa, se ejecuta el código SOS (llamada de solicitud de auxilio) en el pin 13.
El programa tiene distintas partes que tendremos que poner en nuestra librería. En primer lugar, por
supuesto, tenemos las funciones dot() (punto) y dash() (raya) que se encargar de que el led
parpadee de manera corta o larga respectivamente. En segundo lugar, tenemos la línea ledPin que
utilizamos para determinar el pin a utilizar. Por último, está la llamada a la función pinMode() que
inicializa el pin como salida.
Vamos a empezar a convertir el programa en una librería.
Necesitas por lo menos dos archivos en una librería: un archivo de cabecera (con la extensión ".h")
y el archivo fuente (con la extensión ".cpp"). El fichero de cabecera tiene definiciones para la librería:
básicamente una lista de todo lo que contiene, mientras que el archivo fuente tiene el código real.
Vamos a llamar a nuestra biblioteca "Morse", por lo que nuestro fichero de cabecera se Morse.h.
Echemos un vistazo a lo que sucede en ella. Puede parecer un poco extraño al principio, pero lo
entenderá una vez que vea el archivo de origen que va con ella.
El núcleo del archivo de cabecera consiste en una línea para cada función en la biblioteca, envuelto
en una clase junto con las variables que usted necesita:

class Morse

public: Morse(int pin);

void dot();

void dash();

private:

int _pin;
};

Una clase es simplemente una colección de funciones y variables que se mantienen unidos todos
en un solo lugar. Estas funciones y variables pueden ser públicos, lo que significa que puede ser
utilizadas por quienes utilizan la librería, o privadas, lo que significa que sólo se puede acceder desde
dentro de la propia clase. Cada clase tiene una función especial conocida como un constructor, que
se utiliza para crear una instancia de la clase. El constructor tiene el mismo nombre que la clase, y
no devuelve nada.
Usted necesita dos cosas más en el fichero de cabecera. Uno de ellos es un #include, declaración
que le da acceso a los tipos estándar y las constantes del lenguaje de Arduino (esto se añade
automáticamente en todos los programas que hacemos con Arduino, pero no a las librerías), por lo
que debemos incluirlas (poniéndolas por encima de la definición de clase dada anteriormente):

#include "WConstants.h"

Por último, se colocara delante del código la cabecera siguiente:

#ifndef Morse_h

#define Morse_h

// el estamento #include y el resto del código va aquí..

#endif

Básicamente, esto evita problemas si alguien accidentalmente pone #include en la librería dos veces.
Por último, por lo general, se pone un comentario en la parte superior de la librería con su nombre,
una breve descripción de lo que hace, quien la escribió, la fecha y la licencia.
Echemos un vistazo a la cabecera completa disposición del fichero de cabecera h:
Fichero Morse.h

/*

Morse.h - Library for flashing Morse code.

Created by David A. Mellis, November 2, 2007. Released into the public domain.

*/

#ifndef Morse_h

#define Morse_h

#include "WConstants.h"

class Morse

public: Morse(int pin); void dot();

void dash();
private:

int _pin;

};

#endif

Ahora vamos a escribir las diversas partes del archivo fuente de la librería, Morse.cpp.
Primero se ponen un par de declaraciones mediante #include. Estas incluyen resto del código de
acceso a las funciones estándar de Arduino, ya que en las definiciones figuran en el archivo de
cabecera:

#include "WProgram.h"

#include "Morse.h"

Luego viene el constructor. Ahora se indicará lo que debería suceder cuando alguien crea una
instancia a la clase. En este caso, el usuario especifica el pin que les gustaría utilizar. Configuramos
el pin como salida guardarlo en una variable privada para su uso en las otras funciones:

Morse::Morse(int pin)

pinMode(pin, OUTPUT);

_pin = pin;

Hay un par de cosas extrañas en este código. El primero es el Morse:: antes del nombre de la
función. Esto indica que la función es parte de la clase Morse. Verá este de nuevo en las otras
funciones en la clase. La segunda cosa inusual es el guión bajo en el nombre de nuestra variable
privada, _pin. Esta variable puede tener cualquier nombre que desee, siempre y cuando coincida
con la definición que figura en el fichero de cabecera. La adición de un guión bajo al comienzo del
nombre es una convención para dejar claro que las variables son privadas, y también a distinguir el
nombre de la del argumento a la función (pin en este caso).
Después viene el código del programa que queremos convertir en una función (¡por fin!). Parece casi
igual, excepto con Morse:: delante de los nombres de las funciones, y _pin en lugar de pin:

void Morse::dot()

digitalWrite(_pin, HIGH); delay(250);

digitalWrite(_pin, LOW); delay(250);

}
void Morse::dash()

digitalWrite(_pin, HIGH); delay(1000);

digitalWrite(_pin, LOW); delay(250);

Por último, es típico incluir el comentario de cabecera en la parte superior de la fuente así como el
archivo. Vamos a ver el fichero completo:

Fichero Morse.cpp

/*

Morse.cpp - Library for flashing Morse code. Created by David A. Mellis, November 2, 2007
. Released into the public domain.

*/

#include "WProgram.h"

#include "Morse.h"

Morse::Morse(int pin)

pinMode(pin, OUTPUT);

_pin = pin;

void Morse::dot()

digitalWrite(_pin, HIGH); delay(250);

digitalWrite(_pin, LOW); delay(250);

void Morse::dash()

digitalWrite(_pin, HIGH); delay(1000);


digitalWrite(_pin, LOW); delay(250);

Y eso es todo lo que necesita (hay algunas otras cosas opcionales, pero vamos a hablar de eso más
adelante).
Ahora vamos a ver cómo se utiliza la librería.
En primer lugar, debemos crear una carpeta llamada Morse dentro del subdirectorio libraries de la
aplicación Arduino. Copiar o mover los archivos Morse.h y Morse.cpp en esa carpeta. Ahora lanzar
la aplicación Arduino. Si abres el menú Sketch> Import Library, deberás ver el objeto Morse. Si
realiazs alguna modificación en la libería, deberás reiniciar el entorno de Arduino para así
recompilarla. Si aparece algún fallo relacionado con la compilación de la biblioteca, asegúrese de
que están realmente los archivos .cpp y .h (sin extensión adicional .pde o .txt, por ejemplo).
Veamos como podemos escribir nuestro nuevo programa SOS haciendo uso de la nueva librería:

Programa para Arduino

#include <Morse.h>

Morse morse(13);

void setup() {}

void loop()

morse.dot(); morse.dot(); morse.dot();

morse.dash(); morse.dash(); morse.dash();

morse.dot(); morse.dot(); morse.dot();

delay(3000);

Hay algunas diferencias con respecto al antiguo programa (además del hecho de que algunos de los
códigos se han incorporado a la librería).
En primer lugar, hemos añadido un estamento #include en la parte superior del programa. Esto hace
que la librería Morse quede a disposición del programa y la incluye en el código. Esto significa que
ya no necesitan una librería en el programa, usted debe borrar el # include para ahorrar espacio.
En segundo lugar, nosotros ahora podemos crear una instancia de la clase Morse llamado morse:

Morse morse(13);
Cuando esta línea se ejecuta (que en realidad sucede antes incluso de setup()), el constructor de la
clase Morse será invocado y le pasara el argumento que se ha dado aquí (en este caso, sólo 13).
Tenga en cuenta que nuestra parte setup() del programa está vacía, porque la llamada
a pinMode() se lleva a cabo en el interior de la librería (cuando la instancia se construye).
Por último, para llamar a las funciones punto dot() y raya dash(), es necesario colocar el
prefijo morse. – delante de la instancia que queremos usar. Podríamos tener varias instancias de la
clase Morse, cada uno en su propio pin almacenados en la variable privada _pin de esa instancia.
Al llamar una función en un caso particular, especificaremos qué variables del ejemplo debe utilizarse
durante esa llamada a una función. Es decir, si hemos escrito:

Morse morse(13);

Morse morse2(12);

entonces dentro de una llamada a morse2.dot(), _pin sería 12.


Si ha escrito el nuevo programa, probablemente se habrá dado cuenta de que ninguna de nuestras
funciones de la librería fue reconocida por el entorno de Arduino destacando su color. Por desgracia,
el software de Arduino no puede averiguar automáticamente lo que se ha definido en su librería (a
pesar de que sería una característica interesante), por lo que tiene que darle un poco de ayuda. Para
hacer esto, cree un archivo llamado keywords.txt en el directorio Morse. Debe tener este aspecto:

Morse KEYWORD1

dash KEYWORD2

dot KEYWORD2

Cada línea tiene el nombre de la palabra clave, seguida de un tabulador (sin espacios), seguido por
el tipo de palabra clave. Las clases deben ser KEYWORD1 y son de color naranja; las funciones
deben ser KEYWORD2 y serán de color marrón. Tendrás que reiniciar el entorno Arduino para
conseguir reconocer las nuevas palabras clave.
Es interesante que quienes utilicen la libreia Morse tengan algun ejemplo guardado y que aparezca
en el IDE de Arduino cuando seleccionamos dentro de la carpeta ejemplos (Sketch). Para hacer
esto, se crea una carpeta de ejemplos dentro de la carpeta que contiene la librería Morse. A
continuación, movemos o copiamos el directorio que contiene el programa (lo llamaremos SOS) que
hemos escrito anteriormente en el directorio de ejemplos. (Usted puede encontrar el ejemplo
mediante el menú Sketch>Show Sketch Folder). Si reiniciamos el entorno de Arduino veremos un
elemento Library_Morse dentro del menú File > Sketchbook > Examples que contiene su ejemplo.
Es posible que desee añadir algunos comentarios que explicar mejor cómo utilizar la biblioteca.

Librería HX711, Balanza digital con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 05 Octubre 2017
Visto: 2055

Voto 5 Votar
Por favor, vote
 Librería HX711, Balanza digital con Arduino
En este tutorial trabajaremos con la trasmisor de celda de carga HX711, he indicaremos todos los
pasos en su conexión y programación para armar una balanza digital o cualquier uso que lo podamos
dar

Celdas De Carga
Una celda de carga es un transductor capaz de
convertir una fuerza en una señal eléctrica, esto la hace a través uno o más galgas internas que
posee, configuradas en un puente Wheatstone.
Existen diversos tipos de Celdas de carga, en diversos modelos, el que utilizaremos para este tutorial
es el que se muestra en la imagen. Usaremos una celda de carga de 5Kg que es el valor máximo
que puede pensar, pero el tutorial también aplica a celda de carga de 20 Kg y otros modelos.

Trasmisor de celda de carga HX711


Este módulo es una interface entre las celdas de carga y el microcontrolador, permitiendo poder leer
el peso de manera sencilla. Internamente se encarga de la lectura del puente wheatstone formado
por la celda de carga, convirtiendo la lectura analógica a digital con su conversor A/D interno de 24
bits.
Es muy utilizado en procesos industriales, sistemas de medición automatizada e industria médica.
Se comunica con el microcontrolador mediante 2 pines (Clock y Data) de forma serial.
Armando la parte mecánica de nuestra Balanza Digital
Para instalar la celda de carga hay que hacerlo con separadores, los cuales deben de distanciar a la
base y recipiente de la celda para que la parte central quede libre; además hay que tener en cuenta
que el sentido de la flecha indica la dirección de la fuerza o peso a aplicar
La siguiente figura muestra un ejemplo de cómo instalar la celda de carga, pero dependerá de su
aplicación para hacer las variaciones necesarias

Conexiones entre la Celda de carga, módulo HX711 y Arduino.

Conexión entre la Celda de carga y módulo HX711

Celda De Carga Módulo HX711

Cable Rojo Pin E+

Cable Negro Pin E-

Cable Verde Pin A-

Cable Blanco Pin A+

Conexión entre HX711 y Arduino

Módulo HX711 Arduino UNO, MEGA, NANO

Pin GND Pin GND

Pin DT Pin A1
Módulo HX711 Arduino UNO, MEGA, NANO

Pin SCK Pin A0

Pin VCC Pin 5V

La conexión final sería como se muestra en la imagen.

Librería HX711 para Arduino

Estamos utilizando la librería HX711 de Bogde el cual lo pueden descargar desde Github:
- https://github.com/bogde/HX711
Una vez descargado hay que importarla a nuestro IDE de Arduino.

Explicaremos las funciones principales de esta librería.

HX711(byte PinData, byte PinClock)


Es el constructor del objeto HX711, se puede trabajar con cualquiera de los pines.
void tare(byte n);
Establece el peso actual como el peso de tara, n indica el número de lecturas que se realizan para
obtener la tara, por defecto n=10;
void set_scale(float scale);
Establece el valor de la escala, que es el factor de conversión para convertir valor de lectura en un
valor con unidades de peso. Por defecto es scale=1;
long read()
Espera hasta que el dispositivo esté listo y devuelve la lectura del ADC del HX711
long read_average(byte n)
Realiza n veces la lectura del ADC y devuelve el promedio
double get_value(byte n)
Devuelve el valor actual restando el peso de tara. Equivalente a (read_average() - OFFSET) . Si se
especifica un valor de n, devuelve el promedio de n lecturas.
float get_units(byte n)
Devuelve el valor actual restado del peso de tara y dividido por la escala. Es equivalente a
(get_value()/SCALE). Si se especifica un valor de n, devuelve el promedio de n lecturas.

1. Calibrando nuestra Balanza


Lo primero que se debe de hacer es calibrar, que es básicamente hallar el valor de la escala que se
usará; es decir hallar el factor de conversión para convertir valor de lectura en un valor con unidades
de peso. La escala es diferente para cada celda y cambia de acuerdo a la forma de instalar, al peso
máximo o modelo de celda de carga, incluso así se trate del mismo modelo de celdas no
necesariamente tienen el mismo valor de escala.
Primero necesitamos conseguir un objeto con peso conocido, en otras palabras debemos saber el
peso real del objeto. Se recomienda que el peso conocido sea cercano al valor máximo del rango de
trabajo de la celda de carga. En nuestro caso usaremos un peso de 4Kg pues nuestra celda es de
5Kg.

El siguiente paso es cargar el siguiente Sketch a nuestro Arduino.

#include "HX711.h"

#define DOUT A1

#define CLK A0

HX711 balanza(DOUT, CLK);

void setup() {

Serial.begin(9600);

Serial.print("Lectura del valor del ADC: ");

Serial.println(balanza.read());

Serial.println("No ponga ningun objeto sobre la balanza");

Serial.println("Destarando...");

balanza.set_scale(); //La escala por defecto es 1

balanza.tare(20); //El peso actual es considerado Tara.

Serial.println("Coloque un peso conocido:");


}

void loop() {

Serial.print("Valor de lectura: ");

Serial.println(balanza.get_value(10),0);

delay(100);

El programa debe correr sin el peso colocado, pues al inicio de programa calcula la tara.
Después de abrir el monitor serial y esperar para que reste la tara, Se pone el objeto de 4Kg o el
peso con el que estén trabajando.

Después de poner el peso en la balanza, en el monitor serial se mostraran las lecturas del peso, son
lecturas sin escalar, por lo que les deben aparecer números grandes.

Con uno o el promedio de estos datos calculamos el valor de la escala que usaremos, para esto
usaremos la siguiente formula:
El valor del peso debe estar en las unidades con las que queremos que trabaje nuestra balanza, por
ejemplo podría ser 4Kg o 4000g para Kilogramo o gramos respectivamente.
Entonces el valor de la Escala que usaremos es:

Con este dato ya obtenido pasamos a programar el sketch que vamos a utilizar para pesar.

2. Programa final para nuestra Balanza


El programa que se utilizara es similar al programa que usamos para calibrar, con la diferencia que
ya conocemos la escala.

#define DOUT A1

#define CLK A0

HX711 balanza(DOUT, CLK);

void setup() {

Serial.begin(9600);

Serial.print("Lectura del valor del ADC: ");

Serial.println(balanza.read());

Serial.println("No ponga ningun objeto sobre la balanza");

Serial.println("Destarando...");

Serial.println("...");

balanza.set_scale(439430.25); // Establecemos la escala

balanza.tare(20); //El peso actual es considerado Tara.

Serial.println("Listo para pesar");

}
void loop() {

Serial.print("Peso: ");

Serial.print(balanza.get_units(20),3);

Serial.println(" kg");

delay(500);

Como se observa en el código, es necesario encender el Arduino antes de colocar los objetos que
se desean pesar, de lo contrario el peso que esté sobre la balanza se considerará como tara.
A continuación se muestran las lecturas agregando sucesivamente pesos de 1Kg aproximadamente.

Como pueden ver el módulo HX711 es fácil de implementar en cualquier proyecto, la aplicaciones
son varias y espero puedan sacarle provecho.

Arduino y memoria SD y micro SD.


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 22 Junio 2017
Visto: 1299

Voto 5 Votar
Por favor, vote

Desarrollaremos ejemplos para trabajar con tarjetas SD o Micro SD, veremos las conexiones y
características de estos dispositivos.
Las memorias SD son las más usadas por dispositivos portátiles, por su gran capacidad y su reducido
tamaño, debido a su gran demanda son fáciles de conseguir en diferentes capacidades y precios.
Estas características nos dan una buena alternativa de almacenamiento para usarlo en Arduino,
sobretodo cuando necesitamos guarda gran cantidad de información.
Estas memorias vienen en tres tamaños, SD estándar, Mini SD y Micro SD, siendo este
último el tamaño más común, funcionalmente son iguales, pudiéndose usar adaptadores para
utilizarlos en sockets de diferente tamaño.

Con respecto al formato podemos encontrar 4 tipos, las tarjetas SD o SDSC (Standard Capacity),
SDHC (High Capacity), SDXC (Extended Capacity) y las SDIO (Input/Output), permitiéndonos
Arduino trabajar con los dos primeros tipos.
La comunicación de la memoria es por SPI pero trabajan con 3.3V, para utilizarlo con Arduino
necesitamos módulos externos que aparte de tener el socket traen los componentes necesarios para
adaptar los voltajes a TTL y poder conectarlo de forma fácil a nuestro Arduino.
Para este tutorial podemos usar cualquiera de estos dos módulos:
Modulo Micro SD: nos permite insertar una memoria Micro SD que son las más comunes en el
mercado, el modulo se puede alimentar con 3.3V o 5V usando los pines respectivos.

Módulo SD card: Este módulo trae el socket grande para las memorias SD de tamaño estándar,
pero usando un adaptador podemos usar también memorias micro SD
Arduino tiene una librería para usar estas memorias, que funciona con cualquiera de los módulos
antes mencionados. La librería ya viene junto con el IDE de arduinos, por lo que no necesitamos
instalar ni descargar nada.

Para poder usar la librería en nuestro Sketch es necesario incluir a la librería SD al inicio del código:

#include <SD.h>

A continuación explicamos las funciones principales de la librería SD, el cual es un resumen de la


referencia proporcionada en la página oficial de Arduino: https://www.arduino.cc/en/Reference/SD
SD.begin(cspin)
Inicializa la biblioteca SD y la tarjeta, como parámetro se le indica el pin CS al que está conectado el
modulo, si no se especifica cspin , se usa el valor por defecto del CS por hardware. Los demás pines
deben estar conectados al SPI por hardware del Arduino.
SD.exists(filename)
Comprueba si existe el archivo especificado, filename es el nombre del archivo y/o directorio en la
tarjeta SD si este existe la función nos retorna un true, de lo contrario retorna false.
SD.mkdir(directory)
Crea el directorio especificado, si los subdirectorios no existen, también se crearan. Por ejemplo:
SD.mkdir(“Arduino/proyecto1/archivos), crea la carpeta “archivos” y si las carpetas Arduino y
proyecto1 no existen, entonces también se crearan. La función retorna true si la creación del
directorio fue exitosa de lo contrario nos retorna un false
SD.remove(filename)
Elimina el archivo (filename) de la tarjeta SD, se debe de incluir el directorio. Solo elimina el archivo
más no el directorio. Devuelve true se logra eliminar el archivo de lo contrario nos retorna un false.
SD.rmdir(dirname)
Eliminar el directorio (dirname) de la tarjeta SD. El directorio debe estar vacío. Devuelve TRUE si la
eliminación del directorio tuvo éxito o FALSE en caso contrario.
SD.open(filepath, mode)
Abre el archivo especificado y se debe de incluir el directorio si el archivo está en carpetas. Si el
archivo no existe, se creara un archivo con el nombre especificado, pero no será posible crear el
directorio si este no existe. Se puede abrir un archivo como solo lectura (si mode es FILE_READ) o
como lectura y escritura (si mode es FILE_WRITE), el modo por defecto en caso no se especifique
es FILE_READ
Ésta función nos retorna un objeto tipo FILE, el cual es necesario declararlo antes como una variable.
Por ejemplo:

File myFile;

myFile = SD.open("archivo.txt", FILE_WRITE);

Funciones de la clase File:


file.available()
Compruebe si hay bytes disponibles para leer en el archivo y retorna el número de bytes disponibles
file.read()
Lee un byte de la variable File (archivo abierto anteriormente con SD.open())
file.write(data)
Escribe un byte en el archivo, el archivo debe estar abierto en modo lectura y escritura. Usando
file.write(buf, len) se puede escribir un array de byte (buf) pero se debe especificar el tamaño (len).
file.print(data)
Esta función tiene las mismas características que un Serial.print(); data puede ser una variable o
texto, el cual será enviado como caracteres. Si queremos agregar al final un salto o nueva línea se
usa file.println(data)
file.size()
Retorna el tamaño en bytes del archivo
file.position()
Retorna la posición actual en donde se leerá o escribirá el siguiente byte.
file.seek(pos)
Nos ubicamos en una posición específica en el archivo. Pos debe ser un número entre 0 y el tamaño
en bytes del archivo
file.close()
Cerramos el archivo, y recién en este momento los datos se guardan en la SD, pudiendo extraer de
forma segura nuestra SD.
Explicado la librería empecemos viendo como conectar los módulos con nuestro Arduino:

Conexión entre Arduino y modulo SD y micro SD

Las conexiones para el modulo SD son las siguientes;


Módulo SD Arduino Uno, Nano Arduino Mega

GND GND GND

+3.3V No conectado No conectado

+5V 5V 5V

CS 4 4

MOSI 11 51

SCK 13 52

MISO 12 50

GND GND GND

*Se puede alimentar con 5V o 3,3V usando los pines correspondientes, pero no se debe de alimentar
por ambos pines a la vez

Y las conexiones si se trabajan con el módulo micro SD son:


Módulo SD Arduino Uno, Nano Arduino Mega

CS 4 4

SCK 13 52

MOSI 11 51

MISO 12 50

VCC 5V 5V

GND GND GND

3.3V No conectado No conectado

*Se puede alimentar con 3,3V en lugar de 5V usando el pin correspondientes, pero no se debe de
alimentar por ambos pines a la vez

Ej1. Leer un archivo de la SD con nuestro Arduino


En este ejemplo vamos a leer un archivo de texto desde la SD.
Para esto insertamos nuestra SD a la PC, abrimos y creamos un archivo de hoja de texto, por ejemplo
archivo.txt, e ingresamos el texto que posteriormente vamos a leer desde Arduino:
Seguidamente extraemos la SD de la PC, lo insertamos en el módulo SD. Y cargamos el siguiente
sketch en nuestro Arduino:

#include <SD.h>

File myFile;

void setup()

Serial.begin(9600);

Serial.print("Iniciando SD ...");

if (!SD.begin(4)) {

Serial.println("No se pudo inicializar");

return;

Serial.println("inicializacion exitosa");

myFile = SD.open("archivo.txt");//abrimos el archivo

if (myFile) {

Serial.println("archivo.txt:");

while (myFile.available()) {

Serial.write(myFile.read());

myFile.close(); //cerramos el archivo


} else {

Serial.println("Error al abrir el archivo");

void loop()

EL programa envía por el puerto serie todo el contenido del archivo guardado en la SD.

Ej2. Leer datos desde la SD, Manipulando leds desde la SD


En este caso no solo vamos a leer el archivo desde la SD sino vamos a interpretar y realizar ciertas
acciones con los datos.
En un archivo de texto vamos a guardar datos para encender y apagar leds y con esto ejecutar
diferentes secuencias que estarán guardadas en la SD.
Conectamos ocho leds en los pines del 2 al 10, excluyendo el 4, con su resistencia respectiva.
Desde la PC en la SD en una hoja de texto guardamos las secuencias que deseemos realizar.
El primer número de cada línea corresponde a la pausa o tiempo que va a estar presente la
secuencia, los siguientes ocho números corresponde a la secuencia o estado de cada uno de los
ocho leds, ustedes pueden escribir cualquier secuencia o tambien pueden descargar el archivo de
texto que usamos para este ejemplo: Leds.txt
Después de escribir nuestras secuencias de los leds en la hoja de texto guardamos con nombre
Leds.txt e insertamos la SD en el módulo de nuestro Arduino
El Sketch es el siguiente.

#include <SD.h>

File myFile;

int UltimaPocicion=0;

int pausa=1000;

int PinLeds[8]={2,3,5,6,7,8,9,10};//Pines de los Leds

void setup()

Serial.begin(9600);
Serial.print("Iniciando SD ...");

if (!SD.begin(4)) {

Serial.println("No se pudo inicializar");

return;

Serial.println("inicializacion exitosa");

for(int i=0;i<8;i++)

pinMode(PinLeds[i],OUTPUT);

void loop()

myFile = SD.open("Leds.txt");//abrimos el archivo

int totalBytes=myFile.size();

String cadena="";

if (myFile) {

if(UltimaPocicion>=totalBytes) UltimaPocicion=0;

myFile.seek(UltimaPocicion);

//--Leemos una línea de la hoja de texto--------------

while (myFile.available()) {

char caracter=myFile.read();

cadena=cadena+caracter;

UltimaPocicion=myFile.position();

if(caracter==10)//ASCII de nueva de línea

break;
}

//---------------------------------------------------

myFile.close(); //cerramos el archivo

Serial.print("Cadena Leida:");

Serial.print(cadena);

//-----------procesamos la cadena------------

int index=0;

char c=cadena[index++];

pausa=0;

while (c >= '0' && c <= '9')

pausa = 10*pausa + (c - '0');

c = cadena[index++];

Serial.print("pausa=");

Serial.print(pausa);

Serial.print(" LEDS |");

for(int i=0;i<8;i++)

if(cadena[index+i*2]=='1')

digitalWrite(PinLeds[i], HIGH);

Serial.print(" 1 |");

else

digitalWrite(PinLeds[i], LOW);

Serial.print(" 0 |");

}
Serial.println();

Serial.println();

} else {

Serial.println("Error al abrir el archivo");

delay(pausa);

Como se observa Leemos una línea de la SD la procesamos y mostramos la secuencia en los leds
durante el tiempo que también obtenemos desde la SD, es necesario después de cada lectura
guardar la última posición de memoria para que en la segunda lectura continuemos la lectura desde
esa posición, esto porque después de cada lectura cerramos el archivo.
A continuación se muestra la salida del monitor serial, que es un reflejo de lo que se muestra en los
leds:

Ej3. Guardando datos en la SD (Datalogger)


En este ejemplo guardaremos información de variables y sensores en nuestra SD
Para simular los sensores utilizamos 3 potenciómetros que deben estar conectados a los pines A0,
A1 y A2 del Arduino.
El sketch es el siguiente:

#include <SD.h>

File myFile;

void setup()

Serial.begin(9600);

Serial.print("Iniciando SD ...");

if (!SD.begin(4)) {

Serial.println("No se pudo inicializar");

return;

Serial.println("inicializacion exitosa");

void loop()

myFile = SD.open("datalog.txt", FILE_WRITE);//abrimos el archivo

if (myFile) {

Serial.print("Escribiendo SD: ");

int sensor1 = analogRead(0);

int sensor2 = analogRead(1);

int sensor3 = analogRead(2);

myFile.print("Tiempo(ms)=");

myFile.print(millis());

myFile.print(", sensor1=");

myFile.print(sensor1);

myFile.print(", sensor2=");

myFile.print(sensor2);

myFile.print(", sensor3=");
myFile.println(sensor3);

myFile.close(); //cerramos el archivo

Serial.print("Tiempo(ms)=");

Serial.print(millis());

Serial.print(", sensor1=");

Serial.print(sensor1);

Serial.print(", sensor2=");

Serial.print(sensor2);

Serial.print(", sensor3=");

Serial.println(sensor3);

} else {

Serial.println("Error al abrir el archivo");

delay(100);

En el monitor serial muestra los datos que se están escribiendo en la SD:


Y si insertamos la SD en nuestra PC podemos ver el archivo generado:

Ej4. Exportando datos de nuestro datalogger a Excel.


En este caso los datos lo almacenaremos en forma de tabla pero no podremos guardarlos
directamente en un archivo de Excel, sino los guardaremos en formato .csv el cual lo trabajaremos
como si fuera una hoja de texto, las columnas lo separaremos por comas (u otro separador) y las
filas por saltos de línea.
Para Excel también se podría trabajar en un archivo txt, pero en la extensión csv tenemos la
posibilidad de importar no solo a Excel sino a otros programas como Calc de Open Oficce, Gnumeric,
matalb o sistemas web.
Tomaremos el ejemplo anterior con la diferencia que guardaremos los datos en el formato explicado
anteriormente.
El sketch para el Arduino es el siguiente:

#include <SD.h>

File myFile;

void setup()

Serial.begin(9600);

Serial.print("Iniciando SD ...");

if (!SD.begin(4)) {

Serial.println("No se pudo inicializar");

return;

Serial.println("inicializacion exitosa");

if(!SD.exists("datalog.csv"))

myFile = SD.open("datalog.csv", FILE_WRITE);

if (myFile) {

Serial.println("Archivo nuevo, Escribiendo encabezado(fila 1)");

myFile.println("Tiempo(ms),Sensor1,Sensor2,Sensor3");

myFile.close();

} else {

Serial.println("Error creando el archivo datalog.csv");

}
}

void loop()

myFile = SD.open("datalog.csv", FILE_WRITE);//abrimos el archivo

if (myFile) {

Serial.print("Escribiendo SD: ");

int sensor1 = analogRead(0);

int sensor2 = analogRead(1);

int sensor3 = analogRead(2);

myFile.print(millis());

myFile.print(",");

myFile.print(sensor1);

myFile.print(",");

myFile.print(sensor2);

myFile.print(",");

myFile.println(sensor3);

myFile.close(); //cerramos el archivo

Serial.print("Tiempo(ms)=");

Serial.print(millis());

Serial.print(",sensor1=");

Serial.print(sensor1);

Serial.print(",sensor2=");

Serial.print(sensor2);

Serial.print(",sensor3=");

Serial.println(sensor3);
} else {

// if the file didn't open, print an error:

Serial.println("Error al abrir el archivo");

delay(100);

El programa es similar al del ejemplo anterior con la diferencia que al inicio del archivo necesitamos
poner el nombre de los campos o encabezado, esto lo hacemos en setup() si el archivo no existe
,entonces creamos uno y seguidamente escribimos la primera fila, para posteriormente en el void
loop() solo dedicarse a escribir los datos, como el archivo ya ha sido creado, cada vez que se reinicie
o se encienda el Arduino continuara escribiendo desde la última posición, si desean reanudar todo,
deberán manualmente desde la pc eleiminar el archivo o por código en setup() remover el archivo
con SD.remove(filename).
La salida del monitor serial es igual al del ejemplo anterior, pues solo se ha cambiado la forma de
guardar en la SD:

Después de obtener los datos que deseamos, el siguiente paso es ingresar la memoria SD a la PC
ya con los datos guardados por nuestro Arduino.
Al ingresar a la SD deben encontrar el archivo DATALOG.CSV, posteriormente abrimos Excel y en
la barra de menús vamos a Datos y luego a Obtener datos externos - Desde texto.

Seguidamente escogemos el archivo que deseamos importar, en nuestro caso datalog.csv y nos
abrirá el asistente de importación, en el primer paso escogemos archivos delimitados
En el paso 2 en separadores marcamos coma:

En el paso 3 dejamos todas las columnas en general.


Después de dar en finalizar, deberán escoger el lugar en donde se va iniciar la tabla:

Finalmente tenemos los datos ya disponibles en Excel


EL procedimiento para es similar para otras versiones de Excel y otros programas de hojas de
cálculo.

Como conectar Arduino a una red WIFI con el módulo


ESP8266
En nuestra entrada de hoy, conoceremos la tecnología WIFI y haremos una practica en la que
conectamos Arduino a una de estas redes, configuraremos el sistema y enviaremos datos desde
nuestro navegador web a Arduino.
Para hacer esto, hemos elegido el módulo ESP8266, ya que es una de las mejores y más
económicas opciones que nos ofrece el mercado.
En primer lugar, decir que este módulo es muy sencillo de usar y esta diseñado desde el principio
para la corriente tecnológica del Internet de las cosas. Este módulo incluye todo lo necesario para
conectarse a un punto WIFI enviando comandos AT (Comandos de texto) mediante un puerto serie.

Algo sobre la tecnología WIFI.


WI-FI, es una marca comercial de la WIFI-Alliance, esta es la organización encargada de certificar
que los equipos cumplan los standares para usar esta tecnología.
WIFI, es un metodo de conexión de los dispositivos electrónicos de forma inalambrica, con un
alcance de 20m en interiores y algo superior en exteriores.

Conexion del módulo:


-En la siguiente imagen se puede ver una descripción de los pines del módulo.
El pin GND del módulo lo conectamos a GND de Arduino, VCC y RST, lo conectamos al pin de 3,3V
de Arduino. TX lo conectamos al pin 2 de Arduino y RX al pin 3.

Decir que si usamos como fuente de alimentación la que incorpora Arduino de 3,3V tendremos
problemas en el arranque, ya que está fuente nos proporciona una corriente máxima de salida de
50mA y el módulo en su arranque necesita algo más. Aun así para la primera toma de contacto y
hacer algunas pruebas se puede usar los 3,3V de Arduino. Si se dispone de una fuente externa a
Arduino es aconsejable usarla.

Práctica. (Primer programa y comandos AT)


Código
En primer lugar carga el siguiente código en tu Arduino

#include <SoftwareSerial.h>

SoftwareSerial BT1(3, 2); // RX | TX

void setup()

{ Serial.begin(9600);

BT1.begin(9600);

}
void loop()

{ String B= "." ;

if (BT1.available())

{ char c = BT1.read() ;

Serial.print(c);

if (Serial.available())

{ char c = Serial.read();

BT1.print(c);

A continuación abrimos el monitor serial de nuestro arduino y nos aseguramos que esta bien
comfigurado. (Configurar como la imagen)

Si en el monitor serial no aparece nada, desconecta y vuelve a conectar la alimentación, es posible


que el modulo wifi no haya arrancado por el motivo que antes comentábamos.
Como se aprecia en la imagen superior, tiene que aparecer el mensaje “ready” cuando el módulo
haya arrancado. Los símbolos que parecen en las primeras lineas son normales, no hace falta
prestarles mucha atención.

Empezamos con los comandos AT.


El primer comando que usaremos será, AT. Escribimos AT y pulsamos intro.

El módulo os responderá con un OK si recibió correctamente los comandos.


El ESP8266 tiene tres modos de funcionamiento, 1,2y3. La mejor opción según nuestra experiencia
es la 3.
Para cambiarlo usad el comando AT+CWMODE=(número de modo).
Para saber el modo actual usad el comando; AT+CWMODE?, después si no tenéis el modo 3
seleccionado, lo seleccionáis.
El siguiente comando os ayudará a saber que puntos WIFI tenéis a vuestros alrededores.
Este comando es: AT+CWLAP
Aparecen 2, LIBERATEL.ES es la nuestra.
El siguiente paso es conectarse al uno de los puntos WIFI que os apareció antes. Para esto hay que
usar el siguientes comando:
AT+CWLAP= “nombre del punto”, “contraseña”
Al poco tiempo, si todo esta bien, el modulo os responderá con un OK y esto nos indica que esta
conectado correctamente.
Para saber que IP os ha asignado el módulo automáticamente, tecleamos el comando: AT+CIFSR.
A mi en concreto me ha asignado la dirección 192.168.2.100

Ahora se puede empezar con a manejar cosas más interesantes de este módulo, como por ejemplo
montar un pequeño servidor web.
Para activar conecciones simultaneas teclea: AT+CIPMUX=1
y para arrancar un servicio web con el número de servicio 1 y el puerto 80
teclea: AT+CIPSERVER=1,80.

Una vez configurado el módulo para hacer funcionar Arduino como servidor WEB, podéis enviar
datos desde el navegador a Arduino de una forma muy sencilla.
Por ejemplo; escribiendo en el navegador esto...

en el monitor serial aparecerá esto...


¿Qué es un reproductor DFPlayer Mini?
El DFPlayer Mini es un reproductor de audio de bajo coste y pequeño que podemos conectar a un
procesador como Arduino para reproducir audio en formato MP3.
Arduino no tiene potencia potente para reproducir un archivo comprimido como un MP3. Por mucho
que lo intentéis, o incluso si empleáis un procesador más potente, no es función de un autómata
realizar estas tareas. Es mucho mejor delegar en un subprocesador específico.
Existen distintas opciones para
reproducir ficheros MP3 desde Arduino, como diversos shields y placas más o menos caras. Entre
las distintas opciones disponibles los módulos DFPlayer Mini han adquirido una gran popularidad por
su bajo precio y grandes características.
En realidad DFPlayer Mini es un reproductor de audio completo, capaz de reproducir formatos de
fichero MP3, WMA y WAV.
Dispone de un lector micro SD compatible con FAT16 y FAT32, con una capacidad máxima de 32GB.
Soporta hasta 100 carpetas y puede acceder hasta 255 canciones.
El DFPlayer Mini proporciona velocidades de muestreo de 8, 11.025 12 16 22.05 24 32 44.1 y 48
kHz, y salida con DAC de 24 bits. Dispone de 30 niveles de volumen ajustable, ecualizador de 6
niveles, y una relación señal ruido (SNR) de 85dB
EL DFPlayer Mini recibe comandos desde Arduino por puerto serie. Dispone de funciones para
reproducir, detener, pausar, avanzar, retroceder entre canciones. La salida se realiza directamente
al altavoz, a través de los pines correspondientes.
Esquema de conexión
La conexión con el reproductor MP3 DFPlayer Mini es muy sencilla ya que la comunicación con el
módulo se realiza a través del puerto serie.

Simplemente con alimentamos el reproductor MP3 a una fuente de alimentación externa de 5V,
poniendo el Gnd en común con Arduino. Por otro lado, conectamos los pins RX y TX del puerto serie
a Arduino. Por último, conectamos el altavoz al DFPlayer Mini a los pines Spk_1 y Spk_2.
La conexión, vista desde Arduino, sería la siguiente
Ejemplos de código
Para manejar el DFPlayer Mini necesitaremos la librería DFPlayer_Mini_Mp3 disponible en este
enlace.
La librería proporciona ejemplos de código, que resulta aconsejable revisar. Los siguientes ejemplos
son modificaciones a partir de los disponibles en la librería.

1 #include <SoftwareSerial.h>
2 #include <DFPlayer_Mini_Mp3.h>
3
4 SoftwareSerial DFPlayerSerial(10, 11); // RX, TX
5
6 /*
7 mp3_play(); //start play
8 mp3_play(5); //play "mp3/0005.mp3"
9 mp3_pause();
10 mp3_stop();
11 mp3_next();
12 mp3_prev();
13
14 mp3_set_volume(uint16_t volume); //0~30
15 mp3_set_EQ(); //0~5
16 void mp3_single_loop(boolean state); //set single loop
17 void mp3_random_play();
18 */
19
20 void setup()
21 {
22 Serial.begin(9600);
23 DFPlayerSerial.begin(9600);
24 mp3_set_serial(DFPlayerSerial);
25 mp3_set_volume(15);
26 }
27
28 void loop()
29 {
30 mp3_play(1);
31 delay(6000);
32 mp3_next();
33 delay(6000);
34 mp3_prev();
35 delay(6000);
36 mp3_play(4);
37 delay(6000);
38 }

¿Qué es un sensor de color TCS3200?


EL TCS3200 es un sensor óptico que permite detectar el color de un objeto ubicado en frente de él.
Podemos conectarlo este sensor con facilidad a un autómata o procesador como Arduino.
Internamente, el TCS3200 está formado por una matriz de fotodiodos de silicona junto con un
conversor de frecuencia, en un único integrado CMOS.
La matriz dispone de 8 x 8 fotodiodos de 110 µm, de los cuales 16 tienen filtros azules, 16 verdes, 6
rojos, y 16 no tienen filtro. Los fotodiodos están distribuidos de forma que minimizan el efecto la
incidencia no uniforme de la luz.
La salida del TCS3200 es una onda cuadrada del
50% duty, cuya frecuencia es proporcional a la intensidad luminosa. La tensión de alimentación del
sensor es de 2.7V a 5.5V.
Frecuentemente el TCS3200 se distribuye en módulos que incorporan dos o cuatro LED de luz
blanca y un protector de plástico. El objetivo de ambas medidas es minimizar los efectos de la
iluminación ambiente en la medición.
Pese a sus especificaciones y elementos para eliminar la luz ambiente, el TCS3200 no es capaz de
medir de forma precisa el color RGB de un objeto, o la temperatura de color de una fuente luminosa.
Sin embargo, podemos emplearlo para distinguir entre colores básicos. Por ejemplo, podemos
emplearlo para reconocer el color de una tarjeta o un objeto, y guiar a un robot en un recorrido.

Esquema de montaje
El TCS3200 tiene cuatro entradas digitales S0, S1, S2, y S3, y una salida digital Out. Para conectarlo
a Arduino necesitaremos emplear al menos 3 pines digitales.
En primer lugar debemos alimentar el módulo conectando los pines Gnd y Vcc del TCS3200,
respectivamente, a Gnd y Vcc de Arduino.
Los pines S0 y S1 controlan la frecuencia de la salida y la desactivación del módulo. Los conectamos
a dos salidas digitales, o podemos conectarlas a 5V si no queremos poder apagar el módulo.

Power down2%20%100%
s0 L L H H
s1 L H L H

Por otra parte, los pines S2 y S3 seleccionan el color a medir. Deberemos conectarlos a dos salidas
digitales de Arduino.
RedBlueClearGreen
s2 L L H H
s3 L H L H

Finalmente, conectamos la salida del sensor Out a una entrada digital de Arduino por lo que la
conexión empleando los pines, sería la siguiente.

Mientras
que la conexión, vista desde Arduino, sería la siguiente.
Ejemplos de código
En el siguiente ejemplo realizamos la lectura del TCS3200. Para ello empleamos la función PulseIn
para determinar la duración del pulso recibido por el sensor.
Realizamos el proceso para cada color, y empleamos los valores obtenidos para clasificarlo como
rojo, azul o verde.

1 //VCC——5V
2 //GND——GND
3 //S0——D3
4 //S1——D4
5 //S2——D5
6 //S3——D6
7 //OUT——D2
8
9 const int s0 = 8;
10 const int s1 = 9;
11 const int s2 = 12;
12 const int s3 = 11;
13 const int out = 10;
14
15 byte countRed = 0;
16 byte countGreen = 0;
17 byte countBlue = 0;
18
19 void setup() {
20 Serial.begin(9600);
21 pinMode(s0, OUTPUT);
22 pinMode(s1, OUTPUT);
23 pinMode(s2, OUTPUT);
24 pinMode(s3, OUTPUT);
25 pinMode(out, INPUT);
26 digitalWrite(s0, HIGH);
27 digitalWrite(s1, HIGH);
28 }
29
30 void loop() {
31 getColor();
32 Serial.print("Red: ");
33 Serial.print(countRed, DEC);
34 Serial.print("Green: ");
35 Serial.print(countGreen, DEC);
36 Serial.print("Blue: ");
37 Serial.print(countBlue, DEC);
38
39 if (countRed < countBlue && countGreen > 100 && countRed < 80)
40 {
41 Serial.println(" - Red");
42 }
43 else if (countBlue < countRed && countBlue < countGreen)
44 {
45 Serial.println(" - Blue");
46 }
47 else if (countGreen < countRed && countGreen < countBlue)
48 {
49 Serial.println(" - Green");
50 }
51 else {
52 Serial.println("-");
53 }
54 delay(300);
55 }
56
57 void getColor()
58 {
59 digitalWrite(s2, LOW);
60 digitalWrite(s3, LOW);
61 countRed = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
62 digitalWrite(s3, HIGH);
63 countBlue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
64 digitalWrite(s2, HIGH);
65 countGreen = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
66 }
Votar

¿Qué es un sensor de lluvia? Conexión


Este tipo de sensores detectan la presencia de lluvia por la variación de conductividad del
sensor al entrar en contacto con el agua.
Constructivamente son sensores sencillos. Se dispone de dos contactos, unidos a unas pistas
conductoras entrelazadas entre sí a una pequeña distancia, sin existir contacto entre ambas. Al
depositarse agua sobre la superficie, se pone en contacto eléctrico ambos conductores, lo que puede
ser detectado por un sensor.
Los valores analógicos medidos varían desde 0 para una placa totalmente empapada, a 1023

para una placa totalmente seca.


En el caso del sensor de lluvia la señal analógica carece de interés, ya que el sensor no dispone de
la precisión necesaria para medir la cantidad de agua acumulada. En cualquier caso, sería difícil
extrapolar la medición a un valor de litros hora. Es decir, no podemos medir la cantidad de lluvia,
solo su presencia.
El sensor de lluvia puede ser empleado, por ejemplo, para extender un toldo o activar algún otro
mecanismo, hacer sonar una alarma, o registrar la cantidad de tiempo (días, horas) en el que se
producen precipitaciones en una determinada zona.
El sensor de lluvia también puede ser empleado para detectar inundaciones, colocándolo en el suelo
de un sótano o sala de calderas, por ejemplo. También puede ser útil para detectar cuando el agua
de un depósito sobrepasa un determinado nivel.

Conexión
conexionado es de lo más sencillo. Simplemente conectar Tensión y GND y el pin restante es la
señal.
 En este diagrama he pintado unos cables cortos por necesidad, pero cuando montéis este
ejemplo, os recomiendo que pongáis los cables más largos que tengáis, porque la electrónica y
el agua no se llevan bien.
 Tened cuidado de no volcar agua en vuestro Arduino, o morirá en acto de servicio.
 Si insertáis el sensor en agua, para usarlo como medidor de nivel, tened mucho cuidado de no
sumergir los pines de conexión a Arduino, o provocareis un corto.
 No hay suficiente tensión como para provocar un accidente, pero siempre es recomendable
impedir un cortocircuito.

Programa
programa es de lo más simple y sabrá a poco después de las últimas sesiones que hemos tenido.
Vamos a leer la señal del sensor con nuestro A0 y enviaremos la lectura a la consola serie para ver
la medida. Jugando a mojar más o menos el sensor veremos cómo los valores van cambiando a más
cuanto mayor sea la cantidad de agua que detecta.
void setup()
{
Serial.begin(9600);
}

void loop()
{
Serial.println(analogRead(A0));
}
Como se puede ver. Mas fácil imposible.

Arduino y el simulador UnoArduSim. (Tutorial).


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 15 Marzo 2017
Visto: 1149

Voto 5 Votar
Por favor, vote

Un primer contacto para iniciarse en el manejo del programa de simulación de Arduino


UnoArduSim.
Descargar e instalar el programa UnoArduSim en el PC.
Descargar el programa
De la pagina oficial de descargas llamada “Simulator Download” (Descarga del simulador) elijo la
última versión que apare en la parte inferior de la página, que se
denomina UnoArduSimV1.7.2.zip con 1147k firmada por el Prof Simmons de fecha Feb 7,
2017. Al pinchar en la pequeña flecha hacia abajo que esta a la derecha, sorprende la rapidez con
que baja el
fichero zip.

Yo tengo un sistema operativo Windows 10 y el descomprimir este tipo de ficheros es un proceso


casi automático que se realiza en un solo click en una pantalla que te dice por defecto donde te
colocará el fichero en mi caso lo coloco provisionalmente en una carpeta nueva que se crea por
defectos la que se llega por este camino:
C:\Users\Usuario\Downloads\UnoArduSimV1.7.2.zip\UnoArduSimV1.7.2
En el fichero del usuario para descargas, (Downloads), que tiene de forma estándar Windows, se
sitúa el fichero bajado UnoArduSimV1.7.2.zip que al desplegarse, creó la carpeta
llamada UnoArduSimV1.7.2 a la que fueron a parar todos los ficheros descomprimidos que fueron
los siguientes:
Por lógica comenzamos leyendo el fichero READMEV1.7.2, pues tradicionalmente los
fichero REDME han tenido las instrucciones necesarias para instalar la aplicación. En este caso el
fichero dice lo siguiente:

README UnoArduSimV1.7.2
Cuando se ejecuta por primera vez UnoArduSim.exe, verá un conjunto predeterminado de los
dispositivos de E / S (uno de cada uno de los ocho de los “grandes” los dispositivos de E / S, y varios
de cada uno de los “pequeños” los dispositivos de E / S), y un “simple.ino” programa predeterminado
ficticia que puede ejecutar inmediatamente.
Puede utilizar el menú Configurar para ajustar el conjunto de dispositivos de E / S, y desde el diálogo
proporcionado “Guardar” que la configuración para la próxima vez (como un archivo de texto con el
nombre). Ese nombre de archivo se añadirá automáticamente al archivo myArduPrefs.txt que se
carga en el siguiente arranque del programa – para volver a la configuración de inicio
predeterminada, elimine la línea IODevs en el archivo myArduPrefs.txt (o simplemente borrar ese
archivo entero) .
Cuando esté listo, puede cargar y probar el programa de demostración proporcionado
DemoProg1.ino – que el programa tiene que tener un determinado conjunto de dispositivos de E / S
conectados al mismo, a fin de utilizar “Dispositivos Configurar-> IO” y “carga” del
myUnoDevs_DemoProg1.txt archivo. Eso va a cargar los dispositivos (con conexiones de pines pre-
establecido (y los ajustes y valores) que son necesarios por el programa DemoProg1.ino. Ejecutarlo
para ver los dispositivos IO y el programa de acción.
A continuación, puede probar un más complejo (y divertido) DemoProg2.ino programa que tiene la
reproducción musical y dispositivos IO en movimiento a la música (mi reconocimiento al programa
de televisión animada, los Simpson, para que uno). Este segundo programa de demostración
también demuestra que se puede dividir su código (y datos incluidos) entre varios archivos para una
mejor visualización y navegación.
Traductor de Google para empresas:Google Translator ToolkitTraductor de sitios webGlob
Así pues hagamos lo que nos dice, ejecutar por primera vez UnoArduSim.exe, y ver que pasa.
Pinchamos sobre el fichero UnoArduSim.exe y al cabo de un instante aparece la siguiente pantalla.
La pantalla del ordenador aparece dividida en tres secciones, la de la esquina superior izquierda,
destinada a tener el sketch que vamos a probar, a de la esquina inferior izquierda que es la que nos
va a dar el valor de las variables cada vez que se produzca una parada en la ejecución del programa
y la de la derecha que es el simulador de la tarjeta Arduino
Si pinchamos dos veces en cualquier punto de donde aparece el sketch, (secciones la de la esquina
superior izquierda), se abre un editor de textos que nos permite escribir el programa y hacer los
cambios que queramos en el texto como si de un editor corriente y vulgar se tratara.
Por probar, he metido el programa más sencillo que conozco, que no hace más que parpadear el
led que hay en la Tarjeta Arduino asociado al Pin 13. La ventaja de este programa, es que no se
necesita conectar nada a la tarjeta, por lo que podemos probarle en nuestro simulador con las
mínimas complicaciones posibles. Poco a poco iremos complicando la cosa.
El sketch era el siguiente:
void setup() {
// código de configuración, PIN13 como SALIDA, para ejecutar una vez
pinMode(13, OUTPUT);
}
void loop() {
// código principal, encender, esperar, apagar, esperar
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000);
}
Que con un COPY/PASTE vamos a introducir íntegramente en nuestra ventana del editor de textos.
Con lo que la pantalla del editor quedará con un aspecto similar al siguiente:
Y cuando hacenos “Save” (Salvar), clicando en el botón de la derecha, se traspasa a la secciones
del sketch en la esquina superior izquierda, aunque antes, sale una pantalla solicitando la
confirmación de que deseamos el cambio, para evitar errores por despiste. Pero al hacerlo verán,
que debajo del texto introducido,, han aparecido unas lineas de programa que no hemos escrito..
Les amplio esta zona a continuación:
Han aparecido dos lineas de comentario y una función para nosotros desconocida que se llama “int
main()” que dentro de las instrucciones que contiene, llama a la función “setup” y a la
función “loop”.
Esta función se crea automáticamente en el simulador, siempre es igual, y su utilidad es la de ejecutar
una vez la función “setup” y indefinidamente la función “loop” como lo haría realmente la Tarjeta
Arduino, a la vez que controla la emulación gráfica en la sección derecha.
Con saber que la crea el simulador, que se añade automáticamente sin que nosotros hagamos nada,
y que no la tenemos, (ni podemos), tocar, estamos del otro lado. Estas lineas no aparecen en la
ventana del editor de textos, por tanto no hay posibilidad de poder cambiarlas.
Supongamos que comentemos un error de sintaxis en alguna línea de sketch, ¿que pasará?. Por
ejemplo vamos a borrar un punto y como “;” de final de una línea, lo que indica al procesador que la
sentencia se ha acabado, por ejemplo, el punto y coma ”:” situado en la línea donde encendemos
el led (HIGH).
Al traspasar el texto del sketch, automáticamente se pone azul la linea con el error y en el pie de la
pantalla aparece un mensaje, (en inglés), que intenta aclararla razón del error. En nuestro caso
sale PARSE ERROR (ERROR DE ANALISIS), que seamos honestos, mucho no aclara, pero lo que
si aclara bastante es que la línea azul, nos marque en que sentencia está el error.
Corregimos el error y todo vuelve como estaba antes, la linea azul fuera de nuestro texto nos indica
que al menos sintácticamente el programa está bien escrito, es una simulación equivalente a que el
programa se compile cuando probamos en real.
Área de control de variables
Observarán que en este caso, la esquina inferior derecha, donde deberían aparecer las variables,
no aparece nada, porque este programa, excepcionalmente, es tan sencillo que no utiliza ningún
parámetro ni variable, algo rarísimo. En otros ejemplos, veremos que aquí aparecen esas variables,
con los valores como los hayamos inicializado y que van cambiando a medida que el programa
avanza, para resaltarlo se señalara con una raya azul la variable que haya cambiado de valor con la
ejecución de la línea.
Por otra parte observarán que el pin 13 se encuentra en color azul, en vez de gris, lo que indica que
ese pin ha sido activado como pin de OUPUT lo que confirma que encima de el hay una “O” en vez
de una “I” pues los pines por defecto están en INPUT y encima vemos un “0” sobre fondo azul lo que
indica que en este momento no está saliendo corriente eléctrica por ese pin, a diferencia del pin 0
que esta en OUTPUT “O”, que se utiliza también como receptor “Rx” en comunicaciones asíncronas,
que si esta recibiendo electricidad y por ello esta a “1” y en color rojo, (pues la tarjeta se supone que
está conectada al Pc) .
Ejecución del sketch
Por fin hemos conseguido introducir nuestro sketch en el simulador, ahora no nos falta más que
simular su ejecución.
Observen los iconos que aparecen en la esquina izquierda de la pantalla.

La franja del menú, contiene una serie de opciones que al desplegarlos se abre dejando una serie
de subopciones que más o menos son las mismas que se utilizan en todos los sitios, Poco a poco
ya las iremos utilizando y contando para que valen. Hoy nos vanos a centrar en las opciones
de “Execute” (Ejecutar), que permiten lo que pretendemos en este momento, que es simplemente
simular la ejecución del sketch.
Para ello vamos a ver algunas de las subopciones que tiene la opción del
menú “Execute”(Ejecutar),
Si despegamos este submenú veremos que tiene una amplia variedad de subopciones

Reset (Reiniciar)

Hacer “Reset” (Reiniciar), es equivalente a clisar en el botón rojo de la Tarjeta


Arduino , (algo que también se puede), o lo que es lo mismo, dejar todo como está al principio del
programa. Podemos conseguir hacerlo, clicando en el botón rojo de la tarjeta, en esta subopción,
y además en uno de los iconos que hay en la barra de herramientas, como el icono negro que
mostramos situado bajo la opción “VarUpdates”.
Si tuviéramos variables, veríamos que estas adquieren los valores con que las hemos inicializado y
la barra azul que indica qué mandato se está ejecutando se sitúa sobre la función “main” que es la
que controla el proceso de simulación.
Halt (Detener)
“Halt” para o detiene la ejecución ahí donde se encuentre el programa en ese momento.
Es útil tanto para finalizar la ejecución del sketch, como para estudiar con calma los valores de las
variables en ese momento, pues a diferencia de “Reset”, deja las variables con sus valores en el
momento de pararse y no las inicializa.
Hay un icono rojo como el que se muestra que esta a la izquierda de “Reset” que realiza la misma
acción. Que habitualmente esta rojo y que se pone gris cuando para.
Run (Correr)

Al clicar en esta opción ponemos a funcionar, (correr), el programa de la forma más


sencilla, se ejecuta automáticamente. Es decir sin paradas. Lo mismo podemos conseguir con
el icono verde similar al que enseño que está dos iconos a la izquierda del de “Reset”
Si lo clikan, verán que en nuestro caso. el cuadradito amarillo que simula el led asociado al pin 13
se pone a parpadear y así se mantiene por tiempo indefinido, hasta que
apretemos “Reset” o “Halt”. Si hemos apretado “Halt” y volvemos a clicar “Run”, el programa
continua desde ese punto de parada. Puede ser una buena forma de estudiar los valores que toman
las variables en un determinado momento, lo difícil a velocidad normal va a ser acertar con el
momento de parada. Por ello esta opción, por si sola suele ser poco útil, si no tenemos idea de donde
estamos en la ejecución del programa, casi siempre se suele utilizarse conjuntamente con las
subopciones “Animate” (Animar) y “Slow Motión” (Cámara lenta)que veremos a continuación
Animate (Animar)
Nos permite seguir la linea que se está ejecutando. porque aparece una barra azul, que se sitúa
encima de la línea que se esta ejecutando en cada momento. El poner en marcha esta opción. reduce
la velocidad de ejecución del programa lo suficiente, para que nos de tiempo de ver a la barra. Por
tanto, la velocidad de ejecución, deja de simular la que tendría la tarjeta Arduino UNO, para ser más
lenta, sin embargo sigue siendo aun muy rápida, si no para el ojo humano, si para nuestra velocidad
de reacción y comprensión de lo que ocurre, por lo que podemos añadir la opción “Slow
Motión” (Cámara lenta) que expiaremos a continuación como su nombre indica relentiza la acción
Slow Motión (Cámara lenta)
Reduce la velocidad de ejecución de similar a la de la tarjeta, (si el procesador de tu Pc lo soporta,
que es lo normal), a una velocidad unas diez veces más lenta, lo que permite seguir con más facilidad
la evolución del programa y estudiar como cambian de valor las variables en “tiempo real”.
Step into (Entrar en)

Mejore que “Entrar en” hubiera sido traducirlo por “Paso a paso”, pues cada vez que
cliquemos en esta subopción el programa avanzará una línea, En este caso que presenta,os, que es
extrordinariamente sencillo, podemos permitirnos ese lujo de correr todo el programa paso a paso,
pues ademas tenemos un icono amarillo, como el que mostramos, situado a la izquierda del
icono “Run” verde que permite fácilmente clicarlo.
Si tuviéramos variables, veríamos los valores que estas tendrían después de parar en cada una
de las líneas de programa, lo que nos permite fácilmente depurar el programa, cuando tenemos un
punto con especial complejidad. Sin embargo, lo habitual es combinar esta acción con otra que te
pare el programa un poco antes del punto conflictivo, pues no es cosa de correr un programa de 500
lineas de una en una. Eso es lo que hace la subopción siguiente.
Run to (Correr hacia)

Esta subopción permite parar el programa allí donde indiquemos. Para ello hay que
efectuar dos acciones, la primera con el sketch parado marcamos con el ratón en que línea queremos
que pare, para ello basta clicar sobre la linea que queremos parar, (vemos que la linea azul se
desplaza a ese punto) y luego clicar en “Run to”(Correr hacia) o bien en el icono rojo similar al que
indicamos.
Por ejemplo una vez parado el sketch en esa línea podemos recorrer el programa línea a línea
clicando en el icono amarillo de “Step into” con lo que será fácil recorrer la parte más conflictiva
de nuestro sketch olvidándonos del resto del programa.
Una herramienta perfecta para poner a punto los programas
Con esto doy por finalizado por hoy el aprendizaje del manejo de esta simulación. Quiero resaltar la
poderosa herramienta que tenemos para poner a punto los sketch, pues nos permiten un control total
linea por linea del sketch, con un escaneo de los diversos valores que van adquiriendo las variables
en el transcurso de la ejecución. Como veremos en artículos posteriores esto facilita mucho el poner
a punto los programas, por tanto siempre que sea posible pondré a punto los programas en la
simulación antes de construir el Hardware y probarlos en real. En ejemplos más complicados y con
hardware que pongamos en el futuro, podremos probar la utilidad de poder observar estos valores.
Comfigurar el hardware
Aun nos falta hacer una cosa. Si nuestro software no utiliza ningún componente electrónico, ¿por
qué aparece la Tarjeta rodeada de componentes no utilizados? ¿Podemos eliminarlos?
Por supuesto que si hay una opción en el menú “Configure” (Configuración) que al desplegarse
presenta el submenú “I/O Devices” (E/S Dispositivos), que vale para seleccionar los dispositivos
que deseamos manejar (simunladamente) con la tarjeta Arduno.

Si clicamos en ese submenú nos aparece una pantalla con todos los dispositivos que podemos
utilizar con nuestra tarjeta y al lado un número que indica cuantos utilizamos en muestra
configuración.
En nuestro caso aparecen como componentes ligeros, de los cuales puede tener como máximo 16
componentes:

 2 Pusn Button (pulsador)


 4 Side Switch (Interruptores)
 2 Piezo Speakers (Chicharras/Zumbadores)
 6 LEDs
 1 Analog Slder Pars (componete analógico deslizante)

, y como componentes pesados de los cuales solo puede tener 8 componentes

 1 Servo Motors
 1 DC Motors (Motores de Corriente continua)
 0 Sreppers Motor (Motores paso a aso)
 1 Digital Pulsers (Pulsos digitales)
 1 Funtion Generators (Generador de funciones)
 1 Soft Serial Ports (Puertos Series ligeros)
 1 SPI Slaves ( Bus de comunicaciones Serial Periferical Interface Esclavos)
 0 Shift-reg Slaves (Bus de comunicaciones de cambio de registro esclavos)
 1 12C Slaves (bus de comunicaciones 12C esclavos)
 Aparte podemos o no ten seleccionado
 USB Serial (comunicación serial USB)
 SDCARD (Tarjeta de datos SD)
Muchos de esto componentes y comunicaciones muy probablemente no los conozcáis , poco a poco
los iremos utilizando y viendo para que valen,
De momento como en nuestro caso no necesitamos montar ningún componente los vamos a borrar
todos poniendo un cero en las casillas correspondientes.

Una vez que demos al “OK” a la nueva configuración, modificaremos la configuración de hardwara
asociada al programa. Con ello conseguimos que muestra tarjeta parezca ahora sola en la sección
gráfica de la simulación.
Guardar el trabajo realizado
Ahora sólo nos resta, aprender a guardar lo realizado, tamto en lo referente al sketch que hemos
escrito como a la configuración que hemos elegido. El , medio de hacerlo es similar al que se utiliza
en cualquier programa de Windows. Desplegando la primera opción de menú llamada “File”
(Fichero) que mas o menos tiene los habituales submenús

Al opción “Save as” (Salvar como), permite salvar el trabajo realizado con el nombre que prefiramos
y en la carpeta que queramos, yo lo he salvado en la carpeta donde tengo todo lo referente a este
programa llamada UnoArdSinV1.7.2 con el nombre “Blink” que es el tradicional que se da a este
fichero
Si comparan el estado actual del directorio de esa carpeta, con el inicial, observarán, que en la
primera línea de ficheros hay un fichero que antes no estaba llamado “Blink” precedido del logotipo
de Arduino que contiene todo lo que hemos hecho.
explicaré cómo escribir una librería simple con una función para encender y apagar un LED.
Para este tutorial es aconsejable entender cómo funcionan las clases en C++.

¿Qué es una librería y por qué la necesito?


Una librería es un conjunto de funciones prefabricadas que pueden importarse en el código en
que estás trabajando. Imagina que necesitas controlar motores: en vez de escribir tu código desde
cero, puedes incluir una librería que contiene funciones para mover un motor.
Las librerías ahorran trabajo (especialmente si están escritas por
terceros, aunque te recomiendo que escribas tu propio código siempre que sea posible), pero
también simplifican el programa. ¿Por qué? Las definiciones de cada función ocupan espacio en
el código principal, y lo hacen díficil de leer. Por tanto es una buena práctica separar el código
en varios archivos.

Estructura de una librería para Arduino


Las librerías para Arduino se escriben en C++, y de hecho son clases. ¿No tienes muy claro lo que
son las clases? Una clase es como un struct, solo que además de contener variables, puede tener
también funciones.
Habrá que crear dos archivos: “mi_clase.h”, que contendrá las cabeceras de la clase, y
“mi_clase.cpp”, que contendrá todas las definiciones y el código completo de las funciones.
Crea un nuevo directorio con el nombre de la librería (ej. robologs_lib) y dentro crea dos
ficheros: robologs.h y robologs.cpp

El fichero robologs.h creará una clase llamada ‘robologs’ que contendrá dos funciones:
el constructor de la clase y una función blinking que apagará y encenderá un led en intervalos
regulares de tiempo.
//Tutorial de librerias personalizadas con Arduino
1
2 //

3 //Escrita por Transductor


4 //www.robologs.net
5
6 //Primero los include guards
7 #ifndef ROBOLOGS_H
8 #define ROBOLOGS_H
9
10 //Cambia Arduino.h por Wprogram.h si usas una version antigua de la IDE.
11 #include <Arduino.h> //Permite utilizar los comandos de Arduino
12
13 class robologs //Definicion de la clase
14
{
15
16
public:
17
18
19 //Constructor de la clase

20 robologs();
21
22 //Funcion blinking: enciende el led 'pin', espera 'time' segundos y lo apaga
23 void blinking(int pin, int time);
24
25 private:
26
27 //Nada que declarar
28
};
29
#endif
El fichero robologs.cpp contiene el código de las funciones. El constructor está vacío (no tiene
que hacer nada en especial a parte de crear objetos). Por contra, la función blinking encenderá y
apagará un pin digital en intervalos de tiempo que recibirá como parámetro.
#include "robologs.h"
1
2 robologs::robologs(){} //Constructor: no tiene que hacer nada en especial
3
4 void robologs::blinking(int pin, int time)
5
{
6
//Recibe un pin y un tiempo como parametros
7
8 //Enciende y apaga el pin según el tiempo

9
10 //Establecer pin como salida
11 pinMode(pin, OUTPUT);
12
13 //Encenderlo y apagarlo
14 digitalWrite(pin,HIGH);
15 delay(time);
16
digitalWrite(pin, LOW);
17
delay(time);
18
}
Testeando…
Por último queda probar la librería, y para ello debes importarla. Si tienes una versión nueva de la
IDE abre Arduino -> Sketch -> Import Libraries -> Add Library y selecciona el directorio que
has creado. Si tienes una versión antigua tendrás que instalar la librería a mano.
He aquí un código de ejemplo.
#include <robologs.h>
1
2
3 robologs robby;
4
5 void setup()
6 {}
7
8 void loop()
9 {
10 robby.blinking(13, 1500);
11 }
Si lo compilas y lo cargas, verás que el LED D13 se enciende y se apaga.

 Anterior

 Leer un pulsador con Arduino con interrupciones y debounce


 Categoría de nivel principal o raíz: Arduino
 Categoría: Laboratorio ARD
 Publicado: 16 Noviembre 2016
 Visto: 986

Voto 5 Votar
 Por favor, vote

 En la entrada anterior vimos qué son las interrupciones y cómo usarlas para responder a
eventos de hardware en pins.
 También dejamos claro que los dispositivos físicos, como pulsadores, detectores ópticos,
etc, presentan un efecto rebote que interfiere con el uso de interrupciones, y que
necesitamos eliminarlo o no podremos usar interrupciones con estos dispositivos.
 El proceso de eliminación de este rebote se llama “debounce”. En esta entrada
aprenderemos qué es el rebote y aprenderemos a eliminarlo con debounce por hardware y
por software.

 ¿Qué es el debounce?

 Los dispositivos electrónicos al cambiar de estado generan una señal que, sin ser
perfectamente cuadrada, en general es más o menos “limpia”. Veamos, por ejemplo, la
señal que genera Arduino al cambiar el estado de una salida digital de HIGH a LOW.


 Sin embargo el mundo real no es tan bonito. Muchos dispositivos físicos
habitualmente generan ruido en los flancos de señal. Como ejemplo, veamos la variación
de tensión que ocurre cuando el cambio de estado se genera por un pulsador.

 Observar la cantidad de ruido ocurrido tras el flanco. En esencia, en el rango de unos
microsegundos la señal es puro ruido. Todos esos picos pueden provocar disparos
múltiples de una interrupción.

 PROBANDO EL REBOTE
 Para probar el rebote, simplemente vamos a emplear un cable para conectar el Pin 2 y
Ground (también podéis usar un pulsador o un interruptor).

 Activamos la resistencia interna de Pull UP en el Pin 2 y definimos una interrupción al evento
de bajada en el PIN, y en la función ISR asociada simplemente incrementamos un contador.
 En el bucle principal, comprobamos si el contador, y si este ha sido modificado mostramos
su valor por el puerto de serie.

1 const int intPin = 2;

2 volatile int ISRCounter = 0;

3 int counter = 0;

6 void setup()
7 {

8 pinMode(intPin, INPUT_PULLUP);

9 Serial.begin(9600);

10 attachInterrupt(digitalPinToInterrupt(intPin), debounceCount, LOW);

11 }

12

13 void loop()

14 {

15 if (counter != ISRCounter)

16 {

17 counter = ISRCounter;

18 Serial.println(counter);

19 }

20 }

21

22 void debounceCount()

23 {

24 ISRCounter++;

25 }


 Al probar nuestro montaje y poner en contacto el PIN 2 a GROUND, esperaríamos que la
variable se incrementara de uno en uno. Pero veremos que en realidad salta varios
números cada vez (incluso varias decenas).
 Este es el efecto del rebote. El ruido de la señal está generando múltiples interrupciones
cada vez que conectamos el cable.

 Eliminando el rebote
 Disponemos de dos formas de aplicar el debounce. Añadiendo dispositivos electrónicos que
filtren la señal (debounce por hardware) o modificando nuestro código para eliminar el rebote
(debounce por hardware).
 Debounce por hardware
 Aplicar un debounce por hardware tiene la ventaja de no incrementar el tiempo de ejecución
de nuestro código. Además, en general, es una solución más robusta. Por contra, tiene la
desventaja de aumentar la complejidad de nuestro montaje.
 La forma más sencilla de aplicar un debounce por hardware es colocar un condensador
en paralelo con el dispositivo (pulsador, interruptor, sensor…). Un condensador del orden
de 1uF debería ser suficiente para filtrar la mayoría del ruido.
 El esquema de conexión es el siguiente.


 En general siempre es conveniente añadir un filtro por hardware cuando empleamos
entradas físicas con interrupciones.

 Debounce por software


 El debounce por software tiene la ventaja de no requerir componentes adicionales.
Resolvemos el rebote únicamente modificando el código de nuestro programa.
 Como desventaja, incrementa levemente el tiempo de ejecución y la complejidad del código.
Además, si no aplicamos el código correctamente podemos ignorar interrupciones
“verdaderas”.
 La forma más sencilla de aplicar un debounce por software es comprobar el tiempo entre
disparos de la interrupción. Si el tiempo es inferior a un determinado umbral de tiempo
(threshold) simplemente ignoramos la interrupción. En definitiva, hemos definido una “zona
muerta” en la que ignoramos las interrupciones generadas.
 Para aplicar el debounce por software, modificamos la función ISR de la siguiente forma.

1 const int timeThreshold = 150;

2 const int intPin = 2;

3 volatile int ISRCounter = 0;

4 int counter = 0;

5 long timeCounter = 0;

8 void setup()

9 {

10 pinMode(intPin, INPUT_PULLUP);

11 Serial.begin(9600);

12 attachInterrupt(digitalPinToInterrupt(intPin), debounceCount, FALLING);

13 }

14

15 void loop()

16 {

17 if (counter != ISRCounter)

18 {

19 counter = ISRCounter;

20 Serial.println(counter);

21 }

22 }

23

24 void debounceCount()
25 {

26 if (millis() > timeCounter + timeThreshold)

27 {

28 ISRCounter++;

29 timeCounter = millis();

30 }

31 }


 Un tiempo de 100-200ms es correcto para un pulsador pero en otros casos deberemos
ajustar el tiempo de forma que eliminemos el rebote, pero no ignoremos dos posibles eventos
cercanos “verdaderos”.

 En un montaje real, lo mejor es emplear una combinación de ambos sistemas, a la vez
que ajustamos correctamente el valor del condensados y los tiempos del filtro por software
para adaptarlos a nuestro sistema.

Qué son y cómo usar interrupciones en Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 08 Noviembre 2016
Visto: 1012

Voto 5 Votar
Por favor, vote

Las interrupciones son un mecanismo muy potente y valioso en procesadores y autómatas.


Arduino, por supuesto, no es una excepción. En esta entrada veremos qué son las interrupciones, y
como usarlas en nuestro código.
Para entender la utilidad y necesidad de las interrupciones, supongamos que tenemos Arduino
conectado a un sensor, por ejemplo encoder óptico que cuenta las revoluciones de un motor, un
detector que emite una alarma de nivel de agua en un depósito, o un simple pulsador de parada.
Si queremos detectar un cambio de estado en esta entrada, el método que
hemos usado hasta ahora es emplear las entradas digitales para consultar repetidamente el valor
de la entrada, con un intervalo de tiempo (delay) entre consultas.
Este mecanismo se denomina “poll”, y tiene 3 claras desventajas.

 Suponer un continuo consumo de procesador y de energía, al tener que preguntar


continuamente por el estado de la entrada.
 Si la acción necesita ser atendida inmediatamente, por ejemplo en una alerta de colisión,
esperar hasta el punto de programa donde se realiza la consulta puede ser inaceptable.
 Si el pulso es muy corto, o si el procesador está ocupado haciendo otra tarea mientras se
produce, es posible que nos saltemos el disparo y nunca lleguemos a verlo.

Para resolver este tipo de problemas, los microprocesadores incorporan el concepto de interrupción,
que es un mecanismo que permite asociar una función a la ocurrencia de un determinado
evento. Esta función de callback asociada se denomina ISR (Interruption Service Rutine).
Cuando ocurre el evento el procesador “sale” inmediatamente del flujo normal del programa y
ejecuta la función ISR asociada ignorando por completo cualquier otra tarea (por esto se llama
interrupción). Al finalizar la función ISR asociada, el procesador vuelve al flujo principal, en el mismo
punto donde había sido interrumpido.
Como vemos, las interrupciones son un mecanismo muy potente y cómodo que mejora nuestros
programas y nos permite realizar acciones que no serían posibles sin el uso de
interrupciones.

Para usar interrupciones en dispositivos físicos (como pulsadores, sensores ópticos, … ) debemos
antes eliminar el efecto “rebote”.

INTERRUPCIONES EN ARDUINO
Arduino dispone de dos tipos de eventos en los que definir interrupciones. Por un lado tenemos las
interrupciones de timers (que veremos en su momento al hablar de temporizadores. Por otro lado,
tenemos las interrupciones de hardware, que responden a eventos ocurridos en ciertos pines
físicos.
Dentro de las interrupciones de hardware, que son las que nos ocupan en esta entrada, Arduino es
capaz de detectar los siguientes eventos.

 RISING, ocurre en el flanco de bajada de LOW a HIGH.


 FALLING, ocurre en el flanco de subida de HIGH a LOW.
 CHANGING, ocurre cuando el pin cambia de estado (rising + falling).
 LOW, se ejecuta continuamente mientras está en estado LOW.

Los pines susceptibles de generar interrupciones varían en función del modelo de Arduino.
En Arduino y Nano se dispone de dos interrupciones, 0 y 1, asociados a los pines digitales 2 y 3.El
Arduino Mega dispone de 6 interrupciones, en los pines 2, 3, 21, 20, 19 y 18 respectivamente.
Arduino Due dispone de interrupciones en todos sus pines.

Modelo INT0 INT1 INT2 INT3 INT4 INT5


UNO 2 3
Nano 2 3
Mini Pro 2 3
Mega 2 3 21 20 19 18
Leonardo 3 2 0 1 7
Due En todos los pines
LA FUNCIÓN ISR
La función asociada a una interrupción se denomina ISR (Interruption Service Routines) y, por
definición, tiene que ser una función que no recibe nada y no devuelva nada.
Dos ISR no pueden ejecutarse de forma simultánea. En caso de dispararse otra interrupción
mientras se ejecuta una ISR, la función ISR se ejecuta una a continuación de otra.

LA ISR, CUANTO MÁS CORTA MEJOR


Al diseñar una ISR debemos mantener como objetivo que tenga el menor tiempo de ejecución
posible, dado que mientras se esté ejecutando el bucle principal y todo el resto de funciones se
encuentran detenidas.
Imaginemos, por ejemplo, que el programa principal ha sido interrumpido mientras un motor
acercaba un brazo para coger un objeto. Una interrupción larga podría hacer que el brazo no para a
tiempo, tirando o dañando el objeto.
Frecuentemente la función de la ISR se limitará a activar un flag, incrementar un contador, o
modificar una variable. Esta modificación será atendida posteriormente en el hilo principal, cuando
sea oportuno.

No empleéis en una ISR un proceso que consuma tiempo. Esto incluye cálculos complejos,
comunicación (serial, I2C y SPI) y, en la medida de lo posible, cambio de entradas o salidas tanto
digitales como analógicas.

LAS VARIABLES DE LA ISR COMO “VOLATILES”


Para poder modificar una variable externa a la ISR dentro de la misma debemos declararla como
“volatile”. El indicador “volatile” indica al compilador que la variable tiene que ser consultada
siempre antes de ser usada, dado que puede haber sido modificada de forma ajena al flujo normal
del programa (lo que, precisamente, hace una interrupción).
Al indicar una variable como Volatile el compilador desactiva ciertas optimizaciones, lo que supone
una pérdida de eficiencia. Por tanto, sólo debemos marcar como volatile las variables que realmente
lo requieran, es decir, las que se usan tanto en el bucle principal como dentro de la ISR.

EFECTOS DE LA INTERRUPCIÓN Y LA MEDICIÓN DEL TIEMPO


Las interrupciones tienen efectos en la medición del tiempo de Arduino, tanto fuera como dentro
de la ISR, porque Arduino emplea interrupciones de tipo Timer para actualizar la medición del tiempo.

Efectos fuera de la ISR


Durante la ejecución de una interrupción Arduino no actualiza el valor de la función millis y
micros. Es decir, el tiempo de ejecución de la ISR no se contabiliza y Arduino tiene un desfase en
la medición del tiempo.
Si un programa tiene muchas interrupciones y estas suponen un alto tiempo de ejecución, la medida
del tiempo de Arduino puede quedar muy distorsionada respecto a la realidad (nuevamente, un
motivo para hacer las ISR cortas).

Efectos dentro de la ISR


Dentro de la ISR el resto de interrupciones están desactivadas. Esto supone:
 La función millis no actualiza su valor, por lo que no podemos utilizarla para medir el tiempo
dentro de la ISR. (sí podemos usarla para medir el tiempo entre dos ISR distintas)
 Como consecuencia la función delay() no funciona, ya que basa su funcionamiento en la
función millis()
 La función micros() actualiza su valor dentro de una ISR, pero empieza a dar mediciones de
tiempo inexactas pasado el rango de 500us.
 En consecuencia, la función delayMicroseconds funciona en ese rango de tiempo, aunque
debemos evitar su uso porque no deberíamos introducir esperas dentro de una ISR.

CREAR INTERRUPCIONES EN ARDUINO


Para definir una interrupción en Arduino usamos la función:

1 attachInterrupt(interrupt, ISR, mode);

Donde interrupt es el número de la interrupción que estamos definiendo, ISR la función de callback
asociada, y mode una de las opciones disponibles (Falling, Rising, Change y Low)
No obstante, es más limpio emplear la función digitalPinToInterrupt(), que convierte un Pin a la
interrupción equivalente. De esta forma se favorece el cambio de modelo de placa sin tener que
modificar el código.

1 attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

Otras funcionas interesantes para la gestión de interrupciones son:

 DetachInterrupt(interrupt ), anula la interrupción.


 NoInterrupts(), desactiva la ejecución de interrupciones hasta nueva orden. Equivale a sli()
 Interrupts(), reactiva las interrupciones. Equivale a cli()

Probando las interrupciones en Arduino


Para probar las interrupciones en Arduino, vamos a emplear una salida digital de Arduino para emular
una señal digital. En el mundo real, sería otro dispositivo (un sensor, otro procesador…) el que
generaría esta señal, y nosotros la captaríamos con Arduino.
Conectamos mediante un cable el pin digital 10 al pin digital 2, asociado a la interrupción 0.
Haciendo parpadear un LED a través de interrupciones
En el siguiente código definimos el pin digital 10 como salida, para emular una onda cuadrada de
periodo 300ms (150ms ON y 150ms OFF).
Para visualizar el funcionamiento de la interrupción, en cada flanco activo del pulso simulado,
encendemos/apagamos el LED integrado en la placa, por lo que el LED parpadea a intervalos de
600ms (300ms ON y 300ms OFF)
Puede que a estas alturas ver parpadear un LED no parezca muy espectacular, pero no es tan simple
como parece. No estamos encendiendo el LED con una salida digital, si no que es la interrupción
que salta la que enciende y apaga el LED (el pin digital solo emula una señal externa).

1 const int emuPin = 10;


2
3 const int LEDPin = 13;
4 const int intPin = 2;
5 volatile int state = LOW;
6
7 void setup() {
8 pinMode(emuPin, OUTPUT);
9 pinMode(LEDPin, OUTPUT);
10 pinMode(intPin, INPUT_PULLUP);
11 attachInterrupt(digitalPinToInterrupt(intPin), blink, CHANGE);
12 }
13
14 void loop() {
15 //esta parte es para emular la salida
16 digitalWrite(emuPin, HIGH);
17 delay(150);
18 digitalWrite(emuPin, LOW);
19 delay(150);
20 }
21
22 void blink() {
23 state = !state;
24 digitalWrite(LEDPin, state);
25 }

Contando disparos de una interrupción


El siguiente código empleamos el mismo pin digital para emular una onda cuadrada, esta vez de
intervalo 2s (1s ON y 1s OFF).
En cada interrupción actualizamos el valor de un contador. Posteriormente, en el bucle principal,
comprobamos el valor del contador, y si ha sido modificado mostramos el nuevo valor.
Al ejecutar el código, veremos que en el monitor serie se imprimen números consecutivos a intervalos
de dos segundos.

1 const int emuPin = 10;


2
3 const int intPin = 2;
4 volatile int ISRCounter = 0;
5 int counter = 0;
6
7
8 void setup()
9 {
10 pinMode(emuPin, OUTPUT);
11
12 pinMode(intPin, INPUT_PULLUP);
13 Serial.begin(9600);
14 attachInterrupt(digitalPinToInterrupt(intPin), interruptCount, LOW);
15 }
16
17 void loop()
18 {
19 //esta parte es para emular la salida
20 digitalWrite(emuPin, HIGH);
21 delay(1000);
22 digitalWrite(emuPin, LOW);
23 delay(1000);
24
25
26 if (counter != ISRCounter)
27 {
28 counter = ISRCounter;
29 Serial.println(counter);
30 }
31 }
32
33 void interruptCount()
34 {
35 ISRCounter++;
36 timeCounter = millis();
37 }

Lógicamente, nuestro objetivo es emplear interrupciones de hardware no solo con otros


dispositivos digitales, si no también con dispositivos físicos como pulsadores, sensores
ópticos…
Sin embargo, como hemos adelantado, estos dispositivos generan mucho ruido en los cambios
de estado, lo que provoca que las interrupciones se disparen múltiples veces. Este fenómeno se
denomina “rebote”.
fuente: luisllamas.es

Usando una memoria EEPROM con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 05 Octubre 2016
Visto: 2059

Voto 5 Votar
Por favor, vote

Arduino tiene una memoria no volátil de tan sólo 512 bytes, que puede ser insuficiente en algunos
casos.
Pero podemos usar una EEPROM externa, en mi caso he usado una EEPROM serie 24LC256 que
tiene una capacidad de 256 Kbit (32K x 8 bytes) y un precio de 2.88 euros. Os dejo el enlace a
la hoja de especificaciones.
La comunicación entre Arduino y la EEPROM se realiza mediante el bus I2C , que se trata de un bus
de comunicaciones serie formado por dos lineas: una para los datos y otra para el reloj.
La librería Wire permite manejar un bus I2C desde nuestro Arduino, y en este artículo del wiki
encontramos 4 funciones que usando la librería anterior implementan la lectura/escritura en la
EEPROM.
El parámetro deviceaddress al que hacen referencia estas funciones en el caso de esta memoria se
trata del 0x50.
No debemos olvidarnos de inicializar la conexión antes de usar estas funciones:
Wire.begin();

En cuanto a las conexiones de los pines: el pin 5 de la EEPROM (SDA) lo conectamos a la entrada
analógica 4 de nuestro Arduino, el pin 6 (SCL) a la entrada analógica 5 (observar en la foto que los
cables de color naranja se cruzan), el pin 8 a 5V y todos los demás a tierra.

Los pines analógicos 4 y 5 de Arduino son los que usa la librería Wire.
En cuanto al sketch, os pongo el ejemplo con el que lo probé: se trata de escribir una cadena de
caracteres cuando enciende nuestro Arduino y de leerla y enviarla al ordenador repetidamente.

1. /* Ejemplo EEPROM
2. * Autor: kans
3. * Fecha: 05/03/2008
4. */
5.
6. #include <Wire.h> //libreria I2C
7.
8. //Las siguientes funciones para lectura y escritura en una EEPROM se encuentran en el wiki de
Arduino: http://www.arduino.cc/playground/Code/I2CEEPROM
9.
10. void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
11. int rdata = data;
12. Wire.beginTransmission(deviceaddress);
13. Wire.send((int)(eeaddress >> 8)); // MSB
14. Wire.send((int)(eeaddress & 0xFF)); // LSB
15. Wire.send(rdata);
16. Wire.endTransmission();
17. }
18.
19. // WARNING: address is a page address, 6-bit end will wrap around
20. // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32
bytes
21. void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte
length ) {
22. Wire.beginTransmission(deviceaddress);
23. Wire.send((int)(eeaddresspage >> 8)); // MSB
24. Wire.send((int)(eeaddresspage & 0xFF)); // LSB
25. byte c;
26. for ( c = 0; c < length; c++)
27. Wire.send(data[c]);
28. Wire.endTransmission();
29. }
30.
31. byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
32. byte rdata = 0xFF;
33. Wire.beginTransmission(deviceaddress);
34. Wire.send((int)(eeaddress >> 8)); // MSB
35. Wire.send((int)(eeaddress & 0xFF)); // LSB
36. Wire.endTransmission();
37. Wire.requestFrom(deviceaddress,1);
38. if (Wire.available()) rdata = Wire.receive();
39. return rdata;
40. }
41.
42. // maybe let's not read more than 30 or 32 bytes at a time!
43. void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int lengt
h){
44. Wire.beginTransmission(deviceaddress);
45. Wire.send((int)(eeaddress >> 8)); // MSB
46. Wire.send((int)(eeaddress & 0xFF)); // LSB
47. Wire.endTransmission();
48. Wire.requestFrom(deviceaddress,length);
49. int c = 0;
50. for ( c = 0; c < length; c++ )
51. if (Wire.available()) buffer[c] = Wire.receive();
52. }
53.
54.
55. void setup() {
56. char cadena[] = "hola mundo desde una eeprom"; //cadena a escribir
57. Wire.begin(); //es obligatorio inicializar la conexion
58. Serial.begin(9600);
59. i2c_eeprom_write_page(0x50, 0, (byte *)cadena, sizeof(cadena)); //escribir la cadena al
principio de la EEPROM; comentar esta linea para probar que la memoria es no volatil
60. delay(10); //peque�a pausa despues de escribir en la memoria
61. }
62.
63. void loop() {
64. int addr=0; //direccion a leer
65. byte b = i2c_eeprom_read_byte(0x50, 0); //acceso a la primera posicion de memoria
66.
67. while (b!=0) {
68. Serial.print((char)b); //enviar al ordenador
69. addr++; //siguiente direccion
70. b = i2c_eeprom_read_byte(0x50, addr); //acceso a posicion de memoria
71. }
72. Serial.println();
73. delay(2000);
74. }

Al tratarse de una memoria no volátil, podemos comentar la escritura (línea 59) para comprobar que
permanecen los datos guardados con anterioridad.

Sensor de sonido con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 30 Septiembre 2016
Visto: 1002

Voto 5 Votar
Por favor, vote

En muchas peliculas podemos ver como encienden y apagan las luces de su casa con una palmada
¿por qué no hacer eso con Arduino?
Lo único que necesitamos es poder detectar un ruido que supere un determinado umbral, y eso es
lo que
vamos a aprender en este circuito, luego cada uno podrá implementarlo como quiera.
Necesitamos un micrófono para permitir a Arduino "escuchar" lo que ocurre a su alrededor, despues
unicamente tendremos que fijar un umbral mínimo que tiene que alcanzar el sonido para que se
accione lo que deseamos.

Veamos el código, en este caso unicamente vamos a encender el led 13 que viene conectado a
Arduino. Pero podriamos accionar relés, motores, servos.. cualquier cosa que pueda ser controlada
desde Arduino.
1. #define led 13 //Llamamos led a la patilla 13 en la que esta el led integrado en Arduino
2.
3. int umbral= 600; //Declatamos un umbral de sonido minimo.
4.
5. void setup() {
6. pinMode(led, OUTPUT);
7. }
8.
9.
10. void loop() {
11.
12. //declaramos que el sensor de sonido esta en la entrada analogica 0
13. int sensor = analogRead(A0);
14.
15. //Si el sonido detectado supera el umbral, encendemos el led, sino lo apagamos.
16. if(sensor>umbral){digitalWrite(led, HIGH);}else{digitalWrite(led, LOW);}
17.
18. delay(500); //Esperamos antes de tomar una nueva lectura
19. }

Pues esto es todo, ahora podemos usar un relé para encender y apagar las luces de nuestro cuarto,
o podemos darle otro uso a este mismo circuito. Por ejemplo, podríamos implementarlo en un
sistema de alarma.

Sensor Humedad de una Superficie o terreno. Con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 29 Junio 2016
Visto: 1172

Voto 5 Votar
Por favor, vote

Este sensor viene con los 2 conductores que clavaremos en una maceta o jardinera
y trae 3 pines GND, VCC y DAT. Al ser un sensor analógico sólo necesita
alimentación y una entrada de datos analógica.
Sensor Arduino
VCC 5V
GND GND
DAT A0
En este ejemplo lo vamos a conectar a la entrada analógica 0 pero podría ser
cualquier otra, quedando con un aspecto parecido a este:
Una vez tengamos todas las conexiones realizadas, podemos subir este pequeño
ejemplo. Que nos mostrará por el monitor del puerto serie en que estado se
encuentra la tierra de nuestra planta.

// Sensor de Humedad

// Conectamos el sensor de la siguiente forma:

// GND -> GND

// VCC -> 5V

// DAT -> A0

// Por ejemplo conectamos a las entrada Analógica 0

// http://arubia45.blogspot.com.es/

// Descripción de valores del Sensor

// 0 -300 Seco

// 300-700 Húmedo

// 700-950 En Agua

int Valor;

void setup(){

Serial.begin(9600);

Serial.println("http://arubia45.blogspot.com.es");

void loop(){

Serial.print("Sensor de Humedad valor:");

Valor = analogRead(0);

Serial.print(Valor);
if (Valor <= 300)

Serial.println(" Seco, necesitas regar");

if ((Valor > 300) and (Valor <= 700))

Serial.println(" Humedo, no regar");

if (Valor > 700)

Serial.println(" Encharcado");

delay(1000);

El resultado lo vemos en el Monitor del puerto


serie:

Aquí también os dejo


este mismo ejemplo combinando el sensor de
humedad con un led RGB de forma que cuando más azul esté más húmedo estará
el recipiente que estamos
monitorizando.

Sensor Sharp 2Y0A21 - 2Y0A02Y con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 23 Febrero 2016
Visto: 3597

Voto 5 Votar
Por favor, vote

Introducción.
Los Sensores Sharp 2Y0A21 y Sharp 2Y0A02Y son una interesante alternativa a los
sensores de ultrasonido, el punto fuerte de estos pequeños sensores son su precisión ya que como
veremos en otro apartado tienen un alcance muy corto en especial el sensor Sharp 2Y0A21 , estos
sensores trabajan mediante señales infrarrojas y tiene un costo bajo.

Características del Sensor Sharp 2Y0A21 y Sharp 2Y0A02Y


Si necesitas mas datos del sensor puedes consultar su datasheet en este enlace.

 Rango Mínimo 10 cm para el sensor 2Y0A21 , 20 cm para el sensor 2Y0A02Y.


 Rango Máximo 80 cm para el sensor 2Y0A21 , 150 cm para el sensor 2Y0A02Y.
 Tensión en la Salida de 0.3 v a 3.1 v dependiendo de la distancia medida.
 Alimentación de 4.5 a 5.5 v
 Tres Pines (Alimentación, Tierra, Salida)

Requisitos.

 Arduino
 Sensor Sharp 2Y0A21 o Sharp 2Y0A02Y.
 Cables de Conexión o Jumpers
 Protoboard

Repositorio del Proyecto.


Tenemos todos los Archivos Necesarios del Proyecto en nuestro Repositorio en Github

Diagrama de Conexiones.
La conexión se la hizo directamente aunque podrías agregar un protoboard para agregar otras
funcionalidades.
Código Arduino.
Haciendo varias pruebas con el sensor nos dimos cuenta de que lanzaba varias mediciones
incoherentes es por eso que nos vimos de la necesidad de contar con una librería que nos solucione
el problema.
La librería que utilizamos para controlar el sensor se llama SharpIr que nos simplifica el trabajo de
conversiones en los diferentes sistemas de unidades, puedes descargar la librería y su
documentación en el siguiente enlace:

 http://playground.arduino.cc/Main/SharpIR

Importante: No olvides cambiar el tipo de sensor Sharp que tienes en la variable model.
#define ir A0
#define model 1080

SharpIR sharp(ir, 25, 93, model);

// ir: Pin Analogico donde se conecta el sensor


// 25: El numero de lecturas que la libreria hara antes de hacer el calculo de distancias
// 93: la diferencia entre dos medias consecutivas tomadas como validas
// model: Determina el Modelo de tu sensor : 1080 for GP2Y0A21Y
// 20150 for GP2Y0A02Y

void setup(){

Serial.begin(9600);
pinMode (ir, INPUT);

}
void loop(){

delay(2000); // Retardo entre cada medicion


unsigned long pepe1=millis(); // toma el tiempo de cada loop

int dis=sharp.distance(); // retorna la distancia

Serial.print("Distancia: ");
Serial.println(dis);

unsigned long pepe2=millis()-pepe1; // retornal el tiempo de cada medicion


Serial.print("Tiempo (ms): ");
Serial.println(pepe2);
}

Resultados.
Como podemos apreciar en la Imagen las distancias obtenidas están expresadas en centímetros y
tienen una exactitud muy apreciable dado el movimiento del objetivo de medición.

Tanto el Diagrama de conexiones como el código sirven para las dos clases de sensores lo que nos
facilita el trabajo a la hora de probar entre los sensores.

Motor paso a paso con Arduino 28BYJ-48 ULN2003


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 26 Enero 2016
Visto: 1661

Voto 5 Votar
Por favor, vote
El objetivo de este tutorial es tener la primera toma de contacto con los famosos motores paso a
paso, tan útiles que se pueden encontrar en muchas aplicaciones como robots o impresoras 3D.

¿Por qué? Esto es debido a su precisión, ya que puedes controlar el giro del eje del motor con
bastante precisión. Su funcionamiento, de forma muy simplificada, es parecida a la de los servos,
con la diferencia de que no existe la limitación de giro de 180 grados, sino que pueden dar vueltas
completas como si un motor de corriente continua se tratase. Y es justo esta su ventaja frente a los
motores de corriente continua, una mayor precisión en el movimiento de los mismos. Por contra, son
más complejos de usar, lo cual no son
recomendables en proyectos donde no se necesite la ya comentada alta precisión.

Motor de paso a paso 28BYJ-48 y su módulo


controlador compatible ULN2003
Este motor venía con el starter kit que nos compramos para empezar en el mundo de Arduino. ¿No
lo tienes? No te preocupes, son baratos y fáciles de encontrar por la red.

Es pequeño, ligero y funciona a 5V, lo que hace perfecto a la hora de usarlo con la placa Arduino
(aunque el voltaje de entrada puede ampliarse hasta 12V).

En la hoja de catálogo de este componente, nos encontramos que ofrece un par decente a unas 15
RPM (revoluciones por minuto). De los dos modos "de paso" que tiene (half-step mode y full-step
mode), vamos a usar el "hal-step mode"(el recomendado por el fabricante), que nos ofrece el uso de
8 señales de frecuencia de paso con unos resultados de 5.625 grados por paso, un total de 64 pasos
por vuelta.

¿Cómo funciona?

El motor tiene 4 bobinas que son excitadas en una secuencia para hacer girar el eje.

En el modo elegido, primero excitamos la bobina 1, luego la 1 y la 2 a la vez, luego la 2... Y así hasta
completar la secuencia. De ahí las 8 señales necesarias para el funcionamiento, tal y como muestra
la figura:
A (Azul), B (Rosa), C (Amarillo),
D (Naranja), E (Rojo)

Conexiones

La conexión entre el módulo y el motor es bastante


intuitiva ya que tiene un conector con ranuras para guiar el acople entre los dos dispositivos.
Veremos en el módulo que existen 4 leds que indican qué bobina está actuando (mirar esquema de
arriba).

Se recomienda el uso de baterías externas para la alimentación de 5V y no usar la salida de la placa


Arduino, debido a que se necesita más corriente de la que el microcontrolador puede suministrar
(92mA frente a los 40mA máximos que ofrece la placa)..

Los pines IN1, IN2, IN3 e IN4 son los que irán conectados a las salidas digitales del Arduino (pines
digitales del 8 al 11 empezando por el IN1 con el 8).

Programa
Se va a usar un programa diferente al que viene pre-instalado en el IDE de Arduino , ya que dicho
programa usa el full-step mode y nosotros queremos utilizar, por recomendación del fabricante, el
half-step mode.

// Este ejemplo demuestra que el motor 28BYJ-48 opera de forma

// bidireccional, usando un módulo ULN2003.

//La frecuencia de operación es 100Hz. Y la corriente de 92mA.

////////////////////////////////////////////////

//declaración de las variables para los pines del motor

int motorPin1 = 8; // Azul - 28BYJ48 pin 1 motor

int motorPin2 = 9; // Rosa - 28BYJ48 pin 2 motor

int motorPin3 = 10; // Amarillo - 28BYJ48 pin 3 motor

int motorPin4 = 11; // Naranja - 28BYJ48 pin 4 motor

// Rojo - 28BYJ48 pin 5 (VCC) motor

int motorSpeed = 1200; //variable para fijar la velocidad del motor (el retraso entre ca
da secuencia)

int count = 0; // cuenta de los pasos dados

int countsperrev = 512; // número de pasos por vuelta completa

int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

void setup() {

//declare the motor pins as outputs

pinMode(motorPin1, OUTPUT);

pinMode(motorPin2, OUTPUT);

pinMode(motorPin3, OUTPUT);

pinMode(motorPin4, OUTPUT);

Serial.begin(9600);

void loop(){
if(count < countsperrev )

clockwise(); //sentido agujas del reloj

else if (count == countsperrev * 2)

count = 0;

else

anticlockwise(); //sentido antihorario

count++;

//creación funciones giro horario y antihorario

void anticlockwise()

for(int i = 0; i < 8; i++)

setOutput(i);

delayMicroseconds(motorSpeed);

void clockwise()

for(int i = 7; i >= 0; i--)

setOutput(i);

delayMicroseconds(motorSpeed);

void setOutput(int out) //función secuencia giro

digitalWrite(motorPin1, bitRead(lookup[out], 0));


digitalWrite(motorPin2, bitRead(lookup[out], 1));

digitalWrite(motorPin3, bitRead(lookup[out], 2));

digitalWrite(motorPin4, bitRead(lookup[out], 3));

Módulo GPS neo-6m con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 13 Enero 2016
Visto: 1984

Voto 5 Votar
Por favor, vote

El módulo GPS en su modelo GY-GPS6MV2 viene con un módulo de serie U-Blox NEO 6M equipado
en el PCB, una EEPROM con configuración de fábrica, una pila de botón para mantener los datos
de configuración en la memoria EEPROM, un indicador LED y una antena cerámica. También posee
los pines o
conectores Vcc, Rx, Tx y Gnd por el que se puede conectar a algún microcontrolador mediante una
interfaz serial. Para que nuestro módulo GPS funcione a la perfección se recomienda hacer las
pruebas en un ambiente abierto o cercano a la ventana para una correcta recepción de la señal.

Bien, ahora vamos a probar nuestro módulo conectándolo a nuestro Arduino (en este caso se usará
un Arduino UNO) mediante un puerto serie que se emulará por Software ya que usaremos el Rx0 y
TX0 (puerto serie por Hardware) para la comunicación con nuestra PC y así verificar los datos que
recibimos por el módulo GPS.

Vamos a realizar las conexiones que se muestran en la siguiente imagen o seguir los pasos que se
describen a continuación:
- Conecte el pin 3.3V del Arduino UNO al pin Vcc del módulo GPS.
- Conecte el pin GND del Arduino UNO al pin GND del módulo GPS.
- Conecte el pin digital 4 del Arduino UNO al pin Tx del módulo GPS.
- Conecte el pin digital 3 del Arduino UNO al pin Rx del módulo GPS.

Cabe indicar que nuestro módulo GPS también se puede alimentar con una tensión de 5V ya que
posee un regulador integrado dentro de sí.
A continuación, cargaremos el siguiente código a nuestro Arduino, en el cual se puede apreciar que
se emplea la librería SoftwareSerial para emular un puerto serie como se mencionó anteriormente
(no es necesaria instalarla, ya que viene por defecto en nuestro IDE de Arduino).
Codigo:
#include <SoftwareSerial.h>

SoftwareSerial gps(4,3);

char dato=' ';

void setup()
{
Serial.begin(115200);
gps.begin(9600);
}

void loop()
{
if(gps.available())
{
dato=gps.read();
Serial.print(dato);
}
}
Como podemos ver, lo que hace nuestro programa es leer constantemente el módulo GPS a una
velocidad de 9600 baudios que es la velocidad por la que viene configurado por defecto nuestro
módulo GPS y enviar dichos datos a la PC a través del puerto serie físico para poder visualizarlos
en nuestro Monitor Serial. Al abrir nuestro Monitor Serial, nos aseguramos de configurarlo a una
velocidad de 115200 baudios. Podremos ver los datos que recibimos.

Los datos que recibimos en nuestro módulo GPS siguen el protocolo NMEA (siglas de National
Marine Electronics Asociation), las cuales son sentencias estándares para la recepción de datos
GPS. Una de ellas y la más usada son las sentencias $GPRMC, las cuales tienen la siguiente
estructura:

$GPRMC,044235.000,A,4322.0289,N,00824.5210,W,0.39,65.46,020615,,,A*44
Estas coordenadas las podemos leer en la siguiente web: http://rl.se/gprmc
Donde si analizamos la trama de este ejemplo y basándose en el protocolo NMEA, podríamos
determinar las siguientes variables:
- 044235.000 representa la hora GMT (04:42:35)
- “A” es la indicación de que el dato de posición está fijado y es correcto. “V” sería no válido
- 4322.0289 representa la longitud (43º 22.0289´)
- N representa el Norte
- 00824.5210 representa la latitud (8º 24.5210´)
- W representa el Oeste
- 0.39 representa la velocidad en nudos
- 65.46 representa la orientación en grados
- 020615 representa la fecha (2 de Junio del 2015)

Como vimos, de la trama de datos que nos envía nuestro módulo GPS podemos obtener varias
variables, siendo las importantes para proyectos de posicionamiento la latitud y la longitud. Para ello,
vamos a hacer uso de la librería TinyGPS que la podemos descargar de aquí:
https://github.com/mikalhart/TinyGPS
Recuerde que una vez descargada la Libreria, tenemos que importarla copiándola en la carpeta
“Libraries” donde se instaló nuestro IDE de Arduino y luego reiniciar el programa para que sea
cargada correctamente. La librería TinyGPS nos facilitará la identificación tanto de la latitud y
longitud, así como las otras variables descritas anteriormente sin tener que recurrir a algoritmos
complejos para lograr obtenerlas. Para ello ejecutamos un sencillo ejemplo que nos provee la librería,
para lo cual nos vamos a Archivo/Ejemplos/TinyGPS/simple_test en nuestro IDE de Arduino.

A continuación, nos aseguramos de cambiar la velocidad de lectura del puerto serie emulado a 9600
baudios y cargamos nuestro código a nuestra tarjeta Arduino.

Finalmente, podremos abrir nuestro Monitor serial y visualizar las variables mencionadas tal como
se pueden ver en la siguiente imagen:
Drivers genericos para arduino (CH340)
Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 04 Enero 2016
Visto: 1965

Voto 5 Votar
Por favor, vote

En esta entrada proporcionamos los controladores para algunas tarjetas arduino muy económicas y
genericas que existen en tarjetas nano, uno y mega.
Por lo que todo lo que se menciona aquí sirve para cualquier modelo.
Las tarjetas compatibles con arduino reemplazan el tracional FT232RL o el ATMEGA16u2 por
un circuito integrado conocido como CH340. El driver CH340 es el software requerido para
operar el circuito integrado de la interfaz USB en varios sistemas operativos (windows, linux, MAC,
etc.). El driver CH340 se encuentra disponible para
su descarga más abajo. Proporcionamos también las instrucciones para su instalación en Windows,
Linux y MAC a manera de apoyo para nuestros clientes que adquieren estas tarjetas.
Atención: Si deseas pasar a la descarga del driver, los enlaces se encuentran al final de la
página.

Instalación del driver CH340 en Windows


1. Descomprimir el archivo ZIP en una carpeta, encontraremos 2 carpetas. Abrir la carpeta
CH341SER que es la que contiene el instalador del driver CH340

2. Ejecutar
el programa de instalación o “setup.exe”. El sistema operativo puede preguntarnos si confiamos en
el proveedor del software, en este caso debemos aceptar.
3. Después de copiar los drivers, el programa de instalación nos notificará que se ha completado la
instalación

4. Conectamos el arduino a la PC y esperamos a que Windows detecte e instale los drivers para el
dispositivo conectado.

5. Abrimos el administrador de dispositivos (click derecho en equipo > Propiedades > Administrador
de Dispositivos) para comprobar que el driver haya sido correctamente instalado, también podemos
ver el número de puerto serie que ha sido asignado (en este caso COM14).
Descarga del driver CH340 para arduino genéricos
A continuación los enlaces de descarga para el driver CH340:

 Descarga del driver para Windows


 Descarga del driver para MAC
 Descarga del driver para Linux

ATENCION, si tenéis problemas para descargas estos archivos con Internet Explorer, usar un
explorador alternativo como Chrome, Firefox...

Tutorial Sensor Barométrico BMP180 con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 28 Diciembre 2015
Visto: 1307

Voto 5 Votar
Por favor, vote

En este tutorial se aprenderá a utilizar el sensor BMp180, con el cual se puede obtener presión
atmosférica, temperatura y altitud relativa.
El sensor BMP180 es un sensor de presión atmosférica de alta precisión, este dispositivo está
diseñado para ser conectado directamente a un microcontrolador de un dispositivo móvil a través de
I2C. Los datos de presión y la temperatura tienen que ser compensado por los datos de calibración
del E2PROM del BMP180.
Características del Sensor BMP180

 Digital interfaz de dos cables (I2C)


 Amplio rango de medición de presión barométrica
 Ultra-bajo consumo de energía
 Bajo ruido
 Completamente calibrado
 Medición de temperatura incluida
 Ultraplano y pequeño tamaño
 Alimentación: 1.8V – 3.6V
 Rango de medición: 300 – 1100hPa
 Velocidad del protocolo máxima: 3.4 MHz.

Datos de lo Pines

Conexión BMP180 al Arduino.


El código que se utilizara es el siguiente. Este código está basado en uno de los ejemplos que vienen
con la librería. Por lo cual sera necesario descargar la librería y guardarla en la carpeta de librerías de
Arduino IDE.
Descargar Librería

Codigo:
#include <SFE_BMP180.h>
#include <Wire.h>
//Se declara una instancia de la librería
SFE_BMP180 pressure;
//Se declaran las variables. Es necesario tomar en cuenta una presión inicial
//esta será la presión que se tome en cuenta en el cálculo de la diferencia de altura
double PresionBase;
//Leeremos presión y temperatura. Calcularemos la diferencia de altura
double Presion = 0;
double Altura = 0;
double Temperatura = 0;
char status;
void setup() {
Serial.begin(9600);
//Se inicia el sensor y se hace una lectura inicial
SensorStart();
}
void loop() {
//Se hace lectura del sensor
ReadSensor();
//Se imprimen las variables
Serial.println(" ////// ");
Serial.print("Temperatura: ");
Serial.print(Temperatura);
Serial.println(" grados C");
Serial.print("Presion: ");
Serial.print(Presion);
Serial.println(" milibares");
Serial.print("Altura relativa: ");
Serial.print(Altura);
Serial.println(" metros");
delay(10000);
//Cada 10 segundos hará una nueva lectura
}
void SensorStart() {
//Secuencia de inicio del sensor
if (pressure.begin())
Serial.println("BMP180 init success");
else
{
Serial.println("BMP180 init fail (disconnected?)\n\n");
while (1);
}
//Se inicia la lectura de temperatura
status = pressure.startTemperature();
if (status != 0) {
delay(status);
//Se lee una temperatura inicial
status = pressure.getTemperature(Temperatura);
if (status != 0) {
//Se inicia la lectura de presiones
status = pressure.startPressure(3);
if (status != 0)
{
delay(status);
//Se lee la presión inicial incidente sobre el sensor en la primera ejecución
status = pressure.getPressure(PresionBase, Temperatura);
}
}
}
}
void ReadSensor() {
//En este método se hacen las lecturas de presión y temperatura y se calcula la altura
//Se inicia la lectura de temperatura
status = pressure.startTemperature();
if (status != 0)
{
delay(status);
//Se realiza la lectura de temperatura
status = pressure.getTemperature(Temperatura);
if (status != 0)
{
//Se inicia la lectura de presión
status = pressure.startPressure(3);
if (status != 0)
{
delay(status);
//Se lleva a cabo la lectura de presión,</span>
//considerando la temperatura que afecta el desempeño del sensor</span>
status = pressure.getPressure(Presion, Temperatura);
if (status != 0)
{
//Cálculo de la altura en base a la presión leída en el Setup
Altura = pressure.altitude(Presion, PresionBase);
}
else Serial.println("Error en la lectura de presion\n");
}
else Serial.println("Error iniciando la lectura de presion\n");
}
else Serial.println("Error en la lectura de temperatura\n");
}
else Serial.println("Error iniciando la lectura de temperatura\n");
}

Una vez cargado el programa desde Arduino IDE hacia la tarjeta Arduino, haga clic
en Herramientas y después clic en Monitor Serie, para mostrara los valores adquiridos como
se muestra en la siguiente imagen.

Nota: Si manda un
error en lugar de los valores adquiridos, revise que la conexión de la tarjeta del sensor barométrico
hacia la tarjeta Arduino se encuentren de manera correcta.

Quemando Bootloader con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 18 Noviembre 2015
Visto: 1189

Voto 5 Votar
Por favor, vote

Una solución ante las siguiente interrogantes o incovenientes sobre ¿si es


posible cambiar el microcontrolador dañado en el arduino? o si necesitas
otro microcontrolador para realizar un proyecto pero necesitas tener que
comprar otro arduino uno.

En estas situaciones tal vez lo que más nos convenga sea emplear
únicamente el Atmega 328p, solo el microcontrolador y no toda la
plataforma. Para que un Atmega 328p se necesita grabar el bootloader o el
gesto de arranque, se puede hacer con un programador externo
o también con un Arduino uno, en este caso utilizaremos un Arduino uno
para dicho propósito. Siempre y cuando haya comprado Atmegas vírgenes,
claro esta que actualmente es habitual encontrar los Atmega con el
bootloader ya cargado.

Materiales:

 1x Arduino Uno
 1x ATMega328P-PU / ATMega328-PU (preferiblemente el primero)
 1x Cristal de cuarzo a 16Mhz
 2x Condensadores 18-22pF
 1x Resistencia 10kΩ
 3x Resistencias de 220-330Ω (para los LEDs)
 1x Resistencia ~120Ω (110-124Ω,)
 1x Condensador 10uF

Paso1: Lo primero de todo es cargar en nuestro Arduino el programa


ArduinoISP, que viene de serie con el IDE.
Cuando haya terminado de cargar la comunicación ISP en el arduino,
continuamos.

Paso2: Implementar en siguiente esquema:


Si todo ha ido bien, al alimentar con USB la placa el LED verde comenzará
a “latir”.

Paso3: Ahora llega la parte interesante: cómo grabar el bootloader. Como


hemos visto, existen dos modelos de ATMega328 con encapsulado DIP:
El ATMega328-PU y el ATMega328P-PU. Arduino emplea estos últimos,
cuya única diferencia con los primeros es que cuentan con la tecnología
picopower.
Para atmega 328: Es preciso modificar un archivo de configuración del
entorno de Arduino para “engañarlo” y que piense que se trata del otro
modelo de chip.

Para ello, sólo hay que abrir el archivo avrdude.conf, que se encuentra en
hardware/tools/avr/etc/ y encontrar hacia la segunda mitad del archivo la
línea 9245:
signature = 0x1e 0×95 0x0F;
oe en el caso q q este desordenado el block de notas lo buscas así:
signature = 0x1e 0x95 0x0F;
y cambiarla por ésta (lo que viene siendo reemplazar el 0F por un 14):
signature = 0x1e 0×95 0×14;
guardalo y ciérralo.
Para atmega 328p: Se omite el paso 3

Paso4: Configuramos para grabar como ISP.

El siguiente esquema nos indica como grabar el bootloader.

Esperamos a hasta que termine de grabar.

Paso5: Revertimos el paso 3 cambiamos:

signature = 0x1e 0×95 0×14;


Por:
signature = 0x1e 0×95 0x0F;
guardamos y listo. ya podemos quemar le chip con el arduino.

Carga Usando una placa Arduino


Una vez que su ATMEGA328P tiene el bootloader Arduino en él, usted
puede cargar programas para usar el convertidor de USB a serie (chip
FTDI) en una placa Arduino. Para ello, se elimina el microcontrolador de
la placa Arduino por lo que el chip FTDI puede hablar con el
microcontrolador en el tablero en su lugar. El diagrama de la derecha
muestra cómo conectar el RX y TX líneas de la placa Arduino con
el ATmega en la protoboard. Para programar el microcontrolador,
seleccione "Arduino Duemilanove w o nano / ATmega328 "del los menú
Herramientas> Board (o" ATmega328 en una placa (8 MHz de reloj
interno) "si usted está utilizando la configuración mínima se describe a
continuación). A continuación, subir como de costumbre.

Carga de bocetos para un ATmega en una placa. Recuerde quitar el


microcontrolador de la placa Arduino!.

Practica Arduino con giroscopo L3GD20


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 10 Noviembre 2015
Visto: 1870

Voto 5 Votar
Por favor, vote
¿Sabes qué es un giroscopio? Bueno, imagino que has escuchado de ellos, si tienes un Smartphone
o una consola Wii sabes qué son. Qué pensabas que hacía que tu celular girara la pantalla cuando
lo movías? o cuando rotabas tu cámara fotográfica y cambiaba la vista de la foto? o cuando juegas
en el Wii y mueves los controles para poder rescatar a la princesa Peach en Mario Kart? o cuando...
bueno ya me entendiste.
Básicamente podemos usar cualquier giroscopio pero esta vez usaremos el L3GD20 que tiene muy
buena precisión y será muy fácil de programar con Arduino gracias a la librería que han creado para
él.
Lo primero que te diré es que los giroscopios miden la velocidad angular, difícil? quiere decir que
pueden medir la velocidad a la que gira un objeto en el espacio. Así como medirías una velocidad
lineal en metros por segundo (m/s) ó en los carros en Kilómetros por hora (Km/h) pues en estos
sensores obtienes medida de grados por segundo (°/s). ¿Grados? sí, de los grados que mides con
un transportador.
Ahora yo te pregunto ¿has jugado al trompo o peonza? si eres muy joven puede que no sepas con
qué es eso :S averígualo!. Pues te lo pregunto porque mucha de la física que se encuentra cuando
sueltas el trompo y se mantiene girando se usa en el giroscopio, principalmente la inercia. La inercia
es lo que hace que el trompo gire y que el giroscopio mida la velocidad de giro. Puedes leer más de

este sorprendente efecto aqui.


También tendrás que saber que el L3GD20 es un giroscopio de tres ejes de gran precisión con
regulador de voltaje incluido en la placa. La mayoría de estos sensores funcionan a 3.3V así que
gracias al regulador lo puedes alimentar desde 2.5V a 5.5V. Que no se te ocurra colocarle un mayor
voltaje al que te digo! o sino tendrás un agradable olor a semiconductor quemado :(
Cuando dice que es de tres ejes significa que el giro lo puedes medir en tres direcciones por
separado: X, Y y Z que es la convención más común en física y matemática.
Para empezar con lo práctico necesitaremos varias cosas. Estás listo? Entonces ve marcando lo que
ya tienes de esta lista:
1. El giroscopio L3GD20.
2. Un Arduino Uno con su cable USB.
3. Arduino IDE (el entorno de desarrollo).
4. Librería del sensor para Arduino, descárgala aqui!
5. Cablecitos de protoboard.
6. Muchas ganas de aprender :)
Para que no tengas problemas instalando la librería del sensor en Arduino te recomiendo que mires

este rápido tutor ial de cómo hacerlo.

Este sensor es digital y se comunica por medio de I 2C/SPI, así lograrás una comunicación con sólo
dos cables con el microcontrolador. Es por esto que las conexiones que tendrás que hacer
son las siguientes:
Arduino --- L3GD20
SDA <-> SDA
SCL <-> SDA
5V <-> VIN
GND <-> GND
Una vez tengas esas conexiones vamos a hacer el programa. Para eso necesitas
saber que vamos a hacer dos mediciones distintas del sensor con el programa. Sí,
vamos a medir la velocida angular y los grados que se ha movido el giroscopio. Pero
si el sensor sólo nos da valored de velocidad cómo medir los grados? bueno
recordarás de física que realizas la integración de la velocidad angular obtienes el
desplazamiento angular o los grados que se ha movido.

Por último te mostraré el código que


va en tu Arduino para que se realicen los cálculos que te he dicho y el programa te muestre los
valores de velocidad angular y posición en grados por cada eje.
/* Giroscopio L3GD20
* Este programa está diseñado para establecer comunicación
* con el giroscopio por medio de SPI y obtener los valores
* de aceleración angular. Con los valores obtenidos se realiza
* una corrección del offset, cálculo del nivel de ruido y la
* integración de la velocidad para obtener los grados.
*/

// Se incluyen las librerías necesarias


#include <Wire.h>
#include <L3G.h>

L3G gyro; // Declaración del giroscopio

int sampleNum=500; // Número de muestras para el promediar el offset

// Declaración de variables de offset y ruido


int dc_offsetX=0; // Offset en X
double noiseX=0; // Nivel de ruido en X

int dc_offsetY=0; // Offset en Y


double noiseY=0; // Nivel de ruido en Y

int dc_offsetZ=0; // Offset en Z


double noiseZ=0; // Nivel de ruido en Z

// Declaración de variables para muestras de la velocidad


unsigned long time;
int sampleTime=10;
int rateX; // Medición actual de velocidad X
int rateY; // Medición actual de velocidad Y
int rateZ; // Medición actual de velocidad Z

// Declaración de variables para medición del ángulo


int prev_rateX=0; // Medición previa de velocidad X
double angleX=0; // Valor del ángulo en Z

int prev_rateY=0; // Medición previa de velocidad Y


double angleY=0; // Valor del ángulo en Y

int prev_rateZ=0; // Medición previa de velocidad Z


double angleZ=0; // Valor del ángulo en Z

// Bloque de configuración
void setup() {
Serial.begin(9600); // Se abre la comunicación con el PC
Wire.begin(); // Se abre la comunicación con el sensor

// Si no hay respuesta del sensor se muestra un mensaje y


// el programa se detiene
if (!gyro.init())
{
Serial.println("Ha fallado la comunicacion con el sensor");
while (1);
}

gyro.enableDefault(); // Si hay comunicación se configura


// por defecto el sensor
calculoOffset(); // Función para calcular el offset de cada eje
}

// Bloque de Programa
void loop() {
if(millis() - time > sampleTime)
{
time = millis(); // Tiempo de la próxima actualización
gyro.read(); // Lectura de medición de velocidad

// **********************************
rateX=((int)gyro.g.x-dc_offsetX)/100; // Calculo de la velocidad X en °/s

// Sumatoria (integración) de la velocidad para el calculo de grados X


angleX += ((double)(prev_rateX + rateX) * sampleTime) / 2000;

prev_rateX = rateX; // Se debe recordar una muestra previa de velocidad


// Se coloca el ángulo recorrido en una escala de 0 a 360 grados
if (angleX < 0){
angleX += 360;
}
else if (angleX >= 360)
{
angleX -= 360;
}

// **********************************
rateY=((int)gyro.g.y-dc_offsetY)/100; // Calculo de la velocidad Y en °/s

// Sumatoria (integración) de la velocidad para el calculo de grados Y


angleY += ((double)(prev_rateY + rateY) * sampleTime) / 2000;

prev_rateY = rateY; // Se debe recordar una muestra previa de velocidad


// Se coloca el ángulo recorrido en una escala de 0 a 360 grados
if (angleY < 0){
angleY += 360;
}
else if (angleY >= 360)
{
angleY -= 360;
}

// **********************************
rateZ=((int)gyro.g.z-dc_offsetZ)/100; // Calculo de la velocidad Z en °/s

// Sumatoria (integración) de la velocidad para el calculo de grados Z


angleZ += ((double)(prev_rateZ + rateZ) * sampleTime) / 2000;

prev_rateZ = rateZ; // Se debe recordar una muestra previa de velocidad


// Se coloca el ángulo recorrido en una escala de 0 a 360 grados
if (angleZ < 0){
angleZ += 360;
}
else if (angleZ >= 360)
{
angleZ -= 360;
}

// Impresión de los datos por consola


Serial.print("AnguloZ: ");
Serial.print(angleZ);
Serial.print("\tVelZ: ");
Serial.print(rateZ);

Serial.print("\tAnguloY: ");
Serial.print(angleY);
Serial.print("\tVelY: ");
Serial.println(rateY);

Serial.print("\tAnguloX: ");
Serial.print(angleX);
Serial.print("\tVelX: ");
Serial.println(rateX);
}
}

// Función del cálculo de Offset y nivel de ruido


void calculoOffset(){

//**************************************
// Promedio de muestras
for(int n=0;n<sampleNum;n++){
gyro.read();
dc_offsetX+=(int)gyro.g.x;
}
dc_offsetX=dc_offsetX/sampleNum;

// Calculo de nivel de ruido


for(int n=0;n<sampleNum;n++){
gyro.read();
if((int)gyro.g.x-dc_offsetY>noiseX)
noiseX=(int)gyro.g.x-dc_offsetX;
else if((int)gyro.g.x-dc_offsetX<-noiseX)
noiseX=-(int)gyro.g.x-dc_offsetX;
}
noiseX=noiseX/100;

//**************************************
// Promedio de muestras
for(int n=0;n<sampleNum;n++){
gyro.read();
dc_offsetY+=(int)gyro.g.y;
}
dc_offsetY=dc_offsetY/sampleNum;

// Calculo de nivel de ruido


for(int n=0;n<sampleNum;n++){
gyro.read();
if((int)gyro.g.y-dc_offsetY>noiseY)
noiseY=(int)gyro.g.y-dc_offsetY;
else if((int)gyro.g.y-dc_offsetY<-noiseY)
noiseY=-(int)gyro.g.y-dc_offsetY;
}
noiseY=noiseY/100;

//**************************************
// Promedio de muestras
for(int n=0;n<sampleNum;n++){
gyro.read();
dc_offsetZ+=(int)gyro.g.z;
}
dc_offsetZ=dc_offsetZ/sampleNum;

// Calculo de nivel de ruido


for(int n=0;n<sampleNum;n++){
gyro.read();
if((int)gyro.g.z-dc_offsetZ>noiseZ)
noiseZ=(int)gyro.g.z-dc_offsetZ;
else if((int)gyro.g.z-dc_offsetZ<-noiseZ)
noiseZ=-(int)gyro.g.z-dc_offsetZ;
}
noiseZ=noiseZ/100;
}

Sensor de presión atmosférica, con Arduino y GY-68, BMP180


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 05 Noviembre 2015
Visto: 3917

Voto 5 Votar
Por favor, vote

Hoy traemos para ustedes un sencillo tutorial sobre el uso del sensor BMP180, que nos permite
medir presión atmosférica/barométrica y diferencias de alturas entre dos puntos.
Antes de empezar a explicar el funcionamiento del sensor BMP180, me gustaría introducir el
concepto de presión atmosférica o barométrica.
Citaré un artículo de Wikipedia con algunos conceptos sobre este tema.
La presión atmosférica es la fuerza por unidad de superficie que ejerce el aire sobre la superficie
terrestre.
La presión atmosférica en un punto coincide numéricamente con el peso de una columna estática
de aire de sección recta unitaria que se extiende desde ese punto hasta el límite superior de la
atmósfera. Como la densidad del aire disminuye conforme aumenta la altura, no se puede calcular
ese peso a menos que seamos capaces de expresar la variación de la densidad del aire ρ en función
de la altitud z o de la presión p. Por ello, no resulta fácil hacer un cálculo exacto de la presión
atmosférica sobre un lugar de la superficie terrestre. Además tanto la temperatura como la presión
del aire están variando continuamente, en una escala temporal como espacial, dificultando el cálculo.
Podemos obtener una medida de la presión atmosférica en un lugar determina
do pero con ella no se pueden obtener muchas
conclusiones: es la variación de dicha presión a lo largo del tiempo lo que nos permite obtener una
información útil que, unida a otros datos meteorológicos (temperatura atmosférica, humedad y
vientos) nos da una imagen bastante acertada del tiempo atmosférico en dicho lugar e incluso un
pronóstico a corto plazo del mismo.
En pocas palabras, la presión atmosférica se da por la columna de aire que existe sobre nosotros.
La misma está en función de la altura y relacionada con las condiciones meteorológicas de
determinado lugar en determinado momento.
El sensor BMP180 es un sensor de presión atmosférica de alta precisión. En la hoja de datos del
dispositivo se detalla esta información.
Se utiliza la interfaz I2C para comunicación. Las conexiones de este sensor son muy sencillas:

Para el uso de
este sensor existe una librería llamada BMP180, la cual podemos descargar aquí. También podemos
consultar los archivos de la librería en Github.
Vamos a probar nuestro sensor. Primero hacemos las conexiones siguiendo la tabla de la parte
superior.
El sensor BMP180 es capaz de leer presión barométrica (absoluta) y temperatura. Por medio de
cálculos matemáticos es capaz de detectar diferencias de alturas. ¿Cómo? Pues como ya
mencionamos la Presión Atmosférica o Barométrica es inversamente proporcional a la altura sobre
el nivel del mar, es decir, a medida que nos elevamos decrece la presión. Por eso es que cuando
viajamos por carreteras que atraviesan colinas o montañas sentimos que nuestros oídos se tapan al
descender. Esto se debe a que la presión atmosférica aumenta y sentimos el efecto del aumento en
la presión. En el código que presentaré se hará una lectura inicial de la presión barométrica,
expresada en milibares. A medida que nos desplacemos hacia un punto más alto o más bajo el
sensor medirá la diferencia en la presión y la expresará como una variación en la altitud a la cual se
encuentra el sensor con respecto a la medición inicial que será considerada como 0.
Conectemos nuestro sensor al Arduino.

Ahora el código que vamos a utilizar es el siguiente.


Nota: este código está basado en uno de los ejemplos que vienen con la librería; lo he simplificado
y las instrucciones están en español. El ejemplo original está en la carpeta “Examples” dentro del
archivo de la librería y ha sido adaptado a las condiciones locales del almacén de Sparkfun en
Colorado.
// Se importan las librerías
#include <SFE_BMP180.h>
#include <Wire.h>
//Se declara una instancia de la librería
SFE_BMP180 pressure;
//Se declaran las variables. Es necesario tomar en cuenta una presión inicial
//esta será la presión que se tome en cuenta en el cálculo de la diferencia de altura
double PresionBase;

//Leeremos presión y temperatura. Calcularemos la diferencia de altura


double Presion = 0;
double Altura = 0;
double Temperatura = 0;
char status;
void setup() {
Serial.begin(9600);
//Se inicia el sensor y se hace una lectura inicial
SensorStart();
}
void loop() {
//Se hace lectura del sensor
ReadSensor();
//Se imprimen las variables
Serial.println(" ////// ");
Serial.print("Temperatura: ");
Serial.print(Temperatura);
Serial.println(" grados C");
Serial.print("Presion: ");
Serial.print(Presion);
Serial.println(" milibares");
Serial.print("Altura relativa: ");
Serial.print(Altura);
Serial.println(" metros");
delay(2000);
}
void SensorStart() {
//Secuencia de inicio del sensor
if (pressure.begin())
Serial.println("BMP180 init success");
else
{
Serial.println("BMP180 init fail (disconnected?)\n\n");
while (1);
}
//Se inicia la lectura
de temperatura
status = pressure.startTemperature();
if (status != 0) {
delay(status);
//Se lee una temperatura inicial
status = pressure.getTemperature(Temperatura);
if (status != 0) {
//Se inicia la lectura de presiones
status = pressure.startPressure(3);
if (status != 0) {
delay(status);
//Se lee la presión inicial incidente sobre el sensor en la primera ejecución
status = pressure.getPressure(PresionBase, Temperatura);
}
}
}
}
void ReadSensor() {
//En este método se hacen las lecturas de presión y temperatura y se calcula la altura
//Se inicia la lectura de temperatura
status = pressure.startTemperature();
if (status != 0)
{
delay(status);
//Se realiza la lectura de temperatura
status = pressure.getTemperature(Temperatura);
if (status != 0)
{
//Se inicia la lectura de presión
status = pressure.startPressure(3);
if (status != 0)
{
delay(status);
//Se lleva a cabo la lectura de presión,
//considerando la temperatura que afecta el desempeño del sensor
status = pressure.getPressure(Presion, Temperatura);
if (status != 0)
{
//Se hace el cálculo de la altura en base a la presión leída en el Setup
Altura = pressure.altitude(Presion, PresionBase);
}
else Serial.println("error en la lectura de presion\n");
}
else Serial.println("error iniciando la lectura de presion\n");
}
else Serial.println("error en la lectura de temperatura\n");
}
else Serial.println("error iniciando la lectura de temperatura\n");
}
El resultado que obtendremos en el Monitor Serial, cada 2 segundos es el siguiente.
Practica con Arduino y brújula hmc5883L
Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 06 Octubre 2015
Visto: 4834

Voto 5 Votar
Por favor, vote

Hoy os traemos este tutorial para aprender a detectar los puntos cardinales usando una brújula digital
hmc5883L con nuestro Arduino. Esta brújula es capaz de detectar el campo magnético en los ejes
x,y,z. Tendremos que tener en cuenta que la brújula es sensible a los campos magnéticos que la
rodea, por lo tanto si tenemos metales o dispositivos cerca puede influir en el comportamiento del
chip. Usaremos la brújula para detectar el campo magnético terrestre y
así saber donde se encuentra el Sur magnético y por consiguiente saber donde esta el Norte el Este
y el Oeste.
nota: tener en cuenta que el Sur magnético no es lo mismo que el Sur geográfico. Para más info
miraros Wikipedia xD. También hay que tener en cuenta que el sensor detecta los campos
magnéticos en el eje z, por lo tanto lo tenemos que colocar lo más paralelo posible al suelo para
obtener una mayor precisión.
Después del apartado teórico vamos a la práctica. Usaremos dos resistencias de 2.2k tal y como
recomienda el datasheet del sensor entre los pines Vcc-SDA y Vcc-SCL. El pin Vcc deberá ir a la
entrada de 3.3V de nuestro Arduino ya que el sensor necesita un voltaje entre 2.16 a 3.6. Ya que el
sensor funciona mediante I2C, estos es, línea de datos SDA y línea de reloj SCL tenemos que usar
los Pines A4 y A5 de nuestro Arduino respectivamente. Aquí tenemos como vamos a conectar los
pines del sensor a nuestro Arduino.

Antes de programar vamos a necesitar dos librerías.


1- Wire.h que nos permite comunicarnos con el sensor, encontraremos esta librería ya incluida en el
IDE de Arduino. Mas información sobre la librería aquí.
2- hmc5883l.h la librería para controlar el chip en Arduino aquí.
Ahora vamos a programar nuestro Arduino para saber a cuantos grados nos encontramos del Sur
magnético, para ello escribiremos este pequeño ejemplo:

#include <Wire.h>

#include <HMC5883L.h>

HMC5883L brujula; //declaramos la variable

int error = 0; // para detectar algun error en la brujula

void setup(){

// Initialize the serial port.

Serial.begin(9600);

Wire.begin(); // iniciamos el interfaz I2C

brujula = HMC5883L(); // iniciamos la instancia de la brujula

error = brujula.SetScale(1.3); // indicamos la escala que vamos a usar

if(error != 0){

Serial.println(brujula.GetErrorText(error));

}
error = brujula.SetMeasurementMode(Measurement_Continuous);

if(error != 0){

Serial.println(brujula.GetErrorText(error));

void loop(){

MagnetometerRaw raw = brujula.ReadRawAxis(); // recibimos el valor del RAW sin escalar

MagnetometerScaled scaled = brujula.ReadScaledAxis(); // recibimos el valor escalado con


la configuracion eleg

float angulo = atan2(scaled.YAxis, scaled.XAxis) * (180 / 3.14159265) + 180; // arcotang


ete x y. sacamos el angulo en grado

if((angulo < 22.5) || (angulo > 337.5 )){

Serial.print("Sur");

if((angulo > 22.5) && (angulo < 67.5 )){

Serial.print("Suroeste");

if((angulo > 67.5) && (angulo < 112.5 )){

Serial.print("Oeste");

if((angulo > 112.5) && (angulo < 157.5 )){

Serial.print("Noroeste");

if((angulo > 157.5) && (angulo < 202.5 )){

Serial.print("Norte");

if((angulo > 202.5) && (angulo < 247.5 )){

Serial.print("Noreste");

if((angulo > 247.5) && (angulo < 292.5 )){

Serial.print("Este");

if((angulo > 292.5) && (angulo < 337.5 )){

Serial.print("Sureste");
}

delay(100);

Este es el código que nos ayudará a detectar los puntos cardinales, recordad que estamos sobre los
campos magnéticos de la tierra y por lo tanto no coinciden del todo con las coordenadas geográficas.
En el código vemos como calculamos el ángulo y según éste decidimos a que coordenada
corresponde, el significado de los ifs plasmado en una imagen sería:

Genera melodias y descubre como usar un zumbador con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 14 Septiembre 2015
Visto: 2669

Voto 5 Votar
Por favor, vote

Un zumbador es un elemento parecido a un altavoz pero sólo emite zumbidos (típico sonido que
emiten los electrodomésticos).
Para hacerlo sonar utilizaremos los pines 13 y GND.
Sonidos con Arduino

Función tone
Con Arduino también podemos crear sonidos gracias a la función tone cuya sintaxis es la siguiente

tone(pinsalida,frecuencia);

Esta función lo que hace es intercambiar valores HIGH/LOW a la frecuencia deseada en el pin
seleccionado hasta que la volvemos a llamar con otra frecuencia o le ordenamos que pare con esta
función

noTone(pinsalida);
Tenemos que tener en cuenta que sólo es capaz de generar un único tono a la vez. Si llamamos
a la función tone para que genere sonidos en otro pin sin haber detenido el que está sonando no
ocurrirá nada.
En la función loop hacemos la llamada a tone para que suene y noTone para detener el sonido.
Cambiando los valores de la función delay haremos que suene durante más o menos tiempo.

int pinzumbador = 13; // pin del zumbador


int frecuencia = 220; // frecuencia correspondiente a la nota La

void setup()
{
}

void loop()
{
tone(pinzumbador,frecuencia); // inicia el zumbido
delay(2000);
noTone(pinzumbador); // lo detiene a los dos segundos
delay(1000);
}
Podemos observar dos cosas:

•Al cargar el programa suena brevemente el zumbador. Esto se debe a que utilizamos el pin 13 y
éste se pone a HIGH brevemente unas veces cuando se inicia la placa.

•Si variamos la frecuencia a penas varía el tono o no suena. La causa de ésto es que un zumbador
tiene poca capacidad para reproducir sonidos fielmente. La frecuencia influye tan poco que incluso
sonaría conectándolo entre los pines 5V y GND. Para frecuencias demasiado altas el zumbador no
responde.

Música
En este punto utilizaremos un pequeño altavoz. Podéis aprovechar uno que tengáis en algún aparato
que no utilicéis.
El mismo montaje servirá para los dos ejemplos siguientes. El primero consistirá en reproducir una
escala de 220 a 440 HZ con todos sus semitonos. En el segundo reproduciremos música.

Si os fijáis en el esquema he puesto un condensador en serie con el altavoz. Ésto es para eliminar
cualquier componente de continua. Tened en cuenta que si elegís valores muy pequeños puede
recortar las frecuencias más bajas. Con valores de 47 uF o mayores va bien. IMPORTANTE: Si usáis
condensadores electrolíticos (los cilíndricos) tenéis que tener en cuenta que tienen polaridad y si lo
colocáis al revés pueden explotar. Fijaros que tienen una franja con signos “-” en la pata negativa.
Vamos con el primer ejemplo. Para no almacenar todas las frecuencias y tener que escribir la
función tone en nuestro código cada vez que queramos una nueva nota, haremos un pequeño truco.
Almacenaremos sólo el valor de la frecuencia inicial, y las sucesivas notas tendrán la frecuencia de
la anterior multiplicada por 1,059. De este modo escribiremos una sola vez la función para hacerlo
sonar y un bucle for será el encargado de ir incrementando el valor de la frecuencia.
/***********************/
/* recorrido de octava */
/***********************/

int pinaltavoz = 13;


int frecuencia=220; // frecuencia correspondiente a la nota La
int contador; // variable para el contador
float m=1.059; // constante para multiplicar frecuencias

void setup()
{
}

void loop()
{
for(contador=0,frecuencia=220;contador<12;contador++)
{
frecuencia=frecuencia*m; // actualiza la frecuencia
tone(pinaltavoz,frecuencia); // emite el tono
delay(1500); // lo mantiene 1.5 segundos
noTone(pinaltavoz); // para el tono
delay(500); // espera medio segundo
}
}

Ahora pasamos a lo bueno: reproducir música, pero de la que recuerda a los videojuegos con
música de 8 bits.
En este código utilizaremos una función auxiliar que llamaremos nota con la siguiente estructura

nota(frecuencia,duración);
La ventaja es que nos ahorrará escribir decenas de veces la función delay para para indicar el tiempo
que debe durar la nota. Cada vez que llamemos a esa función se ejecutará esta parte del código

void nota(int frec, int t)


{
tone(spk,frec); // suena la nota frec recibida
delay(t); // para despues de un tiempo t
}
Os dejo varios fragmentos de canciones. Podéis buscar partituras de canciones y pasar las notas a
frecuencia y tiempo.

/**************************/
/* popurri para Arduino */
/**************************/

/**************** Antonio Guillermo Pérez Coronilla ***************/

/* declaración de variables */
int spk=13; // altavoz a GND y pin 13
int c[5]={131,262,523,1046,2093}; // frecuencias 4 octavas de Do
int cs[5]={139,277,554,1108,2217}; // Do#
int d[5]={147,294,587,1175,2349}; // Re
int ds[5]={156,311,622,1244,2489}; // Re#
int e[5]={165,330,659,1319,2637}; // Mi
int f[5]={175,349,698,1397,2794}; // Fa
int fs[5]={185,370,740,1480,2960}; // Fa#
int g[5]={196,392,784,1568,3136}; // Sol
int gs[5]={208,415,831,1661,3322}; // Sol#
int a[5]={220,440,880,1760,3520}; // La
int as[5]={233,466,932,1866,3729}; // La#
int b[5]={247,494,988,1976,3951}; // Si

void nota(int a, int b); // declaracion de la funcion auxiliar. Recibe dos numeros enteros.

void setup()
{
/**************************************/
/* HARRY POTTER */
/**************************************/
nota(b[2], 500);
nota(e[3],1000);
nota(g[3], 250);
nota(fs[3],250);
nota(e[3],1000);
nota(b[3],500);
nota(a[3],1250);
nota(fs[3],1000);
nota(b[2], 500);
nota(e[3],1000);
nota(g[3],250);
nota(fs[3],250);
nota(d[3],1000);
nota(e[3],500 );
nota(b[2],1000 );
noTone(spk); delay(1000);
nota(b[2], 500);
nota(e[3],1000);
nota(g[3], 250);
nota(fs[3],250);
nota(e[3],1000);
nota(b[3],500);
nota(d[4],1000);
nota(cs[4],500);
nota(c[4],1000);
nota(a[3],500);
nota(c[4],1000);
nota(b[3],250);
nota(as[3],250);
nota(b[2],1000);
nota(g[3],500);
nota(e[3],1000);
noTone(spk);
delay(2000);

/*******************/
/* STAR WARS */
/*******************/
/**** tema principal ****/
nota(d[1],150);noTone(spk);delay(50);
nota(d[1],150);noTone(spk);delay(50);
nota(d[1],150);noTone(spk);delay(50);
nota(g[1],900);noTone(spk);delay(150);
nota(d[2],900);noTone(spk);delay(50);
nota(c[2],150);noTone(spk);delay(50);
nota(b[1],150);noTone(spk);delay(50);
nota(a[1],150);noTone(spk);delay(50);
nota(g[2],900);noTone(spk);delay(150);
nota(d[2],900);noTone(spk);delay(100);
nota(c[2],150);noTone(spk);delay(50);
nota(b[1],150);noTone(spk);delay(50);
nota(a[1],150);noTone(spk);delay(50);
nota(g[2],900);noTone(spk);delay(150);
nota(d[2],900);noTone(spk);delay(100);
nota(c[2],150);noTone(spk);delay(50);
nota(b[1],150);noTone(spk);delay(50);
nota(c[2],150);noTone(spk);delay(50);
nota(a[1],1200);noTone(spk);delay(2000);

/**** marcha del imperio ****/


nota(g[2],500);noTone(spk);delay(100);
nota(g[2],500);noTone(spk);delay(100);
nota(g[2],500);noTone(spk);delay(100);
nota(ds[2],500);noTone(spk);delay(1);
nota(as[2],125);noTone(spk);delay(25);
nota(g[2],500);noTone(spk);delay(100);
nota(ds[2],500);noTone(spk);delay(1);
nota(as[2],125);noTone(spk);delay(25);
nota(g[2],500);
noTone(spk);delay(2000);

/**********************/
/* entre dos aguas */
/**********************/
nota(a[1],400);noTone(spk);delay(400);
nota(e[1],400);noTone(spk);delay(400);
nota(a[1],400);noTone(spk);delay(200);
nota(e[1],200);noTone(spk);delay(200);
nota(a[1],200);noTone(spk);delay(200);
nota(as[1],100);noTone(spk);delay(100);
nota(b[1],400);noTone(spk);delay(400);
nota(fs[1],400);noTone(spk);delay(400);
nota(b[1],400);noTone(spk);delay(200);
nota(fs[1],200);noTone(spk);delay(200);
nota(b[1],200);noTone(spk);delay(200);
nota(as[1],100);noTone(spk);delay(100);
nota(a[1],400);noTone(spk);delay(400);
nota(e[1],400);noTone(spk);delay(400);
nota(a[1],400);noTone(spk);delay(400);
}

void nota(int frec, int t)


{
tone(spk,frec); // suena la nota frec recibida
delay(t); // para despues de un tiempo t
}

void loop()
{
}
Presentación de otro tipo de montaje que podéis realizar con un zumbador, esta es mas básica pero
no menos importante.
Montaje de Circuito:

Enseguida mostrare el codigo del programa que sera subido al Arduino, en donde esta documentado
para entender la sintaxis.
/*---------------------------------------------
Generar sonido con un Buzzer
---------------------------------------------*/
//--------------------------------------------------
//Declarar puertos de entradas y salidas y variables
//--------------------------------------------------
int buzzer = 9; //Pin del buzzer
int tono = 0; //Pin del potenciometro
//-----------------------------------
//Funcion principal
//------------------------------------
void setup() // Se ejecuta cada vez que el Arduino se inicia
{
// No se configuran parametros inciales, pero se
//coloca la función setup()
}
//------------------------------------
//Funcion ciclicla
//------------------------------------
void loop() // Esta funcion se mantiene ejecutando
{ // cuando se da energia al Arduino

//Variable donde se almacena el valor del potenciometro


int sensor = analogRead(tono);

//Variable donde se escala la frecuencia de 100 a 5000Hz


int frecuencia = map(sensor,0,1023,100,5000);

//Variable para guardar el tiempo


int duracion = 250;

//Funcion tone() que recibe:


// 1ra posición: Pin del elemento sonoro
// 2da posición: Frecuencia en Hz
// 3ra posición: Duración del tono
tone(buzzer, frecuencia, duracion);

delay(100);
}
En el codigo anterior se documento, donde se muestra donde estan declarados los puertos de
entrada y salida, el ciclo que es usado para el potenciometro, la frecuencia y la duracion; al ultimo
se indica donde termina el programa.

Detector de movimiento con Arduino y sensor PIR


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 04 Septiembre 2015
Visto: 1559

Voto 5 Votar
Por favor, vote

¿Que es un sensor PIR?


Los sensores infrarrojos pasivos (PIR) son dispositivos para la detección de movimiento. Son
baratos, pequeños, de baja potencia, y fáciles de usar. Por esta razón son frecuentemente usados
en juguetes, aplicaciones domóticas o sistemas de seguridad.
Los sensores PIR se basan en la medición de la radiación infrarroja. Todos los cuerpos (vivos o
no) emiten una cierta cantidad de energía infrarroja, mayor cuanto es su temperatura. Los
dispositivos PIR disponen de un sensor piezo eléctrico que capta esta radiación y convertirla en una
señal eléctrica.

En realidad cada sensor dividido en dos campos y se dispone de un circuito eléctrico que
compensa ambas mediciones. Si ambos campos reciben la misma cantidad de infrarrojos la señal
eléctrica resultante es nula. Por el contrario, si los dos campos realizan una medición diferente, se
genera una señal eléctrica.
De esta forma, si un objeto atraviesa uno de los
campos se genera una señal eléctrica diferencial, que es captada por el sensor, y se emite una señal

digital.

El otro elemento restante para que todo funcione es la óptica del sensor. Básicamente es una
cúpula de plástico formada por lentes de fresnel, que divide el espacio en zonas, y enfoca la radiación
infrarroja a cada uno de los campos del PIR.
De esta manera, cada uno de los sensores capta un promedio de la radiación infrarroja del entorno.
Cuando un objeto entra en el rango del sensor, alguna de las zonas marcadas por la óptica recibirá
una cantidad distinta de radiación, que será captado por uno de los campos del sensor PIR,
disparando la alarma.
Esquema eléctrico
Este es el esquema de patillaje de un sensor PIR.

El esquema eléctrico que necesitamos es el siguiente.


Montaje
Mientras que el montaje en una protoboard sería el siguiente.
Ejemplo de código
El código necesario para realizar la lectura es simple. Simplemente leemos la salida del PIR, y
hacemos parpadear el LED mientras la señal esté activa.

1 const int LEDPin= 13;


2 const int PIRPin= 2;
3
4 void setup()
5 {
6 pinMode(LEDPin, OUTPUT);
7 pinMode(PIRPin, INPUT);
8 }
9
10 void loop()
11 {
12 int value= digitalRead(PIRPin);
13
14 if (value == HIGH)
15 {
16 digitalWrite(LEDPin, HIGH);
17 delay(50);
18 digitalWrite(LEDPin, LOW);
19 delay(50);
20 }
21 else
22 {
23 digitalWrite(LEDPin, LOW);
24 }
25 }

Si quisiéramos ejecutar una acción una única vez al detectar movimiento, en lugar de todo el tiempo
que la señal este activa, usaríamos el siguiente código.

1 const int LEDPin = 13; // pin para el LED


2 const int PIRPin = 2; // pin de entrada (for PIR sensor)
3
4 int pirState = LOW; // de inicio no hay movimiento
5 int val = 0; // estado del pin
6
7 void setup()
8 {
9 pinMode(LEDPin, OUTPUT);
10 pinMode(PIRPin, INPUT);
11 Serial.begin(9600);
12 }
13
14 void loop()
15 {
16 val = digitalRead(PIRPin);
17 if (val == HIGH) //si está activado
18 {
19 digitalWrite(LEDPin, HIGH); //LED ON
20 if (pirState == LOW) //si previamente estaba apagado
21 {
22 Serial.println("Sensor activado");
23 pirState = HIGH;
24 }
25 }
26 else //si esta desactivado
27 {
28 digitalWrite(LEDPin, LOW); // LED OFF
29 if (pirState == HIGH) //si previamente estaba encendido
30 {
31 Serial.println("Sensor parado");
32 pirState = LOW;
33 }
34 }
35 }
Fuente: luisllamas.es

Control remoto infrarrojo con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 08 Julio 2015
Visto: 2554
Ratio: 5 / 5

Voto 5 Votar
Por favor, vote

Los mandos de infrarrojos


Estamos tan acostumbrados a los mandos a distancia infrarrojos que no dedicamos un momento
a pensar en ellos y simplemente nos parece normal, algo que a nuestros abuelos les hubiera
parecido magia.
Nos parece normal que los equipos electrónicos, televisores, cadenas de música, aires
acondicionados, respondan a nuestras instrucciones sin levantarnos del sofá, pero esto no ha sido
siempre así, es más, es
relativamente reciente, que estos mandos se popularizaron.
Hemos oído que funcionan por infrarrojos y poco más. Me pregunto cuántos usuarios responderían
correctamente a la pregunta de que son los infrarrojos y cuál es el principio de funcionamiento de un
mando a distancia de este tipo.
Para centrar un poco las ideas, empecemos diciendo que las ondas electromagnéticas se
caracterizan, principalmente, por su frecuencia o lo que es lo mismo, por el inverso de ésta que es
la longitud de onda.
Son similares a las ondas de sonido. A las de menor frecuencia las llamamos infrasonidos, y luego
vienen las ondas de sonido claro. Un poco más arriba tenemos los ultrasonidos (Nombres
sorprendentes, que básicamente significan por debajo y por encima de lo que se oye.
En el espectro electromagnético, nos encontramos enseguida con las ondas de radio y luego con
las microondas. Después como veis en este gráfico que he pillado de la Wikipedia viene
el infrarrojo (Por debajo del rojo), el espectro de luz visible con los familiares colores (Que solo son
una forma en que nuestro cerebro percibe las frecuencias de luz) y luego el ultravioleta (Por encima
del violeta, eso es echarle imaginación a los nombres, si señor).
Más arriba en la escala encontramos los rayos X (Cuando el alemán Roentgen descubrió esta
radiación a finales del XIX, no tenía ni idea de que era, y le parecía una buena idea llamarlos Rayos
X, o sea desconocidos, y todavía hoy seguimos con este cachondeo) y por último los rayos gamma
o cósmicos.

La capacidad energética de la radiación crece rápidamente con la frecuencia y por eso los rayos X
y los gamma son muy dañinos para los seres vivos.
Una manera de describir los infrarrojos, seria como una luz con un color diferente, que no vemos,
pero luz a pesar de todo.
Una curiosidad no muy conocida, es que seguramente la cámara de tu teléfono móvil, o tableta es
capaz de ver, y mostrarte, la radiación IR de tus mandos a distancia.
La luz infrarroja es adecuada para hacer mandos a distancia porque:

 Utilizan luz en una frecuencia que no tienen consecuencias en los tejidos vivos. Menos impacto
que la luz visible.
 Como solemos ver la tele a oscuras, no se ve cuando usamos el mando.
 Tiene relativamente poco alcance, pero no solemos ver la tele o tener la cadena de música
más allá de 2 o 3 metros.
Así que es práctico, sencillo y barato (lo que les encanta a los fabricantes), aunque tienen también
inconvenientes.
El principal es que cualquier cosa con una cierta temperatura, incluidos nosotros, emitimos radiación
infrarroja. Es por eso que las cámaras IR que veis en las pelis, pueden mostrar nítidamente en plena
oscuridad a una persona o animal.
Y esto podría interferir con el mando a distancia IR, lo mismo que cosas como la calefacción, el sol
y demás cosas calientes. Así que la solución para evitarlo es modular la señal con una portadora.
La idea básica es mandar un tren de ondas estable (La portadora) y mezclarlo con la información que
queremos enviar (La señal). Este mismo principio se usa con la radio y casi con cualquier señal
radioeléctrica que se envié por el aire.
He encontrado este Gif en la página de sbprojects y me ha parecido ideal para mostrar el proceso
de modulación y transmisión.

El emisor es un sencillo transistor que gobiernan un LED infrarrojo muy similar a los LEDs rojitos
normales que hemos usado hasta ahora, solo que diseñados para emitir luz en un color que no
vemos.
Un pequeño procesador en el mando gobierna, la generación de la señal y la mezcla con la
portadora, para garantizar que nuestra tele no recibe órdenes espurias.

 El proceso de mezclar una señal con la portadora se le llama modular.


 El inverso, extraer la señal de una onda RF y obtener la señal limpia se llama demodular.

El receptor tiene un poco más de complejidad porque, las normas de emisión de IR para mandos a
distancia, aparecieron como setas tras una tormenta y poco menos que cada fabricante presento su
propia norma.
Al final la industria acabo diseñando unos receptores capaces de recibir y demodular casi cualquier
cosa, y como se venden como churros (Porque nos encanta mantener nuestro culo pegado al sofá)
valen muy poco y son un prodigio tecnológico.
Un receptor IR típico actual, incluye el receptor, amplificador demodulador y lo que se te ocurra
encapsulado y listo para usarse. No os imagináis la cantidad de electrónica que va incluido esta
piececita de aspecto inocente.
Receptores de IR
Un típico receptor de infrarrojos, es el AX-1838HS, que se consigue por poco más de unos euros.
En su hoja de normas encontráis este diagrama, y son relativamente fáciles de encontrar, en dos
formas. Independientes y montados en un soporte para utilizar sin complicaciones con nuestros
Duinos.
El esquema de conexión nuevamente es trivial, pues el AX-1838HS solo tiene 3 pines: Vcc, GND y
señal. Como vamos a usar una interrupción para leer la señal es imprescindible, que llevéis el pin de
señal a el pin2 de Arduino (La interrupción 0) o al pin3 (La interrupción 1).
Yo lo voy a conectar al pin 2 y así lo reflejan los programas y los ejemplos.

Programa de control

Para poderlos usar de una forma cómoda, vamos a descargarnos alguna librería, que nos facilite la
vida. De las varias disponibles me ha gustado la de Nico Hood http: //nicohood.wordpress.com/, por
varios motivos.
 Es ligera y muy rápida en decodificar las señales IR y además usa muy poca memoria.
 Aunque no decodifica todo, acepta las normas de NEC y Panasonic y compatibles, y además
tiene un modo de haz lo que puedas que parece ir bastante bien. Lo que nos da un 85% de
probabilidades de que reconozca tu mando
 Funciona por interrupciones, lo que la hace muy ligera y rápida y así vemos un buen ejemplo
de uso de estas.
 Es de las pocas que es capaz de decodificar las señales simultáneas de varios mandos
diferentes, con diferentes protocolos cada uno.

Lo primero es descargarnos la librería IRLremote.zip, y después instalarla siguiendo el procedimiento


habitual que vimos en sesiones anteriores. Una vez hecho para usarla como siempre usamos el
importar librería, que os pondrá:

#include "IRLremote.h"

Y para inicializarla:

IRLbegin<IR_ALL>(interruptIR);

Vamos a empezar por un ejemplo que nos recomienda el autor para reconocer el mando a distancia
que usamos. Podeis cargarlo con ejemplos IRLremote\ReceiveInterrupt

#include "IRLremote.h"

const int interruptIR = 0; // Arduino interrupcion 0: Pin 2

uint8_t IRProtocol = 0; // Variables para recibir los datos

uint16_t IRAddress = 0;

uint32_t IRCommand = 0;

void setup()

{ Serial.begin(115200); // Fijate en la velocidad

Serial.println("Startup");

IRLbegin<IR_ALL>(interruptIR);

void loop()

uint8_t oldSREG = SREG; // Parar las interrupciones

cli();

if (IRProtocol) // Si reconoce el protocolo


{

Serial.print("Protocol:");

Serial.println(IRProtocol);

Serial.print("Address:");

Serial.println(IRAddress, HEX);

Serial.print("Command:");

Serial.println(IRCommand, HEX);

IRProtocol = 0;

SREG = oldSREG;

void IREvent(uint8_t protocol, uint16_t address, uint32_t command)

IRProtocol = protocol; // Recogemos los valores y nos volvemos

IRAddress = address;

IRCommand = command;

Este programa, simplemente tratará de leer tu mando a distancia y enviar esa información a la
consola. Asegúrate de que has puesto la velocidad a 115200:
Como veréis la rutina de servicio de la interrupción simplemente recoge los valores del protocolo que
amablemente reconoce sobre la marcha la librería. Los valores que presenta son

 Nos informa del modelo de señal que usa nuestro mando. En este momento reconoce 4
protocolos y el autor pide la colaboración ciudadana, para aumentar el número de protocolos
disponibles con la librería. Actualmente son:
o IR_NO_PROTOCOL , 0
o IR_USER, 1
o IR_ALL, 2
o IR_NEC, 3.
o IR_PANASONIC, 4
 Address, dirección de tu mando. Cada mando lleva una dirección para identificarle. Podrías
usar más de un mando a distancia para controlar lo que sea, y reconocerlos de forma
diferenciada.
 La orden o identificación del botón pulsado en el mando. Cada botón tiene un código diferente
y estos son los códigos que usaras en tu programa para lanzar acciones diferentes en función
del botón pulsado.

Yo he probado con 5 mandos IR diferentes (Tengo muchos trastos) y me ha reconocido


correctamente 4 a la primera. Los que han entrado sin problemas son los de Panasonic, Sony, LG y
Keyes.
El que no sabía lo que era, ha sido un mando viejo de una TV Schneider que soy incapaz de saber
de dónde ha salido.

 Conviene comentar que si tienes una tele, o VHS o similares que ya no usas, puedes tirar el
aparto si quieres pero conserva el mando porque hay muchas probabilidades de que puedas
leerlo con tu Arduino.
 Además tus antiguos cacharros con mando a distancia incluyen esto receptores de IR que
puedes desarmar y reutilizar para tus cosas. ( Os recomiendo desarmar solo los aparatos
viejos e inútiles, no los que están funcionando, que luego no quiero responsabilidades).

Y en este programa está ya implícito todo lo necesario para utilizar un mando IR en tus proyectos.
EL resto de la sesión será sencillamente un ejemplo de cómo gestionar esos golpes de teclas con u
Swuitch que es una instrucción C++ que hasta ahora no habíamos usado y que nos viene al pelo.
Vamos a montar un circuito con Arduino y 4 LEDs de colores para encerderlos de uno en uno o
apagarlos todos de golpe, mediante el mando IR a distancia.

Sensor de temperatura y humedad DHT11 - DHT22 para Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 26 Junio 2015
Visto: 2321

Voto 5 Votar
Por favor, vote

Como Añade sensor de temperatura y humedad a tus proyectos fácilmente.


Vamos a centrarnos en los sensores DHT11 o DHT22. Elegimos éste modelo porque con un único
sensor podemos medir temperatura y humedad.
Una particularidad de estos sensores es que la señal de salida es digital, por lo tanto, lo tendremos
que conectar a pines digitales.
Llevan un pequeño microcontrolador interno para hacer el tratamiento de señal.

Cómo funcionan?
Los DHT11 y DHT22 se componen de un sensor capacitivo para medir la humedad y de un termistor.

La principal diferencia entre ambos es que el ciclo de operación es menor en el DHT11 que en el
DHT22, sin embargo, el DHT22 tiene rangos de medida más amplios y mayor resolución, a cambio
de resultar algo más caro.
Ambos sensores están calibrados en laboratorio y tienen una buena fiabilidad.
Son además muy fáciles de conectar y sólo requieren de un pin de Arduino.
Podéis descargar el Data Sheet de aqui.

Encapsulado.
Existen en el mercado tres variantes:
El sensor suelto, con un encapsulado azul y cuatro pines disponibles para conectar. (Será necesario

añadir la resistencia pull-up)

El sensor con una placa soldada, con tres pines disponibles para conectar y una resistencia pull-up
(normalmente de 4,7-10 kΩ).

El mismo formato que el anterior, pero con un condensador de filtrado (normalmente de 100 nF).
A modo de recomendación, si podéis, comprarlo con la resistencia pull-up y evitar tener que soldarla,
nos hace más sencillo la construcción.

Características de cada uno de los sensores:


Parámetro DHT11 DHT22
Alimentación 3Vdc ≤ Vcc ≤ 5Vdc 3.3Vdc ≤ Vcc ≤ 6Vdc
Señal de Salida Digital Digital
Rango de medida Temperatura De 0 a 50 °C De -40°C a 80 °C
Precisión Temperatura ±2 °C <±0.5 °C
Resolución Temperatura 0.1°C 0.1°C
Rango de medida Humedad De 20% a 90% RH De 0 a 100% RH
Precisión Humedad 4% RH 2% RH
Resolución Humedad 1%RH 0.1%RH
Tiempo de respuesta 1s 2s
Tamaño 12 x 15.5 x 5.5mm 14 x 18 x 5.5mm

Ciclo de operación.
Es el tiempo que el sensor tarda en ofrecer una respuesta desde que se le pide.
Formato de datos de un solo bus para la comunicación y sincronización entre MCU y el
sensor. El proceso de comunicación es de 4 ms aproximadamente.
Una transmisión de datos completa es de 40 bits. Donde obtenemos la temperatura y la humedad.

Ejemplo: Recibimos 40 bits:

 0011 0101 0000 0000 0001 1000 0000 0000 0100 1101

High humidity 8 + Low humidity 8 + High temp. 8 + Low temp. = 8 Parity bit
Calculando:

 0011 0101+0000 0000+0001 1000+0000 0000= 0100 1101

Datos correctos recibidos:

 Humedad:0011 0101 = 35H = 53%RH


 Temperatura:0001 1000 = 18H = 24℃

El microcontrolador externo y el microcontrolador que lleva integrado el sensor, se hablan entre sí


de la siguiente manera:

 Se inicia la comunicación.
 El sensor responde estableciendo un nivel bajo de 80us y un nivel alto de 80us.
 El sensor envía 5 bytes con la información de temperatura y humedad.

Ahora que ya sabemos esto, podemos decidir si utilizar la libreria que nos proporciona para arduino,
o simplemente realizar éstas operaciones nosotros mismos sin necesidad de libreria.

Pinout.

Los pines del DHT11 y del DHT22 siguen el mismo orden.

 VCC.
 Señal.
 NC.
 GND.

Conexión de un DHT11 a Arduino Uno.


Del montaje realizado, destacamos que no utilizamos el pin 3, y que el resistor tiene que conectarse
entre la alimentación y el pin de salida de datos.
Si hemos comprado el sensor suelto, debemos basarnos en este esquema para conectar con nuestro
arduino.

Conectamos el sensor con arduino.

Por el contrario, si hemos comprado el sensor con la resistencia pull-up conectamos cada ping con
arduino directamente.
Seguramente necesiteis descargar tambien la libreria del sensor. Descargar aqui.
Vemos el skecth con el que tenemos que programar el microcontrolador.

#include "DHT.h"
#include <LiquidCrystal.h>
#define DHTPIN 8 //Data
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
dht.begin();
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();

lcd.setCursor(0,0);
lcd.print("Temperatura ");
lcd.print(t,0);
lcd.print("C");
lcd.setCursor(0,1);
lcd.print("Humedad ");
lcd.print(h,0);
lcd.print("%");
delay(1200);

En éste caso utilizaremos una pantalla LCD para ver el resultado que nos envía el sensor.
También es interesante recordar, que aunque el sensor entrega señales de naturaleza analógica
como son la humedad y la temperatura, estas señales las leemos por un pin digital de Arduino y que
en un solo pin somos capaces de obtener dos lecturas, viendo así la ventaja que aportan las señales
digitales frente a las analógicas: menos cables y más simplicidad en los montajes.
Fuente: omniblug.com

USANDO EL PUERTO SERIE DEL ARDUINO


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 12 Junio 2015
Visto: 1543

Voto 5 Votar
Por favor, vote

En este tutorial vamos a explicar cómo se usa el puerto serie del Arduino, ya que este se usa en
varias ocasiones para transmitir y recibir datos de otros dispositivos como un PC o de otro
microcontrolador.
El puerto serie del Arduino Uno usa los pins 0(RX) y 1(TX). Estos están conectados al controlador
FTDI (ATmega 16u2) que es el que permite la traducción del formato serie TTL a USB. Estos pins
no pueden ser utilizados mientras se usa la comunicación serie.
El puerto serie del Arduino utiliza un buffer de 64 bytes. Para entender el uso del buffer normalmente
se usa el ejemplo de la sala de espera del médico. Esta sala de espera es el buffer, que tiene una
capacidad de 64 pacientes. Cada paciente es 1 byte. El médico va atendiendo cada paciente uno
por uno por orden de llegada. La enfermera que deja entrar a los pacientes a la sala de espera son
los baudios (la velocidad de recibir datos), cuando más grande sea la velocidad, más gente entra en
la sala. Si la sala está completa con 64 pacientes y llegan más, estos serán rechazados (drop o loss).
Para usar el puerto serie del Arduino hay varias funciones de programación que hay que saber:
-begin(velocidad) Abre el puerto serie y establece la velocidad. La velocidad de
conexión (baudios o Baud Rate) es la velocidad que llegan los datos al puerto serie. Normalmente
se usa 9600bps o 115000bps.
-available() Esta función devuelve el estado del buffer del puerto serie y rebela si hay datos dentro
de este.
-read() Lee un carácter del buffer. Es importante entender que lee un solo carácter (byte).
-write() Escribe caracteres a través del puerto serie. A diferencia de read(), escribe
tantos caracteres como quieras.
-print() Imprime los datos al puerto serie como texto ASCII.
-println() Imprime los datos al puerto serie como texto ASCII seguido de un retorno de carro (ASCII
13, o ‘\r’) y un carácter de avance de línea (ASCII 10, o ‘\n’). Este comando tiene la misma forma
que Serial.print ().
-flush() Vacía el buffer de entrada de datos.
-end() Desactiva la comunicación serie, permitiendo a los pines 0(RX) y 1 (TX) ser usadoscomo
entradas o salidas digitales. Para volver a activar la comunicación serie, llamar
la función Serial.begin().
Para enviar y recibir datos, el Arduino utiliza el código ASCII
Enviar datos del Arduino al PC
Para empezar, vamos a enviar datos desde el Arduino al PC. El IDE de Arduino tiene un Monitor
Serial para comunicarse con el PC.

Vamos a enviar el valor 81 en formato decimal al PC. El programa sería el siguiente:

void setup()
1
2{
3 Serial.begin(9600);
4}
5
6 void loop()
7{
8 Serial.println(81);
9}
Si cargamos el programa al Arduino y abrimos el Monitor Serial, vemos que va imprimiendo el valor
81 constantemente.
También podemos determinar el formato de salida del valor que enviamos (decimal, binario,
hexadecimal, octal o byte).
Enviar el valor 81 en formato decimal, podemos hacerlo con el programa anterior o también con este:

1 void setup()
2{
3 Serial.begin(9600);
4}
5
6 void loop()
7
{
8
9 Serial.println(81,DEC); //Imprime "81"
}
Para enviar el valor 81 en formato hexadecimal:

void setup()
1
2{
3 Serial.begin(9600);
4}
5
6 void loop()
7{
8 Serial.println(81,HEX); //Imprime "51"
9}
Para enviar el valor 81 en formato octal:

void setup()
1
2{
3 Serial.begin(9600);
4}
5
6 void loop()
7{
8 Serial.println(81,OCT); //Imprime "121"
9}
Para enviar el valor 81 en formato binario:

void setup()
1
2{
3 Serial.begin(9600);
4}
5
6 void loop()
7{
8 Serial.println(81,BIN); //Imprime "1010001"
9}
Y para enviar el valor 81 como un byte se tiene que usar la función write()

1 void setup()
2{
3 Serial.begin(9600);
4}
5
6 void loop()
7{
8
Serial.write(81); //Imprime "Q", el qual representa el carácter ASCII del valor "81"
9
}

Recibir datos del PC


Ahora vamos a invertir el proceso, vamos a enviar datos del PC al Arduino. El programa básico para
recibir datos es el siguiente:

void setup()

1 {
2 Serial.begin(9600);
3 }
4
5 void loop()
6 {
7
if(Serial.available()>0) //Comprobamos si en el buffer hay datos
8
{
9
10 int dato=Serial.read(); //Lee cada carácter uno por uno y se almacena en una

11 variable
12
13 Serial.println(dato); //Imprimimos en la consola el carácter recibido
14 }
}
Y aquí se complica un poco la cosa. ¿Por qué? Pues porqué como hemos explicado antes, el buffer
del puerto serie recibe los datos byte por byte y en formato decimal, quiere decir, los caracteres
recibidos serán números correspondientes al código ASCII (El Arduino ve Símbolos de del tabla
ASCII y los traduce a Decimal).
Por ejemplo: Enviamos desde el PC la palabra “ARDUINO”. El buffer lee uno por uno los caracteres
recibidos, primero la “A”, después la “R”,…, hasta la “O”, y los captura como carácter decimal
correspondiente a la tabla del código ASCII. Quiere decir que el Arduino ve los siguientes valores:
65 82 68 85 73 78 79
Que corresponden a A R D U I N 0
Para solucionar esto podemos usar la función write() en vez de println(). Porque write() envía uno o
varios bytes en forma de datos binarios. De esta manera, cuando enviamos desde el PC la palabra
“ARDUINO”, en el Monitor Serial imprimirá “ARDUINO”.

1 void setup()
2 {
3 Serial.begin(9600);
4 }
5
6 void loop()
7 {
8 if(Serial.available()>0) //Comprobamos si en el buffer hay datos
9
{
10
int dato=Serial.read(); //Lee cada carácter uno por uno y se almacena en una
11
12 variable
13
14 Serial.write(dato); //Imprimimos en la consola el carácter recibido
}
}
Lo que hace la función write() con los valores recibidos (65 82 68 85 73 78 79) es enviarlos al
Monitor Serial con su carácter correspondiente de la tabla del código ASCII. Así visualizamos los
mismos caracteres que hemos escrito inicialmente en el PC.
Otra forma similar de hacerlo sin cambiar el println() es en vez de usar el tipo de variable int para
leer los datos del buffer, usaremos el tipo de variable char que es un tipo de dato que ocupa un byte
de memoria y almacena un valor de carácter (almacena el símbolo de la tabla ASCII).

void setup()

1 {
2 Serial.begin(9600);
3 }
4
5 void loop()
6 {
7
if(Serial.available()>0) //Comprobamos si en el buffer hay datos
8
9 {
10 char dato=Serial.read(); //Lee cada carácter uno por uno y se almacena en una

11 variable
12
13 Serial.println(dato); //Imprimimos en la consola el carácter recibido
14 }
}
Pero y si queremos usar datos recibidos dentro del programa. Por ejemplo: si queremos enviar el
valor 51 desde el PC al Arduino, y este queremos que a este valor 51 le sumemos un valor 2 para
que nos salga un valor 53. ¿Cómo lo podemos hacer? Ya que cuando el Arduino reciba el valor 51,
lo va a interpretar como un 53(5) y 49(1).
Usaremos un código muy sencillo. Creamos un array tipo char para que almacene los datos en forma
de cadena de caracteres (String). Lo que haremos es convertir esta cadena de caracteres a un
número entero usando la función atoi(), que no es una función de Arduino sino de C++, pero que
está incluido automáticamente en todos los sketches. También usaremos la
función memset() (también procedente de C++) para limpiar el array después de cada lectura.

1 void setup()
2 {
3 Serial.begin(9600);
4 }
5
6 char cadena[30]; //Creamos un array que almacenará los caracteres que escribiremos en la
7 consola del PC. Le asignamos un tope de caracteres, en este caso 30
8
byte posicion=0; //Variable para cambiar la posición de los caracteres del array
9
10 int valor; //Variable del valor entero
11
12 void loop()
13 {
14 if(Serial.available()) //Nos dice si hay datos dentro del buffer
15 {
16 memset(cadena, 0,sizeof(cadena));//memset borra el contenido del array "cadena" desde
17
la posición 0 hasta el final sizeof
18
19
while(Serial.available()>0) //Mientras haya datos en el buffer ejecuta la función
20
{
21
22 delay(5); //Poner un pequeño delay para mejorar la recepción de datos
23 cadena[posicion]=Serial.read();//Lee un carácter del string "cadena" de la
24 "posicion", luego lee el siguiente carácter con "posicion++"
25 posicion++;
26 }
27
28 valor=atoi(cadena);//Convertimos la cadena de caracteres en enteros
Serial.println(valor+2);//Imprimimos el valor sumandole un valor +2
posicion=0;//Ponemos la posicion a 0
}

Lectura de datos de Raspberry PI a un Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 06 Junio 2015
Visto: 1414

Voto 5 Votar
Por favor, vote

¡Hola! En el tutorial de hoy seguimos con la conexión de Arduino y Raspberry Pi.


En este artículo, haremos una lectura de varios componentes que habrá conectados a Arduino.
Serán un LDR, un botón y un potenciómetro.
Exposición del proyecto
Desde Raspberry Pi, y mediante un código en Python (muy sencillo), mandaremos comandos al
Arduino para que nos devuelva los datos que esté leyendo. Si por ejemplo mandamos una ‘P‘, nos
devolverá el valor del potenciómetro. Si mandamos una ‘B‘, Arduino nos informará de si el botón está
pulsado o no. Finalmente, si mandamos una ‘L‘, podremos leer el valor del LDR.

Realización del proyecto


Del mismo modo que en el tutorial anterior de Arduino y Raspberry Pi, dividiré el artículo en dos
partes distintas:

 Parte 1: Arduino (código y montaje)


 Parte 2: Raspberry Pi (código y ejecución)

– Parte 1: Arduino
Antes de nada, veremos el montaje. Utilizaré un LDR, un botón y un potenciómetro. Si no disponéis
de ellos, no importa, simplemente mandaremos un mensaje de ejemplo para saber que funciona.

El código de Arduino en caso de que NO realices el montaje (no tienes los componentes) es:
1 voidsetup(){
2 Serial.begin(9600);//Inicializo el puerto serial a 9600 baudios
3 }
4 voidloop(){
5 if(Serial.available()){//Si está disponible
6 charc=Serial.read();//Guardamos la lectura en una variable char
7 if(c=='H'){//Si es una 'H', enciendo el LED
8 Serial.println("'H' pulsada");
9 }elseif(c=='L'){//Si es una 'L', apago el LED
10 Serial.println("'L' pressed");
11 }else{
12 Serial.println("Caracter no reconocido");
13 }
14 }
15 }

El código de Arduino en caso de que SÍ realices el montaje (sí tienes los componentes) es:

1 intLDRPin=0;
2 intvalor;
3
4 intmin=0;
5 intmax=1023;
6
7 intboton=8;
8
9 voidsetup(){
10 Serial.begin(9600);
11 pinMode(boton,INPUT);
12 }
13
14 voidloop(){
15 if(Serial.available()){
16 charc=Serial.read();
17 if(c=='B'){
18 valor=digitalRead(boton);
19 if(valor==0){
20 Serial.println("Boton no pulsado");
21 }else{
22 Serial.println("Boton pulsado");
23 }
24 }elseif(c=='L'){
25 valor=analogRead(LDRPin);
26 valor=map(valor,min,max,0,100);
27 Serial.println(valor);
28 }elseif(c=='P'){
29 Serial.println(analogRead(1));
30 }
31 }
32 }

– Parte 2: Raspberry Pi
A continuación, veremos la parte de Raspberry Pi. Crearemos un archivo
llamado Arduino_ReadData.py con el fin de poder mandar comandos por serial al Arduino. Este
código es muy parecido al del tutorial anterior, así que no veréis nada raro.
Antes de nada, si no lo habéis hecho ya, tenéis que introducir el siguiente comando en la Raspberry
Pi. Si es la primera vez que lo hacéis, se os instalará la librería python-serial, para que podáis usar
la conexión serie. Si ya lo habíais hecho antes, os dirá que ya estaba instalado, como me pasa a mí:

1 sudo apt-get install python-serial


1 importserial
2 importtime
3
4 arduino=serial.Serial('/dev/ttyACM0',baudrate=9600,timeout=3.0)
5 arduino.open()
6 txt=''
7
8 whileTrue:
9 var=raw_input("Introducir un Comando: ")
10 arduino.write(var)
11 time.sleep(0.1)
12 whilearduino.inWaiting()>0:
13 txt+=arduino.read(1)
14 printtxt
15 txt=''
16 arduino.close()

Únicamente hemos añadido una parte del código, que se encarga de esperar a que Arduino se
comunique con él, es decir, que devuelva los datos que se le han pedido:
1 whilearduino.inWaiting()>0:
2 txt+=arduino.read(1)
3 printtxt
4 txt=''

Ejecutaremos el código de la siguiente manera:

1 python Arduino_ReadData.py
Aquí tenemos algunos resultados:

Si queréis verlo funcionando, aquí os dejo el vídeo. Además, también está la explicación de este
mismo post, por si queréis que os lo cuente mientras lo programo:

El código está también en GitHub.


Sacado de: geekytheory.com
Practica con ARDUINO + BLUETOOTH
Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 26 Mayo 2015
Visto: 3996

Voto 5 Votar
Por favor, vote

En este tutorial vamos a dotar al Arduino de comunicación Bluetooth usando un módulo


Bluetooth, veremos cómo configurarlo y cómo enviar y recibir datos desde un dispositivo
Android.

Material
-Arduino Uno Rev 3
-Módulo Bluetooth JY-MCU
-Dispositivo Android con Bluetooth
-Leds rojo, amarillo y verde
-Resistencias 220 ohms x 3, 5K6, 10K

Módulo Bluetooth
El Bluetooth es un estándar de comunicación inalámbrica que permite la transmisión de datos a
través de radiofrecuencia en la banda de 2,4 GHz. Existen muchos módulos Bluetooth para usarlos
en nuestros proyectos de electrónica, pero los más utilizados son los módulos de JY-MCU, ya que
son muy económicos y fáciles de encontrar en el mercado. Son módulos pequeños y con un consumo
muy bajo que nos permitirán agregar funcionalidades Bluetooth a nuestro Arduino. Estos módulos
contienen el chip con una placa de desarrollo con los pins necesarios para la comunicación serie.
Existen dos modelos de módulos Bluetooth: el HC-05 que puede ser maestro/esclavo (master/slave),
y el HC-06 que solo puede actuar como esclavo (slave). La diferencia entre maestro y esclavo es
que en modo esclavo es el dispositivo quien se conecta al módulo, mientras que en modo maestro
es el módulo quien se conecta con un dispositivo.
Físicamente, los dos módulos son muy parecidos, solo varían algunas conexiones. Los pins que
encontraremos son los siguientes:
-Vcc: Alimentación del módulo entre 3,6V y 6V.
-GND: La masa del módulo.
-TXD: Transmisión de datos.
-RXD: Recepción de datos a un voltaje de 3,3V.
-KEY: Poner a nivel alto para entrar en modo configuración del módulo (solo el modelo HC-05)
-STATE: Para conectar un led de salida para visualizar cuando se comuniquen datos.

Comandos AT
Los comandos AT son un tipo de comandos que sirven para configurar el módulo Bluetooth a través
de un microcontrolador, un ordenador o con cualquier dispositivo que posea una comunicación serie
(Tx/Rx). Son unas instrucciones que nos permiten cambiar los baudios del módulo, el PIN, el nombre,
etc. Para usar los comandos AT el módulo Bluetooth no debe estar vinculado a ningún dispositivo
(led rojo del módulo parpadeando). Según las especificaciones del módulo, el tiempo que se tiene
que respetar entre el envío de un comando AT y otro tiene que ser de 1 segundo. Si se envía un
comando AT y en menos de un segundo se envía otro, el módulo no devuelve respuesta.
Ahora vamos a configurar el módulo Bluetooth a través de comandos AT enviados desde el Monitor
Serial del Arduino. El código del Arduino necesario tanto por el módulo HC-05 como el HC-06 es el
siguiente:
1 #include <SoftwareSerial.h> //Librería que permite establecer comunicación serie en otros
2 pins
3
4
//Aquí conectamos los pins RXD,TDX del módulo Bluetooth.
5
SoftwareSerial BT(10,11); //10 RX, 11 TX.
6
7
8 void setup()
9 {
10 BT.begin(9600); //Velocidad del puerto del módulo Bluetooth
11 Serial.begin(9600); //Abrimos la comunicación serie con el PC y establecemos velocidad
12
}
13
14
15 void loop()
16 {
17 if(BT.available())
18 {
19 Serial.write(BT.read());
20 }
21
22 if(Serial.available())
23
{
BT.write(Serial.read());
}
}
Entre los dos modelos de módulo Bluetooth existen diferencias a la hora de enviar los comandos AT:

HC-06
En el HC-06 solo se necesitan cuatro pins: Vcc, GND, TXD y RXD. El pin KEY no es necesario.
Al enviar un comando AT no se debe enviar ningún carácter de LF (nueva línea) ni CR (retorno de
carro) al final del comando. En el Monitor Serial del Arduino tenemos que poner No hay fin de líena.
Los comandos AT que se pueden enviar en este módulo son los siguientes:

Comando AT Descripción Respuesta


AT Test de comunicación. Responde con un OK
AT+VERSION Retorna la versión del Modulo OKlinvorV1.8
AT+BAUDx Configura la velocidad de trasmisión AT+BAUD4 Configura la
del modulo según el valor de “x”1 = velocidad a 9600 baud rate
1200 bps Responde con OK9600

2 = 2400 bps
3 = 4800 bps
4 = 9600 bps (por defecto)
5 = 19200 bps
6 = 38400 bps
7 = 57600 bps
8 = 115200 bps
9 = 230400 bps
A = 460800 bps
B = 921600 bps
C = 1382400 bps
AT+NAMEx Configura el nombre con el que se AT+NAMEDIYMakers
visualizara el modulo, soporta hasta 20 Configura el nombre del modu
caracteres a DIYMakers Responde
con OKsetname
AT+PINxxxx Configura el Pin de acceso al modulo AT+PIN1122 Configura el pin
(password).1234 por defecto. 1122 Responde con OKsetPIN

Una vez compilado el código en el Arduino, abrimos el Monitor Serial y enviamos el comando AT,
vemos que el módulo Bluetooth nos responde con un OK.
HC-05
El HC-05 es necesario poner el pin KEY del módulo a nivel alto (5V) para enviar comandos AT.
Además, al enviar un comando AT hay que enviar un carácter de LF (nueva línea) y de CR (retorno
de carro) al final del comando. Por lo tanto, en el Monitor Serial de Arduino pondremos Ambos NL
& CR.
En el HC-05 se pueden enviar muchos más comandos AT que en el HC-06. Aquí os dejamos un
archivo pdf con todos los comandos AT.
En el HC-05 se pueden enviar muchos más comandos AT que en el HC-06. Aquí os dejamos un
archivo pdf con todos los comandos AT.

En el HC-05 se pueden enviar muchos más comandos AT que en el HC-06. Aquí os dejamos un
archivo pdf con todos los comandos AT.
Descarga aquí.

Recibir datos de un dispositivo Android


Ahora que ya sabemos cómo conectar y configurar un módulo Bluetooth en nuestro Arduino,
vamos a vincularlo a un dispositivo Android con Bluetooth y enviar datos al Arduino mediante la
aplicación BlueTerm, que es un emulador de terminal que permite comunicarse con un dispositivo
Bluetooth para enviar y recibir información vía serie. La app es gratuita y se puede descargar
desde este enlace.
Conectaremos tres leds de diferentes colores al Arduino y mediante unos comandos que
ingresaremos en la app BlueTerm los encenderemos y apagaremos. En este ejemplo hemos usado
un módulo HC-06 pero se puede usar también un HC-05 ya que no hay diferencia en este caso.
Código Arduino
1
/*
2
3 www.diymakers.es
4 by A.García
5 Arduino + Bluetooth
6 Tutorial en: http://diymakers.es/arduino-bluetooth/
7 */
8
9 #include <SoftwareSerial.h> //Librería que permite establecer comunicación serie en otros
10 pins
11
12
//Aquí conectamos los pins RXD,TDX del módulo Bluetooth.
13
14 SoftwareSerial BT(10,11); //10 RX, 11 TX.
15
16 int green=4;
17 int yellow=5;
18 int red=6;
19 char cadena[255]; //Creamos un array de caracteres de 256 cposiciones
20 int i=0; //Tamaño actual del array
21
22
23 void setup()
24 {
25 BT.begin(9600);
26 Serial.begin(9600);
27
pinMode(green,OUTPUT);
28
29 pinMode(yellow,OUTPUT);
30 pinMode(red,OUTPUT);
31 }
32
33 void loop()
34 {
35 //Cuando haya datos disponibles
36 if(BT.available())
37
{
38
char dato=BT.read(); //Guarda los datos carácter a carácter en la variable "dato"
39
40
41 cadena[i++]=dato; //Vamos colocando cada carácter recibido en el array "cadena"
42
43 //Cuando reciba una nueva línea (al pulsar enter en la app) entra en la función
44 if(dato=='\n')
45 {
46 Serial.print(cadena); //Visualizamos el comando recibido en el Monitor Serial
47
48 //GREEN LED
49
if(strstr(cadena,"green on")!=0)
50
{
51
52 digitalWrite(green,HIGH);

53 }
54 if(strstr(cadena,"green off")!=0)
55 {
56 digitalWrite(green,LOW);
57 }
58
//YELLOW LED
59
if(strstr(cadena,"yellow on")!=0)
60
61 {

62 digitalWrite(yellow,HIGH);
63 }
64 if(strstr(cadena,"yellow off")!=0)
65 {
66 digitalWrite(yellow,LOW);
67 }
68
69 //RED LED
70 if(strstr(cadena,"red on")!=0)
71 {
72 digitalWrite(red,HIGH);
73
}
74
if(strstr(cadena,"red off")!=0)
75
76 {

77 digitalWrite(red,LOW);
78 }
79 //ALL ON
80 if(strstr(cadena,"on all")!=0)
81 {
82 digitalWrite(green,HIGH);
83
digitalWrite(yellow,HIGH);
84
digitalWrite(red,HIGH);
85
86 }
87 //ALL OFF
88 if(strstr(cadena,"off all")!=0)
89 {
90 digitalWrite(green,LOW);
91 digitalWrite(yellow,LOW);
92
digitalWrite(red,LOW);
93
}
94
95
96 BT.write("\r"); //Enviamos un retorno de carro de la app. La app ya crea una línea

97 nueva
98 clean(); //Ejecutamos la función clean() para limpiar el array
}
}
}

//Limpia el array
void clean()
{
for (int cl=0; cl<=i; cl++)
{
cadena[cl]=0;
}
i=0;
}
El código es bastante simple. Primero creamos un array de 256 posiciones tipo char
llamado cadena para almacenar los caracteres que recibiremos de la app. Cuando haya datos
disponibles los vamos guardando uno por uno en forma de carácter en la variable dato. Después
ponemos estos caracteres por orden en el array cadena. Cuando reciba un carácter de fin de línea
(\n), se compara el texto almacenado en el array con el texto que deseamos. Para hacer la
comparación se usa la función strstr() que procede de C++ y que permite encontrar partes de texto
en un String. Después de esto, se limpia el array poniendo a 0 todas las posiciones usadas para
recibir el siguiente comando.

Configurar app Android


Una vez descargada la app la abrimos y en ajustes ponemos Conectarse a un dispositivo.
Pulsamos Buscar dispositivos y escogemos nuestro módulo Bluetooth que en nuestro caso le
hemos puesto el nombre DIYMakers. Si no lo habéis cambiado pondrá por defecto LINVOR o HC-
06.
Ponemos el PIN del módulo. Si no lo habéis modificado será 1234.
Después de esto, arriba a la derecha pondrá conectado:<nombre> Significa que tenemos
asociado nuestro dispositivo Android con nuestro módulo Bluetooth y el led de este deja de
parpadear y se queda fijo.
Luego solo hay que poner los comandos para encender y apagar los leds. Cuando se escribe un
comando tenemos que pulsar Enter del teclado para enviarlos al Arduino. En el terminal no se
pueden borrar caracteres, por lo que si nos equivocamos pulsamos Enter y lo volvemos a escribir.
Reloj con Arduino y RTC DS1307
Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 21 Abril 2015
Visto: 3017

Voto 5 Votar
Por favor, vote

Arduino RTC (Real Time Clock)

Un reloj en tiempo real (en inglés, real-time clock, RTC) es un reloj de un ordenador, incluido en
un circuito integrado, que mantiene la hora actual. Los RTC están presentes en la mayoría de los
aparatos electrónicos que necesitan guardar el tiempo exacto.

En otras palabras un RTC mantiene tanto la hora como la fecha incluso si desconectas la
alimentación principal. En mi caso utilizare el DS1302:

Este modelo es muy fácil de utilizar solo debes conseguir las librerías adecuadas, yo utilizo la
librería Virtualboty RTC he probado varias y prefiero esta porque es muy fácil de utilizar.
Lo primero es conectar el RTC a tu Arduino lo harás de esta forma:
VCC_______ 5V
GND______ GND
Pin 8______ RST
Pin 7______ DAT (I/O)
Pin 6______ CLK

Cuando este conectado lo primero sera configurar la hora en el RTC con este codigo:

#include <virtuabotixRTC.h> // Incluye la librería


virtuabotixRTC myRTC(6, 7, 8); // Define los pines de CLK, DAT y RST en ese
//orden y nombra al RTC "myRTC" para llamarlo de esa manera luego
void setup() {
// Graba seg, min, hor, dia sem, dia mes, mes, año
myRTC.setDS1302Time(00, 20, 15, 3, 2, 9, 2014)

// Mar 10/9/2014 15:20:00


}
void loop() {
}

Con esto grabamos la fecha y la hora pero esta fecha y hora se gravaran cada vez que conectemos
nuestro arduino a la PC o a alguna fuente de alimentación.
¿Porque? simple el código en el arduino iniciara siempre que lo conecten, porque los
microcontroladores leen el código desde el inicio hasta el final y solo se detienen si programan una
rutina que se repita una y otra vez en este caso void loop.

Con el siguiente código veremos lo que programamos con el primero es decir la fecha y la hora.

#include <virtuabotixRTC.h>
virtuabotixRTC myRTC(6, 7, 8);
void setup() {
Serial.begin(9600); // Inicia el serial a 9600 baudios
}

void loop() {
myRTC.updateTime(); // Lee los datos del RTC
switch (myRTC.dayofweek) { // Lee el Dia Sem y escribe el dia correspondiente
case 1:
Serial.print("Domingo");
break;
case 2:
Serial.print("Lunes");
break;
case 3:
Serial.print("Martes");
break;
case 4:
Serial.print("Miercoles");
break;
case 5:
Serial.print("Jueves");
break;
case 6:
Serial.print("Viernes");
break;
case 7:
Serial.print("Savado");
break;
}
Serial.print(" ");
Serial.print(myRTC.dayofmonth);
Serial.print("/");
Serial.print(myRTC.month);
Serial.print("/");
Serial.print(myRTC.year);
Serial.print(" ");
Serial.print(myRTC.hours);
Serial.print(":");
Serial.print(myRTC.minutes);
Serial.print(":");
Serial.println(myRTC.seconds);
delay( 1000);
}

Luego habríamos el monitor serial y nos mostrara esto:


HC-SR04 Sensor ultrasonico de distancia y arduino
Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 21 Enero 2015
Visto: 1805

Voto 5 Votar
Por favor, vote

El HC-SR04 es un sensor de distancia que funciona por ultrasonido. Básicamente lo que hace es
enviar un pulso llamado trigger, inaudible para cualquier ser humano, rebotar en algún objeto y
recibirlo (eco). Con este principio es posible medir distancias sabiendo que la velocidad del sonido
es de 345m/s.
Podemos calcular la distancia con una sencilla formula:
Tensión de trabajo: 5VDC
Corriente de reposo: <2mA
Angulo: <15º
Distancia: 2 a 450cm
Resolución: 0,3cm

Con el sensor HC-SR04 y una placa Arduino podemos armar un medidor de distancia en menos de
5 minutos. Utilizando la librería Ultrasonic (disponible para la descarga en forma gratuita) podemos
medir distancias con muy poco código. Por defecto solo es posible medir hasta 51cm de distancia,
pero con una sencilla modificación en el archivo ultrasonic.ccp podemos llegar hasta los 5m.
Buscamos la siguiente línea y modificamos el valor de time_out:

Time_out=3000; // 30ms para 5 metros // 3ms para 50cm

A continuación el ejemplo que viene con la librería. Funciona muy bien y es sencillo de implementar:

Código:
// Ultrasonic - Library for HR-SC04 Ultrasonic RangingModule.
// Rev.4 (06/2012)
// J.Rodrigo ( www.jra.so )
// more info at www.ardublog.com

#include <Ultrasonic.h>

Ultrasonic ultrasonic(9,8); // (Trig PIN,Echo PIN)

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.print(ultrasonic.Ranging(CM)); // CM or INC
Serial.println(" cm" );
delay(100);
}

También se puede resolver el código sin utilizar librerías. Haciendo uso del comando pulseIn que
nos brinda el entorno Arduino podemos hacer lo mismo con un poco más de elaboración. El ejemplo
a continuación:

Código:

// HC-SR04 & ARDUINO

#define ECHO 8 // Pin para recibir el pulso de eco


#define TRIGGER 9 // Pin para enviar el pulso de disparo

unsigned int tiempo, distancia;

void setup() {
Serial.begin(9600);
pinMode(ECHO, INPUT);
pinMode(TRIGGER, OUTPUT);
}

void loop() {
digitalWrite(TRIGGER, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
// Calcula la distancia midiendo el tiempo del estado alto del pin ECHO
tiempo = pulseIn(ECHO, HIGH);
// La velocidad del sonido es de 340m/s o 29 microsegundos por
centimetro
distancia= tiempo/58;
//manda la distancia al monitor serie
Serial.print(distancia);
Serial.println(" cm");
delay(200);
}

Display de 7 segmentos. Practicas con Arduino


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 16 Diciembre 2014
Visto: 1547

Voto 5 Votar
Por favor, vote

Introducción teórica
Un display de segmentos (o visualizador) es un componente electrónico que se utiliza
para representar números. Como su propio nombre indica y, como se puede observar
en la imagen siguiente, el display está compuesto por 7 segmentos, los cuales se
encenderán y/o apagarán en función del número a representar.
De forma interna, se asemeja a siete LEDs conectados estratégicamente formando el
número 8, aunque externamente dicha semejanza no se observa, de ahí su simplicidad.
Cada uno de los segmentos que componen este display se denominan a, b, c, d, e,
f y g,tal y como se muestra a continuación.

Para mostrar el número 0, tendremos que encender a, b, c,


d, e y f.
Para el número 2, tendríamos a, b, g, e y d.
Y de la misma forma para cualquier otro número.
El P simboliza el punto decimal.

En cuanto a la clasificación, existen de dos tipos:


1. Display de segmentos de cátodo común, en la que todos los cátodos de los LEDs
estan internamente unidos a una patilla común, la cual está conectada al potencial
negativo de la placa.
2. Display de segmentos de ánodo común, en la que todos los ánodos se encuentran
al positivo.

Para nuestro caso, disponemos de uno de tipo cátodo común, el LMS5161AS (luz roja,
tamaño de dígito 0.56'').

Conexiones
En lo que se refiere a las conexiones, tenemos que tener en cuenta cada segmento a
qué pin lo vamos a conectar, para poder efectuar una llamada a los pines correcta. En
nuestro caso, hemos hecho las siguientes conexiones (puede variar la designación
según convenga):

Segmento a - pin 7
Segmento b - pin 8
Segmento c - pin 9
Segmento d - pin 10
Segmento e - pin 11
Segmento f - pin 12
Segmento g - pin 13

Ejemplo
Vamos a realizar un ejemplo en el cual nuestro display irá mostrando de forma
ascendente todos los números con un intervalo de separación de 1 segundo.
Aquí tenemos el sketch:

int pausa=1000; // Variable que define el intervalo


// de tiempo entre cada digito

void setup()
{
pinMode(7, OUTPUT); // Asignación de las salidas digitales
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}

void display (int a, int b, int c, int d, int e, int f, int g)


// Funcion del display
{
digitalWrite (7,a); //Se reciben 7 variables y se asignan
digitalWrite (8,b); //a cada una de las salidas
digitalWrite (9,c);
digitalWrite (10,d);
digitalWrite (11,e);
digitalWrite (12,f);
digitalWrite (13,g);
}
void loop() //Funcion principal
// Dependiendo de cada dígito, se envía a la función display
// los estados (0 y 1) a cada uno de los segmentos
{
display (1,1,1,1,1,1,0); //escribe 0
delay(pausa);
display (0,1,1,0,0,0,0); //escribe 1
delay(pausa);
display (1,1,0,1,1,0,1); //escribe 2
delay(pausa);
display (1,1,1,1,0,0,1); //escribe 3
delay(pausa);
display (0,1,1,0,0,1,1); //escribe 4
delay(pausa);
display (1,0,1,1,0,1,1); //escribe 5
delay(pausa);
display (1,0,1,1,1,1,1); //escribe 6
delay(pausa);
display (1,1,1,0,0,0,0); //escribe 7
delay(pausa);
display (1,1,1,1,1,1,1); //escribe 8
delay(pausa);
display (1,1,1,0,0,1,1); //escribe 9
delay(pausa);
}

Hola mundo en Pantalla LCD1602 con arduino y la libreria LiquidCrystal


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 09 Diciembre 2014
Visto: 8047

Voto 5 Votar
Por favor, vote

LiquidCrystal
La librería LiquidCrystal te permite controlar displays LCD que sean complatibles con el driver
Hitachi HD44780. Hay muchos de ellos ahí fuera, y puedes comunicarte con ellos a través del interfaz
de 16 pines.
Este sketch de ejemplo imprime "Hello World!" en el LCD y muestra el tiempo en segundos desde
que Arduino fué reseteado por última vez.

El LCD tiene un interfaz paralelo, significando esto que el microcontrolador tiene que manipular varios
pines del interfaz a la vez para controlarlo. El interfaz consta de los siguientes pines:
Un pin de selección de registro (RS) que controla en qué parte de la memoria del LCD estás
escribiendo datos. Puedes seleccionar bien el regisro de datos, que mantiene lo que sale en la
pantalla, o un registro de instrucción, que es donde el controlador del LCD busca las instrucciones
para saber cual es lo siguiente que hay que hacer.
El pin de lectura/escritura (R/W)que selecciona el modo de lectura o el de escritura.
Un pin para habilitar (enable) que habilita los registros.
8 pines de datos (D00-D07). Los estados de estos pines (nivel alto o bajo) son los bits que estás
escribiendo a un registro cuando escribes, o los valores de lectura cuando estás leyendo.
Hay también un pin de contraste del display (Vo), pines de alimentación (+5V y GND) y pines
de retro-iluminación (Bklt+ y Bklt-), que te permiten alimentar el LCD, controlar el contraste del
display, o encender y apagar la retro-iluminación, respectivamente.
El proceso de controlar el display involucra la colocación de los datos que componen la imagen de
lo que quieres mostrar, en los registros de datos, y luego, colocar las instrucciones, en el registro de
instrucciones. La librería LiquidCrystal te simplifica todo este proceso de forma que no neesitas saber
las instrucciones de bajo nivel.
Los LCD-s compatibles con Hitachi pueden ser controlados de dos modos: 4 bits u 8 bits. El modo
de 4 bits requiere siete pines de E/S de Arduino, mientras el modo de 8 bits requiere 11 pines. Para
mostrar texto en la pantalla, puedes hacer la mayoría de las cosas en modo 4 bits, por lo que el
ejemplo muestra como controlar un LCD de 2x16 en modo de 4 bits.

Circuito

 El pin RS del LCD conectado a la E/S digital en el pin 12


 El pin enable del LCD conectado a la E/S digital en el pin 11.
 Los pines D4 - D7 conectado a las E/S digitales desde el pin 5 hasta el 2.
 Los pines de voltaje y tierra conectados a +5V y tierra.
 El pin Vo, que controla el constraste, conectado a un potenciómetro. Ajusta el potenciómetro
para que el texto tenga


Esquemático:
Code:

/*
LiquidCrystal Library - Hello World

Demonstrates the use a 16x2 LCD display. The LiquidCrystal


library works with all LCD displays that are compatible with the
Hitachi HD44780 driver. There are many of them out there, and you
can usually tell them by the 16-pin interface.

This sketch prints "Hello World!" to the LCD


and shows the time.

The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)

Library originally added 18 Apr 2008


by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe

This example code is in the public domain.

http://www.arduino.cc/en/Tutorial/LiquidCrystal
*/

// include the library code:


#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins


LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
}

void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
}

TUTORIAL DE PRIMEROS PASOS CON ARDUINO YÚN


Categoría de nivel principal o raíz: Arduino
Categoría: Laboratorio ARD
Publicado: 20 Noviembre 2014
Visto: 1867

Voto 5 Votar
Por favor, vote

El objetivo va a ser configurarla y hacer que parpadee un LED.


PASO 1
Lo primero que vamos a hacer es conectar la placa por puerto USB:
PASO 2
Se encenderá y veremos una nueva red WiFi disponible y que tiene el prefijo “Arduino Yun-“. Vamos
a conectarnos a ella:
PASO 3
Una vez nos hemos conectado a la red del Arduino Yún, entramos a la Web arduino.local y ya
podremos realizar la configuración.

Como contraseña tenemos que poner: arduino


Una vez hemos entrado con la contraseña, nos aparecerá una ventana en la que podremos
ver la información de nuestra placa:
Vamos a configurarla haciendo click en el botón CONFIGURE y le damos al Arduino el nombre que
queramos y, también podemos cambiar la contraseña. Configuraremos la red WiFi para que se
conecte a ella y poder trabajar con él:

Finalmente, hacemos click en Configure & Restart para acabar la configuración del Arduino y
reiniciarlo.
¡Atención! Para volver a entrar a la configuración de Arduino, introducid el nombre
que le habéis dado concatenado con “.local”. En mi caso sería arduinomario.local.
Lo digo porque llevo 20 minutos intentando entrar a arduino.local sin mucho éxito.

PASO 4: INSTALACIÓN DEL IDE DE ARDUINO


Necesitamos instalar como mínimo la versión 1.5 para poder utilizar el Arduino Yún. Para ello, vamos
a este enlace y lo descargamos para la plataforma que nos corresponda. En mi caso es Linux 64bit
y a día de hoy es la versión 1.5.7 BETA.
PASO 5: PRIMER PROGRAMA
Abrimos el IDE que acabamos de instalar. Nos dirigimos a Herramientas->Puerto y seleccionamos
nuestro Arduino:
En el modelo de placa, seleccionad Arduino Yún. Si no, no funcionará.
Vamos a realizar este montaje, que va a consistir en un LED conectado al pin número 13 para que
parpadee. El típico ejemplo de siempre.

el código que vamos a utilizar es el siguiente:

Arduino

1
2 voidsetup(){
3
4 pinMode(13,OUTPUT);
5
6 }
7
8 voidloop(){
9
digitalWrite(13,HIGH);

delay(1000);

digitalWrite(13,LOW);

delay(1000);

Lo cargamos y nos pedirá la contraseña del Arduino:

Una vez hayamos subido el sketch, el LED estará parpadeando. He subido el programa dos veces
para ver si me pedía siempre la contraseña y, a la seguna vez ya no me la ha pedido, así que no va
a ser algo tedioso cada vez que programemos algo para este modelo de Arduino.

También podría gustarte