Arduino (IoT): Tutorial de Sensores Avanzados

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Sensores Avanzados

Ok es cierto, ya sabemos leer datos de un sensor de Temperatura y Humedad.  Estos son datos que podemos obtener fácilmente de muchas fuentes.  Pero si quisiéramos datos mas específicos como para hacer una estación ambiental?

Requisitos:

  1. Computadora (mac)
  2. Arduino UNO.  Aqui utilizamos la UNO por el pinout que es identico al del Grove Shield.  El pinout (osea las conexiones) de la MEGA son ligeramente distintas.
  3. Sensores CO2 & Polvo (Dust) tipo Grove
  4. Breadboard
  5. Grove Shield
  6. Arduino IDE (https://www.arduino.cc/en/Main/Software)

La tarjeta Grove Shield es una shield y como tal se ensambla sobre la UNO.

Arduino Grove Tutorial Santiapps Marcio Valenzuela
Arduino Grove Shield

Esta shield tiene 4 puertos para sensores análogos, 8 puertos para sensores digitales y 4 puertos para sensores con conexión tipo I2C que es un protocolo de conexión digital avanzada.

Nosotros estaremos usando 2 sensores; (1) de CO2 y (2) de Dust o Polvo.  Iniciemos con el sensor de polvo:

Arduino Grove Dust Sensor de Polvo Tutorial Santiapps Marcio Valenzuela
Arduino Grove Dust Sensor de Polvo

Es tan sencillo como conectarlo a uno de los puertos digitales marcados con una “D” en la Grove shield y luego ensamblar la Grove Shield sobre la UNO de la siguiente manera:

Arduino Dust Sensor Tutorial Santiapps Marcio Valenzuela
Arduino Dust Sensor Tutorial

El código es aun mas sencillo:

int pin = 2;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 30000;//sampe 30s ;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
void setup() {
Serial.begin(9600);
pinMode(8,INPUT);
starttime = millis();//get the current time;
}
void loop() {
duration = pulseIn(pin, LOW);
lowpulseoccupancy = lowpulseoccupancy+duration;
if ((millis()-starttime) > sampletime_ms)//if the sampel time == 30s
{
ratio = lowpulseoccupancy/(sampletime_ms*10.0); // Integer percentage 0=>100
concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
Serial.print(lowpulseoccupancy);
Serial.print(",");
Serial.print(ratio);
Serial.print(",");
Serial.println(concentration);
lowpulseoccupancy = 0;
starttime = millis();
}
}

De donde sale el código para saber que el dato que genera el sensor, aqui leido como pulseIn, es lo que es y que significa?  Facil!  El fabricante de los sensores suele proveer la documentación que define los datos:

http://www.seeedstudio.com/wiki/Grove_-_Dust_Sensor

En este caso el fabricante de la Grove Shield da la información necesaria pero los fabricantes de los módulos también.

Subamos el código a la UNO.

El resultado de este proyecto se puede ver aquí:

Arduino Dust Sensor Grove Tutorial Santiapps Marcio Valenzuela
Arduino Dust Sensor Grove

 

También tenemos a disposición un sensor de CO2.  En este caso conectas el sensor al D8 de la Grove Shield (D8 usa los pines 7 & 8).  El sensor es este:

Arduino Tutorial Grove CO2 Sensor Santiapps Marcio Valenzuela
Arduino Tutorial Grove CO2 Sensor

El código es un poco mas complejo pero repasémoslo brevemente:

#include <SoftwareSerial.h>
#define DEBUG 0
const int pinRx = 8;
const int pinTx = 7;
SoftwareSerial sensor(pinTx,pinRx); //Definimos los pines Rx/Tx
const unsigned char cmd_get_sensor[] = {
0xff, 0x01, 0x86, 0x00, 0x00,
0x00, 0x00, 0x00, 0x79
};
unsigned char dataReceive[9]; //Creamos un array de data
int temperature;
int CO2PPM; //Creamos un par de variables
void setup() {
sensor.begin(9600);
Serial.begin(115200);
Serial.println("get a 'g', begin to read from sensor!");
Serial.println("********************************************************");
Serial.println(); // iniciamos el monitor serial
}
void loop() {
if(dataReceive()) {
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print(" CO2: ");
Serial.print(CO2PPM);
Serial.println(""); //Si recibimos data, la imprimimos
}
delay(1000);
}
bool dataReceive(void) { //la data la pedimos al sensor
byte data[9];
int i = 0;
//transmit command data
for(i=0; i<sizeof(cmd_get_sensor); i++) {
sensor.write(cmd_get_sensor[i]);
}
delay(10);
//begin reveiceing data
if(sensor.available()) { //Si el sensor esta disponible...
while(sensor.available()) {
for(int i=0;i<9; i++) {
data[i] = sensor.read(); //Leemos la data
}
}
}
#if DEBUG
for(int j=0; j<9; j++) {
Serial.print(data[j]);
Serial.print(" ");
}
Serial.println("");
#endif
if((i != 9) || (1 + (0xFF ^ (byte)(data[1] + data[2] + data[3]
+ data[4] + data[5] + data[6] + data[7]))) != data[8]) {
return false; //Verificamos que la data es valida
}
CO2PPM = (int)data[2] * 256 + (int)data[3];
temperature = (int)data[4] - 40;
return true; //Si es valida, la almacenamos en las variables creadas
}

Los resultados son así:

Arduino Sensor CO2 Grove Tutorial Santiapps Marcio Valenzuela
Arduino Sensor CO2 Grove Tutorial

Ok ya sabemos utilizar varios sensores para crear una estación de datos (en este caso ambiental) que genere los datos.  Que tal si:

  • Pudiéramos comunicar esos datos a otros dispositivos?
  • Y si esos dispositivos estuvieran conectados al internet?
  • Quizás podríamos crear un web service que provea datos al publico!

Que interesante!  Veamos como podemos ahora conectar una MEGA al internet 🙂

Arduino (IoT) Video Serie: Kit de Carro Parte 7 (Guante)

Arduino Honduras Santiapps Marcio Valenzuela

Arduino (IoT): MPU6050 Accelerometro para Carro 4×4 Parte 7 (Control de Carro via Guante)

En un tutorial anterior vimos como crear un carro 4×4 y controlarlo via instrucciones:

  • Pre-cargadas en el codigo
  • Via IR
  • Via Bluetooth
  • Via Sensor Ultrasonico

En otro tutorial anterior vimos como usar un accelerometer MPU6050 para visualizar movimiento (aceleración) en cualquiera de los 3 ejes de las 3 dimensiones espaciales.  Usamos los datos del sensor para mover una gráfica de una ‘aeroplano’ en un programa llamado Processing y así visualizar el movimiento de nuestro sensor en una pantalla:

Ahora veremos como combinar los datos de aceleración espacial para controlar un carro 4×4:

Arduino (IoT): Video Serie Smart Car 4WD Kit Auto-dirigido by Santiapps Marcio Valenzuela
Arduino (IoT): Video Serie Smart Car 4WD Kit Auto-dirigido

Las conexiones serian las mismas que las del ultimo carro, el 4×4, pero desconectamos el servo que gira el ultrasonido y usamos la conexión al pin 2 como la data que entrará del sensor IR.

La idea es conectar una nano (la cual debido a su tamaño puede ser montada en un guante) y adjuntarle un sensor MPU6050 y un modulo Tx de IR para enviar la aceleración del MPU6050 al receptor Rx.  Del lado del Rx estara nuestra UNO con la L293D shield que teníamos en el carro 4×4 ultrasonido.

El Jumper

Este jumper cuando esta interrumpido significa que la L293D usará la potencia de la fuente externa (las 4xAA) para los motores y debemos suplir una fuente alterna para la Arduino UNO.  Anteriormente solo usábamos 2 motores por lo cual no era necesario mas potencia pero ahora que usaremos 4 motores si es necesario.  Es decir, los 4 motores se usaran de manera mas continua debido a que el Arduino se continuara moviendo en distintas direcciones mientras decide cual es el mejor camino para avanzar.

Una vez removido el jumper, podemos conectar ambas fuentes de poder y listo!

Analicemos el código final para el transmisor:

#include <IR.h>
#include <SPI.h>
#include "Wire.h" //For communicate
#include "I2Cdev.h" //For communicate with MPU6050
#include "MPU6050.h" //The main library of the MPU6050
MPU6050 mpu;

int data[2];
void setup() {
Serial.begin(9600);
mpu.initialize(); //Initialize the MPU object
}
void loop() {
delay(2000); // Delay so DHT-22 sensor can stabalize

data[0] = map(350, -17000, 17000, 300, 400 ); //Send aX axis data
data[1] = map(155, -17000, 17000, 100, 200); //Send aY axis data
Serial.println(data[0]);
Serial.println(data[1]);
}

y para el codigo receptor:

// Include dependant SPI Library 
#include  
#include 
//Define packet for the direction (X axis and Y axis)
int data[2];

AF_DCMotor motor1(1, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
AF_DCMotor motor2(2, MOTOR12_64KHZ); // create motor #2, 64KHz pwm
AF_DCMotor motor3(3, MOTOR12_64KHZ); // create motor #3, 64KHz pwm
AF_DCMotor motor4(4, MOTOR12_64KHZ); // create motor #4, 64KHz pwm

String str_out;

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

void loop() {
// Set buffer to size of expected message
    int receivedData[3] = {0};
    uint8_t buflen = sizeof(receivedData);
    if (rf_driver.recv((uint8_t*)receivedData, &buflen)) {
       for (byte i = 0; i < 3; i++) { Serial.print(receivedData[i]); Serial.println("..."); //Serial.print('\t');} if(receivedData[0] > 380){left(); Serial.println("LEFT"); //motor back left}
    if(receivedData[0] < 310){ right(); Serial.println("RIGHT"); //motor back right } if(receivedData[1] > 180){ forward(); Serial.println("FORWARD"); //motor bl and br direction 1}
    if(receivedData[1] < 110){ backward(); Serial.println("BACKWARD"); //motor bl and br direction 2 } if(receivedData[0] > 330 && receivedData[0] < 360 && receivedData[1] > 130 && receivedData[1] < 160);
      //brake();
      stopCar();
      Serial.println("STOP");
    }
  }
}

void forward(){
  Serial.println("running forward");
  motor1.run(FORWARD);   
  motor2.run(FORWARD);
  motor3.run(FORWARD);   
  motor4.run(FORWARD);     

}
void backward(){
  Serial.println("running backward");
  motor1.run(BACKWARD);   
  motor2.run(BACKWARD);
  motor3.run(BACKWARD);    
  motor4.run(BACKWARD);    
}

void left(){
  motor3.run(FORWARD);   
  //motor3.run(BACKWARD);   
}
void right(){
  motor4.run(FORWARD);    
  //motor3.run(FORWARD);     
}

void brake(){
  motor1.run(RELEASE);    
  motor2.run(RELEASE);    
  motor3.run(RELEASE);    
  motor4.run(RELEASE);      
}

void stopCar(){
  motor1.run(RELEASE);    
  motor2.run(RELEASE);    
  motor3.run(RELEASE);    
  motor4.run(RELEASE);     
}

Aquí esta el video:

Arduino (IoT): Simple Tutorial Bluetooth & Servo

Arduino Honduras Santiapps Marcio Valenzuela

Tutorial Bluetooth & Servo

 

Esta vez vamos a mover el Servo, pero en lugar de dejar los datos escritos adentro del código o usar el monitor serial para enviarlos al motor, los vamos a enviar desde un dispositivo con Bluetooth.
Usaremos el BT de un celular para enviar la data.  Para esto es necesario bajar una aplicación que envia datos por Bluetooth. Podríamos crear una pero se sale un poco del tema Arduino.  Además hay varias aplicaciones en las tiendas de apps que ya hacen eso.
Lo haremos con un Android pero también se puede desde una laptop o tablet.
Requerido
  1. Computadora (mac)
  2. Arduino MEGA (u otra similar como UNO)
  3. Breadboard
  4. Motor Servo
  5. Modulo Bluetooth HC-05 (u otro similar Master/Slave)
  6. Arduino IDE
Conexiones…los módulos BT son sencillos.
Arduino Bluetooth Servo Tutorial Santiapps Marcio Valenzuela
Arduino Bluetooth Servo Tutorial
Tienen sus pines 5V y GND y tienen pines de Rx y Tx.  Aquí es importante destacar 2 cosas:
Módulos son un componente que cumple una función específica, única y sencilla así como el sensor DHT11 o el modulo BT.  Los pines vienen “al aire” y fácilmente se les conectar los cables.  Los módulos son relativamente pequeños.
Shields son los mismos módulos integrados (soldados) a una tarjeta pequeña de circuito integrado.  Cumplen la misma función pero por le general traen una composición de pines idéntica a las tarjetas para las cuales fueron creadas.  Estas Shields están diseñadas para encajar directamente sobre la tarjeta microcontroladora.  Es decir los pines de la shield se alinean perfectamente con los de la tarjeta principal.  Por ejemplo una shield de BT para la UNO trae el mismo numero de pines y en la misma secuencia que la UNO.  Una shield BT para la UNO no encajar perfectamente con una MEGA.
El segundo punto importante a destacar es que las tarjetas están diseñadas para comunicarse via pero serial.  Para ello se necesita un pin de transmisión (Tx) y uno de recepción (Rx).  En la UNO son los pines 0&1.  Estos son hardware pins.  Sin embargo es posible crear software pies usando una library llamada software serial. Esto es común y lo usaremos porque piensen en lo siguiente:
La MEGA necesita una comunicación con la computadora.  Esto se logra vida un puerto serial pero en realidad conectamos a la computadora vida un cable USB.  Esto es porque en la tarjeta hay un componente llamado USB-to-Serial converter que hace el trabajo de convertir entre ambos protocolos.  Necesitamos esos pines 0&1 para transmisión de data entre la computadora y la tarjeta.  Así es como cargamos el código a la tarjeta y también como visualizamos la data en el monitor serial.  Pero ahora vamos a querer comunicarnos vía BT.  El modulo BT se tiene que comunicar con la tarjeta usando otros pines!  Por eso tendremos que crear software pies alternos.
Las conexiones son 4 del modulo BT al breadboard y a la MEGA:
– VCC es al 5V de la MEGA
– GND es al GND de la MEGA
– Tx es al Rx de la MEGA
– Rx es al Tx de la MEGA
Arduino Bluetooth Servo Tutorial Santiapps Marcio Valenzuela
Arduino Bluetooth Servo
OJO con el Tx/Rx de la MEGA.  En nuestro caso usamos un puerto serial de software y no de hardware.  Es decir que no usaremos los pines 0 (Rx) & 1 (Tx) en la MEGA.  En lugar de eso, usaremos los pines que designemos nosotros para poder ver los datos en el monitor serial (el cual usa los pines 0 & 1).  En nuestro código designamos los pines 10 & 11 como veremos a continuación.
Es necesario bajar una app gratuita en Android llamada BlueSPP.  Es una app que simplemente envía comandos a un dispositivo BT.  Puede ser cualquier app que envíe comandos a una terminal BT.  Creo que también hay para iOS.
Una vez descargada, es importante conectarse el modulo bluetooth el cual aparece como HC-05 y su clave de pairing por lo general es 1234.  Ahora estamos listos para enviar comandos al modulo BT.
Arduino Bluetooth Servo Tutorial Santiapps Marcio Valenzuela
Arduino Bluetooth Servo
Arduino Bluetooth Servo Tutorial Santiapps Marcio Valenzuela
Arduino Bluetooth Servo
Código

#include <Servo.h>
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(11,10); //Rx, Tx method signature
Servo myServo;
void setup() {
delay(500); // esperar que arranque modulo BT
bluetooth.begin(9600); // Iniciar el BT
Serial.begin(57600);// Esto solo es para leer el Serial
myServo.attach(4, 1000, 2000); // Normalmente 544 & 2400
}
void loop() {
if(bluetooth.available()>0) {
char c = (char)bluetooth.read();
bluetooth.println(c);
if(c=='1') { // Si los datos leidos en el BT = 1
myServo.write(1000); //escribir esta posición
}
if(c=='0') { // Si los datos leídos son = 0
myServo.write(2000);
}
}
}
Resultado
https://youtu.be/oPlRZLOwtqA
Podríamos modificar el código para que envíe exactamente la posición que queremos también.  Lo dejaremos para otro tutorial mas avanzado pero básicamente involucra recibir carácter por carácter del BT, almacenando en un array y luego usándolo para mover el motor.

Excelente!  Hemos ingresado al mundo de las comunicaciones.  Esto abre el abanico de oportunidades de proyectos:

  • Todo lo que hemos hecho hasta ahora lo podremos hacer via bluetooth, es decir, remotamente.
  • Piensa en los flujos de electricidad que puedes controlar hacia luces, motores, válvulas, juguetes, otros robots, sensores!
  • Mas importante, ya tenemos la base para otros tipos de comunicación los cuales exploraremos pronto; WiFi, GPRS etc.

Ahora compliquemos un poco un robot de sensores para luego poder complicar asi mismo sus habilidades de comunicación!