/* 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);
}