This shows you the differences between two versions of the page.
pm:prj2025:fstancu:stefania.fintina [2025/05/29 22:07] stefania.fintina [Software Design] |
pm:prj2025:fstancu:stefania.fintina [2025/05/30 01:33] (current) stefania.fintina [Software Design] |
||
---|---|---|---|
Line 63: | Line 63: | ||
4. **Modul microSD (SPI)** | 4. **Modul microSD (SPI)** | ||
Legături: | Legături: | ||
- | * CS → GPIO 15, pin digital liber utilizat ca chip select | + | * CS → GPIO 5, pin digital liber utilizat ca chip select |
* MOSI → GPIO 23, pin SPI hardware standard | * MOSI → GPIO 23, pin SPI hardware standard | ||
* MISO → GPIO 19, pin SPI hardware standard | * MISO → GPIO 19, pin SPI hardware standard | ||
Line 85: | Line 85: | ||
* Un capăt → GND | * Un capăt → GND | ||
* Celălalt → GPIO 33, pin digital cu INPUT_PULLUP, stabil în această configurație | * 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)** | 8. **LED-uri (indicatori)** | ||
Verde: | Verde: | ||
Line 123: | Line 126: | ||
1. Mediul de dezvoltare | 1. Mediul de dezvoltare | ||
- | Aplicatia este dezvoltata in Arduino IDE , un mediu de dezvoltare 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. | + | 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. |
Line 138: | Line 141: | ||
| SPI.h | Comunicare SPI cu modulul microSD | | | SPI.h | Comunicare SPI cu modulul microSD | | ||
| SD.h | Scriere si citire fisiere pe cardul microSD | | | SD.h | Scriere si citire fisiere pe cardul microSD | | ||
- | | Adafruit\_GFX.h | Functii grafice generice pentru ecrane (folosita de SSD1306) | | + | | driver/gpio.h | Acces direct la registrele GPIO pentru citire/scriere eficienta | |
- | | WiFi.h (optional) | Pentru extinderea ulterioara cu server web local | | + | |
3. Algoritmi si structuri implementate | 3. Algoritmi si structuri implementate | ||
- | Codul foloseste o structura bazata pe evenimente si verificari ciclice in bucla principala (loop), precum si intreruperi hardware. | + | Codul foloseste o structura bazata pe evenimente (interuperi hardware) si verificari ciclice in bucla principala loop(). |
- | Bucla loop() verifica constant ora curenta, starea butoanelor si a senzorului de vibratii. | + | Bucla loop() verifica constant: |
- | Hrana este eliberata automat la ore fixe (08:00, 14:00, 20:00) pe baza valorii returnate de RTC, corectata cu un offset de +3 ore pentru ora Romaniei. | + | * ora curenta obtinuta de la RTC (DS3231), |
- | Hrana poate fi eliberata si manual, prin apasarea unui buton conectat la o intrerupere externa (attachInterrupt()). | + | * starea butoanelor (hranire manuala, reset, afisare log), |
- | Evenimentele importante (hranire automata/manuala, reset contor, vibratie detectata) sunt inregistrate pe cardul SD, in fisierul log.txt. | + | * semnalul de la senzorul de vibratii (conectat pe GPIO32). |
- | Display-ul OLED afiseaza ora ultimei hraniri si ora curenta, actualizata in fiecare secunda. | + | |
- | LED-urile indica nivelul estimativ al rezervorului de mancare in functie de numarul de hraniri: | + | Hrana este eliberata automat la orele 08:00, 14:00 si 18:00, pe baza valorii returnate de modulul RTC. |
- | verde: 0–3 hraniri | + | |
- | galben: 4–5 hraniri | + | 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(). |
- | rosu: 6–7 hraniri | + | |
- | Servo motorul este controlat pentru a elibera mancarea (deschidere si revenire), iar buzzer-ul emite un semnal sonor la fiecare hranire. | + | Evenimentele importante sunt inregistrate pe cardul microSD, in fisierul log.txt. Acestea includ: |
- | Senzorul de vibratii este verificat si, daca detecteaza miscari (logica LOW), se logheaza un eveniment corespunzator. | + | * hraniri automate si manuale, |
+ | * resetarea contorului de hraniri, | ||
+ | * detectia vibratiilor (cand pisica interactioneaza cu bolul). | ||
+ | |||
+ | 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: | ||
+ | * Verde: 0–3 hraniri | ||
+ | * Galben: 4–6 hraniri | ||
+ | * Rosu: peste 6 hraniri | ||
+ | |||
+ | 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. | ||
Line 160: | Line 175: | ||
| Functie / Structura | Descriere | | | Functie / Structura | Descriere | | ||
- | | | | | + | | | |
- | | `setup()` | Initializarea componentelor hardware si a comunicatiei seriale | | + | | `setup()` | Initializeaza componentele hardware: servo, RTC, SD, OLED, GPIO, | |
- | | `loop()` | Executia ciclica principala; verifica timpul, intreruperi, senzori | | + | | | LED-uri, si seteaza intreruperile | |
- | | `getLocalTime()` | Returneaza ora locala prin adaugarea offsetului de fus orar | | + | | `loop()` | Executa periodic verificarile: ora curenta, butoane, senzori, etc. | |
- | | `feed(String source)` | Executa o secventa completa de hranire (servo, buzzer, log, afisare) | | + | | `onFeedInterrupt()` | Functie ISR pentru tratarea intreruperii de la butonul de hranire | |
- | | `resetFeed()` | Reseteaza contorul de hraniri si LED-urile | | + | | `feed(String source)` | Porneste servo-ul, suna buzzer-ul, logheaza actiunea si actualizeaza | |
- | | `updateLEDs()` | Actualizeaza LED-ul activ in functie de `feedCount` | | + | | | contorul si LED-urile | |
- | | `logEvent(String msg)` | Scrie un mesaj text in `log.txt` pe cardul SD | | + | | `resetFeed()` | Reseteaza contorul de hraniri, actualizeaza LED-urile si logheaza | |
- | | `displayLastFeedTime()` | Afiseaza ora ultimei hraniri pe OLED | | + | | `updateLEDs()` | Activeaza LED-ul corespunzator in functie de numarul de hraniri | |
- | | `displayCurrentTime()` | Afiseaza ora curenta pe OLED, actualizata la fiecare ciclu | | + | | `displayTime(DateTime)` | Afiseaza ora curenta pe OLED sau mesajul temporar de reset | |
- | | `onFeedInterrupt()` | Rutina de tratare a intreruperii pentru butonul de hranire manuala | | + | | `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) | ||
+ | |||
+ | <code cpp>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 | ||
+ | } </code> | ||
+ | |||
+ | |||
+ | 2. **PWM** (ESP32Servo.h – control servo motor) | ||
+ | |||
+ | <code cpp>servo.setPeriodHertz(50); | ||
+ | servo.attach(SERVO_PIN, 500, 2400); | ||
+ | servo.write(180); | ||
+ | delay(500); | ||
+ | servo.write(0);</code> | ||
+ | |||
+ | 3. **SPI** (SPI.h + SD.h – pentru cardul microSD) | ||
+ | <code cpp>#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(); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | 4. **I2C** (Wire.h – folosit implicit pentru RTC și OLED) | ||
+ | |||
+ | <code cpp>#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(); | ||
+ | </code> | ||
+ | |||
+ | 5. **Intreruperi** (hardware interrupt pe butonul de hranire) | ||
+ | |||
+ | <code cpp>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"); | ||
+ | } | ||
+ | </code> | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
+ | |||
+ | https://github.com/stefaniafintina/Cat-Feeder/blob/main/cat_feeder/cat_feeder.ino | ||
+ | |||
+ | **Demo** | ||
+ | |||
<html><iframe width="560" height="315" src="https://www.youtube.com/embed/ye6EFscBKPs?si=YrYVbhwpP93aBfx3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></html> | <html><iframe width="560" height="315" src="https://www.youtube.com/embed/ye6EFscBKPs?si=YrYVbhwpP93aBfx3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></html> | ||
===== Concluzii ===== | ===== Concluzii ===== | ||
- | ===== Download ===== | ||
- | <note warning> | + | ===== Jurnal ===== |
- | O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). | + | |
- | Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:pm:prj20??:c?** sau **:pm:prj20??:c?:nume_student** (dacă este cazul). **Exemplu:** Dumitru Alin, 331CC -> **:pm:prj2009:cc:dumitru_alin**. | + | 07.05.2025 - Alegerea temei |
- | </note> | + | |
- | ===== Jurnal ===== | + | 07.05.2025 - Introducere si Descriere generală si Schema Bloc |
+ | |||
+ | 15.05.2025 - Completarea secțiunii Hardware Design si Schema electrica | ||
- | <note tip> | + | 18.05.2025 - Scrierea codului |
- | Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. | + | |
- | </note> | + | |
===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
- | <note> | + | [[https://www.youtube.com/watch?v=dqr-AT5HvyM&list=LL&index=8]] |
- | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | + | |
- | </note> | + | |
- | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | + | [[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]] |