Brainstorming uart.js functionalities #1627
Replies: 21 comments
-
Posted at 2021-04-08 by Robin Thr 2021.04.08 Hi @jgrizou and Kudos on your ease of project success!
I know that @gfwilliams will appreciate your kind words for all the hard work and determination he has put into the the creation and success of the Espruino project, making it's ease of use a core goal for evey newcomer. > 'The ability to publish information from the embedded device to the webpage' There is a great starting page tutorial with embedded 'Try Me' buttons for each snippet that demonstrate BLE communication both ways:
> http://www.espruino.com/Web+Bluetooth I'm only able to provide some assistance using Windows10, but this page should assist visually in the connectivity part: > http://www.espruino.com/Quick+Start+BLE I'll defer to Gordon for the technical explanation for the eval() funtionality, and your comments/discussions questions. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-08 by @gfwilliams Hi! That looks like a really neat little robot design! Are you planning to publish it anywhere?
That is actually possible right now. It's not well documented for UART.js, but there is an example for the https://www.espruino.com/Web+Bluetooth#two-way-communications or https://www.espruino.com/Bangle.js+Data+Streaming There was some talk of whether this could be made easier though - effectively being able to register a
That's really neat! I guess we could have a UART object defined on the device itself, and then just query the keys for that. Another option is actually you can dynamically handle key accesses using While that won't work on Espruino, on the PC you could happily call
So if you call a function that doesn't exist it's no big deal - it just creates a referenceError on Espruino. In a way, I guess while this could be in UART.js, maybe it even makes sense to built it as a separate library on top of it, that is Espruino specific? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-09 by jgrizou Thanks @robin @gfwilliams for sharing all this, it makes total sense and sounds feasible!
I tried with good success.
Amazing! The Proxy thing is great and even more hands-off for the user.
Understanding this better now, I agree that a separate library makes more sense. I will work on a first version and share it here when it is ready ;)
Thanks! It is a quick prototype but you are right, I will make a repo with some basic info (BOM, wiring, code, etc) and share it with the community. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-12 by @gfwilliams That's great - thanks! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-20 by jgrizou_email_login Hi, I have tried to work on this a bit and got confused by the use of connections in uart.js. I would like to use the nice utility functions UART.write() and UART.eval() but do not want them to trigger their own connect event (that is showing up the select a port screen). I would like to connect only once when the user decides to and be able to all operations from there. But using the connection.on("data", cb) pattern and the write() and eval() helper function from UART seems incompatible as the UART.write() and UART.eval() are using their own separate internal connection variable. It feels not optimal to have to duplicate that part of the code: https://github.com/espruino/EspruinoWebTools/blob/13032d0e862d9976ed5eed33b42f07e93e6c25c3/uart.js#L403-L500 entirely to replicate the UART functionalities from a connection that I would open using the method described in https://www.espruino.com/Web+Bluetooth#two-way-communications This is actually commented in the code by saying that the UART.connect function output a connection different from the one used by write() and eval(), see image attached. I guess my questions are:
If that does not work, I guess I will have to reimplement something similar to write and eval functionality but with the connection.on("data", cb) working somehow on the with it. I am guessing I am a bit confused with how connection works under the hood but I hope that makes some sense :) Thanks in advance for any guidance on that!Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-21 by @gfwilliams As I understand it, UART.write/eval will create a connection (internally) and will then use that - so if you're writing to just a single device then that's all you need. You're prompted on the first call and after that it 'just works'.
Yes, you're right. The write/eval there should really be some common functionality in the connection object, or at the very least should take a connection as an argument so could be used on multiple connections. Are you interested in making that change, or should I look at it?
I believe after you're connected, you can just do |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-21 by jgrizou_email_login Thanks for the feedback!
Yes. My only issue is that I want to explicitly connect to the device before sending commands, to be sure the robot is ready and two way communication is established before starting the control loops. I guess a work around is to trigger a connect by sending an empty |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-21 by @gfwilliams
Yes, that's what I'd do... Sometimes it's good practice to send a |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-21 by jgrizou Quick update. I got UART.write, UART.eval, and a custom When I register a custom Code is very rough right now, just working my way around things. But, if curious, for now code is here: https://editor.p5js.org/jgrizou/sketches/Si31amD_p (see robot.js and sketch.js) and testable at https://editor.p5js.org/jgrizou/present/Si31amD_p Next I will try the proxy trick :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-22 by @gfwilliams That's great - thanks! I just created an issue for UART.js to keep track of this: espruino/EspruinoWebTools#6 I'm not sure when I'll get time, but hopefully I'll get those issues fixed. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-24 by jgrizou I am banging my head trying to make proxy work for all cases which seems very hard, if not impossible. Ideally I would like both
The problem I am having is knowing if Some ressources I used:
I am quite stuck so I will stop now. I am aware all can be solved by relying on setter and getter function on the device, e.g getSpeed() and setSpeed(), and then building the proxy assuming all Any thoughts on this? As an alternative route, is there a method to list all user defined variable and function on the Espruino device? That way we could ask for that list when connecting and decide what can and cannot be called. == One learning to maybe add to the issue -> it would be good to have the eval function return 'undefined' when it receives 'undefined' (right now it catch an error, print it, and call the cb with null instead). This way we can use eval for all actions and know if it actually crashed or ran well but got undefined back. That would be around here: https://github.com/espruino/EspruinoWebTools/blob/13032d0e862d9976ed5eed33b42f07e93e6c25c3/uart.js#L491-L497 Also I implemented a simple promise system on top of eval, works very well! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-24 by Robin Sat 2021.04.24
I presume after upload to the device? Will > 'but I start to feel it is impossible because we can only know if it is a function or the object after we return something and see if it is later called as a function again' Honestly @jgrizou, I'm not sure I understand the dilemma, is this what you are after? See Heading 'Complex Data' (near end of page)
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-24 by jgrizou Thanks @robin
Imagine we have this code on the device:
I am trying to create a Check again the first few posts for more details. I hope that makes some sense. == I might have found a way around my problem with an additional call |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-24 by jgrizou
Ok that approach work. It is a tricky code with a few promise and using https://github.com/kozhevnikov/proxymise on top. Code is very rough right now, just working my way around things. But, if curious, for now code is here: https://editor.p5js.org/jgrizou/sketches/Si31amD_p (see robot.js and sketch.js) and testable at https://editor.p5js.org/jgrizou/present/Si31amD_p For example, if you have a espruino device with a code like:
You can load this page https://editor.p5js.org/jgrizou/present/Si31amD_p, click connect button and connect to the device. Then in the webbrowser console the following commands should work:
A lot of cleaning, refactoring, bulletproofing is required, but the conceptual basis are there and it seems to work so I have hope, see head of sketch.js at https://editor.p5js.org/jgrizou/sketches/Si31amD_p. That was fun anyway! I will try to handle the In time, I will make it a standalone and actually usable library but for now I am exploring. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-26 by @gfwilliams That looks great! While Good point about I'm not sure if you found this, but you might be able to make |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-26 by jgrizou Thanks fo the feedback!
Yes!
I meant In other words, in the example above, This try/catch mechanism is great when we got an error and should be kept, but would be nice to have a third case for
Do you mean something like this?
Would be perfect indeed, but does not seem to work for functions. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-26 by @gfwilliams Thanks - that's great. Just filed an issue for it here: espruino/EspruinoWebTools#7 The issue may actually be more widespread - because I guess if you |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-05-18 by jgrizou Nothing new on that front yet but I just found out about https://www.npmjs.com/package/proxy-deep. Posting here to keep track. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-11-27 by Abhigkar @jgrizou did you publish the STL files for this robo kart somewhere? I really like the design and wanted to build one for my kids |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-11-27 by jgrizou_email_login @abhigkar thanks for asking, I just exported and uploaded them at https://github.com/jgrizou/phonebot/tree/main/stl You can find the original design on OnShape at https://cad.onshape.com/documents/858420b45d74a6c130741a27/w/ccd74c6c91d1447417ffa0b3/e/e34cca09c53379cb87889070?renderMode=0&uiState=62501d0795faa529ca2ae411 You should be able to copy this and make modification as needed. I hope this helps! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2022-11-27 by Abhigkar @jgrizou_email_login /@jgrizou Thanks :). I love to build this.. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-08 by jgrizou
Hi Gordon, all,
I started playing making a robot controlled via a webpage using Espruino, see photos attached and video here: https://youtu.be/xKEqqFrYgNQ
Building the robot took a few hours. And both embedded code + remote control via basic webluetooth page using uart.js less than one hour, I really didn't expect it would be so quick to get a MVP, the Espruino toolchain and REPL spirit is amazing. See very basic interface here: https://editor.p5js.org/jgrizou/present/osAAXLUtL. It also seem that I could connect several webpage to the same robot which is quite cool!
This was mind blowing to me on two aspects:
So first, thanks for developing all this!
--
I would like to brainstorm uart.js extension ideas here and collect the community opinion as to wether it is technically feasible and where I should start to implement it if I wanted to.
At the moment, I can see two ways to use the UART, write and eval:
And my understanding is that eval is calling write with an eval statement
"\x10eval(process.env.CONSOLE).println(JSON.stringify('+expr+'))\n"
. I not 100% sure how this work but it makes sense.Source code here: https://github.com/espruino/EspruinoWebTools/blob/master/uart.js
--
I would be interested in:
Maybe via a function sendToUart(), which can be tested using something like:
By doing
setInterval(function() {console.log({'value': true}}), 500);
, I could see the packet being sent to the webpage but they would need to be processed and formatted. It might also make it harder to differentiate between self-published messages and messages sent after an eval() was called maybe. Althought eval() calls seemed to work well despite that noise.Just to be clear, I am interested in self-published events from the robot. That is I want to avoid having to call eval() from the browser at fixed interval.
In the background, all these call would use uart.js write and eval function. Function to be published could be made explicit via some sort of export statement in the embedded code like:
exportUart({stop, left, right})
Similar to module export in javascript.
--
Do you have thought on this? To be clear I am not asking anyone to implement this, but rather for some comments/discussions on:
Thank you for your time reading this long post, any insight from the community would be very appreciated!
Jonathan
Attachments:
Beta Was this translation helpful? Give feedback.
All reactions