Todo Sobre Arduino
Todo Sobre Arduino
Todo Sobre Arduino
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.
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
}
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
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().
• 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.
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 (. . . - - - .
. . ).
void setup()
pinMode(pin, OUTPUT);
void loop() //Programa principal que genera '. . .', '- - -' y '. . .'
digitalWrite(pin, HIGH);
delay(250);
digitalWrite(pin, LOW);
delay(250);
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
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"
#ifndef Morse_h
#define Morse_h
#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
/*
Created by David A. Mellis, November 2, 2007. Released into the public domain.
*/
#ifndef Morse_h
#define Morse_h
#include "WConstants.h"
class Morse
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()
}
void Morse::dash()
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()
void Morse::dash()
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:
#include <Morse.h>
Morse morse(13);
void setup() {}
void loop()
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);
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.
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.
Pin DT Pin A1
Módulo HX711 Arduino UNO, MEGA, NANO
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.
#include "HX711.h"
#define DOUT A1
#define CLK A0
void setup() {
Serial.begin(9600);
Serial.println(balanza.read());
Serial.println("Destarando...");
void loop() {
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.
#define DOUT A1
#define CLK A0
void setup() {
Serial.begin(9600);
Serial.println(balanza.read());
Serial.println("Destarando...");
Serial.println("...");
}
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.
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>
File myFile;
+5V 5V 5V
CS 4 4
MOSI 11 51
SCK 13 52
MISO 12 50
*Se puede alimentar con 5V o 3,3V usando los pines correspondientes, pero no se debe de alimentar
por ambos pines a la vez
CS 4 4
SCK 13 52
MOSI 11 51
MISO 12 50
VCC 5V 5V
*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
#include <SD.h>
File myFile;
void setup()
Serial.begin(9600);
Serial.print("Iniciando SD ...");
if (!SD.begin(4)) {
return;
Serial.println("inicializacion exitosa");
if (myFile) {
Serial.println("archivo.txt:");
while (myFile.available()) {
Serial.write(myFile.read());
void loop()
EL programa envía por el puerto serie todo el contenido del archivo guardado en la SD.
#include <SD.h>
File myFile;
int UltimaPocicion=0;
int pausa=1000;
void setup()
Serial.begin(9600);
Serial.print("Iniciando SD ...");
if (!SD.begin(4)) {
return;
Serial.println("inicializacion exitosa");
for(int i=0;i<8;i++)
pinMode(PinLeds[i],OUTPUT);
void loop()
int totalBytes=myFile.size();
String cadena="";
if (myFile) {
if(UltimaPocicion>=totalBytes) UltimaPocicion=0;
myFile.seek(UltimaPocicion);
while (myFile.available()) {
char caracter=myFile.read();
cadena=cadena+caracter;
UltimaPocicion=myFile.position();
break;
}
//---------------------------------------------------
Serial.print("Cadena Leida:");
Serial.print(cadena);
//-----------procesamos la cadena------------
int index=0;
char c=cadena[index++];
pausa=0;
c = cadena[index++];
Serial.print("pausa=");
Serial.print(pausa);
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 {
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:
#include <SD.h>
File myFile;
void setup()
Serial.begin(9600);
Serial.print("Iniciando SD ...");
if (!SD.begin(4)) {
return;
Serial.println("inicializacion exitosa");
void loop()
if (myFile) {
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);
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 {
delay(100);
#include <SD.h>
File myFile;
void setup()
Serial.begin(9600);
Serial.print("Iniciando SD ...");
if (!SD.begin(4)) {
return;
Serial.println("inicializacion exitosa");
if(!SD.exists("datalog.csv"))
if (myFile) {
myFile.println("Tiempo(ms),Sensor1,Sensor2,Sensor3");
myFile.close();
} else {
}
}
void loop()
if (myFile) {
myFile.print(millis());
myFile.print(",");
myFile.print(sensor1);
myFile.print(",");
myFile.print(sensor2);
myFile.print(",");
myFile.println(sensor3);
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 {
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:
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.
#include <SoftwareSerial.h>
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)
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...
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 }
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
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.
Voto 5 Votar
Por favor, vote
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)
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:
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++.
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 //
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
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.
3 int counter = 0;
6 void setup()
7 {
8 pinMode(intPin, INPUT_PULLUP);
9 Serial.begin(9600);
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.
4 int counter = 0;
5 long timeCounter = 0;
8 void setup()
9 {
10 pinMode(intPin, INPUT_PULLUP);
11 Serial.begin(9600);
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 {
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.
Voto 5 Votar
Por favor, vote
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.
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.
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.
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.
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.
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.
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
// VCC -> 5V
// DAT -> A0
// http://arubia45.blogspot.com.es/
// 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(){
Valor = analogRead(0);
Serial.print(Valor);
if (Valor <= 300)
Serial.println(" Encharcado");
delay(1000);
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.
Requisitos.
Arduino
Sensor Sharp 2Y0A21 o Sharp 2Y0A02Y.
Cables de Conexión o Jumpers
Protoboard
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
void setup(){
Serial.begin(9600);
pinMode (ir, INPUT);
}
void loop(){
Serial.print("Distancia: ");
Serial.println(dis);
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.
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.
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
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.
////////////////////////////////////////////////
int motorSpeed = 1200; //variable para fijar la velocidad del motor (el retraso entre ca
da secuencia)
int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
void setup() {
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
Serial.begin(9600);
void loop(){
if(count < countsperrev )
count = 0;
else
count++;
void anticlockwise()
setOutput(i);
delayMicroseconds(motorSpeed);
void clockwise()
setOutput(i);
delayMicroseconds(motorSpeed);
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);
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.
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:
ATENCION, si tenéis problemas para descargas estos archivos con Internet Explorer, usar un
explorador alternativo como Chrome, Firefox...
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
Datos de lo Pines
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.
Voto 5 Votar
Por favor, vote
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
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
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 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.
// 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
// 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
// **********************************
rateY=((int)gyro.g.y-dc_offsetY)/100; // Calculo de la velocidad Y en °/s
// **********************************
rateZ=((int)gyro.g.z-dc_offsetZ)/100; // Calculo de la velocidad Z en °/s
Serial.print("\tAnguloY: ");
Serial.print(angleY);
Serial.print("\tVelY: ");
Serial.println(rateY);
Serial.print("\tAnguloX: ");
Serial.print(angleX);
Serial.print("\tVelX: ");
Serial.println(rateX);
}
}
//**************************************
// Promedio de muestras
for(int n=0;n<sampleNum;n++){
gyro.read();
dc_offsetX+=(int)gyro.g.x;
}
dc_offsetX=dc_offsetX/sampleNum;
//**************************************
// Promedio de muestras
for(int n=0;n<sampleNum;n++){
gyro.read();
dc_offsetY+=(int)gyro.g.y;
}
dc_offsetY=dc_offsetY/sampleNum;
//**************************************
// Promedio de muestras
for(int n=0;n<sampleNum;n++){
gyro.read();
dc_offsetZ+=(int)gyro.g.z;
}
dc_offsetZ=dc_offsetZ/sampleNum;
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.
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.
#include <Wire.h>
#include <HMC5883L.h>
void setup(){
Serial.begin(9600);
if(error != 0){
Serial.println(brujula.GetErrorText(error));
}
error = brujula.SetMeasurementMode(Measurement_Continuous);
if(error != 0){
Serial.println(brujula.GetErrorText(error));
void loop(){
Serial.print("Sur");
Serial.print("Suroeste");
Serial.print("Oeste");
Serial.print("Noroeste");
Serial.print("Norte");
Serial.print("Noreste");
Serial.print("Este");
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:
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.
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 */
/***********************/
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
/**************************/
/* popurri para Arduino */
/**************************/
/* 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);
/**********************/
/* 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 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
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.
Voto 5 Votar
Por favor, vote
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.
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.
Voto 5 Votar
Por favor, vote
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 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.
#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"
uint16_t IRAddress = 0;
uint32_t IRCommand = 0;
void setup()
Serial.println("Startup");
IRLbegin<IR_ALL>(interruptIR);
void loop()
cli();
Serial.print("Protocol:");
Serial.println(IRProtocol);
Serial.print("Address:");
Serial.println(IRAddress, HEX);
Serial.print("Command:");
Serial.println(IRCommand, HEX);
IRProtocol = 0;
SREG = oldSREG;
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.
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.
Voto 5 Votar
Por favor, vote
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
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.
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.
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:
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.
VCC.
Señal.
NC.
GND.
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
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.
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
}
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
}
Voto 5 Votar
Por favor, vote
– 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í:
Ú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=''
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:
Voto 5 Votar
Por favor, vote
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:
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í.
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.
Voto 5 Votar
Por favor, vote
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:
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);
}
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:
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>
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:
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);
}
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 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:
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);
}
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
Esquemático:
Code:
/*
LiquidCrystal Library - Hello World
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)
http://www.arduino.cc/en/Tutorial/LiquidCrystal
*/
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);
}
Voto 5 Votar
Por favor, vote
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.
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);
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.