#include <WiFi.h>
#include <DHT.h>
#include "ThingSpeak.h"
#include <Adafruit_BMP085.h>
#include <Ticker.h>

// Configuración de WiFi y ThingSpeak
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* myWriteAPIKey = "XHC72T0TLNIOLIXO";
WiFiClient client;
unsigned long myChannelNumber = 2540012;

// Sensores y Pines
DHT dht(15, DHT22);  // Sensor DHT22 conectado al pin GPIO 15
Adafruit_BMP085 bmp; // Sensor BMP180 (I2C)

Ticker sensorTicker;

// Pines y configuraciones de sensores
const int led = 26;          // Pin GPIO 26 para el LED de movimiento
const int motionSensor = 27; // Pin GPIO 27 para el sensor de movimiento PIR
const int humsuelo = 34;     // Pin GPIO 34 para el sensor de humedad del suelo
const int ledPin = 13;       // Pin GPIO 13 para el LED indicador de humedad del suelo
const int lightPin = 36;     // Pin GPIO 36 para el sensor LDR (medidor de luz)
const int gPin = 33;         // Pin GPIO 33 para el LED verde (indicador de luz)
const int rPin = 25;         // Pin GPIO 25 para el LED rojo (indicador de luz)
const int sensorPin = 32;  // Pin del sensor de velocidad del viento
float veloc1 = 0;           // Variable para la velocidad del viento


// Variables de Tiempo y Movimiento
unsigned long lastTrigger = 0;
bool motion = false;
bool lastMotionState = false;

void setup() {
    Serial.begin(115200);
    dht.begin();
    setupWiFi();
    ThingSpeak.begin(client);
    sensorTicker.attach(10, readSensors);  // Llama a readSensors cada 5 segundos

    // Configuración de pines
    pinMode(led, OUTPUT);
    pinMode(motionSensor, INPUT);
    pinMode(lightPin, INPUT);
    pinMode(gPin, OUTPUT);
    pinMode(rPin, OUTPUT);
    pinMode(humsuelo, INPUT);
    pinMode(ledPin, OUTPUT);
    analogReadResolution(12);         // Establece la resolución de lectura analógica a 12 bits

    // Inicializar BMP180
    if (!bmp.begin()) {
        Serial.println("No se encontró el BMP180, revisar cables");
        while (1) {}
    }
}

void loop() {
    //reconnectWiFi();
    checkPIR();
}

void setupWiFi() {
    WiFi.begin(ssid, password);
    Serial.print("Conectando a ");
    Serial.println(ssid);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("\nConectado.");
}

void reconnectWiFi() {
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("Error: No se pudo conectar a WiFi. Intentando reconectar...");
        WiFi.reconnect();
        delay(1000);
    }
}

void checkPIR() {
    bool motionDetected = (digitalRead(motionSensor) == HIGH);
    if (motionDetected && !motion) {
        motion = true;
        lastTrigger = millis();
        digitalWrite(led, HIGH);
        Serial.println("Movimiento Detectado!!!");
        sendDataToThingSpeak(3, 1);
    }

    if (motion && (millis() - lastTrigger > 10000)) {
        digitalWrite(led, LOW);
        motion = false;
        Serial.println("Movimiento Finalizado");
        sendDataToThingSpeak(3, 0);
    }

    if (motionDetected != lastMotionState) {
        //Serial.print("Estado de Movimiento: ");
        //Serial.println(motionDetected ? "Detectado" : "No Detectado");
        sendDataToThingSpeak(3, motionDetected ? 1 : 0);
        lastMotionState = motionDetected;
    }
}

void readSensors() {
    float temp = dht.readTemperature();
    float humidity = dht.readHumidity();
    int lightVal = analogRead(lightPin);
    int soilHumidity = map(analogRead(humsuelo), 4092, 0, 0, 100);
    int bmpTemp = bmp.readTemperature();
    int bmpPressure = bmp.readPressure();
    float v1 = analogRead(sensorPin);   // Lectura del sensor de velocidad del viento
    veloc1 = v1 * 0.190;                 // Conversión de lectura a velocidad en km/h

    // Imprimir valores de los sensores
    Serial.print("Temperatura DHT22: ");
    Serial.print(temp);
    Serial.println(" °C");
    Serial.print("Humedad DHT22: ");
    Serial.print(humidity);
    Serial.println(" %");
    
    Serial.print("Valor de luz (LDR): ");
    Serial.println(lightVal);
    
    Serial.print("Humedad del suelo: ");
    Serial.print(soilHumidity);
    Serial.println(" %");
    
    Serial.print("Temperatura BMP180: ");
    Serial.print(bmpTemp);
    Serial.println(" °C");
    
    Serial.print("Presión BMP180: ");
    Serial.print(bmpPressure);
    Serial.println(" Pa");

    Serial.print("Anemometro: ");
    Serial.print(veloc1);
    Serial.println(" km/h");

    // Enviar datos a ThingSpeak
    if (!isnan(temp) && !isnan(humidity)) {
        sendDataToThingSpeak(1, temp);
        sendDataToThingSpeak(2, humidity);
    }
    if (lightVal >= 0) {
        sendDataToThingSpeak(4, lightVal);
    }
    if (!isnan(bmpTemp) && !isnan(bmpPressure)) {
        sendDataToThingSpeak(5, bmpTemp);
        sendDataToThingSpeak(6, bmpPressure);
    }
    if (soilHumidity >= 0) {
        sendDataToThingSpeak(7, soilHumidity);
    }

    if (veloc1 >= 0){
      sendDataToThingSpeak(8, veloc1);
    }

    if (lightVal < 700) {
        digitalWrite(gPin, HIGH);
        digitalWrite(rPin, LOW);
    } else {
        digitalWrite(gPin, LOW);
        digitalWrite(rPin, HIGH);
    }

    if (soilHumidity > 75) {
        digitalWrite(ledPin, HIGH); // Enciende el LED si la humedad supera el 75%
    } else {
        digitalWrite(ledPin, LOW);  // Apaga el LED si la humedad es menor o igual al 75%
    }
}

bool sendDataToThingSpeak(int field, float value) {
    int attempts = 3;
    while (attempts > 0) {
        ThingSpeak.setField(field, value);
        int response = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
        if (response == 200) {
            Serial.println("Datos enviados correctamente.");
             delay(5000); // Esperar 5 segundos entre cada envío
            return true;
        } else if (response == -401) {
            //Serial.println("Error de autenticación. Verifica tu clave API y número de canal.");
            return false;  // No reintentar si hay un problema de autenticación
        } else if (response == -210) {
            //Serial.println("Error de conexión. Reintentando...");
        } else {
            //Serial.println("Error al enviar datos. Código de error HTTP: " + String(response));
        }
        attempts--;
        delay(1000);
    }
    return false;
}
$abcdeabcde151015202530fghijfghij
bmp180Breakout