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.

2 comentarios:

  1. hola ... sabes que esta linea me da error

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

    ResponderBorrar
    Respuestas
    1. Va a depender de qué placa estás utilizando!

      Borrar