-
Update on my previous post.
- added the
\x03\x10
back in - increased the delay between 20-byte chunks to 0.1 second
The update Python code on RPi code has been running now for 3.5 hours.
It transfers 4 small text textfiles (20-30 textlines each) every minute to Bangle storage, so that is 3.5*60*4 = 840 separate BLE connections
- no more catastrofic errors like "garbled data" or "bangle screen shifted right 50%" or "FIFO FULL", my Bangle App keeps running flawless
- appr. 88 times the BLE connection has failed, that's like 10%
So it seems likes the suggestions are working :-)
Next steps:
- let it run overnight and look at the behaviour and the numbers
- add code for reconnection if connect fails
- think of a way to check whether the transfer was successful. That's a challenge considering the
\x10
switches response from the Bangle OFF ;-)
All in all, making progress.
- added the
-
Ok, so I added
setConnectionInterval
in the code, but I do not see a major difference.response=""; NRF.setConnectionInterval(100); setInterval(function () { print("connecting"); NRF.requestDevice({ filters: [{ services: ['1823'] }] }).then(function(device) { require("ble_http").httpRequest(device, "pur3.co.uk/hello.txt", function(d) { response=JSON.stringify(d); print(response); }); }); }, 10000);
Selection from output
connecting Connected Uncaught Error: Unhandled promise rejection: Disconnected WARNING: Softdevice error BLE error 0x11 (BUSY) (bluetooth.c:818) connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Uncaught Error: Unhandled promise rejection: No device found matching filters connecting Uncaught Error: Unhandled promise rejection: No device found matching filters connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Uncaught Error: Unhandled promise rejection: Disconnected WARNING: Softdevice error BLE error 0x11 (BUSY) (bluetooth.c:818) connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Uncaught Error: Unhandled promise rejection: Disconnected connecting Connected Uncaught Error: Unhandled promise rejection: Disconnected connecting Connected Uncaught Error: Unhandled promise rejection: Disconnec
The dreaded "Unhandled promise rejection ..." is still prominently present, with a scarce "BLE busy..".
-
Hi,
Had a look at the App Loader (in a hurry) as a solution for me, but had trouble getting it working, surely my mistake. Now I know it has XON/XOFF it's again on the "candidate" list.
I getting used to the fact that a BLE connection is not 100% reliable, so I have to adapt my code for that.
Yes, saw the \x03\x010 in your original code:
- for testing purposes I removed the \x10 so I could monitor the response from the Bangle, when I saw it returning
=undefined
I knew that my transfer was succesfull. - I was uncertain about the purpose of the \x03 and removed it also
So next steps for me:
- Will put the '\x03\x10` back in and see how that goes.
- will change my code to allocate for a failed connection.
Thanks for your help!
- for testing purposes I removed the \x10 so I could monitor the response from the Bangle, when I saw it returning
-
The contents of "buffer" was expected, so apologies that I have mislead you with my post.
When tested:
- the Bangle was connected to the WebIde to monitor the response from the EspruinoHub, I understand that might require "juggling" when connecting to the Hub as well.
- No other devices were connecting to the HUB.
- distance between Raspberry/Hub and Bangle was 30 cm.
- based on previous experience I was not surprised about the scarce connection errors, was expecting them. Will do some testing withe the connectionInterval later.
The error that bugs me the most is
Uncaught Error: Unhandled promise rejection: Disconnected
.Because I had this error many times too when I coded my own BLE-UART-client on Bangle i.c.w. my own coded BLE-peripheral-server on an ESP32 (ref. in my post above). Thought it was due to my inexperience with Espruino and BLE.
Now I'm using your code on Bangle and on Raspberry the same error appears, that gives me a little more confidence in my own coding skills ;-)
Thought that reporting it here would give you some inspiration on the cause of this error. - the Bangle was connected to the WebIde to monitor the response from the EspruinoHub, I understand that might require "juggling" when connecting to the Hub as well.
-
Thanks for the tip. Until now the data I have sent was "simple text". If the text would contain newlines, single or double quotes, backticks, etc I'm sure that I'm in trouble.
I am searching for a reliable way to provide a Bangle app with data from "the internet", and wanted to try this.
My current code sends 4 short textfiles to the Bangle, every minute via a crontab. Added a short delay after each 20-byte chunk, without it I ran into several "FIFO FULL" errors.
Work reasonable reliable, during a 1 hour test I had no fails.
But sometimes:
- I get a "connection failed"
- while transferring data something goes wrong. data is garbled, and the Bangle gets confused because it does not recognise valid commands anymore. And the picture on the Bangle screen is shifted 50% to the left. Looks like a memory error of some sort. Maybe the 0.05 second delay is too small, and causes a memory error.
So I'm not out of the woods yet, but had fun learning.
Thanks for this wonderfull project!
- I get a "connection failed"
-
FYI
For sending simple commands to Bangle using Noble/BluePy/Gattool there is an extensive description with examples here: http://www.espruino.com/Interfacing#python
The BluePy example code can be modified to send a file with Espruino commands in it to Bangle for execution by replacing
command = "\x03\x10clearInterval()\n\x10setInterval(function() {LED.toggle()}, 500);\n\x10print('Hello World')\n"
with something like
f = open(sys.argv[2], "r") command = f.read()
The BluePy example code can be changed to send a text file to Bangle Storage by replacing
command = "\x03\x10clearInterval()\n\x10setInterval(function() {LED.toggle()}, 500);\n\x10print('Hello World')\n"
with something like
f = open(sys.argv[2], "r") command = f.read() command = 'var Storage = require("Storage");var f = Storage.open("' + sys.argv[2] + '","w");f.write(`' + command + '`);\n'
Maybe it's for use for someone.
-
Hi,
I installed Espruino Hub on my RPi, and loaded the example code (added a setInterval) from https://www.espruino.com/BLE+HTTP+Proxy on my Bangle.
response=""; setInterval(function () { print("connecting"); NRF.requestDevice({ filters: [{ services: ['1823'] }] }).then(function(device) { require("ble_http").httpRequest(device, "pur3.co.uk/hello.txt", function(d) { response=JSON.stringify(d); print(response); }); }); }, 10000);
Sometimes the Bangle gets the expected response from the Hub, sometimes I get error
Uncaught Error: Unhandled promise rejection: Disconnected
.____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |____|___| _|_| |___|_|_|_|___| |_| espruino.com 2v06 (c) 2019 G.Williams > WARNING: Softdevice error BLE error 0x11 (BUSY) (bluetooth.c:818) connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Uncaught Error: Unhandled promise rejection: Disconnected connecting Connected Uncaught Error: Unhandled promise rejection: Disconnected connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Got service Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Got service WARNING: Softdevice error BLE error 0x11 (BUSY) (bluetooth.c:818) Got characteristic Set URI Got characteristic Written GET Disconnected {"buffer":[72,101,108,108,111,32,87,111,114,108,100,33,10],"byteOffset":0,"byteLength":13} connecting Connected Uncaught Error: Unhandled promise rejection: Disconnected WARNING: Softdevice error BLE error 0x11 (BUSY) (bluetooth.c:818)
I got similar errors when I used my own code in the Bangle and a self-coded BLE server on my Esp32 (ref http://forum.espruino.com/conversations/349804/#comment15369436);
Could this be caused be an "issue" in the BLE handling of Espruino, or is it unreliability in the BLE protocol?
-
Hmmmmmm, major error on my part :-(
My code from the emulator:
g.clear(); // fill screen with green g.setColor(0,1,0); // green g.fillRect(0,0,239,239); // reset getModified area m=g.getModified(true); print(m); g.setColor(1,0,0); // red // g.fillRect(100,100,120,120); m=g.getModified(); print(m); g.clearRect(m.x1,m.y1,m.x2,m.y2);
Output is:
>{ "x1": 0, "y1": 0, "x2": 239, "y2": 239 } >undefined >Uncaught Error: Cannot read property 'x1' of undefined at line 20 col 14 g.clearRect(m.x1,m.y1,m.x2,m.y2); ^ >
I see now dat getModified(true) returns an
undefined
. I was completely mislead by the response>{ "x1": 0, "y1": 0, "x2": 239, "y2": 239 }
and assumed that this was the area that was set.Apologies for wasting your time (red face), appreciate the help.
-
Hi @Gordon, thanks for getting back to me.
Yes, your example works fine, as intended:
- reset the
getModified
- draw something
- the
getModified
defines the "touched" area.
But ........ I have an App where sometimes (depending on the code) there is no drawing done, when I clear the
getModified
area, it blanks the screen, and that's not what I want.I thought it would be more applicable if
getModified(true)
would be set to "nothing is modified, so nothing needs to be cleared"{ x1: 0, y1: 0, x2: 0, y2: 0}
. Or ....... it would be set toundefined
, that's logical to me too.I don't get the logic for resetting to the entire screen, am I missing something?
- reset the
-
@allObjects - Ok, off-topic.
We seem to have a similar 'senior' background, I started decades ago with the Intel's like 8080/Z80,80x86 then moved to AVR-Arduino, in the last years ESP8266/ESp32.
Really love the ESP's for their Wifi connection. It runs Arduino, Micropython and Espruino. Nothing else needed........ EXCEPT for wearables... they're power hungry beasts
Just for fun I bought an NRF52832 development board to dable with BLE. Tried Arduino (works fine), Micropython (so,so) and Espruino.
Was to lazy to solder a TFT display tot the NRF52832 so I'm using Bangle now. Considering my background Javascript is little "quirky" but the help from the forum I'm getting there. Also great info on NRF52832 on gitter here if you're interested in the hard-core details : https://gitter.im/nRF51822-Arduino-Mbed-smart-watch/Lobby
There's 1 thing I miss in Bangle/Espruino : a Wifi connection!! My Bangle App is "done" but it needs feeding data from the internet. So I'm testing tools on Raspberry that function as a bridge between the internet and the Bangle. Exciting timings :-)
All in all, @Gordon is doing a tremendous job!
Cheers, see you!
-
I've been working with Espruino for Bangle now for some days. Javascript a an "experience" after many years of Arduino ;-)
Must say that Gordon has created a terrific environment with Espruino, excellent documentation and a fantastic development platform on the BangleJS. Kudo's to him.
After the limited 1-week experience with Espruino I love the environment for prototyping. The "nasties" I experience(like with getModified" are limited, and I can live with them.
The fun is in the "learning", right?
-
-
-
@NebbishHacker
Your suggestion on usinggetModified
was "spot on", shame on me ;-)Here's my latest code including a random 'drawString` to check that the override is now OK. Seems that it's perfect for me now.
Ofcourse it requires some bookkeeping of the m variable if you change to a complete different screen.
var m=0; // override drawString function to: // - allocate proper line spacing between successive lines (here 5 pixels) // - clear the area where the previous drawString was displayed g._ds = g.drawString; g.drawString = function(s,x,y) { s=s.toString(); sa=s.split("\n"); spacing=5+g.getFontHeight(); g.clearRect(m.x1, m.y1, m.x2, m.y2); // Will clear the precise area affected by the previous drawString calls g.getModified(true); // Reset modified area sa.forEach(function(line){ //call the original drawString g._ds(line,x,y); y+=spacing; }); m=g.getModified(); // save modified area for clearing on next drawString }; // write a random string of random size at random x and y positions setInterval(function () { g.setFontVector(80*Math.random()); g.setColor(1,0,0); getal=1000*Math.random(); getal=getal.toFixed(0); g.drawString(getal,Math.random()*239,Math.random()*239); }, 1000); g.clear();
-
Fixed a bug in my override function, updated the code in the post above.
And also found some flaws in my override code.
If the
drawString
string is replacing a previous WIDER string the `clearRect' area is to narrow, so parts of the previous string will still be visible.Back to the drawing board :-(
-
@NebbishHacker
As you can see in the post above I did not use yourgetModified
suggestion at the moment.My app is currently limited to text, I'm a lazy programmer, so this was the most efficient solution for me now.
When I get to the graphics part of my app I will remember your suggestion, thanks!
-
Changed my
drawString
override function toclearRect
the area where the string is going to be displayed.Not extensively tested, but seems to work ok for me. It saves a lot of
clearRect
s in my code :-)Comments and suggestions welcome!
Code is like this:
// override drawString function to: // - allocate proper line spacing between successive lines // - clear the area where the string will be displayed g._ds = g.drawString; g.drawString = function(s,x,y) { s=s.toString(); sa=s.split("\n"); spacing=5+g.getFontHeight(); sa.forEach(function(line){ // clear the area where the string will be written g.clearRect(x,y,x+g.stringWidth(line), y + spacing); // now call the original drawString g._ds(line,x,y); y+=spacing; }); };
-
@Gordon
Thanks for the tip, will have look at `apploader.js';In the meantime I found out that you could use the
espruino
commandline tool for uploading Espruino code that writes text to a textfile on the Bangle.You feed the 'espruino' tool with an Espruino program to write a file, something like this:
var Storage = require("Storage"); var f = Storage.open("messages.txt","w"); f.write(` Peter:How are you? Paul:Arrive 5 minutes later! Mary:Love you xxx ` );
Ofcourse you could the same with the left part of the Espruino WebIDE.
My "use case" is that I want to feed a Bangle app with data residing on my Raspberry every few minutes, without manual intervention.
Will see if
apploader.js
is the solution for me.Thanks.
-
@NebbishHacker
I was thinking about this strategy for my drawstring override:- get the area that is going to be covered by the string using fontHeight/fontWidth accounting for newlines in the string
- clear this area with clearRect
- then call the original drawstring
- done, nice and simple, no further bookkeeping.
But using getModified is more universal as it seems to cover all graphics. I have an App that uses many screens, so I would have to do a lot of bookkeeping with the different getModified areas.
Hmmmmm...... pondering .........
- get the area that is going to be covered by the string using fontHeight/fontWidth accounting for newlines in the string
-
-
@Gordon - I guess this means that we can forget about a "structural solution"for the problem on the short term, and I will have to live with my
drawString
override for now. Right?Maybe I will add the
g.clearRect(x, y, x+g.stringWidth(text), y+g.getFontHeight())
to my override, in my case it's always required with everydrawstring
. -
Found this a few minutes ago, not sure if it does what you want
https://github.com/espruino/EspruinoToolsI Installed it on my Mac and it works as commandline for the Bangle using BLE.
iMac19-9:~ gerard$ espruino Espruino Command-line Tool 0.1.31 ----------------------------------- Using first port, {"path":"f3-2c-dc-06-01-95","description":"Bangle.js 0195","type":"bluetooth"} Connecting to 'f3-2c-dc-06-01-95' >Connected >help Uncaught ReferenceError: "help" is not defined at line 1 col 1 help ^ >process.env ={ VERSION: "2v06", GIT_COMMIT: "21168a2b", BOARD: "BANGLEJS", FLASH: 524288, SPIFLASH: 4194304, STORAGE: 4194304, RAM: 65536, SERIAL: "2e5db521-5511cd11", CONSOLE: "Bluetooth", MODULES: "Flash,Storage,hea" ... "tensorflow,locale", EXPTR: 536882556 } >1+1 =2 >
-
Fair enough, your suggestion is cleaner.
But I wanted a "fix" for the drawString problem.
Found my inspiration here http://forum.espruino.com/conversations/302392/ and thought "hey that's clever" and coded away.
I'm a lazy coder, so in this way I did not have to change my code ;-)
And if Gordon comes up with a fix to "drawString" I delete the override and I'm ready.
Ok, thanks. Now I know at least that I did not cause the error in my own code.
My knowledge about BLE is rather scarce, so I'm afraid that I can't help you there.
But I'm good at testing, so if you need my help at some point ........