Uso de módulo WiFi Esp8266 con Arduino UNO e IoT en Thingsboard

/* AmbiSensor - Sensor Ambiental (simulación) - IoT (Internet of Things)
   Julio César Sandria Reynoso - Mayo 2026
   Este programa genera aleatoriamente datos ambientales de
   Temperatura, Humedad, CO2 e Iluminación, y los envía a
   un servidor en la nube para poder ver los datos en tiempo
   real desde cualquier dispositivo 
  Hardware: Arduino UNO, Módulo WiFi Esp8266, Fuente de poder para protoboard,
  protoboard, 2 resistencias de 1K, cables dupont.
*/

// Incluimos la librería WiFiEspAT que es más reciente que WiFiEsp
#include <WiFiEspAT.h>

// Si usamos Arduino Mega o Leonardo USAR_MEGA = true
// Si usamos Arduino Uno o Nano USAR_MEGA = false
// const bool USAR_MEGA = true; // true = Arduino Mega | false = Arduino Uno

// Configuración dinámica de puertos Serial según la placa
// usando directivas del precompilador
#if defined(ARDUINO_AVR_MEGA2560) || defined(__AVR_ATmega2560__)
  // Si Arduino IDE detecta un Arduino Mega o Leonardo
  // Conecta pin 18 (TX1) a pin RX del Esp, con divisor de voltaje a 3.3V
  // Conecta pin 19 (RX1) a pin TX del Esp
  #define EspSerial Serial1
#else
  #include <SoftwareSerial.h>
  // En Arduino Uno o Nano:
  // Conecta pin 2 (RX) a pin TX del Esp
  // Conecta pin 3 (TX) a pin RX del Esp, con divisor de voltaje a 3.3V
  SoftwareSerial softSerial(2, 3); 
  #define EspSerial softSerial
#endif

// Credenciales Wi-Fi
const char* ssid     = "nombre-red-wifi";
const char* password = "clave-red-wifi";

// Configuración del servidor ThingsBoard
const char* server   = "thingsboard.cloud";
const int port       = 80;
const char* token    = "TOKEN";

// Variables de ambiente
float temp = 25;          // En grados Celcius
float humedad = 62;       // En porcentaje (%)
int co2 = 450;            // En ppm (partes por millón)
int luz = 780;            // En luxes o valor analógico (0-1023)

void setup() {
  Serial.begin(9600);
  Serial.println("Iniciando programa AmbiSensor - Sensor Ambiental...");

  // Inicializar la comunicación serial con el módulo WiFi Esp8266
  EspSerial.begin(9600); // Velocidades preferentes 115200 (Mega) o 9600 (Uno)

  Serial.println("Inicializando modulo Wi-Fi...");
  WiFi.init(&EspSerial);

  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("No se encontró el módulo Wi-Fi AT");
    while (true); // Detener el programa si no hay módulo
  }

  // Conectar a la red Wi-Fi
  Serial.print("Conectando a Wi-Fi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n¡Conectado a la red!");
}

void loop() {
  // Asegurar que seguimos conectados antes de enviar datos
  if (WiFi.status() == WL_CONNECTED) {
    
    WiFiClient client;
    
    // Abrir conexión TCP con el servidor
    if (client.connect(server, port)) {
      Serial.println("Conectado al servidor de ThingsBoard");

      // *** AQUÍ SE DEBEN TOMAR LECTURAS DE LOS SENSORES REALES ***
      // Para este ejemplo, vamos simulando lecturas aleatorias
      temp += 2-random(5);        // En grados Celcius
      humedad += 2-random(5);     // En porcentaje (%)
      co2 += 7-random(15);        // En ppm (partes por millón)
      luz += 7-random(15);        // En luxes o valor analógico (0-1023)

      // 2. Preparar un JSON con múltiples variables
      // El formato final será: 
      // {"temperature":24.5,"humidity":62.5,"co2":450,"light":780}
      String sDatos = "{";
      sDatos += "\"temperature\":" + String(temp) + ",";
      sDatos += "\"humidity\":" + String(humedad) + ",";
      sDatos += "\"co2\":" + String(co2) + ",";
      sDatos += "\"light\":" + String(luz);
      sDatos += "}";

      // 3. Enviar la petición HTTP POST
      client.print("POST /api/v1/");
      client.print(token);
      client.println("/telemetry HTTP/1.1");
      
      // Encabezados
      client.print("Host: ");
      client.println(server);
      client.println("Content-Type: application/json");
      client.print("Content-Length: ");
      client.println(sDatos.length());
      client.println("Connection: close"); // Buena práctica para liberar memoria en el servidor
      
      // Línea en blanco obligatoria
      client.println(); 
      
      // Cuerpo de los datos (sDatos)
      client.print(sDatos);
      client.println();

      Serial.println("Datos enviados: " + sDatos);

      // 4. Leer la respuesta del servidor (para asegurarnos 
      // del 200 OK, que significa datos recibidos correctamente)
      unsigned long timeout = millis();
      while (client.available() == 0) {
        if (millis() - timeout > 5000) {
          Serial.println(">>> ¡Timeout!");
          client.stop();
          return;
        }
      }

      // Imprimir solo la primera línea (donde viene el código 200) 
      // para no saturar el monitor
      if (client.available()) {
        String status_line = client.readStringUntil('\r');
        Serial.println("Status: " + status_line);
      }

      // Cerrar la conexión
      client.stop();
    } else {
      Serial.println("Error: No se pudo conectar al servidor");
    }
  } else {
    Serial.println("Wi-Fi desconectado. Intentando reconectar...");
  }

  // Esperar 10 segundos antes del siguiente envío
  delay(10000);
}

Deja un comentario