-
-
Check issue #1777 Improve ESP32 implementation for fixed and open issues.
Thanks. Not much BLE related there however, I see only
- NRF.updateServices() needs fixing issue 2292
- BLE/NRF error , check issue 2493, issue 2292
so I guess this patch mentioned above solves/helps with #2292 which is actually quite old and known
So it makes sense there is no info in the list about using BLE characteristics (writing callback + notifications) since nobody could try with NRF.setServices not working.
- NRF.updateServices() needs fixing issue 2292
-
There are indeed some issues with ESP32, sad
Yes, not a long time ago only advertising worked well on ESP32 so even this state is much better. If setting up service with characteristics did not work (at all I guess?) and is fixed only now it means nobody used it before. Does at least reading and writing values of characteristics work? As a workaround for now it may be good enough to read characteristics periodically instead of using notifications.
Oh but you said writing does not work because the callback is not called so you don't get the new value. Oh, well.
I don't know what project are you working on but if you just need some bidirectional communication you may use the interpreter console itself over BLE to pass the data. Sorry I don't use ESP32 with Espruino for BLE so I am not sure what already works, @MaBe does at least the Nordic UART console work over BLE on ESP32?
Or maybe @Gordon knows what is BLE state for ESP32 and what is still missing? I've seen some significant BLE related work done for ESP32 port in recent year.
-
-
I'll try to build from source
it is actually very easy, on typical linux (ubuntu, debian) or in WSL you just checkout the Espruino github repo and run provision script that will download stuff for specific BOARD and its platform. I think on Ubuntu this works just with
apt-get install build-essential python-is-python3 python3-pip git curl
~$ git clone https://github.com/espruino/Espruino ; cd Espruino ~/Espruino$ . scripts/provision.sh ESP32 Provision BOARDNAME = ESP32 Provision FAMILY = ESP32 ===== ESP32 pip 20.3.4 from /usr/lib/python3/dist-packages/pip (python 3.9) python/pip installed pyserial installed installing app folder installing esp-idf folder installing xtensa-esp32-elf-gcc ESP_IDF_PATH=/home/fanoush/Espruino/esp-idf ESP_APP_TEMPLATE_PATH=/home/fanoush/Espruino/app PATH=$PATH:/home/fanoush/Espruino/xtensa-esp32-elf/bin/ GCC is /home/fanoush/Espruino/xtensa-esp32-elf/bin//xtensa-esp32-elf-gcc ~/Espruino$ make BOARD=ESP32 RELEASE=1 clean Cleaning targets ~/Espruino$ make BOARD=ESP32 RELEASE=1
Also you can trick it and just use github to build it for you, ESP32 is part of build checks, so if you go to
https://github.com/espruino/Espruino and click the green checkmark next to some recent commit you go e.g. to
https://github.com/espruino/Espruino/actions/runs/8781555980/job/24093818739
if you expand the "Upload ESP32 Artifact" step there isArtifact ESP32 has been successfully uploaded! Final size is 2908638 bytes. Artifact ID is 1434877087 Artifact download URL: https://github.com/espruino/Espruino/actions/runs/8781555980/artifacts/1434877087
so just click that link to download zip of build results for that commit.
So you can just fork Espruino repo, push change(s) to your forked repo and get the result zip of your custom ESP32 build.
-
May be there are some bugs in ESP32 code
yes, it is not so stable, there is no official ESP32 based Espruino device so this is just community effort.
I don't have device to test but I think this could helpdiff --git a/targets/esp32/BLE/esp32_gatts_func.c b/targets/esp32/BLE/esp32_gatts_func.c index 7fd09fdc2..30d7171b5 100644 --- a/targets/esp32/BLE/esp32_gatts_func.c +++ b/targets/esp32/BLE/esp32_gatts_func.c @@ -449,10 +449,10 @@ void gatts_char_init(JsvObjectIterator *ble_char_it){ const char *errorStr; ble_uuid_t ble_uuid; gatts_char[ble_char_pos].service_pos = ble_service_pos; - if((errorStr = bleVarToUUIDAndUnLock(&ble_uuid,jsvObjectIteratorGetKey(&ble_char_it)))){ + if((errorStr = bleVarToUUIDAndUnLock(&ble_uuid,jsvObjectIteratorGetKey(ble_char_it)))){ jsExceptionHere(JSET_ERROR,"invalid Char UUID:%s",errorStr); } - JsVar *charVar = jsvObjectIteratorGetValue(&ble_char_it); + JsVar *charVar = jsvObjectIteratorGetValue(ble_char_it); gatts_char[ble_char_pos].char_uuid.len = ESP_UUID_LEN_16; gatts_char[ble_char_pos].char_uuid.uuid.uuid16 = ble_uuid.uuid; gatts_char[ble_char_pos].char_perm = 0;
attached is result of the build with that patch applied. maybe it helps, maybe you'll hit another bug
-
sorry, I don't use ESP32 very much but when looking at similar nrf52 code here
https://github.com/espruino/Espruino/blob/master/targets/nrf5x/bluetooth.c#L3127
I think it takes&serviceit
which isJsvObjectIterator serviceit;
while I think in ESP32 code it already takes pointer to iterator https://github.com/espruino/Espruino/blob/master/targets/esp32/BLE/esp32_gatts_func.c#L448JsvObjectIterator *ble_char_it
and it passes another reference to it
https://github.com/espruino/Espruino/blob/master/targets/esp32/BLE/esp32_gatts_func.c#L452jsvObjectIteratorGetKey(&ble_char_it)
I guess there should be
ble_char_it
used instead of&ble_char_it
in that method (possibly in more places).If you can build from source maybe you can try to fix it?
-
Oh that is strange. The code is common for all platforms
https://github.com/espruino/Espruino/blob/master/libs/bluetooth/bluetooth_utils.c#L135
and the error message you see in your first example is here
https://github.com/espruino/Espruino/blob/master/libs/bluetooth/bluetooth_utils.c#L167Are you using recent/latest version of Espruino?
EDIT: the specific ESP32 code printing the message starting with "invalid Char UUID:" is here
https://github.com/espruino/Espruino/blob/master/targets/esp32/BLE/esp32_gatts_func.c#L453
but for parsing it is calling the commonbleVarToUUIDAndUnLock
methodand what is also strange is that it probably parses the service ID in same format
on line 510, before it breaks few lines below on parsing characteristics here
https://github.com/espruino/Espruino/blob/master/targets/esp32/BLE/esp32_gatts_func.c#L521
so looks like maybe it reads the string from some wrong place and gets some garbage(?) -
Steps to reset NR52 Device
grab software here
The apps built in Rust so you'll need that plus Rust package manager cargo
also need "sudo apt-get install libusb-1.0-0-dev librust-pkg-config-dev"
Then run nrf-recoverWell what I meant is nrf_recover command/script defined inside OpenOCD nrf52 target https://github.com/openocd-org/openocd/blob/master/tcl/target/nrf52.cfg#L73 which can be typed in openocd command line as instructed by that message.
But it is great you are not satisfied with doing stuff in easy ways. The https://github.com/probe-rs/probe-rs used by that code looks like nice rust library for using those debug probes.
-
Just tried your original code with quotes with nrf52 and it works as is with no change so it is issue of ESP32 port.
Also this works on nrf52 (16bit ids without double quotes)NRF.setServices({ 0x1901 : { 0x1902 : { readable : true, writable : true, notify : true, onWrite: (event) => { console.log("Got: ", event); } } } }); NRF.setAdvertising({}, { name: "ISP" });
and even this works with long ids without quotes and dashes
NRF.setServices({ a18419019ed149b3b998172d8f29b213 : { a18419029ed149b3b998172d8f29b213 : { readable : true, writable : true, notify : true, onWrite: (event) => { console.log("Got: ", event); } } } });
and I verified in nrfConnect that those IDs are indeed used correctly when connecting to the device.
So looks like parsing of BLE ids for ESP32 is done by different code than for nrf52 and it does not work as expected.
-
-
-
-
you still need to store and transmit a square buffer even for the round screen, so you're wasting 1/4 of your memory and bandwidth.
Actually it is a bit of pain but it is doable, if you store the circle as lines with variable length and keep size (or accumulated offset) of each line (which is even symmetrical) you can save the memory. then the pixel location in the framebuffer is not y*width+x but something like yoffsets[y]+x. when sending over spi it is sent by lines so is not that much slower. Did not do it in the end but was thinking about it for the G5 watch (454x454 resolution). 454*454=206116, 3.14*227^2~=161802
So I would save about 21.5% of memory - a bit less with some rounding/byte padding. Not that much actually but still something. -
Yes, but they didn't invent rectangular watches
Indeed, and by
"apple-like" rectangular shape
I would understand something bulky, curved, with rotating crow.
Also I'd say Bangle 2 is not ugly at first sight so it is definitely not "apple-like" rectangular shape ;-) https://www.google.com/search?q=apple+watch+ugly -
For ear buds - I just wonder what features Espruino could add in an ear bud?
In theory what we could add is hacking some way of streaming audio into the ear buds from other BLE espruino devices. However the chances of nrf52 being in earbuds is probably zero, maybe newer (nrf53 and up) are a bit more likely with BLE audio coming.
Or when linking some text to speech engine into the ear buds firmware the data transfers could be pretty low (just sending text). Or MIDI over BLE could work. Also it could act as a HID device.
-
Will i be able to recharge the battery if i attach VDD?
you mean 3.3V? no, the battery is 3.7-4.2V but you can attach 5V like it was meant to be used when the device is closed. You could even do it with Pico - take 5V feeding the Pico and connect it to 5V charger input pins on the watch. Just ignore the 3.3V
-
Device has AP lock engaged". So i'll have to use a real segger programmer anyway
No need for segger for that, Pico with CMSIS-DAP and OpenOCD could do it too, newer OpenOCD versions even print helpful message how to do that.
nRF52 device has AP lock engaged (see UICR APPROTECT register). Debug access is denied. Use 'nrf52_recover' to erase and unlock the device.
So just use 'nrf52_recover' command.
And BTW you could also unlock it from the device via software by erasing and rewriting UICR from javascript.
-
it is safer to schedule it again via setTimeout after println returns.
actually I did not check how setInterval is done, but I always had issues when code in setInterval run longer than the interval. Since the interpreter is single threaded it won't run the code again if it did not finish but maybe it runs again right after previous one ends not giving chance to any other code or idle loop to run? So maybe GC is not done or other intervals may not run (pinging watchdog in this case) etc?
-
I'd replace setInterval by scheduled setTimeout, it is fixed to 100ms here
https://github.com/espruino/EspruinoDocs/blob/master/tutorials/Web%20Bluetooth%20Dashboard.md?plain=1#L214
so if sending (theBluetooth.println(..)
) takes longer than 100ms it may overflow and reboot(?). it is safer to schedule it again via setTimeout after println returns. -
just have a led blink on every loop on the device, and force a bad signal on the phone running the web page.
which loop do you mean is there some specific looping code you can link (your code or that puck.js)? One idea is watchdog - if you have watchdog kicking in setInterval then any busy loop or delay in native code preventing intervals from running could trigger such reboot. Another issue causing this may be be overflowing the stack or memory - generating data faster than it could be sent filling memory or call stack (by somehow nesting calls when error happens?)
-
...fixed it ;)
Actually you was probably right before. C3 does not have USB OTG. It only has fixed function USB CDC Serial + JTAG. So no generic purpose USB that could do HID or mass storage or anything. So USB is there just for flashing and console so you don't need to have usb to serial chip on devboard. S3 has same fixed serial/jtag interface + USB OTG on same pins so you need to select at runtime one or another (you can't have both) but C3 only has that fixed function one.
-
Are you using active or passive scan (options.active = 1)? With active scan for every device found it tries to request scan response from it. So when doing this I am guessing it may miss other device advertising at the same time? The scan response request/response is done on same channel as the advertising packet received. And I think it is done immediately after receiving the packet since the advertising device waits only short window for scan response request after sending advertising packet. Anyway, changing scan to passive could IMO help to just listen for the whole window instead of transmitting into the same channel for every device that is found possibly increasing noise and missing something.
BTW just found interesting document about active scanning and its issues "Anti-Collision Adaptations of BLE Active Scanning for Dense IoT Tracking Applications" https://zaguan.unizar.es/record/75799/files/texto_completo.pdf?version=1
-
In general there is no reason to disconnect the battery (as long as you use just GND,DIO,CLK), it is even better too keep it connected as the device may check battery voltage and shut down when it is 'low'. Also when you don't mess with power you can attach and detach SWD without affecting the device at all. If you need to reset the device it can be done over SWD without disconnecting the power.
BTW at least with openocd when you end the session it keeps the nrf5x debugging bits powered on so battery will drain fast. With CMSIS-DAP debugger it is possible to detach it in more sensible way via
nrf52.dap dpreg 4 0 ; shutdown
, this will power off debug interface before detaching so power draw is back to normal. Maybe J-Link does it automatically, I don't know.
The Storage https://www.espruino.com/Reference#Storage already has its own simplified filesystem so no spiffs is needed/possible there. The main feature of Storage is that each file takes continuous area of flash and files are directly mappable to some memory address. The disadvantage is that you cannot append to such file or overwrite existing data, you need to create it with some size and either fill it with data completely at creation time or write only to areas not written yet = bytes with all bits set (0xff = 255). So it is something between low level flash access and simplified filesystem.
Then there is a hybrid on top of it https://www.espruino.com/Reference#StorageFile which can append but cannot write/contain 0xff=255 bytes.
But while it is limited as described it can work just fine for serving text files with webserver.