-
• #2
The
/n
is probably wrong, you are not sending correct end of line, try\n
-
• #3
Hi ,Thanks for that.
It displayed on the watch so, so far so good.
This is the shell output
Connecting...
Connected
Writing command
RX> bytearray(b"E.showMessage(\'Hello")
RX> bytearray(b"\',\'A")
RX> bytearray(b" Title\')\r\n")
Waiting for data
RX> bytearray(b'Uncaught ReferenceEr')
RX> bytearray(b'ror: "nE" is not def')
RX> bytearray(b'ined\r\n at line 1 col')
RX> bytearray(b" 36\r\n...ssage(\'Hello")
RX> bytearray(b"\',\'A Title\')/nE.show")
RX> bytearray(b"Message(\'Hello\',\'A T")
RX> bytearray(b"itle\')...\r\n ")
RX> bytearray(b' ')
RX> bytearray(b' ^\r\n>')
Done!
It doesnt look to clean. Is that down to how much data it can send?
Also do you now anything re UUIDNORDIC TX and RX?
Many Thanks -
• #4
Having got the data to the bangle can any one advise how this could be captured by an app on the bangle to manage the code style etc
Many thanks -
• #5
Ok, that looks good - the
Uncaught ReferenceError: "nE" is not defined
would be because you'd previously sent the wrong command (wrong\n
) and it was still in the input buffer, so when you later sent the correct command it errored because of the misplacedn
.If you run it a second time it'd work fine.
how this could be captured by an app on the bangle to manage the code style etc
You have three options -
Create a function, and then send the JS code to call it
This is by far the easiest and what I'd recommend. So right now you're sending
E.showMessage('Hello','A Title')
.Define a function on the Bangle and upload it - let's just call it
X
:function X(some, data) { E.showMessage(some, data); // or display some other way }
For this to work alongside other apps, you want to write this into a storage file called
myapp.boot.js
.Then you can connect and send something like
"X('Hello','A Title')\n"
.Have the app 'grab' the Bluetooth Serial port and handle all data that comes in.
Bluetooth.on('data',function(d) { print("Got some data",d); }); Terminal.setConsole();
This isn't ideal though - you have to handle the fact that the data sent will be split up into ~20 byte chunks. On top of that, debugging is a complete pain, because if you're grabbing the serial port that means you're no longer able to connect with the Web IDE.
Custom service
You could create a custom service with
NRF.setServices
and then handle writes using theonWrite
handler. It's more secure, but a bit of a pain to set up. -
• #6
This isn't ideal though - you have to handle the fact that the data sent will be split up into ~20 byte chunks
You could create a custom service with NRF.setServices and then handle writes using the onWrite handler. It's more secure, but a bit of a pain to set up.
As for custom service, not sure if it helps but I implemented AT command handler as a custom service to emulate DS-D6, HX03W fitness trackers so it can be used with original android app. The code is here and for useful bits start from the bottom. Those trackers implement actually two similar/same services 0x190A,0x190B and both have its own set of read and write characteristics similar to nordic UART. If there is something useful there, it is the handleWrite()+handleCommand() methods that will receive 20 byte arrays, join it to string and call handleATLine on complete lines and then get the response as a string and split it to 20 byte replies and fires the notifications with response. Basically if you would replace handleATLine by eval and catch exceptions there it would evaluate javascript like espruino console.
Also if you would try it beware of
uart:false
there that kills the console so keep it as true or have a way to callenableNordicUART()
to restore it. -
• #7
Hi Guys,
Thanks for your replies.
Fanoush, your approach is a little beyond my experience at this point but thank you.
Gordan , are (some, data) variables passed to the functon?
Does myapp.boot.js run in the background or do i need to to write an info file as described in your tutorials.
Sorry for the basic level of my response. -
• #8
are (some, data) variables passed to the function?
Yes, you can pass literally anything, you just have to turn it into a string. I'd suggest using Python's built-in functions for creating JSON, so then you can just define whatever Python variable you want, then send the command
"X("+json.dumps(my_data)+")\n".
Does myapp.boot.js run in the background
Yes, any '.boot.js' file will get automatically loaded along with an app, so you'll be fine without an info file. And if you want to add your code to the app loader all you need is something like this:
-
• #9
Hi Gordon,
Many thanks for the response.
I decided to make an app for this to make things a bit more visible.
However I get an error with json.dumps, which isTraceback (most recent call last): File "/home/pi/bleak-test.py", line 15, in <module> command = b"X("+json.dumps(dict)+")\n" TypeError: can't concat str to bytes
I added this snippet to bleak to creates the variable.
import json [#create](https://forum.espruino.com/search/?q=%23create) dictionary for the data to be sent dict = {'Code': '10'}
And for completeness my app does this
E.showMessage("Hello Code"); function X(dict) { E.showMessage(dict); }
So do I have to convert the json to bytes?
Thanks for your patience
mike -
• #10
yes, or remove
b
fromb"X
-
• #11
Thanks I will try that.
-
• #12
Fanoush,
Thank you tried but still get an errorFile "/home/pi/bleak-test.py", line 34, in run await client.write_gatt_char(UUID_NORDIC_TX, bytearray(c[0:20]), True) TypeError: string argument without an encoding
-
• #13
https://docs.python.org/3/library/functions.html#func-bytearray says
'If it is a string, you must also give the encoding'. For a start you can use 'ascii' as encoding.Or you can add encode call to
c=command
line to convert string to bytes. -
• #14
thanks for that
I have amended the code.command = "X('+json.dumps(dict).encode('utf-8')+')/n"
and
await client.write_gatt_char(UUID_NORDIC_TX,bytearray((c[0:20]),'utf-8') , True) c = c[20:]
Not sure if I need both utf-8's, however I am assuming that passing this to my function I will need to decode it.
-
• #15
Not sure if it is just forum formatting but the first part came out wrong(?) It looks like you are still a bit confused about which part is python and which is JS, which part is executed where, and also what is the difference between bytes/bytearrays vs strings in python. I think that just the second change would fix that last error.
BTW, Espruino interpreter does not handle utf-8 so ascii would be better. But maybe in this case it makes no difference anyway as json.dumps will hopefully quote non-ascii characters properly.
-
• #16
Thanks fanoush.
Re my understanding yes you are probably right.
To clarify I thought this line converted the python dictionary to a string:-command = "X('+json.dumps(dict)+')/n"
and this line converted the json string to bytes:-
await client.write_gatt_char(UUID_NORDIC_TX,bytearray((c[0:20]),'utf-8') , True) c = c[20:]
I thought this would then be sent and my function would decode the bytes back to a json string:-
E.showMessage("Hello Code"); function X(dict) { msg = json.loads(dict.decode('utf-8')); E.showMessage(msg); }
I dont now get the previous error, but the bleak library seems a little unreliable and gives a connection failure after a few attempts. However I am getting no response on the watch so I cant say its working yet.
I will try ascii and see if there's a difference,but I really need a more reliable bluetooth tranfer code. Hopefully the code comes out OK.
Many thanks for your help.
mike -
• #17
json.loads and dict.decode is python code so it won't run on the watch, it is not neeed however if you quote the
command=
... stuff right (as it was before) -
• #18
Hi fanoush, thanks for your patience.
So to go back I made the following changes but I stiil get no display on the watch. Just to note the function has changed to Y rather than X.
This is the console output.Connecting... Connected Writing command Waiting for data RX> bytearray(b'Y({"Code": "10"})/n') RX> bytearray(b'Y({"Code": "10"})/n') Done!
Putting the command back to what is was
command = "Y("+json.dumps(dict)+")/n"
and my app function is now
E.showMessage("Hello Code"); function Y(dict) { E.showMessage(dict); }
-
• #19
end of lines again
-
• #20
I am sorry I dont understand what you mean?
-
• #21
post #2,
\n
-
• #22
Thanks got you.
I now get output on the watch. Not what I want but progress.
Watch shows+json.dumps(dict)+
Console shows
Connecting... Connected Writing command Waiting for data RX> bytearray(b'Y({"Code": "10"})\r\n') RX> bytearray(b'Y({"Code": "10"})\r\n') RX> bytearray(b'Uncaught ReferenceEr') RX> bytearray(b'Uncaught ReferenceEr') RX> bytearray(b'ror: "nY" is not def') RX> bytearray(b'ror: "nY" is not def') RX> bytearray(b'ined\r\n at line 1 col') RX> bytearray(b'ined\r\n at line 1 col') RX> bytearray(b" 25\r\nY(\'+json.dumps(") RX> bytearray(b" 25\r\nY(\'+json.dumps(") RX> bytearray(b'dict)+\')/nY({"Code":') RX> bytearray(b'dict)+\')/nY({"Code":') RX> bytearray(b' "10"})/nY({"Code": ') RX> bytearray(b' "10"})/nY({"Code": ') RX> bytearray(b'"10"}...\r\n ') RX> bytearray(b'"10"}...\r\n ') RX> bytearray(b' ^\r\n>') RX> bytearray(b' ^\r\n>') Done!
`
I will try the acii next.
Thanks -
• #23
Sorry console didnt post right
Connecting... Connected Writing command Waiting for data RX> bytearray(b'Y({"Code": "10"})\r\n') RX> bytearray(b'Y({"Code": "10"})\r\n') RX> bytearray(b'Uncaught ReferenceEr') RX> bytearray(b'Uncaught ReferenceEr') RX> bytearray(b'ror: "nY" is not def') RX> bytearray(b'ror: "nY" is not def') RX> bytearray(b'ined\r\n at line 1 col') RX> bytearray(b'ined\r\n at line 1 col') RX> bytearray(b" 25\r\nY(\'+json.dumps(") RX> bytearray(b" 25\r\nY(\'+json.dumps(") RX> bytearray(b'dict)+\')/nY({"Code":') RX> bytearray(b'dict)+\')/nY({"Code":') RX> bytearray(b' "10"})/nY({"Code": ') RX> bytearray(b' "10"})/nY({"Code": ') RX> bytearray(b'"10"}...\r\n ') RX> bytearray(b'"10"}...\r\n ') RX> bytearray(b' ^\r\n>') RX> bytearray(b' ^\r\n>') Done!
-
• #24
I think what you've got is this line:
command = "X('+json.dumps(dict)+')/n"
Note that you're using two different types of quotes - so you're actually just sending the string
X('+json.dumps(dict)+')/n
which is exactly what Espruino is seeing.If you did:
command = "X("+json.dumps(dict)+")/n"
Then you may have more success - that should actually send the data in
dict
rather than just the textjson.dumps(dict)
. -
• #25
Thanks Gordon,
I have tried your suggestion but bleak throws an error, which I will show below.
My single quotes show jason.dump etc as before. This is also below.
However I am confused, as per conversation with fanoush, I thought my problem is for my function to convert the bytearray back to a string using javascript. ( Icant find a way to do this yet) but any clarity on this matter would help.
With the followingcommand = "Y("+json.dumps(dict)+")\n"
gives an error. Note I am not convinced that this is due to the command line as bleak seems a bit unstable.
File "/home/pi/.local/lib/python3.7/site-packages/bleak/backends/bluezdbus/client.py", line 146, in connect raise BleakError(str(e)) bleak.exc.BleakError: org.bluez.Error.Failed: Software caused connection abort
With this
command = "Y('+json.dumps(dict)+')\n" ``Console gives
Connecting...
Connected
Writing command
RX> bytearray(b"Y(\'+json.dumps(dict)")
RX> bytearray(b"Y(\'+json.dumps(dict)")
RX> bytearray(b"+\')")
RX> bytearray(b"+\')")
RX> bytearray(b'\r\n')
RX> bytearray(b'\r\n')
Waiting for data
RX> bytearray(b'=undefined\r\n>')
RX> bytearray(b'=undefined\r\n>')
Done!The watch displays
+json.dumps(dict)+
```
As a follow on from a previous post( Espruino Hub and BLE) I am trying to connect a raspberrypi to the bangle and send from the pi a short message or two digit code.
I have researched the espruino ref https://www.espruino.com/Interfacing#bluetooth-le, and in so doing came across a ble wrapper called bleak.
This seems suited to my purpose but whilst it will connect and appear to send data it the data does not show on the bangle.
I also do not know what ref I would need for these to entries (UUID_NORDIC_TX = ""
UUID_NORDIC_RX = ""
If it helps this is the shell output
Connecting...
Connected
Writing command
RX> bytearray(b"E.showMessage(\'Hello")
RX> bytearray(b"\',\'A")
RX> bytearray(b" Title\')/n")
Waiting for data
Done!
and this is the python code
Any guidance appreciated.