Envió de datos por GPRS y esp32 a un servidor remoto
2 meses hace adminComponentes Necesarios
-
ESP32
-
Módulo SIM800L
-
Sensor DHT11 o DHT22
-
Fuente de alimentación para SIM800L (3.7V-4.2V)
-
Cables y protoboard
???? Esquema de Conexiones
text
ESP32 SIM800L ----- ------- 3.3V --> VCC GND --> GND GPIO16 --> TX GPIO17 --> RX ESP32 DHT11/DHT22 ----- ----------- 3.3V --> VCC GND --> GND GPIO4 --> DATA
???? Código Arduino IDE
cpp
#include <HardwareSerial.h> #include <DHT.h> // Configuración del DHT #define DHT_PIN 4 #define DHT_TYPE DHT11 DHT dht(DHT_PIN, DHT_TYPE); // Configuración SIM800L HardwareSerial sim800(1); // Usar UART2 // Configuración del servidor const char* SERVER = "tudominio.com"; const char* PATH = "/api/temperatura.php"; const int PORT = 80; // Variables para datos float temperatura = 0; float humedad = 0; void setup() { Serial.begin(115200); dht.begin(); // Inicializar SIM800L sim800.begin(9600, SERIAL_8N1, 16, 17); // RX=16, TX=17 Serial.println("Iniciando sistema..."); // Configurar módulo GSM inicializarGSM(); delay(5000); } void loop() { // Leer sensor leerSensor(); // Enviar datos al servidor if (enviarDatosServidor()) { Serial.println("Datos enviados correctamente"); } else { Serial.println("Error al enviar datos"); } // Esperar 5 minutos antes de la siguiente lectura delay(300000); } void leerSensor() { temperatura = dht.readTemperature(); humedad = dht.readHumidity(); if (isnan(temperatura) || isnan(humedad)) { Serial.println("Error leyendo el sensor DHT"); temperatura = 0; humedad = 0; return; } Serial.print("Temperatura: "); Serial.print(temperatura); Serial.print("°C, Humedad: "); Serial.print(humedad); Serial.println("%"); } void inicializarGSM() { Serial.println("Configurando módulo GSM..."); // Esperar que el módulo esté listo delay(10000); // Comandos de configuración básicos enviarComando("AT", "OK", 5000); enviarComando("AT+CPIN?", "READY", 5000); enviarComando("AT+CREG?", "0,1", 5000); enviarComando("AT+CGATT?", "1", 5000); enviarComando("AT+CSQ", "OK", 5000); enviarComando("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK", 5000); enviarComando("AT+SAPBR=3,1,\"APN\",\"internet\"", "OK", 5000); enviarComando("AT+SAPBR=1,1", "OK", 5000); enviarComando("AT+HTTPINIT", "OK", 5000); } bool enviarComando(String comando, String respuesta, int timeout) { Serial.print("Enviando: "); Serial.println(comando); sim800.println(comando); unsigned long startTime = millis(); String response = ""; while (millis() - startTime < timeout) { if (sim800.available()) { char c = sim800.read(); response += c; Serial.write(c); } if (response.indexOf(respuesta) != -1) { Serial.println("Comando exitoso"); return true; } } Serial.println("Timeout en comando"); return false; } bool enviarDatosServidor() { // Construir los datos POST String postData = "temperatura=" + String(temperatura) + "&humedad=" + String(humedad); // Configurar HTTP String comandoHTTP = "AT+HTTPPARA=\"URL\",\"http://" + String(SERVER) + String(PATH) + "\""; if (!enviarComando(comandoHTTP, "OK", 10000)) return false; // Configurar contenido if (!enviarComando("AT+HTTPPARA=\"CONTENT\",\"application/x-www-form-urlencoded\"", "OK", 5000)) return false; // Configurar tamaño de datos String dataLength = "AT+HTTPDATA=" + String(postData.length()) + ",10000"; if (!enviarComando(dataLength, "DOWNLOAD", 5000)) return false; // Enviar datos sim800.print(postData); delay(5000); // Realizar petición POST if (!enviarComando("AT+HTTPACTION=1", "200", 15000)) return false; // Cerrar HTTP enviarComando("AT+HTTPTERM", "OK", 5000); return true; }
???? Código PHP para el Servidor
temperatura.php
php
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
// Configuración de la base de datos
$servername = "localhost";
$username = "tu_usuario";
$password = "tu_password";
$dbname = "nombre_base_datos";
// Crear conexión
$conn = new mysqli($servername, $username, $password, $dbname);
// Verificar conexión
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Obtener datos POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$temperatura = isset($_POST['temperatura']) ? floatval($_POST['temperatura']) : null;
$humedad = isset($_POST['humedad']) ? floatval($_POST['humedad']) : null;
if ($temperatura !== null && $humedad !== null) {
// Preparar y ejecutar consulta
$stmt = $conn->prepare("INSERT INTO temperaturas (temperatura, humedad, fecha) VALUES (?, ?, NOW())");
$stmt->bind_param("dd", $temperatura, $humedad);
if ($stmt->execute()) {
echo json_encode(array("status" => "success", "message" => "Datos guardados"));
} else {
echo json_encode(array("status" => "error", "message" => "Error al guardar"));
}
$stmt->close();
} else {
echo json_encode(array("status" => "error", "message" => "Datos incompletos"));
}
} else {
echo json_encode(array("status" => "error", "message" => "Método no permitido"));
}
$conn->close();
?>
????️ Estructura de la Base de Datos MySQL
sql
CREATE DATABASE iot_temperatura; USE iot_temperatura; CREATE TABLE temperaturas ( id INT AUTO_INCREMENT PRIMARY KEY, temperatura DECIMAL(4,2) NOT NULL, humedad DECIMAL(4,2) NOT NULL, fecha DATETIME DEFAULT CURRENT_TIMESTAMP ); -- Opcional: Crear usuario específico para la aplicación CREATE USER 'iot_user'@'localhost' IDENTIFIED BY 'password_seguro'; GRANT INSERT, SELECT ON iot_temperatura.temperaturas TO 'iot_user'@'localhost'; FLUSH PRIVILEGES;
???? PHP para Mostrar los Datos
mostrar_datos.php
php
<?php // Configuración de la base de datos $servername = "localhost"; $username = "tu_usuario"; $password = "tu_password"; $dbname = "nombre_base_datos"; // Crear conexión $conn = new mysqli($servername, $username, $password, $dbname); // Verificar conexión if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Obtener últimos 50 registros $sql = "SELECT temperatura, humedad, fecha FROM temperaturas ORDER BY fecha DESC LIMIT 50"; $result = $conn->query($sql); ?> <!DOCTYPE html> <html> <head> <title>Datos de Temperatura y Humedad</title> <style> table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } tr:nth-child(even) { background-color: #f9f9f9; } </style> </head> <body> <h1>Registros de Temperatura y Humedad</h1> <?php if ($result->num_rows > 0): ?> <table> <tr> <th>Temperatura (°C)</th> <th>Humedad (%)</th> <th>Fecha y Hora</th> </tr> <?php while($row = $result->fetch_assoc()): ?> <tr> <td><?php echo $row["temperatura"]; ?></td> <td><?php echo $row["humedad"]; ?></td> <td><?php echo $row["fecha"]; ?></td> </tr> <?php endwhile; ?> </table> <?php else: ?> <p>No hay datos disponibles</p> <?php endif; ?> <?php $conn->close(); ?> </body> </html>
⚙️ Configuración Adicional
1. Configuración APN (depende de tu operador)
cpp
// Para Movistar México: enviarComando("AT+SAPBR=3,1,\"APN\",\"internet.movistar.mx\"", "OK", 5000); // Para Telcel: enviarComando("AT+SAPBR=3,1,\"APN\",\"internet.itelcel.com\"", "OK", 5000); // Para AT&T: enviarComando("AT+SAPBR=3,1,\"APN\",\"proxy.movil.att.com.mx\"", "OK", 5000);
2. Mejoras del Código
cpp
// Agregar manejo de errores mejorado void manejarErrorGSM() { Serial.println("Reiniciando módulo GSM..."); // Agregar lógica de reinicio si es necesario } // Función para verificar conexión GPRS bool verificarConexionGPRS() { return enviarComando("AT+CGATT?", "1", 5000); }
???? Solución de Problemas Comunes
-
SIM800L no responde: Verificar alimentación (usar fuente externa)
-
Error de conexión GPRS: Verificar APN y saldo de la SIM
-
Datos incorrectos del sensor: Verificar conexiones del DHT
-
Error 403 en servidor: Verificar permisos del archivo PHP
Este sistema te permitirá monitorear temperatura y humedad de forma remota usando GSM/GPRS y almacenar los datos en una base de datos MySQL.
