domingo, 28 de octubre de 2018

Módulo GSM con mqtt

Bueno, hoy (en continuación al post del módulo GSM) les traigo cómo utilizar mqtt con un módulo gsm, hay una librería que se encarga de hacer todo el manejo de gprs y las conexiones y nos da un sistema simplificado. El código es el siguiente:



/**************************************************************
 *
 * For this example, you need to install PubSubClient library:
 *   https://github.com/knolleary/pubsubclient/releases/latest
 *   or from http://librarymanager/all#PubSubClient
 *
 * TinyGSM Getting Started guide:
 *   http://tiny.cc/tiny-gsm-readme
 *
 **************************************************************
 * Use Mosquitto client tools to work with MQTT
 *   Ubuntu/Linux: sudo apt-get install mosquitto-clients
 *   Windows:      https://mosquitto.org/download/
 *
 * Subscribe for messages:
 *   mosquitto_sub -h test.mosquitto.org -t GsmClientTest/init -t 
 *   GsmClientTest/ledStatus -q 1
 * Toggle led:
 *   mosquitto_pub -h test.mosquitto.org -t GsmClientTest/led -q 1 -m 
 *   "toggle"
 *
 * You can use Node-RED for wiring together MQTT-enabled devices
 *   https://nodered.org/
 * Also, take a look at these additional Node-RED modules:
 *   node-red-contrib-blynk-websockets
 *   node-red-dashboard
 *
 **************************************************************/

// elegimos el modem:
#define TINY_GSM_MODEM_SIM800
// #define TINY_GSM_MODEM_SIM808
// #define TINY_GSM_MODEM_SIM900
// #define TINY_GSM_MODEM_A6
// #define TINY_GSM_MODEM_A7
// #define TINY_GSM_MODEM_M590
// #define TINY_GSM_MODEM_ESP8266
// #define TINY_GSM_MODEM_XBEE

#include <TinyGsmClient.h>
#include <PubSubClient.h>

// credenciales de gprs
// en caso de no tener usuario y contraseña no llenar
const char apn[]  = "tuapn";
const char user[] = "";
const char pass[] = "";

// para las placas Mega, Leonardo, Micro utilizar el serie por hardware
#define SerialAT Serial1

// o Software Serial para Uno y Nano
//#include <SoftwareSerial.h>
//SoftwareSerial SerialAT(2, 3); // RX, TX

TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
PubSubClient mqtt(client);

const char* broker = "test.mosquitto.org";

const char* topicLed = "GsmClientTest/led";
const char* topicInit = "GsmClientTest/init";
const char* topicLedStatus = "GsmClientTest/ledStatus";

#define LED_PIN 13
int ledStatus = LOW;

long lastReconnectAttempt = 0;

void setup() {
  pinMode(LED_PIN, OUTPUT);

  // elegimos una velocidad de datos
  Serial.begin(115200);
  delay(10);

  // elegimos la velocidad para el módulo
  SerialAT.begin(115200);
  delay(3000);

  // reiniciamos el módulo, demora mucho
  Serial.println("inicializando modem...");
  modem.restart();

  String modemInfo = modem.getModemInfo();
  Serial.print("Modem: ");
  Serial.println(modemInfo);

  // si la sim tiene contraseña ponerla acá
  //modem.simUnlock("1234");

  Serial.print("esperando por red...");
  if (!modem.waitForNetwork()) {
    Serial.println(" fallo");
    while (true);
  }
  Serial.println(" OK");

  Serial.print("conectando a ");
  Serial.print(apn);
  if (!modem.gprsConnect(apn, user, pass)) {
    Serial.println(" fallo");
    while (true);
  }
  Serial.println(" OK");

  // MQTT Broker setup
  mqtt.setServer(broker, 1883);
  mqtt.setCallback(mqttCallback);
}

boolean mqttConnect() {
  Serial.print("conectando a ");
  Serial.print(broker);
  if (!mqtt.connect("GsmClientTest")) {
    Serial.println(" fallo");
    return false;
  }
  Serial.println(" OK");
  mqtt.publish(topicInit, "GsmClientTest iniciado");
  mqtt.subscribe(topicLed);
  return mqtt.connected();
}

void loop() {

  if (mqtt.connected()) {
    mqtt.loop();
  } else {
    // Reconnect every 10 seconds
    unsigned long t = millis();
    if (t - lastReconnectAttempt > 10000L) {
      lastReconnectAttempt = t;
      if (mqttConnect()) {
        lastReconnectAttempt = 0;
      }
    }
  }

}

void mqttCallback(char* topic, byte* payload, unsigned int len) {
  Serial.print("mensaje recibido [");
  Serial.print(topic);
  Serial.print("]: ");
  Serial.write(payload, len);
  Serial.println();

  // solo lo ejecutamos si coinciden los tópicos
  if (String(topic) == topicLed) {
    ledStatus = !ledStatus;
    digitalWrite(LED_PIN, ledStatus);
    mqtt.publish(topicLedStatus, ledStatus ? "1" : "0");
  }
}



En donde dice "tuapn" en la línea 43, tendremos que ingresar el APN de nuestro proveedor de telefonía, a continuación les dejo los apn de las compañías de argentina:

CLARO: igprs.claro.com.ar
MOVISTAR: wap.gprs.unifon.com.ar usuario: wap contraseña: wap
PERSONAL: datos.personal.com usuario: datos contraseña: datos
TUENTI: internet.movil usuario:internet contraseña: internet

Para otros países solamente hay que googlear: apn nombre_compañia de nombre_país (en mi caso busqué "apn de todas las compañias de argentina").

Esto código sirve para encender un led a través de mqtt por internet (las aplicaciones podrían llegar a ser increíbles, como encender algo a distancia), para hacerlo funcionar tendremos que subscribirnos a los tópicos "GsmClientTest/init" y "GsmClientTest/ledStatus", en el primer tópico el equipo va a notificar cuando se conecte y en el segundo nos va a notificar el estado del led (encendido o apagado). Si publicamos en el tópico "GsmClientTest/led" podremos cambiar el estado del led mandando un mensaje cualquiera en ese tópico.

domingo, 21 de octubre de 2018

LDR

Hoy les traigo un post corto sobre LDR, o resistencias variables por luz. Estas resistencias van a variar según sea la cantidad de luz que reciben y las hay de dos tipos, las que aumentan la resistencia con la luz y las que disminuyen su resistencia con la luz. Estas resistencias son (o al menos eran) muy usadas para hacer lúces automáticas (las que se prenden automáticamente cuando oscurece), aunque el funcionamiento para esas aplicaciones es comparando con un valor de resistencia fijo (cuando el valor de la LDR está por debajo o por encima del valor con el cuál se compara enciende o apaga la luz), nosotros vamos a darle un uso un poco más amplio y vamos a intentar medir la cantidad de lúmenes en luxes. Esto nos va a permitir (saber si es de día o de noche) ampliar nuestra estación meteorológica y conocer las variaciones lumínicas en el tiempo.

Vamos a utilizar la librería "LightDependenResistor" que nos simplifica muchísimo el cálculo de todo. Esta librería se "alimenta" del valor de una resistencia en serie con la LDR y el modelo de la misma. Acá nos topamos con la primer barrera, como saber el modelo de nuestra resistencia variable por luz, esto es un poco difícil, en mi caso empecé a buscar imágenes que coincidieran con mi LDR y luego comencé a buscar los modelos asociados a esas imágenes, en mi caso era la GL5528 (justo coincide con el modelo del ejemplo). Una vez solucionado el tema del modelo realizamos el siguiente circuito:

Esta imágen la saqué del repositorio de github de la librería

y utilizamos el código de ejemplo de la librería, si abrimos el monitor serie de arduino, vamos a ver que nos entrega el valor en lux y en "foot candle" que es otra forma de medir la intensidad de la luz.

En el post de la semana que viene vamos a utilizar este nuevo sensor y la base de datos para realizarle una mejora a nuestra estación meteorológica.