//Importamos las librerias
#include <ESP32Servo.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h> //Javascript object notation
//URL / ruta a conectar
const char* apiEndpoint = "https://automatic-dollop-gww46wq6jwfv5pq-5000.app.github.dev/sensor_bote";
//coneccion a la red
const char* ssid = "Wokwi-GUEST";
const char* password = "";
//variables
const int ServoPin = 27; // declara el pin para el Servo
const int PirPin = 15; // declara el pin para el sensor de movimiento
const int ledPin1 = 14; // declara the bin full indicator led pin
const int ledPinBar[] = {5, 18, 19, 21, 22, 23, 26, 25, 33, 32}; //declara los pines de la grafica de pines
const int PIN_TRIG = 13; // declara el pin trig
const int PIN_ECHO = 4; // declara el pin echo
const int speed = 30; // constante para la velocidad del servo
int lidState = LOW; // Inicializacion asumiendo que el bote esta cerrado
int pirState = LOW; // Inicializacion asumiendo que no hay movimiento
int val = 0; // variable para obtener el estado del sensor
int pos = 90; // variable para la posicion maxima del Servo
bool openLid = false; //variable para abrir el bote
//Variables de valores
int porcentaje;
int contadorInt;
//funcion wifi
void setupWifi(){
Serial.begin(115200);
Serial.print("Connecting to WiFi");
//funcion wifi que se conecta a la red (inicializa la red)
WiFi.begin(ssid, password);
//condicion cuando se esta conectando
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.print(" Connected: ");
//extrae su ip
Serial.println(WiFi.localIP());
}
//crea el objeto servo
Servo servo;
void setup() {
Serial.begin(115200);
//inicializacion para la posicion del servo
servo.attach(ServoPin, 500, 2400);
//declara los pines como input y output respectivamente
pinMode(PirPin, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(PIN_TRIG, OUTPUT);
pinMode(PIN_ECHO, INPUT);
//funcion para declarar todos los leds para la grafica de leds como output
int ledCount = sizeof(ledPinBar) / sizeof(ledPinBar[0]);
for (int i = 0; i < ledCount; i++) {
pinMode(ledPinBar[i], OUTPUT);
}
setupWifi();
}
//envio de datos
void sendData(float capacidad, int porcentaje){
Serial.print("Sending data to API: ");
// Set up HTTP connection with the API endpoint
HTTPClient http;
http.begin(apiEndpoint);
//avisar que es lo que se va a llegar (tipos de datos) de los endpoints
http.addHeader("Content-Type", "application/json");
// Create a JSON document using the ArduinoJson library
StaticJsonDocument<200> doc;
// Agrega los datos para el formato json
doc["capacidad"] = capacidad;
doc["porcentaje"] = porcentaje;
// Serializa los documentos Json a un string
String json;
serializeJson(doc, json);
// Envia un request POST al API
int httpResponseCode = http.POST(json);
if (httpResponseCode > 0){
// Imprime el codigo de respuesta
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
//Deserializa el formato Json recibido del API
// Lee la respuesta del documento Json
DynamicJsonDocument responseDoc(200);
deserializeJson(responseDoc, http.getString());
// Extrae los valores respectivos desde la respuesta Json
String messageString = responseDoc["message"].as<String>(); //Mensaje de respuesta
Serial.println("Received response: " + messageString);
} else{
// Print the error code
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
http.end();
}
//Funcion que calcula la salida del sensor en CM
float distanciaCM() {
digitalWrite(PIN_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(PIN_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PIN_TRIG, LOW);
int duration = pulseIn(PIN_ECHO, HIGH);
return duration * 0.034 / 2;
}
//Funcion para abrir el bote
void open () {
if (lidState == LOW) {
digitalWrite(ledPin1, HIGH);
Serial.println("no motion");
if (pirState == HIGH) {
pirState = LOW;
}
while(pos >= 1) {
servo.write(pos);
pos -= 1;
delay(speed);
}
// pos = 0;
lidState = HIGH;
}
close();
}
//funcion para cerrar el bote
void close() {
if (lidState == HIGH) {
digitalWrite(ledPin1, LOW);
while(pos <= 89) {
servo.write(pos);
pos += 1;
delay(speed);
}
// pos = 90;
lidState = LOW;
}
}
//Inicia la funcion loop
void loop() {
val = digitalRead(PirPin); // Read input value
// Resultado
float capacidad = distanciaCM();
//calculo de porcentaje
porcentaje = (capacidad / 400) * 100;
Serial.println(capacidad);
delay(2500);
//condicion para saber si se detecto un movimiento
if (val == HIGH) {
const int numLeds = 10;
int ledIndex = min(numLeds, static_cast<int>((porcentaje - 1) / (100 / numLeds)) + 1); //calcula el index de los LEDs
for (int i = 0; i < 10; i++) {
digitalWrite(ledPinBar[i], i < ledIndex ? HIGH : LOW);
}
Serial.print("El bote está ");
Serial.print(ledIndex * 10); // Print the percentage
Serial.println("% lleno");
//condicion para saber si ya se lleno el bote
if (porcentaje > 98) {
Serial.println("Vacie el bote");
delay(3500);
}
else{
if (pirState == LOW && porcentaje <= 98) {
pirState = HIGH;
openLid = true;
}
else if (pirState == HIGH || porcentaje > 100) {
pirState = LOW;
close();
}
if (openLid) {
open();
delay(3000); // Adjust the delay based on your requirements
openLid = false; // Reset the flag
}
else {
digitalWrite(ledPin1, LOW);
if (pirState == HIGH) {
pirState = LOW;
}
close();
}
}
sendData(capacidad, porcentaje);
}
}