/* NovaGuard Firmware V1 LoRa TX · Sótano · Cliente 102 ESP32 + MQ2 + MQ5 + DHT22 + Agua + Buzzer + LoRa TX Función: - Lee sensores en el sótano. - Genera paquete JSON compacto. - Lo transmite por LoRa al receptor del departamento. - Opcionalmente puede usar WiFi/HTTP si se agrega endpoint. IMPORTANTE: - Ajustar pines según tu placa LoRa real. - Para Heltec ESP32 S3 LoRa SX1262, conviene adaptar a RadioLib o librería oficial Heltec. - Este firmware usa la librería LoRa clásica como base genérica SX127x. */ #include #include #include #define PIN_DHT 4 #define PIN_MQ2 34 #define PIN_MQ5 35 #define PIN_AGUA 32 #define PIN_BUZZER 25 // Pines LoRa genéricos. Ajustar según placa. #define LORA_SS 18 #define LORA_RST 14 #define LORA_DIO0 26 #define LORA_FREQ 433E6 #define DHTTYPE DHT22 DHT dht(PIN_DHT, DHTTYPE); const char* CLIENTE_ID = "102"; const char* EQUIPO_ID = "sotano_tx_102"; const char* UBICACION = "Sotano Garcia"; const int UMBRAL_MQ2 = 1800; const int UMBRAL_MQ5 = 1800; const int UMBRAL_AGUA = 1600; unsigned long lastSend = 0; const unsigned long SEND_INTERVAL = 5000; void iniciarLoRa(){ LoRa.setPins(LORA_SS, LORA_RST, LORA_DIO0); if(!LoRa.begin(LORA_FREQ)){ Serial.println("ERROR: no inicia LoRa"); while(true){ digitalWrite(PIN_BUZZER, HIGH); delay(150); digitalWrite(PIN_BUZZER, LOW); delay(850); } } LoRa.setTxPower(17); LoRa.setSpreadingFactor(10); LoRa.setSignalBandwidth(125E3); LoRa.setCodingRate4(5); LoRa.enableCrc(); Serial.println("LoRa TX listo"); } void enviarLoRa(String payload){ LoRa.beginPacket(); LoRa.print(payload); LoRa.endPacket(); Serial.println("TX LoRa:"); Serial.println(payload); } void setup(){ Serial.begin(115200); delay(800); pinMode(PIN_BUZZER, OUTPUT); digitalWrite(PIN_BUZZER, LOW); dht.begin(); iniciarLoRa(); Serial.println("NovaGuard LoRa TX Sótano listo"); } void loop(){ float temp = dht.readTemperature(); float hum = dht.readHumidity(); int mq2 = analogRead(PIN_MQ2); int mq5 = analogRead(PIN_MQ5); int agua = analogRead(PIN_AGUA); bool alarmaGas = mq2 > UMBRAL_MQ2 || mq5 > UMBRAL_MQ5; bool alarmaAgua = agua > UMBRAL_AGUA; bool alarma = alarmaGas || alarmaAgua; digitalWrite(PIN_BUZZER, alarma ? HIGH : LOW); String payload = "{"; payload += "\"cliente_id\":\"" + String(CLIENTE_ID) + "\","; payload += "\"equipo_id\":\"" + String(EQUIPO_ID) + "\","; payload += "\"ubicacion\":\"" + String(UBICACION) + "\","; payload += "\"tipo\":\"LORA_TX_SOTANO\","; payload += "\"temp\":" + String(temp) + ","; payload += "\"hum\":" + String(hum) + ","; payload += "\"mq2\":" + String(mq2) + ","; payload += "\"mq5\":" + String(mq5) + ","; payload += "\"agua\":" + String(agua) + ","; payload += "\"alarma_gas\":" + String(alarmaGas ? "true" : "false") + ","; payload += "\"alarma_agua\":" + String(alarmaAgua ? "true" : "false") + ","; payload += "\"alarma\":" + String(alarma ? "true" : "false"); payload += "}"; if(millis() - lastSend > SEND_INTERVAL){ lastSend = millis(); enviarLoRa(payload); } delay(500); }