Dispensador Automático de Agua con Monedas usando ESP32

 Materiales Necesarios

  • 1 × ESP32 (NodeMCU ESP32 o similar)

  • 1 × Display LCD 16×2 con módulo I2C

  • 2 × Botones pulsadores

  • 1 × Sensor de monedas (lector de monedas de 5 unidades)

  • 1 × Sensor de presencia (infrarrojo o ultrasonido)

  • 1 × Bomba de agua DC 5-12V

  • 1 × Relé para controlar la bomba de agua

  • 1 × Depósito de agua

  • 1 × Tubo para dispensar agua

  • 1 × Recipiente para monedas

  • 1 × Diodo LED (indicador de estado)

  • 1 × Resistencia 220Ω para el LED

  • 2 × Resistencias 10kΩ (opcional, para botones si no usa pull-up interno)

  • 1 × Fuente de alimentación 12V para la bomba

  • 1 × Regulador de voltaje 5V para el ESP32

  • Cables y protoboard

 Construcción

1. Conexiones Eléctricas

LCD I2C:

  • SDA → GPIO 21 (ESP32)

  • SCL → GPIO 22 (ESP32)

  • VCC → 5V

  • GND → GND

Botones (con pull-up interno):

  • Botón 1L → GPIO 13

  • Botón 0.5L → GPIO 12

  • Ambos botones conectados también a GND

Sensor de Monedas:

  • Señal → GPIO 14

  • VCC → 5V

  • GND → GND

Sensor de Presencia:

  • Trig → GPIO 27 (si es ultrasonido)

  • Echo → GPIO 26 (si es ultrasonido)

  • VCC → 5V

  • GND → GND

  • (Si es IR, OUT → GPIO 27)

Bomba de Agua:

  • Control a través de relé

  • Relé IN → GPIO 33

  • VCC del relé → 5V

  • GND del relé → GND

LED Indicador:

  • Ánodo → GPIO 32 con resistencia 220Ω

  • Cátodo → GND

2. Montaje Mecánico

  1. Instalar el depósito de agua en la parte superior

  2. Colocar la bomba de agua cerca del depósito

  3. Montar el tubo dispensador con el sensor de presencia

  4. Instalar el lector de monedas en una ranura accesible

  5. Fijar el display LCD en un lugar visible

  6. Colocar los botones de selección de cantidad

 Código Programa

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Configuración del LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Dirección I2C 0x27, display 16x2

// Pines
const int boton1L = 13;
const int boton05L = 12;
const int sensorMoneda = 14;
const int sensorPresencia = 27;
const int releBomba = 33;
const int ledIndicador = 32;

// Variables
int credito = 0;
bool recipientePresente = false;
unsigned long tiempoDispensado = 0;
bool dispensando = false;

// Precios
const int precio1L = 10;
const int precio05L = 5;

void setup() {
  Serial.begin(115200);
  
  // Inicializar LCD
  lcd.init();
  lcd.backlight();
  lcd.clear();
  
  // Configurar pines
  pinMode(boton1L, INPUT_PULLUP);
  pinMode(boton05L, INPUT_PULLUP);
  pinMode(sensorMoneda, INPUT);
  pinMode(sensorPresencia, INPUT);
  pinMode(releBomba, OUTPUT);
  pinMode(ledIndicador, OUTPUT);
  
  digitalWrite(releBomba, LOW); // Asegurar que la bomba está apagada
  digitalWrite(ledIndicador, LOW);
  
  mostrarMensajeInicial();
}

void loop() {
  // Leer sensor de presencia
  recipientePresente = digitalRead(sensorPresencia) == HIGH;
  
  // Detectar monedas
  if (digitalRead(sensorMoneda) == HIGH) {
    delay(50); // Debounce
    if (digitalRead(sensorMoneda) == HIGH) {
      credito += 5;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Credito: ");
      lcd.print(credito);
      lcd.print(" unidades");
      delay(1000);
      mostrarMenu();
    }
  }
  
  // Verificar botones
  if (digitalRead(boton1L) == LOW && !dispensando) {
    dispensarAgua(1000, precio1L); // 1000 ml = 1L
  }
  
  if (digitalRead(boton05L) == LOW && !dispensando) {
    dispensarAgua(500, precio05L); // 500 ml = 0.5L
  }
  
  // Actualizar display si no está dispensando
  if (!dispensando && millis() % 5000 < 100) {
    mostrarMenu();
  }
  
  // Controlar LED indicador
  digitalWrite(ledIndicador, recipientePresente);
}

void dispensarAgua(int cantidadML, int precio) {
  if (credito >= precio && recipientePresente) {
    credito -= precio;
    dispensando = true;
    
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Dispensando...");
    lcd.setCursor(0, 1);
    lcd.print(cantidadML);
    lcd.print(" ml");
    
    // Encender bomba
    digitalWrite(releBomba, HIGH);
    
    // Calcular tiempo de dispensado (ajustar según flujo de bomba)
    // Suponiendo 100 ml por segundo
    unsigned long tiempo = (cantidadML * 1000) / 100;
    tiempoDispensado = millis();
    
    while (millis() - tiempoDispensado < tiempo) {
      // Verificar que el recipiente sigue presente
      if (digitalRead(sensorPresencia) == LOW) {
        break; // Detener si quitan el recipiente
      }
      delay(100);
    }
    
    // Apagar bomba
    digitalWrite(releBomba, LOW);
    
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Dispensado OK!");
    lcd.setCursor(0, 1);
    lcd.print("Credito: ");
    lcd.print(credito);
    
    delay(2000);
    dispensando = false;
    mostrarMenu();
    
  } else {
    lcd.clear();
    if (!recipientePresente) {
      lcd.setCursor(0, 0);
      lcd.print("Coloque");
      lcd.setCursor(0, 1);
      lcd.print("recipiente!");
    } else {
      lcd.setCursor(0, 0);
      lcd.print("Credito");
      lcd.setCursor(0, 1);
      lcd.print("insuficiente!");
    }
    delay(2000);
    mostrarMenu();
  }
}

void mostrarMenu() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("1L:");
  lcd.print(precio1L);
  lcd.print(" 0.5L:");
  lcd.print(precio05L);
  lcd.setCursor(0, 1);
  lcd.print("Credito: ");
  lcd.print(credito);
}

void mostrarMensajeInicial() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Dispensador");
  lcd.setCursor(0, 1);
  lcd.print("de Agua");
  delay(2000);
  mostrarMenu();
}

 Ajustes y Calibración

  1. Calibración del sensor de monedas: Ajustar la sensibilidad según las monedas de 5 unidades

  2. Tiempo de dispensado: Ajustar el cálculo del tiempo según el flujo de tu bomba específica

  3. Sensor de presencia: Calibrar la distancia de detección según la posición del recipiente

 Funcionamiento

  1. El usuario inserta monedas de 5 unidades

  2. El crédito se acumula en el display

  3. Selecciona la cantidad deseada (1L o 0.5L)

  4. El sistema verifica que haya un recipiente colocado

  5. Dispensa la cantidad seleccionada

  6. Descuesta el monto correspondiente del crédito

 Consideraciones de Seguridad

  • Implementar un timeout para devolver el crédito si no se usa

  • Incluir protección contra sobreflujo

  • Asegurar que la bomba se apaga automáticamente en caso de error

  • Usar materiales aptos para contacto con agua potable

Este proyecto proporciona una base completa para construir un dispensador automático de agua controlado por monedas usando ESP32.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *