fbpx

Conecta tu proyecto a la Red Global
con el broker MQTT de Centynova

Guía rápida para publicar datos desde tus sensores al broker de Centynova IoT

Centynova Móvil te permite conectar cualquier microcontrolador o módulo compatible con MQTT (como ESP32, ESP8266, SIM800L, SIM7000G, etc.) a su infraestructura de IoT.

A través del broker MQTT de Centynova podrás publicar y consultar datos en tiempo real de manera segura.

¿Qué es el broker MQTT de Centynova?

Es el centro de conexión inteligente donde llegan todos los datos que tus dispositivos generan. Desde módulos con ESP32, ESP8266, SIM800L, SIM7000G, etc.., hasta placas con WiFi o LTE, todo lo que se conecta a Centynova.

Este broker no es para pruebas ni juegos: es la vía oficial para todos los proyectos IoT que usen la red móvil Centynova, con cobertura en todo el mundo.

Datos de conexión

  • Broker (host): mqtt.centynova.com
  • Puerto: 1883
  • Protocolo: MQTT
  • Seguridad: Autenticación obligatoria (credenciales únicas por dispositivo)

Autenticación

Cada dispositivo tiene su propia llave, porque cada conexión es única. Para enviar datos debes incluir:

  • x-api-device → el ID del dispositivo

  • x-api-key → la clave privada generada desde tu panel Centynova

Tu módulo se identifica con estos datos y entra oficialmente a la red IoT Centynova.

Ejemplo con TTGO V1.3 ESP32 + Red IoT

							
							
					/*************************************************
 * TTGO T-Call V1.3 ESP32 + SIM800L + RED IOT .   
 * Sensores: DHT11 
 * MQTT via RED IOT
 * movil.centynova.com
 *************************************************/
 
#define TINY_GSM_MODEM_SIM800
#define TINY_GSM_RX_BUFFER 1024

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

// UART
#define SerialMon Serial
#define SerialAT  Serial1

// Configuración APN Centynova IoT
const char apn[]   = "i-smsr.net";
const char user[]  = "";
const char pass[]  = "";

// Configuración MQTT
const char* mqtt_server = "mqtt.centynova.com";
const int   mqtt_port   = 1883;
const char* mqtt_user   = "[Device ID]";
const char* mqtt_pass   = "[Clave Privada]";

const char* mqtt_topic_temperatura = "[Device ID]/sensores/temperatura";
const char* mqtt_topic_humedad     = "[Device ID]/sensores/humedad"; 

// Pines TTGO T-Call
#define MODEM_RST            5
#define MODEM_PWKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define I2C_SDA              21
#define I2C_SCL              22

// Pines sensores
#define DHTPIN               32
#define DHTTYPE              DHT11 

// IP5306 (power manager)
#define IP5306_ADDR          0x75
#define IP5306_REG_SYS_CTL0  0x00
bool setPowerBoostKeepOn(int en) {
  Wire.beginTransmission(IP5306_ADDR);
  Wire.write(IP5306_REG_SYS_CTL0);
  Wire.write(en ? 0x37 : 0x35);
  return Wire.endTransmission() == 0;
}

// Instancias globales
TinyGsm modem(SerialAT);
TinyGsmClient gsmClient(modem);
PubSubClient client(gsmClient);
DHT dht(DHTPIN, DHTTYPE);

// ------------------------------------
// SETUP: CONFIGURACIÓN INICIAL
// ------------------------------------
void setup() {
  SerialMon.begin(115200);
  delay(10);
  SerialMon.println("Iniciando TTGO T-Call V1.3 con SIM800L...");

  Wire.begin(I2C_SDA, I2C_SCL);
  bool isOk = setPowerBoostKeepOn(1);
  SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));

  pinMode(MODEM_PWKEY, OUTPUT);
  pinMode(MODEM_RST, OUTPUT);
  pinMode(MODEM_POWER_ON, OUTPUT);
  digitalWrite(MODEM_PWKEY, LOW);
  digitalWrite(MODEM_RST, HIGH);
  digitalWrite(MODEM_POWER_ON, HIGH);

  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
  delay(3000);

  SerialMon.println("Inicializando módem SIM800L...");
  if (!modem.restart()) {
    SerialMon.println("❌ ERROR: No se pudo reiniciar el módem.");
    while (true);
  }
  SerialMon.println("✅ Módem SIM800L inicializado correctamente.");

  SerialMon.println("📡 Conectando a la red IOT...");
  if (!modem.waitForNetwork(180000L)) {
    SerialMon.println("❌ ERROR: No se pudo registrar en la red IOT.");
    while (true);
  }
  SerialMon.println("✅ Registro exitoso en la red IOT.");
  SerialMon.print("📡 Operador: ");
  SerialMon.println(modem.getOperator());

  int signalQuality = modem.getSignalQuality();
  SerialMon.print("📶 Señal (RSSI): ");
  SerialMon.println(signalQuality);

  // Intentar conexión red IOT con reintentos
  SerialMon.println("🌐 Conectando a red IOT...");
  bool iot_ok = false;
  for (int i = 0; i < 5 && !iot_ok; i++) {
    SerialMon.print("Intentando red IOT, intento ");
    SerialMon.println(i + 1);
    iot_ok = modem.gprsConnect(apn, user, pass);
    if (!iot_ok) delay(5000);
  }
  if (!iot_ok) {
    SerialMon.println("❌ ERROR: No se pudo conectar a red IOT.");
    while (true);
  }

  if (modem.isGprsConnected()) {
    SerialMon.println("✅ IOT conectado exitosamente.");
  } else {
    SerialMon.println("❌ ERROR: No se logró conectar a red IOT.");
    while (true);
  }

  SerialMon.print("🌐 IP asignada: ");
  SerialMon.println(modem.localIP());

  dht.begin();

 
  client.setServer(mqtt_server, mqtt_port);
  reconnect();
}

// ------------------------------------
// FUNCIÓN PARA REINICIO DEL MÓDEM
// ------------------------------------
void resetModem() {
  SerialMon.println("🔄 Reiniciando módulo SIM800L...");
  digitalWrite(MODEM_RST, LOW);
  delay(100);
  digitalWrite(MODEM_RST, HIGH);
  delay(5000);
  SerialMon.println("✅ Módulo reiniciado.");
}

// ------------------------------------
// FUNCIÓN PARA CONEXIÓN MQTT
// ------------------------------------
void reconnect() {
  while (!client.connected()) {
    Serial.print("Conectando al broker MQTT...");
    String clientId = "ESP32-" + String(random(0xffff), HEX);
    if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {
      Serial.println("MQTT conectado ✅");
    } else {
      Serial.print("Error: ");
      Serial.print(client.state());
      Serial.println(" -> Reintentando en 5 segundos...");
      delay(5000);
    }
  }
}
 

// ------------------------------------
// LOOP: VERIFICACIÓN CONTINUA
// ------------------------------------
int fallosReconexion = 0;

void loop() {
  if (modem.isGprsConnected()) {
    SerialMon.println("✅ Red activa y funcionando...");
    fallosReconexion = 0;

    if (!client.connected()) {
      reconnect();
    }
    client.loop();
// ------------------------------------
// AQUI VAN TUS FUNCIONES:
// ------------------------------------

    obtenerInformacionRedIOT();

    obtenerInformacionTemperaturaHumedad();

// ------------------------------------
// ------------------------------------
  } else {
    SerialMon.println("⚠️ Desconectado de la red IOT. Intentando reconexión...");
    if (modem.gprsConnect(apn, user, pass)) {
      SerialMon.println("✅ Reconexión IOT exitosa.");
      fallosReconexion = 0;
    } else {
      SerialMon.println("❌ Fallo en reconexión IOT.");
      fallosReconexion++;
      if (fallosReconexion > 3) {
        resetModem();
        fallosReconexion = 0;
      }
    }
  }

  delay(300000); // 5 minutos
}


// ------------------------------------
// FUNCIÓN PARA OBTENER INFORMACIÓN RED IOT
// ------------------------------------
void obtenerInformacionRedIOT() {
  SerialMon.println("📡 Obteniendo información de la red IOT");

  SerialMon.print("📶 Señal (RSSI): ");
  SerialMon.println(modem.getSignalQuality());

  SerialMon.print("💳 ICCID de la SIM: ");
  SerialMon.println(modem.getSimCCID());

  SerialMon.print("🌐 IP asignada: ");
  SerialMon.println(modem.localIP());
 
  SerialMon.print("📡 Estado de la red: ");
  SerialMon.println(modem.getRegistrationStatus());

  SerialMon.print("🌐 Red conectado: ");
  SerialMon.println(modem.isGprsConnected() ? "Sí" : "No");
}

// ------------------------------------
// FUNCIÓN SENSOR TEMPERATURA/HUMEDAD
// ------------------------------------
void obtenerInformacionTemperaturaHumedad() {
    float humedad = dht.readHumidity();
    float temperatura = dht.readTemperature();

    if (!isnan(humedad) && !isnan(temperatura)) {
      client.publish(mqtt_topic_temperatura, String(temperatura, 1).c_str());
      client.publish(mqtt_topic_humedad, String(humedad, 1).c_str());
      Serial.println("🌡️ Temp: " + String(temperatura) + " °C | 💧 Humedad: " + String(humedad) + " %");
    } else {
      Serial.println("❌ Error DHT11");
    }
}
				
			

Tu proyecto siempre conectado *

Ejemplo con ESP32 + WiFi

							
					#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "TU_RED_WIFI";
const char* password = "TU_PASSWORD_WIFI";

const char* mqtt_server = "mqtt.centynova.com";
const int mqtt_port = 1883;

const char* deviceID = "6973092336";
const char* apiKey   = "1910378488";

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
}

void reconnect() {
  while (!client.connected()) {
    if (client.connect("ESP32Client", deviceID, apiKey)) {
      // Conectado
    } else {
      delay(2000);
    }
  }
}

void setup() {
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
}

void loop() {
  if (!client.connected()) reconnect();
  client.loop();

  // Publicar en tópico "sensores/humedad"
  float humedad = 55.2;
  client.publish("sensores/humedad", String(humedad).c_str());

  delay(10000); // Cada 10 segundos
}
				
			

No importa si estás usando WiFi o datos móviles. Mientras tengas conectividad, tu proyecto hablará con la red.

¿Cómo organizo mis datos?

Puedes usar cualquier estructura de tópico según tus necesidades, pero te recomendamos seguir el siguiente estándar:

							
					sensores/[tipo]				
			

Ejemplos:

  • sensores/temperatura
  • sensores/humedad
  • alertas/gas
  • ubicacion/gps

Buenas prácticas

  • Usa tópicos separados por tipo de sensor.
  • No publiques datos innecesarios o muy frecuentes (usa intervalos razonables).
  • Utiliza tu panel Centynova para monitorear los datos y generar nuevas llaves.

¿Cómo consultar los datos publicados?

  • Una vez publicados, puedes usar la API REST Centynova IoT para recuperar los datos por tópico o historial completo.
  • Desde tu panel Centynova App
Ir al contenido