This shows you the differences between two versions of the page.
pm:prj2025:rnedelcu:alexandru.trifu2712 [2025/05/27 22:01] alexandru.trifu2712 |
pm:prj2025:rnedelcu:alexandru.trifu2712 [2025/05/27 23:12] (current) alexandru.trifu2712 |
||
---|---|---|---|
Line 42: | Line 42: | ||
* Întreruperi – pentru input eficient | * Întreruperi – pentru input eficient | ||
- | **Diagrama electrică și conexiunile** vor fi incluse în arhiva de descărcare. | + | **Conectivitate:** |
- | {{:pm:prj2025:rnedelcu:whatsapp_image_2025-05-13_at_11.43.37.jpeg?700 |}} | + | ^ Modul ^ Semnal ^ ESP32 Pin ^ |
+ | | INMP441 | I2S SCK | GPIO33 | | ||
+ | | | I2S WS (LRCL) | GPIO25 | | ||
+ | | | I2S SD | GPIO32 | | ||
+ | | | VCC | 3.3V | | ||
+ | | | GND | GND | | ||
+ | ^ Modul ^ Semnal ^ ESP32 Pin ^ | ||
+ | | SD Card | CS | GPIO2 | | ||
+ | | | MOSI | GPIO13 | | ||
+ | | | MISO | GPIO12 | | ||
+ | | | SCK | GPIO14 | | ||
+ | | | VCC | 3.3V | | ||
+ | | | GND | GND | | ||
+ | |||
+ | ^ Modul ^ Semnal ^ ESP32 Pin ^ | ||
+ | | TFT Display | CS | GPIO5 | | ||
+ | | | MOSI | GPIO23 | | ||
+ | | | SCK | GPIO18 | | ||
+ | | | DC | GPIO21 | | ||
+ | | | RESET | GPIO22 | | ||
+ | | | BL (Backlight) | GPIO4 | | ||
+ | | | VCC | 3.3V/5V | | ||
+ | | | GND | GND | | ||
+ | |||
+ | {{:pm:prj2025:rnedelcu:whatsapp_image_2025-05-27_at_22.48.41.jpeg?700 |}} | ||
===== Software Design ===== | ===== Software Design ===== | ||
- | **Mediu de dezvoltare::** | + | **Mediu de dezvoltare:** |
* Thonny | * Thonny | ||
* Platforma de testare: ESP32 + MicroPython | * Platforma de testare: ESP32 + MicroPython | ||
- | **Librării utilizate:** | + | **Biblioteci utilizate:** |
* machine, network, urequests, json, time, gc, os | * machine, network, urequests, json, time, gc, os | ||
- | |||
- | **Structuri implementate:** | ||
- | * Clasa WorkingSDCard: gestionare comunicație SPI cu cardul SD | ||
- | * Clasa SimpleCoffeeFS: sistem simplu de fișiere pentru salvarea entry-urilor | ||
- | * Funcții pentru randare pe ecran folosind font bitmap 8x8 | ||
- | * Funcții de conectare WiFi și de trimitere cereri către API-ul OpenAI | ||
- | * Funcții pentru gestionare meniuri, log-uri, afișare text scrollabil, etc. | ||
**Implementare:** | **Implementare:** | ||
+ | * Clasa **WorkingSDCard** este responsabilă de gestionarea comunicației SPI software cu cardul SD, folosind transmisie bit cu bit (bit-banging) prin pini digitali. Aceasta implementează funcționalități de inițializare a cardului, trimitere de comenzi standard (CMD0, CMD8, CMD17, etc.), și scriere/citire blocuri de 512 bytes. | ||
+ | * Clasa **SimpleCoffeeFS** acționează ca un mini-sistem de fișiere, folosind un singur sector predefinit de pe cardul SD pentru a salva un jurnal cu ultimele cafele consumate. Structura fiecărei înregistrări conține timestamp-ul, numele cafenelei și tipul de cafea. Această clasă gestionează atât încărcarea datelor la pornire, cât și salvarea înregistrărilor noi, menținând un număr limitat de intrări pentru a nu depăși limita de memorie a unui sector. | ||
+ | <code python> | ||
+ | def add_entry(self, shop_name, coffee_type): | ||
+ | """Add coffee entry and save to SD card""" | ||
+ | try: | ||
+ | print(f"Adding coffee entry: {shop_name} - {coffee_type}") | ||
+ | | ||
+ | # Add to memory first | ||
+ | timestamp = time.ticks_ms() | ||
+ | entry = { | ||
+ | 'timestamp': timestamp, | ||
+ | 'shop': shop_name, | ||
+ | 'coffee': coffee_type | ||
+ | } | ||
+ | | ||
+ | self.entries.append(entry) | ||
+ | | ||
+ | # Keep only recent entries to fit in one sector | ||
+ | if len(self.entries) > self.max_entries_per_sector: | ||
+ | self.entries = self.entries[-self.max_entries_per_sector:] | ||
+ | | ||
+ | # Save to SD card | ||
+ | success = self._save_entries() | ||
+ | | ||
+ | if success: | ||
+ | print(f"✅ Coffee entry saved to SD card!") | ||
+ | else: | ||
+ | print(f"⚠️ Entry saved to memory but SD write failed") | ||
+ | | ||
+ | return True # Always return True since we have it in memory | ||
+ | | ||
+ | except Exception as e: | ||
+ | print(f"❌ Error adding entry: {e}") | ||
+ | return False | ||
+ | </code> | ||
+ | * Funcțiile pentru randare pe ecran folosesc un font bitmap 8x8 stocat ca dicționar. Caracterele sunt desenate pixel cu pixel direct pe ecranul TFT prin funcții dedicate precum draw_large_char() și draw_large_char_line(). | ||
+ | * Pentru conectivitate, există **funcții de conectare la rețeaua WiFi** (connect_wifi) și de **trimitere a cererilor către API-ul OpenAI** (make_openai_request). Acestea permit dispozitivului să obțină sugestii inteligente pe baza jurnalului de cafea, folosind modelul GPT. Cererile sunt trimise în format JSON și răspunsul este extras și afișat într-un mod ușor de parcurs. | ||
+ | <code python> | ||
+ | def connect_wifi(): | ||
+ | """Connect to WiFi""" | ||
+ | print("Connecting to WiFi...") | ||
+ | | ||
+ | wlan = network.WLAN(network.STA_IF) | ||
+ | wlan.active(True) | ||
+ | | ||
+ | if not wlan.isconnected(): | ||
+ | print(f"Connecting to {WIFI_SSID}...") | ||
+ | wlan.connect(WIFI_SSID, WIFI_PASSWORD) | ||
+ | | ||
+ | timeout = 15 | ||
+ | while not wlan.isconnected() and timeout > 0: | ||
+ | print(f"Waiting... {timeout}s") | ||
+ | time.sleep(1) | ||
+ | timeout -= 1 | ||
+ | | ||
+ | if wlan.isconnected(): | ||
+ | print("WiFi connected!") | ||
+ | print(f"IP: {wlan.ifconfig()[0]}") | ||
+ | return True | ||
+ | else: | ||
+ | print("WiFi connection failed!") | ||
+ | return False | ||
+ | else: | ||
+ | print("Already connected") | ||
+ | return True | ||
+ | </code> | ||
+ | * Interfața aplicației este implementată prin funcții care gestionează **meniurile, logarea, afișarea intrărilor și recomandările AI**. Funcții precum show_coffee_menu(), log_coffee_entry(), view_coffee_logs() și get_coffee_recommendation() definesc fluxul principal al aplicației, cu o interfață simplă, intuitivă și adaptată limitărilor hardware. | ||
===== Rezultate Obținute ===== | ===== Rezultate Obținute ===== | ||
- | * Dispozitivul este capabil să logheze cafele offline pe SD Card, păstrând persistența datelor la repornire. | + | * Dispozitivul este capabil să logheze cafele offline pe SD Card, păstrând persistența datelor la repornire. |
- | * Răspunsuri corecte și relevante de la OpenAI pe baza jurnalului de cafele. | + | * Răspunsuri corecte și relevante de la OpenAI pe baza jurnalului de cafele. |
- | * Afișare grafică completă: meniu, text, recomandări scrollabile. | + | * Afișare grafică completă: meniu, text, recomandări scrollabile. |
- | * Modularitate bună pentru extensii viitoare (cloud sync, voice, statistici). | + | * Modularitate bună pentru extensii viitoare (cloud sync, voice, statistici). |
===== Concluzii ===== | ===== Concluzii ===== | ||
- | BrewMate demonstrează că un sistem embedded poate oferi o experiență interactivă și personalizată, integrând funcții moderne de AI într-o interfață minimalistă. Dispozitivul are potențial real pentru dezvoltare într-un produs comercial pentru cafegii și entuziaști tech deopotrivă. | + | BrewMate demonstrează că un sistem embedded poate oferi o experiență interactivă și personalizată, integrând funcții moderne de AI într-o interfață minimalistă. Dispozitivul are potențial real pentru dezvoltare într-un produs comercial pentru pasionații de cafea și entuziaști tech deopotrivă. |
===== Download ===== | ===== Download ===== | ||
- | <note warning> | + | Software-ul este disponibil aici: [[https://github.com/alexandrutrifu/BrewMatePM|]] |
- | 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**. | ||
- | </note> | ||
- | |||
- | ===== Jurnal ===== | ||
- | |||
- | <note tip> | ||
- | 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> | <note> | ||
- | Listă cu documente, datasheet-uri, resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. | + | **Resurse Software:** |
+ | * [[https://techtotinker.com/2021/04/08/024-esp32-micropython-how-to-use-sd-card-in-micropython/|]] | ||
+ | * [[https://randomnerdtutorials.com/getting-started-thonny-micropython-python-ide-esp32-esp8266/|]] | ||
+ | * [[https://micropython-stubs.readthedocs.io/en/main/11_install_stubs.html|]] | ||
+ | |||
+ | **Resurse Hardware:** | ||
+ | * [[https://invensense.tdk.com/wp-content/uploads/2015/02/INMP441.pdf|]] | ||
+ | * [[https://www.instructables.com/ESP32-Mic-Testing-With-INMP441-and-DumbDisplay/|]] | ||
+ | * [[https://randomnerdtutorials.com/esp32-tft-touchscreen-display-2-8-ili9341-arduino/|]] | ||
+ | * [[https://www.electronicwings.com/esp32/microsd-card-interfacing-with-esp32|]] | ||
+ | * [[https://www.youtube.com/watch?v=rq5yPJbX_uk|]] | ||
+ | * [[https://lastminuteengineers.com/arduino-micro-sd-card-module-tutorial/|]] | ||
+ | |||
</note> | </note> | ||
<html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | <html><a class="media mediafile mf_pdf" href="?do=export_pdf">Export to PDF</a></html> | ||