This shows you the differences between two versions of the page.
iothings:proiecte:2025sric:cv_example [2025/05/29 08:52] veaceslav.cazanov |
iothings:proiecte:2025sric:cv_example [2025/05/29 09:24] (current) veaceslav.cazanov |
||
---|---|---|---|
Line 301: | Line 301: | ||
==== Statistics transmission in Wi-Fi station role ==== | ==== Statistics transmission in Wi-Fi station role ==== | ||
- | The statistics transmission is triggered if there is anything to send. Locally, the information is stored in `/spiffs/stats.txt` with the `<artist>\t[album]\t<title>\n` format. Cover arts are stored in individual files `/spiffs/artN` files. Cover art files are usually `.jpg` and, in order to correspond cover art to a track correctly, `<artist>\t[album]\t<title>\n` is injected in `.jpg` binary before the actual `.jpg` header and data starts. This information is known by statistics receiver and cover arts are parsed and organized accordingly. | + | The statistics transmission is triggered if there is anything to send. Locally, the information is stored in `/spiffs/stats.txt` with the `<artist>\t[album]\t<title>\n` format. Cover arts are stored in individual files `/spiffs/artN` files. Cover art files are usually `.jpg` and, in order to correspond cover art to a track correctly, `<artist>\t[album]\t<title>\n` is injected in `.jpg` binary before the actual `.jpg` header and data starts. This information is known by statistics receiver and cover arts are parsed and organized accordingly. If ESP32 never connected to a Wi-Fi network with Internet access, or the transmission failed for other reasons, local data will not be removed. On transmission success, the local data becomes redundant, thus it is deleted from local storage. |
+ | |||
+ | ==== Wi-Fi network provisioning ==== | ||
+ | In order to provide a complete user experience, ESP32 code must adapt to environment changes. The user is able to provide more Wi-Fi networks to which ESP32 will try to connect prior to sending local statistics. ESP32 will try for 10 seconds to connect to each known Wi-Fi network. If ESP32 fails to connect to every known network, or no network is provided at all, it enters in Wi-Fi AP mode. If a smartphone or PC connects to the ESP32 hotspot, a webpage will pop-up ([[https://en.wikipedia.org/wiki/Captive_portal|Captive Portal]]), which will prompt the user to introduce Wi-Fi credentials of a valid network, or to continue without recording statistics. If the user opts for ignoring statistics, the choice will be remembered, and it can be reset by holding the red pushbutton on ESP32 startup (basically, press ESP32's reset while holding the pushbutton). This information is also given to user on the captive webpage. | ||
+ | |||
+ | {{:iothings:proiecte:2025sric:veaceslav-cazanov-captive.png?500|}} | ||
+ | |||
+ | ===== Python TCP server -- statistics receiver ===== | ||
+ | There is a Python server in the Internet ''iot.echipa3.xyz:50993'' (domain and hosting inherited from other project) which listens for already described information in //Bluetooth music streaming// section. It stores the information in local volume managed by Docker, as a directory tree: ''artist/[album]/title/plays.txt,time.txt,art.jpg''. | ||
+ | |||
+ | ===== Nginx webserver -- neat statistics presentation ===== | ||
+ | There is a simple frontend server by nginx on ''https://iot.echipa3.xyz'' which shares the data volume with the Python statistics server and presents it in a neat form to the user. The information on it is update dynamically. | ||
+ | |||
+ | {{:iothings:proiecte:2025sric:veaceslav-cazanov-front.png?500|}} | ||
+ | |||
+ | ====== Challenges ====== | ||
+ | - The whole custom cover art gather implementation | ||
+ | - Captive portal | ||
+ | - Arduino IDE taking an eternity to compile an image | ||
+ | - The cover art will just not transfer. The music must be paused for some time. New transfer attempt is made each 5 seconds. | ||
+ | - YouTube Music triggering 2-5 track change events for a single track change. | ||
+ | - ''E (13054) task_wdt: esp_task_wdt_reset(705): task not found'' spam on boot until reaches ~20000. | ||
+ | |||
+ | ====== Conclusions ====== | ||
+ | Implemented a working solution which forwards Bluetooth sound to mini-jack. An adequate user interface is provided, Wi-Fi credentials provisioning, status LED and pushbutton. The solution may still crash randomly, though it was used without issues while writing this documentation (earphones connected to jack and music streaming from an iPhone). As the code was mainly tested with an iPhone, there may be issues with other source devices, for example, Windows 11 laptop with web version of YouTube Music, doesn't report the album, neither it's cover art. The Python server may also refuse to receive statistics sometimes. This all means that the code requires polishing on all levels. | ||
Line 310: | Line 334: | ||
[[https://en.wikipedia.org/wiki/SBC_(codec)|Wikipedia -- SBC (codec)]] | [[https://en.wikipedia.org/wiki/SBC_(codec)|Wikipedia -- SBC (codec)]] | ||
+ | |||
+ | [https://medium.com/@atacanymc/creating-a-captive-portal-with-esp32-a-step-by-step-guide-9e9f78ab87b8|Creating a Captive Portal with ESP32: A Step-by-Step Guide]] //highly modified in my implementation// | ||
+ | |||
+ | [[https://github.com/pschatzmann/ESP32-A2DP)|pschatzmann/ESP32-A2DP]] | ||
+ | |||
+ | [[https://github.com/pschatzmann/arduino-audio-tools|pschatzmann/arduino-audio-tools]] | ||
+ | |||