Dispensador de mascotas programable con menú LCD

Vamos a transformar el proyecto del dispensador para que en vez de un relevador + motor uses un servomotor (por ejemplo, SG90 o MG996R). El servo es ideal porque puede mover una compuerta o palanca que deje caer la comida en el momento programado.


 Materiales

  • ESP32 DevKit v1    
  • LCD 16×2 con interfaz I2C
  • 3 botones (Arriba, Abajo, OK)
  • Servomotor (SG90 para cargas pequeñas, MG996R si necesitas más torque)
  • Fuente de alimentación adecuada (el servo requiere corriente estable, mejor usar fuente externa de 5V)
  • Opcional: RTC DS3231 para mantener la hora precisa

Conexiones

  • LCD I2C: igual que antes (SDA → GPIO21, SCL → GPIO22).
  • Botones: GPIO32, GPIO33, GPIO25 con INPUT_PULLUP.
  • Servo:
    • Señal: GPIO26
    • VCC: 5V (fuente externa si es servo grande)
    • GND: común con ESP32

Lógica

  • El menú en la LCD permite programar horas de alimentación.
  • A la hora programada, el ESP32 mueve el servo a un ángulo que abre la compuerta del dispensador, espera unos segundos y regresa a la posición inicial.
  • Puedes ajustar el ángulo de apertura y cierre según tu mecanismo.

 Código de ejemplo (Arduino IDE)

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <RTClib.h>   // Opcional si usas DS3231

LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS3231 rtc;
Servo servo;

const int BTN_UP    = 32;
const int BTN_DOWN  = 33;
const int BTN_OK    = 25;
const int SERVO_PIN = 26;

struct FeedTime {
  int hour;
  int minute;
  bool enabled;
  bool ranToday;
};

FeedTime feed1 = {8, 0, true, false};
FeedTime feed2 = {18, 0, true, false};

int openAngle = 90;   // ángulo de apertura
int closeAngle = 0;   // ángulo de reposo
int dispenseSeconds = 3;

void setup() {
  Wire.begin();
  lcd.init();
  lcd.backlight();

  pinMode(BTN_UP, INPUT_PULLUP);
  pinMode(BTN_DOWN, INPUT_PULLUP);
  pinMode(BTN_OK, INPUT_PULLUP);

  servo.attach(SERVO_PIN);
  servo.write(closeAngle);

  if (!rtc.begin()) {
    lcd.setCursor(0,0); lcd.print("Sin RTC");
  } else {
    if (rtc.lostPower()) {
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }
  }
}

void triggerServo() {
  servo.write(openAngle);
  delay(dispenseSeconds * 1000);
  servo.write(closeAngle);
}

void loop() {
  DateTime now = rtc.now();
  int h = now.hour();
  int m = now.minute();

  // Mostrar hora
  lcd.setCursor(0,0);
  lcd.print("Hora ");
  lcd.print(h); lcd.print(":"); lcd.print(m);

  // Checar horarios
  if (feed1.enabled && h == feed1.hour && m == feed1.minute && !feed1.ranToday) {
    triggerServo();
    feed1.ranToday = true;
  }
  if (feed2.enabled && h == feed2.hour && m == feed2.minute && !feed2.ranToday) {
    triggerServo();
    feed2.ranToday = true;
  }

  // Reset flags a medianoche
  if (h == 0 && m == 0) {
    feed1.ranToday = false;
    feed2.ranToday = false;
  }

  delay(1000);
}

 Diferencias clave respecto a la versión con relevador

Con relevador + motor Con servomotor
Activa un motor externo (más potencia) Mueve directamente una compuerta/palanca
Requiere fuente separada para motor Servo puede alimentarse con 5V estable
Control binario (ON/OFF) Control preciso de ángulo (0–180°)
Ideal para dispensadores grandes Ideal para dispensadores pequeños/medianos

 

Deja una respuesta

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