This shows you the differences between two versions of the page.
pm:prj2024:azamfir:cosmina.mihoreanu [2024/05/16 22:30] cosmina.mihoreanu |
pm:prj2024:azamfir:cosmina.mihoreanu [2024/05/27 15:44] (current) cosmina.mihoreanu |
||
---|---|---|---|
Line 35: | Line 35: | ||
{{ :pm:prj2024:azamfir:updated_buttons.png?800 |}} | {{ :pm:prj2024:azamfir:updated_buttons.png?800 |}} | ||
+ | |||
+ | ** Constrângeri cablaj ** | ||
+ | |||
+ | * Pinul de input de la senzorul de sunet este tras la pinul GPIO36 al plăcii, deoarece este nevoie de un pin de tip ADC_1. Pinii de ADC_2 pun probleme de funcționare în cazul activării funcției de WiFI pe ESP32, esențială pentru acest proiect. | ||
+ | |||
+ | * Butoanele sunt conectate la placă la pinii GPIO33, 32, 25, 26, 27, aceștia fiind pini pe care există rezistențe interne de pull-up. Pinii 36, 39, 34, 35 nu au legate astfel de rezistențe. | ||
+ | |||
+ | * Display-ul este conectat la pinii corespunzători protocolului SPI, conform datasheet-ului plăcii (VSPI_MOSI și VSPI_CLK). | ||
+ | |||
+ | ** Cablaj final ** | ||
+ | |||
+ | {{ :pm:prj2024:azamfir:cablaj_cm.jpeg?700 |}} | ||
===== Software Design ===== | ===== Software Design ===== | ||
Line 50: | Line 62: | ||
* WiFi | * WiFi | ||
* HTTPClient | * HTTPClient | ||
- | * **Flow general:** la inițializare ESP32-ul se va conecta la internet folosind biblioteca WiFi și apoi va comunica prin cereri HTTP cu API-ul Spotify, prin funcțiile expuse de bibliotecii HTTPClient; apăsarea butoanelor și acționarea rotary encoder-ului vor genera întreruperi care vor seta și modifica variabile și flag-uri globale, ale căror valori vor fi verificate continuu în bucla „loop” din main.cpp; aceste modificări vor declanșa generarea de noi cereri HTTP corespunzătoare, iar răspunsurile la acestea vor updata informația afișată pe ecran. | + | * **Logică generală:** la inițializare ESP32-ul se va conecta la internet folosind biblioteca WiFi și apoi va comunica prin cereri HTTP cu API-ul Spotify, prin funcțiile expuse de bibliotecii HTTPClient; apăsarea butoanelor și acționarea rotary encoder-ului vor genera întreruperi care vor seta și modifica variabile și flag-uri globale, ale căror valori vor fi verificate continuu în bucla „loop” din main.cpp; aceste modificări vor declanșa generarea de noi cereri HTTP corespunzătoare, iar răspunsurile la acestea vor updata informația afișată pe ecran. |
+ | * **Flow și componente principale:** | ||
+ | |||
+ | **WiFI** | ||
+ | * configurarea WiFi-ului este una manuală: este pornit dispozitivul in mod de Access Point, și se pornește pe el un server cu o rută care întoarce o pagină simplă cu un form de login, unde pot fi introduse datele rețelei dorite. Datele introduse sunt extrase de server și salvate în variabilele globale **ssid** și **pasword**; | ||
+ | * se trece dispozitivul în modul Station și se conectează la rețeaua dată, după care se oprește serverul; toate funcțiile de inițializare și configurare se găsesc in WiFi.h; | ||
+ | * adresele IP și instrucțiunile de accesare sunt afișate pe ecran. | ||
+ | |||
+ | **Spotify API** | ||
+ | * după conectarea la WiFi se face automat o cerere de acces către Spotify API (**accounts.spotify.com/authorize**), de la care se primește ca răspuns un link de autentificare; | ||
+ | * se deschide un nou server pe un port diferit (același port poate provoca bind errors în unele cazuri), cu o rută care redirecționează către link-ul de autentificare de la Spotify; | ||
+ | * după verificarea identității, Spotify Web API răspunde prin redirecționarea către un URL dat de program prin **redirectURI**, și care trebuie să fie înregistrat în Dashboard-ul personal de pe Spotify for Developers; redirecționarea include un fragment denotat de **#** care conține access token-ul, care va fi extras de un script din pagina întoarsă de ruta de pe server setată pentru această redirectare; | ||
+ | * adresele IP și instrucțiunile de accesare sunt afișate pe ecran; | ||
+ | * următoarele interacțiuni cu API-ul se fac prin cereri la **/me/player** pentru informații legate de piesa curentă, **/me/player/previous** și **/me/player/next** pentru schimbarea piesei, **/me/player/shuffle** pentru toggle-ul stării de shuffle, **/me/player/pause** și **/me/player/play** pentru start-stop, **/me/player/volume** to set the volume. | ||
+ | |||
+ | **Periferice** | ||
+ | * **display:** conectat prin SPI și acționat prin bibliotecile Adafruit pentru grafică; se configurează inițial culorile și orientarea, după care la fiecare piesa este re-randat întreg ecranul; | ||
+ | * **butoane:** butoanele sunt setate pe modul INPUT_PULLUP, și li se atașează întreruperi care modifică în true flag-urile corespunzătoare, care vor fi verificate în main loop; este implementat și un debounce software, prin setarea unui timp minim de apăsare între apăsări succesive valide; | ||
+ | * **rotary encoder:** pinii sunt configurați pentru INPUT, respectiv INPUT_PULLUP în cazul pinului de switch care expune funcționalitatea de push-button; se atașează o întrerupere pe pinul CLK, care se declanșează atunci cand encoderul este rotit, iar citirea digitală a pinului DT indică direcția de rotire, după care se modifică variabila globală **volume**; | ||
+ | * **senzor sunet:** atunci câand este activat modul de auto-volume (prin buton), este citită cu o rezoluție de 12 biți valoarea pinul Analog Output a senzorului, si transformată într-o valoare a volumului; astfel, plaja de valori 960 - 1045 este mapată la intervalul 100 - 0 pentru volum; doar atunci cand se detectează variații de volum de minim 10 unități se trasnmite schimbarea către Spotify. | ||
+ | |||
+ | **Timer** | ||
+ | * este folosit timer-ul 0 al plăcii ESP32, cu un interval de declanșare de 1 secundă, și o întrerupere care setează un flag verificar in main loop; astfel, la fiecare secundă este re-randat timestamp-ul în melodie și bara de progres, iar la fiecare 4 secunde se trimite o cerere la Spotify API la **/me/player** pentru reactualizarea datelor legate de player-ul curent. | ||
+ | |||
+ | |||
+ | Implementare completă disponibilă la: | ||
+ | |||
+ | [[https://github.com/cos-mih/spotify-remote-controller|GitHub Repo]] | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
+ | |||
+ | Rezultatul proiectului este un mini dispozitiv cât de cât util care poate comunica cu Spotify API și poate controla cu succes starea player-ului curent. Funcționalitatea este cea dorită, putând fi aduse, desigur, și alte îmbunătățiri ulterioare. | ||
+ | |||
+ | Există unele limitări ale performanței și responsivității din cauza request-urilor către Spotify care pot lua destul de mult timp, comparativ cu interacțiunile directe cu dispozitivul. | ||
+ | |||
+ | Un demo video al flow-ului de funcționare se găsește la adresa: | ||
+ | |||
+ | [[https://www.youtube.com/watch?v=7bttivGVqa8|Spotify Remote Controller Demo]] | ||
===== Concluzii ===== | ===== Concluzii ===== | ||
- | ===== Download ===== | + | A fost un proiect foarte instructiv, a fost nevoie să mă familiarizez cu multe noțiuni și tehnici practice noi, dar a fost distractiv all in all. Debugging-ul hardware destul de complicat, și autentificarea în mai mulți pași pe API-ul de la Spotify a pus destul de multe probleme care nu au putut fi rezolvate decât prin rute de redirectare și scripturi de JS injectate în pagini HTML. |
===== Jurnal ===== | ===== Jurnal ===== | ||
Line 65: | Line 113: | ||
* 3 mai - completat documentație milestone 1 + comandat piese noi (butoane noi și rotary encoder) | * 3 mai - completat documentație milestone 1 + comandat piese noi (butoane noi și rotary encoder) | ||
* 11 mai - completat documentație milestone 2 (hardware) + cablaj inițial pe breadboard si expansion board | * 11 mai - completat documentație milestone 2 (hardware) + cablaj inițial pe breadboard si expansion board | ||
+ | * 24 mai - completat documentație milestone 3 (software) + funcționare parțială | ||
+ | * 26 mai - upload demo + rezultate + github | ||
+ | * 27 mai - GitHub public după git rebase + push --force pentru a scoate client_secret (pentru Spotify API) din commit-uri vechi | ||
</note> | </note> | ||
===== Bibliografie/Resurse ===== | ===== Bibliografie/Resurse ===== | ||
+ | |||
+ | [[https://www.electronicshub.org/wp-content/uploads/2021/02/ESP32-Pinout-1.jpg|Pinout ESP32]] | ||
+ | |||
+ | [[https://www.epitran.it/ebayDrive/datasheet/25.pdf|Rotary Encoder Datasheet]] | ||
+ | |||
+ | [[https://www.youtube.com/watch?v=ZFqVvDtgLLU|ST7789 Display Pinout and Tutorial]] | ||
+ | |||
+ | [[https://lastminuteengineers.com/handling-esp32-gpio-interrupts-tutorial/#google_vignette|ESP32 Button Intrerrupts Tutorial]] | ||
+ | |||
+ | [[https://www.upesy.com/blogs/tutorials/how-to-connect-wifi-acces-point-with-esp32|WiFi Connection Tutorial]] | ||
+ | |||
+ | [[https://developer.spotify.com/documentation/web-api|Spotify Web API Documentation]] | ||