Table of Contents

Cat Feeder - FÎNTÎNĂ Ştefania-Maria

Introducere

Descriere generală

Placa de dezvoltare ESP32 acționează ca unitate de control principală. Aceasta gestionează toate componentele periferice, inclusiv servo motorul pentru distribuirea hranei, afișajul OLED, buzzer-ul, LED-urile de stare și butoanele de control. De asemenea, comunică cu un modul RTC (ceas în timp real) pentru programarea automată a hrănirii și poate salva evenimentele pe un card SD pentru jurnalizare.

Comunicarea cu afișajul OLED și modulul RTC se face prin protocolul I²C, utilizând pinii hardware ai ESP32. În plus, un senzor de vibrații este utilizat pentru a detecta eventualele mișcări sau lovituri ale hrănitorului, ca formă de interacțiune sau alertă.

Funcționalitate generală:

Componente de control și interacțiune:

Alimentare:

Dispozitivul este alimentat dintr-un modul cu 2 baterii Li-Ion 18650 conectate în paralel, printr-un modul TP4056 pentru încărcare și protecție. Tensiunea este stabilizată la 5V cu ajutorul unui modul step-up/down YL-46, care alimentează ESP32 și restul componentelor.

Funcționare:

La pornire, ESP32 inițializează ceasul RTC. La fiecare interval prestabilit sau la apăsarea butonului de hrănire, servo-ul distribuie hrană. După fiecare activare, contorul se incrementează și LED-urile se actualizează. Feedback-ul este oferit atât vizual (LED), cât și auditiv (buzzer). Afișajul OLED arată starea curentă a sistemului și istoricul recent al hrănirilor.

Totodată, interfața web integrată permite monitorizarea obiceiurilor alimentare ale pisicii, oferind o experiență completă și accesibilă de la distanță.

Hardware Design

1. Servomotor SG90

 Legături:
    * Semnal (portocaliu) → GPIO 26, pin PWM hardware, potrivit pentru controlul unui servo, nu interferează cu alte periferice
    * VCC (roșu) → VIN (5V), servo-ul necesită alimentare de 5V
    * GND (negru/maro) → GND

2. Afișaj OLED 0.96” (I2C)

 Legături:
    * SDA → GPIO 21, pin I2C hardware standard
    * SCL → GPIO 22, pin I2C hardware standard
    * VCC → 3.3V, tensiunea recomandată pentru modulul OLED
    * GND → GND

3. RTC DS3231

 Legături:
    * SDA → GPIO 21, partajat cu OLED, I2C permite mai multe dispozitive pe aceiași pini
    * SCL → GPIO 22
    * VCC → 3.3V, compatibil cu ESP32
    * GND → GND

4. Modul microSD (SPI)

 Legături:
   * CS → GPIO 5, pin digital liber utilizat ca chip select
   * MOSI → GPIO 23, pin SPI hardware standard
   * MISO → GPIO 19, pin SPI hardware standard
   * SCK → GPIO 18, pin SPI hardware standard
   * VCC → 3.3V, unele module SD nu au regulator intern
   * GND → GND

5. Senzor de vibrații SW-420

 Legături:
   * DO → GPIO 32, pin digital liber, bun pentru citiri simple
   * VCC → 3.3V, compatibil cu ESP32
   * GND → GND

6. Buzzer activ

 Legături:
    * + → GPIO 27, pin digital folosit pentru semnal simplu HIGH
    * – → GND

7. Butoane

 Buton hrănire:
    * Un capăt → GND
    * Celălalt → GPIO 4, pin digital liber, configurat cu INPUT_PULLUP
 Buton resetare:
    * Un capăt → GND
    * Celălalt → GPIO 33, pin digital cu INPUT_PULLUP, stabil în această configurație
 Buton log:
    * Un capăt → GND
    * Celălalt → GPIO 34, pin digital citit direct (nu suportă INPUT_PULLUP), verificat cu gpio_get_level()

8. LED-uri (indicatori)

 Verde:
    * Anod → GPIO 12, pin digital simplu
    * Catod → GND prin rezistor
 Galben:
    * Anod → GPIO 13, pin digital simplu
    * Catod → GND prin rezistor
 Roșu:
    * Anod → GPIO 14, pin digital simplu
    * Catod → GND prin rezistor

Software Design

1. Mediul de dezvoltare

Aplicatia este dezvoltata in Arduino IDE , compatibil cu platforma ESP32 DevKit v1, utilizata in proiect. Codul este scris in limbajul C++, iar incarcarea pe placa se realizeaza prin port USB. Serial Monitor-ul este folosit pentru debug si afisarea mesajelor in timpul executiei.

2. Librarii si surse third-party utilizate

Biblioteca Scop
Wire.h Comunicare I2C cu RTC si display OLED
ESP32Servo.h Controlul servo motorului prin PWM specific ESP32
RTClib.h Gestionarea modulului RTC DS3231 (ora si data)
Adafruit\_SSD1306.h Afisare text pe display OLED monocrom
SPI.h Comunicare SPI cu modulul microSD
SD.h Scriere si citire fisiere pe cardul microSD
driver/gpio.h Acces direct la registrele GPIO pentru citire/scriere eficienta

3. Algoritmi si structuri implementate

Codul foloseste o structura bazata pe evenimente (interuperi hardware) si verificari ciclice in bucla principala loop(). Bucla loop() verifica constant:

Hrana este eliberata automat la orele 08:00, 14:00 si 18:00, pe baza valorii returnate de modulul RTC.

Hrana poate fi eliberata si manual, prin apasarea butonului conectat pe GPIO4. Acesta genereaza o intrerupere externa configurata cu attachInterrupt(), care seteaza un flag ce este tratat in loop().

Evenimentele importante sunt inregistrate pe cardul microSD, in fisierul log.txt. Acestea includ:

Display-ul OLED conectat prin I2C afiseaza ora curenta si, temporar, mesaje precum “Contor resetat” sau ultimul eveniment logat.

LED-urile indica nivelul estimativ al rezervorului de mancare:

Servo motorul este controlat prin PWM pentru a elibera mancarea. Buzzer-ul este controlat prin registre (GPIO.out_w1ts / GPIO.out_w1tc) si emite un sunet scurt la fiecare hranire.

Senzorul de vibratii este verificat periodic. Daca se detecteaza vibratii (nivel LOW) si a trecut timpul de ignorare (10 secunde dupa hranire), se considera ca pisica a mancat si se logheaza evenimentul.

4. Surse si functii implementate

Functie / Structura Descriere
`setup()` Initializeaza componentele hardware: servo, RTC, SD, OLED, GPIO,
LED-uri, si seteaza intreruperile
`loop()` Executa periodic verificarile: ora curenta, butoane, senzori, etc.
`onFeedInterrupt()` Functie ISR pentru tratarea intreruperii de la butonul de hranire
`feed(String source)` Porneste servo-ul, suna buzzer-ul, logheaza actiunea si actualizeaza
contorul si LED-urile
`resetFeed()` Reseteaza contorul de hraniri, actualizeaza LED-urile si logheaza
`updateLEDs()` Activeaza LED-ul corespunzator in functie de numarul de hraniri
`displayTime(DateTime)` Afiseaza ora curenta pe OLED sau mesajul temporar de reset
`logSimple(String)` Scrie o intrare in `log.txt` si verifica scrierea pe cardul SD
`showLastLog()` Citeste si afiseaza ultima intrare din `log.txt` pe display OLED
`printSDLog()` Afiseaza in consola toate intrarile din `log.txt`

Notiuni din laborator

1. GPIO (driver/gpio.h – pentru control pini digitali)

gpio_set_direction((gpio_num_t)BUTTON_FEED, GPIO_MODE_INPUT);
gpio_set_pull_mode((gpio_num_t)BUTTON_FEED, GPIO_PULLUP_ONLY);
gpio_set_direction((gpio_num_t)BUTTON_RESET, GPIO_MODE_INPUT);
gpio_set_pull_mode((gpio_num_t)BUTTON_RESET, GPIO_PULLUP_ONLY);
gpio_set_direction((gpio_num_t)BUTTON_LOG, GPIO_MODE_INPUT);
 
gpio_set_direction((gpio_num_t)BUZZER_PIN, GPIO_MODE_OUTPUT);
gpio_set_direction((gpio_num_t)VIBRATION_PIN, GPIO_MODE_INPUT);
 
if (!gpio_get_level((gpio_num_t)BUTTON_RESET)) {
  resetFeed();
  delay(300);
}
 
if (gpio_get_level((gpio_num_t)BUTTON_LOG)) {
  showLastLog();
  delay(300);
}
 
if (millis() > vibrationIgnoreUntil && !gpio_get_level((gpio_num_t)VIBRATION_PIN)) {
  // log event
} 

2. PWM (ESP32Servo.h – control servo motor)

servo.setPeriodHertz(50); 
servo.attach(SERVO_PIN, 500, 2400); 
servo.write(180); 
delay(500);
servo.write(0);

3. SPI (SPI.h + SD.h – pentru cardul microSD)

#include <SPI.h>
#include <SD.h>
 
#define SD_CS 5
 
if (!SD.begin(SD_CS)) Serial.println("Eroare card SD!");
 
File f = SD.open("/log.txt", FILE_APPEND);
if (f) {
  f.println(logEntry);
  f.close();
}
 
File fRead = SD.open("/log.txt");
if (fRead) {
  while (fRead.available()) {
    lastLine = fRead.readStringUntil('\n');
  }
  fRead.close();
}

4. I2C (Wire.h – folosit implicit pentru RTC și OLED)

#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_SSD1306.h>
 
RTC_DS3231 rtc;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
 
if (!rtc.begin()) Serial.println("Eroare RTC!");
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) Serial.println("Eroare OLED!");
 
DateTime now = rtc.now(); 
display.clearDisplay();   
display.setCursor(...);   
display.println(...);     
display.display();        

5. Intreruperi (hardware interrupt pe butonul de hranire)

volatile bool feedInterrupt = false;
 
void IRAM_ATTR onFeedInterrupt() {
  feedInterrupt = true;
}
 
attachInterrupt(digitalPinToInterrupt(BUTTON_FEED), onFeedInterrupt, FALLING);
 
// in loop():
noInterrupts();
bool shouldFeed = feedInterrupt;
feedInterrupt = false;
interrupts();
 
if (shouldFeed) {
  feed("manuala");
}

Rezultate Obţinute

https://github.com/stefaniafintina/Cat-Feeder/blob/main/cat_feeder/cat_feeder.ino

Demo

Concluzii

Jurnal

07.05.2025 - Alegerea temei

07.05.2025 - Introducere si Descriere generală si Schema Bloc

15.05.2025 - Completarea secțiunii Hardware Design si Schema electrica

18.05.2025 - Scrierea codului

Bibliografie/Resurse

https://www.youtube.com/watch?v=dqr-AT5HvyM&list=LL&index=8

https://www.youtube.com/watch?v=_sKWP6fl-NU&list=LL&index=1\

https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf