MQTT a Excel

Un inconveniente que me suelo encontrar al trabajar con sensores remotos es el hecho de monitorear las mediciones y recolectar los datos de forma sencilla. Si bien existen herramientas geniales como ThingSpeak que nos permiten ver los datos en un gráfico; muchas veces trabajamos con equipos que solo implementan un protocolo MQTT y lo necesitamos para operar.

Para ello arme un pequeño programa en Python que permite conectarse a un servidor broker, suscribirse a uno o mas tópicos del servidor e ir registrando en una planilla de cálculo os datos de estos dispositivos remotos.

Además del nombre del servidor, toma el nombre con el que se va a guardar el archivo Excel y la cantidad de registros que deseamos almacenar; si no indicamos este ultimo parámetro la librería solo tomara 10 registros.

Serán los primeros 10 que lleguen, es decir si le indicamos que se suscriba a dos tópicos: TOPIC1 y TOPIC2, y recibimos 9 mensajes de TOPIC1 y solo 1 de TOPIC2 esos serán los 10 registros que se almacenaran en la planilla.

El link al repositorio es el siguiente:
https://github.com/gsampallo/mqtt2excel

Antes de comenzar a utilizarlo será necesario tener instalado Python en la pc además de dos librerías:

1. xlwt Para el manejo de la planilla de cálculo, se instala por medio de pip:

pip install xlwt

2. paho.mqtt brinda la posibilidad de conectarnos a un servidor broker, también lo instalamos por medio de pip:

pip install paho.mqtt

Luego que se haya completado el paso anterior, podemos editar el archivo example.py para adecuarlo a nuestro uso; solo necesitamos modificar en dos puntos:

from MQTT2Excel import MQTT2Excel

broker_server = "AQUI INDICAMOS EL SERVIDOR BROKER"

m2e = MQTT2Excel(broker_server,"demo1.xls")

m2e.setRecordsNumber(50) #indicamos que registre 50 lecturas (la suma de todos los mensajes de los topicos)

m2e.addTopics("TOPICO1") #Indicamos el nombre del topico al que queremos suscribirnos
# Si tuvieramos mas simplemente agregamos una linea con el nombre del segundo topico
# m2e.addTopics("TOPICO2")

m2e.start()

De esta forma el programa tomara 50 lecturas y las almacenara en una planilla excel junto con la fecha y hora en que fue recibido el mensaje.

Luego simplemente es cuestion de ejecutar el programa example.py (pueden cambiarle el nombre si lo desean)

Comenzaremos a ver los datos que llegan desde el dispositivo.

Al cabo de un tiempo tendremos completos los 50 registros (salvo que cambiemos la cantidad que requerimos) y el programa se detendrá.

En ese punto ya dispondremos de nuestro archivo excel.

Como se puede apreciar es bastante sencillo de utilizar, quedan algunas cosas por pulir por ejemplo parametrizar si el servidor broker requiere un usuario y clave (aunque solo basta agregar dos lineas); y llegado el caso detectar el tipo de dato que se recibe para formatear la celda, pero no es un problema mayor en mi caso.

Teclado y pantalla lcd con solo dos pines

Un problema habitual al trabajar con estos componentes es que requieren muchos puertos de nuestro microcontrolador; para el caso de ejemplo utilizaremos un ESP8266, un NodeMCU.

¿Cual es la trampa?

Necesitamos de otro chip que se ocupe de extender los puertos necesarios, para el caso del teclado utilizaremos un MCP23017, es lo que tengo a mano, pero estimo que puede ser cualquier chip de la familia. Requeriremos además tres resistencias de 10k, el diagrama de como conectarlo es el siguiente:

Requeriremos además instalar la librería keypad, si ya la tenemos instalada no será necesario. Para instalar desde el IDE de Arduino, debemos ir al menú Programa – Incluir Librería – Añadir desde ZIP.

Además también sera necesario arduino_keypads-master, simplemente debemos descomprimir dentro de la carpeta Libraries (en mi caso esta en C:\Users\Guillermo\Documents\Arduino\libraries ).

Luego que se hayan instalados estas librerías y construido el circuito anterior, es conveniente chequear cual es la dirección que tiene nuestro chip MCP23017 para poder comunicarnos adecuadamente con él; para ello cargaremos en el nodemcu un sketch para buscar las direcciones disponibles:

Si copia y pega el código verifique que no vayan caracteres incorrectos, tengo la mala experiencia que en oportunidades al pegar no llevar el carácter adecuado. Pueden descargar el zip si lo desean.

#include  <Wire.h>
  
void setup() {
  Wire.begin();
 
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}
 
 
void loop() {
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    } else if (error==4) {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}

Si todo esta correctamente conectado, en el monitor serie deberíamos ver un mensaje como el siguiente:

Donde 0x20 es la dirección de MCP23017.

El paso siguiente seria cargar el ejemplo para poder interactuar con el teclado:

#include <Keypad_MC17.h>
#include <Keypad.h>
#include <Wire.h>

#define I2CADDR 0x20

const byte ROWS = 4; //four rows
const byte COLS = 4; //five columns

char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'#','0','*','D'}
};
byte rowPins[ROWS] = {7, 6, 5, 4};
byte colPins[COLS] = {3, 2, 1, 0};

Keypad_MC17 customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR); 

void setup(){
//  Wire.begin( );
  customKeypad.begin( );        // GDY120705
  Serial.begin(9600);
  Serial.println("Iniciando");
}
  
void loop(){
  char customKey = customKeypad.getKey();
  
  if (customKey != NO_KEY){
    Serial.println(customKey);
  }
}

De esta forma podemos conectar el teclado a una placa NodeMCU, también funciona con Arduino, utilizando solo dos pines.

Queda por ver si es posible utilizar los otros 8 pines restantes del MCP23017 para realizar otras operaciones y ampliar aún mas la cantidad de entradas y salidas.