ARTIK Cloud IoT en acción: Enciendo LEDs

ARTIK Cloud IoT en acción: Enciendo LEDs

¡Donde hay led hay alegría!

Continuando con la serie de tutoriales que empezamos la semana pasada que nos muestra qué se puede hacer en ARTIK Cloud, hoy nos disponemos a comunicar un led de colores con ARTIK Cloud. La comunicación entre los dispositivos y ARTIK Cloud la vamos hacer, en esta ocasión, usando el protocolo de comunicaciones MQTT. Dejaremos las APIs REST y WebSocket para futuros proyectos.
Sobre MQTT no vamos ha entrar en detalles, solamente diremos que es un protocolo de mensajería ligero. Es adecuado para IoT, ya que es eficiente en ancho de banda y usa poca energía de la batería.

 

Componentes

En esta ocasión vamos a necesitar:

Un Arduino con wifi (Arduino MKR1000)*. Personalmente, no tengo todavía ningún Arduino con conectividad wifi. Así que voy a usar un dispositivo esp8266 para ser precisos el nodemcu esp-12e devkit 1.0. Lo vamos a programar como si fuera una Arduino cualquiera (salvando las distancias: los pines no son los mismo, por ejemplo.).

*El no disponer de un MKR1000 (o similar) ha hecho que el proyecto sea más largo (y divertido!) de la cuenta pero no voy a adelantar acontecimientos.

Usaremos el IDE de Arduino para programar el esp8266 (desde ahora lo llamaré ESP).

Una Raspberry. Yo he usado una Raspberry Pi 2 pero se puede usar cualquier otro modelo.

Un led RGB. No os preocupeis si no tenéis un led RGB, aunque el resultado que se consigue con un led RGB mola mucho, podemos usar varios led y encender uno u otro según la señal que le llegue de ARTIK Cloud.

Usaremos cualquier editor de texto plano para la edición de archivos.
Estoy enamorado de Sublime,y cuando no tengo ratón o trackpad, Vi es mi compañero perfecto. ¿Cuál es vuestro editor favorito?

Por último y no menos importante paciencia y buen humor. Recordar que estamos aprendiendo y que es normal que nada salga bien a la primera. Cada vez en los proyectos vamos introduciendo más variables, y nuestro nivel de “estar atentos a que nada falle” debe de subir de nivel. Sólo la experiencia os hará subir de nivel. Cuidar cada detalle con una sonrisa en la cara… Ánimo!

Arquitectura

El led RGB (desde ahora lo llamaré led sin el RGB) estará conectado al esp8266 será quién lo controle en función las acciones que ARTIK Cloud le envíe.
Ahora la explicación de porqué estamos usando la raspberry aquí.

En una sesión MQTT, ARTIK Cloud actúa como broker (el que organiza y maneja los mensajes) y los dispositivos ARTIK Cloud* actúan como clientes. Éstos pueden publicar Mensajes de solo texto en ARTIK Cloud o suscribirse para recibir Acciones de ARTIK Cloud.

*Hablamos de “dispositivo ARTIK Cloud”, que son las abstracciones de nuestros dispositivos reales, lo que nosotros definimos en la parte developer de ARTIK Cloud.

ARTIK Cloud tiene un requisitimo que deben de cumplir los dispositivos que se quieran comunicar con la plataforma mediante el protocolo MQTT y es que el dispositivo debe ser compatible con SSL para que pueda validar el certificado del servidor.
Este es el motivo de por qué no podemos conectar el ESP (o Arduino Uno con la shield Ethernet o similar) directamente con ARTIK Cloud mediante MQTT seguro.
La petición de MQTT segura ocupa más memoria de la que contienen este tipo de dispositivos. Así que nos toca hacer un off-load de MQTT. ¿Dónde la hacemos? En la Raspberry.

La Raspberry será nuestro servidor MQTT local. Además tiene la misión de estar escuchando todo lo que ARTIK Cloud tenga que decir y luego publicarlo, en el canal oportuno pero esta vez sin seguridad.

Es cierto, sé que no lo estamos haciendo bien del todo. Estamos pasando de un entorno seguro a uno que no lo es y es fácilmente manipulable. Pero recordar que estamos aprendiendo y que no tengo mejores componentes.

Esquemático

Este sería el esquemático que vamos a montar.

La raspberry sólo hará de broker. La raspberry debe estar conectada al a misma red donde este conectado nuestro ESP.

Un viaje por la petición

Es muy importante que sepamos hacia dónde vamos para tener claro qué queremos hacer. Parace obvio pero es bueno recordarlo 😉

ARTIK Cloud envía un mensaje (que no es más que un JSON) al canal de nuestro dispositivo. La Raspberry está escuchando (suscrito) ese canal y escucha el mensaje. Cuando lo escucha lo escribe de nuevo en otro canal de su propiedad y local (ARTIK Cloud no sabe que existe este canal). Nuestro ESP está suscrito al canal de la Raspberry, así que todo lo que ella escriba el ESP lo escucha. Así que cuando el ESP escucha la orden enciéndete él lo hace.

Este es el recorrido que debe hacer la petición. Ahora vamos hacerlo 🙂

Crear y conectar un nuevo dispositivo

Aunque ya lo hemos visto en el otro proyecto, vamos a repasarlo rápidamente.
Vamos a crear el ESP en la parte developer

Lo hemos llamado NodeMCU

Vamos a definir los 3 campos que tiene que corresponden con los colores rojo, verde y azul.
Como acciones vamos a ponerle setColorRGB.
Además vamos a restringir el rango de valores de 0 a 255.

Con esto ya tendremos el tipo de dispositivo creado.

Vamos a crear uno en My Cloud.

Sólo es seleccionar el tipo de dispositivos que queremos crear y darle un nombre.


Vamos a generar el token y copiar eso datos.
Hacemos clic en el dispositivo que acabamos de crear.

Y hacemos clic en Generate device token.

Debemos de anotar ese token.

Por cierto, no lo he comentado hasta ahora pero … son mis datos (token device, etc.) no debéis de usarlo. Usar los vuestro 🙂

Configurar Arduino

Vamos a programar el esp8266 con el IDE de Arduino. Para esto hay que configurar el IDE. Esto se hace en dos pasos:
En las preferencias del IDE tenemos que poner:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Luego nos vamos al gestor de tarjetas, que está dentro de dónde seleccionamos qué placa estamos programando e buscamos esp8266.
Instalamos y reiniciamos el IDE

Recomiendo cargar el ejemplo de blink para saber que todo va bien.

Una vez verificamos todo vamos … vamos a programar!

Este es el código:

 
#include
#include
#include

const char* _SSID = "TuWifi"; //Wi-Fi SSID
const char* _PASSWORD = "TuClave"; // Wi-Fi Password

// MQTT params
char mqttCloudServer[] = "192.168.1.135";
int mqttCloudPort = 1883;
char mqttCloudClientName[] = "ARTIK-Arduino"; // or whatever you prefer
char mqttCloudTopic[] = "/v1.1/messages/1ee7070c1d1941499249cea411313cad"; // FIX
char mqttCloudActionsIn[] = "presence";
float insTemp, desTemp, outTemp;
char receivebuf[200]; // Json Data to Artik Cloud
char buf[100];
//led SET
const int redPin = D7;
const int greenPin = D8;
const int bluePin = D6;

WiFiClient wClient;
MQTTClient mqttCloudClient;

void setup() {

Serial.begin(115200);
Serial.println();
Serial.println("Starting ...");
// Wifi Setting
WiFi.begin(_SSID, _PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

Serial.println("start ARTIK Cloud connect");
mqttCloudClient.begin(mqttCloudServer, mqttCloudPort, wClient);
mqttCloudClient.connect(mqttCloudClientName);
delay(500);
Serial.print("Test connection: ");

if (!mqttCloudClient.connected())
{
Serial.println(" Disconnected.");
}
else{
Serial.println(" Connected.");
}

mqttCloudClient.subscribe(mqttCloudActionsIn);
mqttCloudClient.onMessage(messageReceived);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
loadBuffer(0,0,0);

Serial.println("Setup finished.");
}

void loop() {
if (!mqttCloudClient.connected())
{
Serial.println(" Reconnecting...");
mqttCloudClient.connect(mqttCloudClientName);
mqttCloudClient.subscribe(mqttCloudActionsIn);
}
mqttCloudClient.loop();
delay(1000);
}

void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
String t = topic;

if(t == mqttCloudActionsIn)
{
parseBuffer(payload);
}
}

void setColor(int red, int green, int blue)
{
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}

void loadBuffer(int red, int green, int blue) {
StaticJsonBuffer<200> jsonBuffer;
JsonObject& dataPair = jsonBuffer.createObject();

dataPair["D7"] = red;
dataPair["D8"] = green;
dataPair["D6"] = blue;

dataPair.printTo(buf, sizeof(buf));
}

void parseBuffer(String _payload) {
StaticJsonBuffer<200> jsonBuffer;
String json = _payload;

json.toCharArray(receivebuf,200);

JsonObject& root = jsonBuffer.parseObject(receivebuf);
if (!root.success()) {
Serial.println("parseObject() failed");
}

const char* nameparam = root["actions"][0]["name"];
int red = root["actions"][0]["parameters"]["colorRGB"]["red"];
int green = root["actions"][0]["parameters"]["colorRGB"]["green"];
int blue = root["actions"][0]["parameters"]["colorRGB"]["blue"];

Serial.println(nameparam);
Serial.print("red:");
Serial.println(red);
Serial.print("green:");
Serial.println(green);
Serial.print("blue:");
Serial.println(blue);

setColor(red,green,blue);
}

Vamos a explicar el código en línea generales. Como sabemos el código en Arduino se divide en dos la parte de setup y la parte de loop.
En la parte de setup es donde se configura todo lo que vamos ha usar:

Conexión wifi (Cuidad debes de poner tu wifi y tu clave). Mi place ESP sólo soporta 2.4Ghz ojo con el detalle.

 
WiFi.begin(_SSID, _PASSWORD);

Cuando ya tenemos conectividad, nos conectamos al MQTT de la Raspberry. (Sí, lo sé aún no lo hemos configurado, pero por algún lado tenía que empezar. Haz un salto de fe y vamos a configurarlo):
Configuramos la conexión

 
mqttCloudClient.begin(mqttCloudServer, mqttCloudPort, wClient);

Nos conectamos

 
mqttCloudClient.connect(mqttCloudClientName);

Y una vez que nos conectamos nos suscripbimos

 
mqttCloudClient.subscribe(mqttCloudActionsIn);

y le decimos qué hacer con cada mensaje nuevo que llegue.

 
mqttCloudClient.onMessage(messageReceived);

Lo que hacemos con el mensaje JSON que nos llega desde ARTIK Cloud
lo deserializamos

 
json.toCharArray(receivebuf,200);

y los valores los pasamos directamente a los valores de los pines del ESP

 
setColor(red,green,blue);

¿Tienes duda? Dínoslo en los comentarios 😉

Configurando la Raspberry

Antes no lo hemos comentado pero es necesario que la Raspberry esté conectada a internet y sepamos su dirección IP local.

Para empezar siempre es bueno actualizar nuestra pequeña Pi

apt-get update
apt-get upgrade

Luego hemos instalado mosquitto que es nuestro broker de mensajes, hemos instalado npm para trabajar node y hemos instalado la librería mqtt de node.

apt-get install mosquitto
apt-get install mosquitto-clients
apt-get install npm
npm install mqtt --save

La idea como hemos dicho anteriormente es conectar con ARTIK Cloud usando una conexión segura y después publicar todos los mensajes que nos llegue a un canal no seguro.
Esto lo hemos hecho así debido a las limitaciones que tiene nuestro dispositivo esp8266.

Aquí el código:

var mqtt = require('mqtt')
var mqttCloudServer = "mqtts://api.artik.cloud";
var mqttCloudPort = 8883;
var mqttCloudClientName = "ARTIK-Arduino";
var mqttCloudUsername = "1ee7070c1d1941499249cea411313cad";
var mqttCloudPassword = "06b1f87560e24459ae36ce839c16658d";
var mqttCloudActionsIn = "/v1.1/actions/1ee7070c1d1941499249cea411313cad";

var options = {
client_id: mqttCloudClientName,
username: mqttCloudUsername,
password: mqttCloudPassword,
port: mqttCloudPort,
reconnectPeriod: 1000 * 1
}

var client = mqtt.connect(mqttCloudServer, options)
var ARTIKAction = "";

var optionsLocal = {
reconnectPeriod: 1000 * 1
}
var clientLocal = mqtt.connect('mqtt://127.0.0.1', optionsLocal)

clientLocal.on('connect', function() {
clientLocal.subscribe('presence')
})

clientLocal.on('message', function(topic, message) {
// message is Buffer
console.log(message.toString())
})

client.on('connect', function() {
client.subscribe(mqttCloudActionsIn)
});

client.on('message', function(topic, message) {
// message is Buffer
ARTIKAction = message.toString();
console.log(message.toString());
clientLocal.publish('presence', ARTIKAction)
});

client.on("error", function(error) {
console.log("ERROR: ", error);
});

client.on('offline', function() {
console.log("offline");
});

client.on('reconnect', function() {
console.log("reconnect");
});

Al igual que antes vamos a explicarlo muy por encima:
Necesitamos dos clientes, uno que escuche el canal seguro con ARTIK Cloud y otro que publique en el canal local.

var options = {
client_id: mqttCloudClientName,
username: mqttCloudUsername,
password: mqttCloudPassword,
port: mqttCloudPort,
reconnectPeriod: 1000 * 1
}

var client = mqtt.connect(mqttCloudServer, options)

var optionsLocal = {
reconnectPeriod: 1000 * 1
}
var clientLocal = mqtt.connect('mqtt://127.0.0.1',optionsLocal)

Haremos que no se pierda la conexión con el broker haciendo uso de la siguiente línea en las opciones

reconnectPeriod: 1000 * 1

Y aquí está la verdadera función que hace nuestra Pi

client.on('message', function(topic, message) {
// message is Buffer
ARTIKAction = message.toString();
console.log(message.toString());
clientLocal.publish('presence', ARTIKAction)
});

El trozo de código de arriba hace lo siguiente. Cada vez que client (en el caso el cliente que está comunicando con ARTIK Cloud) reciba un mensaje, se lo pasará a clientLocal y éste lo publicará en el canal presence.

Lo reconozco esta parte es la que me ha costado más no sé programar en Node, he tirado las 4 líneas que veis. ¿Alguna sugerencia de mejora? Haznoslo saber en los comentarios.

Dando color

Vamos a ver todo funcionando.
Primero hay que preparar dos sesiones en la raspberry.
En una estamos conectados a ARTIK Cloud. Nos hemos llamado de mosquitto.

mosquitto_sub -h api.artik.cloud -p 8883 -P 06b1f87560e24459ae36ce839c16658d -u 1ee7070c1d1941499249cea411313cad -d -t /v1.1/actions/1ee7070c1d1941499249cea411313cad --capath /etc/ssl/certs/

En la otra sesión hemos lanzado nuestro programa en node

node testMQTT.js

Ademas hemos dejado conectado el ESP al IDE de Arduino así podremos ver su salida.

Para lanzar la acción tenemos que irnos a la parte de My Cloud. Después, nos vamos a nuestro dispostivo y le damos a “Send action to device”

Configuramos los valores con lo que queremos iluminar el led rgb.

Enviamos la acción.

Este es el resultado en la raspberry


Este en la consola de arduino

En todas vemos como se propaga el mensaje de acción

{"actions":[{"name":"setColorRGB","parameters":{"colorRGB":{"red":30,"green":237,"blue":0}}}]}

Y este es el resultado en el led.

Es cierto, que la última foto no corresponde al mismo momento (olvidé sacar una foto) pero el resultado fue el mismo 🙂 además el dispositivo esp8266 es wifi, aquí demostramos la portabilidad del mismo :). Funciona gracias a una bateria Xiaomi.

¡Compartid!

Bola Extra

Si nos hemos venido un poco arriba con el tema de ver luces de colores … sabíais que ARTIK Cloud tiene un app para móviles. Es muy fácil de configurar y el resultado de cambiar el led de color con el móvil mola aquí y en Australia.

Autor: Jawier Andrade

Share This Post On

Deja un comentario

A %d blogueros les gusta esto:
Bitnami