Bluetooth PlatformIO ESP-32 leertopic

Lucky Luke

Special Member

Waarde mede-CO-ers,

In dit topic dacht ik wat verslag te doen van hoe ik met bluetooth aan het prutsen ben, ter lering ende vermaak en ook in de hoop dat u allen af en toe een duwtje de goeie kant op geeft en dat dat weer kan leiden tot lering en vermaak bij mijzelf anderen die met hetzelfde (of vergelijkbaar) bijltje willen hakken.

Bluetooth
Bluetooth lijkt me iets dat niet meer te bitbangen valt en sowiso met een-of-andere library moet. En waarbij je sowiso van fabrikantspecifieke hardware afhankelijk bent. Verder zijn zoekmachines een beetje stuk en krijg ik van alles over een Noorse koning, maar deze tutorial van sparkfun vond ik een aardig overzicht geven (de tekst, niet zo zeer het filmpje): https://learn.sparkfun.com/tutorials/bluetooth-basics/all

Ik wil gewoon een-of-ander hello-world iets. Een seriële terminal over bluetooth lijkt me wel aardig, dat ik met een terminalprogramma op de computer kan verbinden met een MCU en dan 'Hello World' zie.

Later lijkt het me ook leuk eventueel iets met bluetooth audio te doen, een mcu waar je bluetooth koptelefoon mee kan pairen en dat je dan een 1 kHz sinus hoort. Niet nuttig, maar lijkt me een aardige hello world.

MCU: ESP-32 Wrover
Als hardware ga ik een ESP-32 gebruiken, omdat ik die heb liggen (ooit een bordje gekregen met een ESP32-Wrover, druktoetsjes en een RGB-LED, en TTL-serial interface)

Ontwikkelomgeving: ESP-IDF op PlatformIO op VScode op Debian
Als ontwikkelomgeving wil ik PlatformIO gebruiken (dat ook nieuw is voor me). PlatformIO dan als extensie op Microsoft Visual Studio (VScode). En als extentie op platformio dan weer ESP-EDF als ontwikkelframework voor de ESP-32. (het wordt een hele ui aan softwarelagen. Maar platformIO is vast ook handig als ik eens wat met een RP2040 wil gaan doen, en het kan ook PIC en AVR en ... - het lijkt me dus handig/leuk daar eens wat mee te doen. Als ik het in kleinere stapjes wil knippen zou ik zelfs nog eerst iets met een AVR in platformio kunnen doen)

VScode draait prima op mijn mac, Platformio ook. ESP-IDF vereist echter dependencies via brew en brew vind mijn macOS te oud. Dus om niet teveel te yakshaven heb ik het nu op mijn Linux (debian) laptop geinstalleerd. Meelezers kunnen op Mac/Linux en windows meelezen, Vscode en PlatformIO zijn platformonafhankelijk.

Stap één is dus VScode te installeren, dan binnen VScode Platformio, en als PlatformIO binnen is, dan ESP-IDF. ESP-EDF heeft ook onder debian wat dependencies nodig: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-starte…. En in aanvulling op wat daar genoemd wordt, python3-pip (sudo apt-get install python3-pip)

Dan binnen Platformio een example project starten, gebaseerd op een wrover-board. Daarna dacht ik eens wat bluetooth examples te gaan bekijken en te kijken of die willen compilen en eventueel runnen op het bordje dat ik heb. En daarna eens eigen software proberen te schrijven.

Goed. Bovenstaande zal wel enigszins ongestructureerd opgeschreven zijn, maar u allen kunt daar wel tegen. Shoot@it zou blackdog zeggen. (maar wel een beetje liev graag :) )

Alle linkjes nog eens op een overzichtelijk rijtje
(ik ben van plan de startpost af en toe te editten en toe te voegen wat jullie aandragen en wat ik zelf tegenkomen)

Bluetooth
Overzichtje/starter: https://learn.sparkfun.com/tutorials/bluetooth-basics/all
Bluetooth architectuur in een ESP32:
https://www.espressif.com/sites/default/files/documentation/esp32_blue…

ESP-IDF:
dependencies: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-starte… (De rest van de installatie gaat via VScode, maar dingen als ninja en Cmake en python enzo moeten er eerst zijn.)
API reference: https://docs.espressif.com/projects/esp-idf/en/v5.0.1/esp32/api-refere…
Examples op github: https://github.com/espressif/esp-idf/tree/master/examples/bluetooth
Example projecten bekijken of gebruiken als startpunt:
https://github.com/espressif/vscode-esp-idf-extension/blob/4c3336bea97…
(Want via pio home lijkt niet te werken?)

PlatformIO, VScode, etc:
Hier visual studio downloaden:https://code.visualstudio.com/
Dan in Visual studio de plaformIO extensie installeren: https://docs.platformio.org/en/latest//integration/ide/vscode.html#ins…
Dan de ESP-IDF extentie installeren: https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs…

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)
JoWi

Special Member

Bij het experimenteren met ESP32 bordjes heb ik een hoop plezier gehad van de voorbeelden op deze site: https://randomnerdtutorials.com/getting-started-with-esp32/
Gebruik trouwens ook VisualCode met PlatformIO.

[Bericht gewijzigd door JoWi op 10 april 2023 17:48:06 (13%)

Ignorance is bliss

Da's toevallig. Ik ben nu ook net begonnen met bluetooth op ESP32.

Van de examples ben ik begonnen met bluedroid/classic_bt/bt_spp_vfs_acceptor/

Dat werkt in één keer. Direct verbinden vanaf de PC en data versturen vanuit een terminal programma.

Lucky Luke

Special Member

Via platformIO home met de grote 'example project' knop een example project starten lukt binnen het arduino-framework, maar niet met het esp-idf framework (arduino-blink).

Er is nog een andere manier om een example project te openen/starten: https://github.com/espressif/vscode-esp-idf-extension/blob/4c3336bea97…
Dat werkt wel:

Click menu View -> Command Palette... and type ESP-IDF: Show Examples Projects

(en daarna wijst het zichzelf of zie voorgaande link)

Daarmee heb ik het example project dat deKees noemt (bluedroid/classic_bt/bt_spp_vfs_acceptor/) kunnen laten compilen en flashen. Na enig zoeken naar een bluetooth-dongeltje is het zelfs gelukt er een verbinding mee te maken. (De volgende stap is dan een seriële poort en 'hello world' vanaf de esp32 naar de pc te sturen, maar dat wordt een andere dag)

Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Er zit wel een dikke bug in die example applicatie.

code:

    char bda_str[18] = {0};

Deze buffer wordt 2 keer aangemaakt in main.c. Probleem is dat die buffer te klein is want er is geen ruimte voor de nul terminator.

Dat gaat soms goed, en soms crasht de applicatie.

Dus best een extra byte reserveren:

code:

    char bda_str[18+1] = {0};

Twee BT moduultje kopen (ik ging voor o.a. tinytronics BT-04) waar je een seriele terminal aanhangt. Kan een Arduino zijn met een geschikt programmaatje. Op mijn telefoon gebruik ik een Serial-bluetooth-app en voila, je kunt met je terminal praten via BT.

Niet alles wat op internet staat is waar... Dat geldt ook voor CO.

Nu blijkt dat er 2 demo apps zijn.

bluedroid/classic_bt/bt_spp_acceptor/
en
bluedroid/classic_bt/bt_spp_vfs_acceptor/

Die 2e (vfs) versie zit nogal ingewikkeld in elkaar. Die andere gaat een stuk gemakkelijker in 2 richtingen.

vfs (virtual file descriptor) werkt met een fd om te lezen en te schrijven. Maar dat schrijven werkt niet lekker bij mij. Als er al data doorkomt dan is het incompleet.

De andere (CB mode) werkt met events. Een callback functie wordt aangeroepen om de inkomende data op te vangen, en dan kun je data terugsturen dmv esp_spp_write(); Dat lijkt beter te werken.

Lucky Luke

Special Member

Ook bij de 'simpele' kom ik niet verder dan 'pairen met het bluetooth-apparaat'. Daarna zie ik in de monitor van de ESP dat er een verbinding gemaakt is, vervolgens wordt die verbinding automatisch verbroken. Er seriële data mee uitwisselen lukt nog niet.

Ook: ik zie in de code nog niks dat seriele data schrijft, het lijkt 'alleen pairen' te zijn, en eventueel data weergeven:

c code:


case ESP_SPP_DATA_IND_EVT:
#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
        /*
         * We only show the data in which the data length is less than 128 here. If you want to print the data and
         * the data rate is high, it is strongly recommended to process them in other lower priority application task
         * rather than in this callback directly. Since the printing takes too much time, it may stuck the Bluetooth
         * stack and also have a effect on the throughput!
         */
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len:%d handle:%d",
                 param->data_ind.len, param->data_ind.handle);
        if (param->data_ind.len < 128) {
            esp_log_buffer_hex("", param->data_ind.data, param->data_ind.len);
// HIERZO?
        }
#else
        gettimeofday(&time_new, NULL);
        data_num += param->data_ind.len;
        if (time_new.tv_sec - time_old.tv_sec >= 3) {
            print_speed();
        }
#endif
        break;

Wat gebruik je aan de computer-kant, deKees?
Of stuur je data vanaf een 2e ESPtje?

Als ik simpelweg 'hello!' wil terugsturen op het moment dat er eender welke data binnenkomt, kan ik dan op de plek gemarkeerd HIERZO? een esp_spp_write("Hello!/n"); toevoegen?

(moet ik dus alsnog de seriele-poort-op-de-computer kant werkend krijgen... Ik had verwacht gewoon een poort extra te zien in het terminalprogramma na het pairen via bluetooth, maar zo eenvoudig is het niet.)

Op 11 april 2023 00:17:14 schreef deKees:
Deze buffer wordt 2 keer aangemaakt in main.c. Probleem is dat die buffer te klein is want er is geen ruimte voor de nul terminator.

Voor zover ik zie, wordt daar het MAC-adress in gestopt. 12 getallen gescheiden door 5 maal :, totaal 17 tekens. Met nul terminatie 18 chars, precies de grootte van de string.

c code:


    sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
            p[0], p[1], p[2], p[3], p[4], p[5]);
Eluke.nl | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Klopt. De acceptor examples doen alleen aan ontvangen van data. Er wordt niks teruggestuurd. Terugsturen staan in de initiator examples. Wel jammer. Maar je kunt wel stukjes code overzetten.

Je gebruikt nu de MODE_CB zo te zien. Dan kun je data terugsturen dmv esp_spp_write(). Maar het is wel tricky, want je moet daarna wachten op het WriteComplete event voordat je weer nieuwe data kunt sturen. Zie documentatie van esp_spp_write(). En je mag niet blijven hangen in de callback functie want dan zit de hele bluetooth stack geblokkeerd.

Ik verstuur data via een terminal programma (minicom) op de PC (Debian). Dat gaat via een standaard virtuele Comport. Dat kan ook op een windows PC als je tenminste een bluetooth transceiver hebt.

PS: Je hebt gelijk. Die buffer is toch groot genoeg. Verkeerd geteld blijkbaar.

Op linux moet je handmatig je bluetooth device koppelen aan een tty device. De benodigde drivers moest ik eerst installeren.

Serial poort aanmaken gaat dan met:

code:

sudo rfcomm bind /dev/rfcommX 00:14:01:22:10:88

Vervang X door een volgnummer (bijv 3), en het mac adres door het juiste Mac adres, die kun je vinden in de bluetooth device status.

Daarna kun je communiceren met:

code:

minicom -D /dev/rfcomm3
marcob

Golden Member

People tend to overestimate what can be done in one year and to underestimate what can be done in five or ten years