-
• #27
You mean a Bangle.js watch controlling your car? Absolutely - I don't think you need to use HID for that.
As an example, there's the Smartibot app - that communicates with a Smartibot (which also runs Espruino): https://github.com/espruino/BangleApps/blob/master/apps/smartibot/app.js
But basically all it does is:
- Connects
- Uploads some JS code (not required as you could have already programmed your car)
- Sends JS commands like
w(1,0,0,0)
to control the motors
- Connects
-
• #28
Thanks @Gordon I will use that as an example. That will be nice option for controlling it. I didnt know about that project and its using espruino! Its cool, might be a nice Christmas gift for my toddler. They also have a web app controller so it might be a good starting point.
I think I have my three options: phone webapp, Bangle watch and IDE testing plugin.
BTW quick google search and I found this: https://www.instructables.com/ESP32-Bluetooth-BLE-Remote-Control/
I think it should work for me as well. I have something similar. I made a post about in the past.
Probably the best and default option should be just using a phone with a webapp anyway. -
• #29
That's good - so it should be possible. To be honest 90% of the code in that instructable seems to be handling scanning for services and things - which Espruino handles for you anyway - so doing similar in Espruino should be pretty easy.
I just wish I had one here to try out :)
-
• #30
Project update:
I spend some time over Christmas break on the web joystick for the BolidJS. I feel like it should be separate project that could be used for other RC things. That might be idea for future or a fork of a current joystick. Anyway the code is here: repo WebJoystick and can be tested here: test WebJoystick
Right now its very prototype like with lots of debug features.
Main things to address:- controls scaling/placement
- for debug steering and acceleration knobs are directly wired to gauges
- no web bluetooth commands yet
The code needs some refactoring as well :) I feel like the tiny dash controls will have to be replaced with something that scales. Any suggestions for a library with gauges and graphs are welcome.
- controls scaling/placement
-
• #31
I am wondering what is the best approach for updating a motor PWM over web bluetooth from the joystick or other device. In the past pre-espruino implementations I would just send data frame and commands would be just fired periodically (or on event) on the control board. With espruino you can send a whole command over BLE like:
mot.dcMotorControl(mot.dir.FWD,0.05);
I have a feeling if I do that with too hight update rate by moving a knob in my web joystick that would cause problems. It would be fine for toggling lights but not for continuously updated value. Do I just have to setInterval on the controller side or I could listen for an event from BLE? I think listening for an event would be best. Maybe with some mechanism for discarding uncaught events so they dont queue. Is there a best practice here?
-
• #32
If you can connect to a different characteristic, and send the "commands" there, I think you should define a custom characteristic for controlling the car. NRF.setServices, and handle the
onWrite
event.
I imagine pretty similar to what you did previously.
And since payload for one command would be less than the packet size, the whole command arrives as one unit, command handling would be extremely simple, no need for buffering or anything like that. And not "polluting" the Nordic Uart with car control commands. -
• #33
I assume you pair - you have a connection - where you exchange data. So you would be able to even have handshake - ack / nack - to make sure your commands get thru.
On the sending side you can poll your controls and if do not notice any change (or change within boundaries) you do not send the information. When you send the information, you want to get it acknowledged - ack received for that command. If nack or any tampering has happened, you resend / retry. In addition to that you may also implement a heart bead. If your bolidJS does not get the beat anymore, it just stops. Ao you can make controler side a queue for outgoing commands. Feeding the queue you use the ui and handle it the same way: poll continuously and for each change you put a command into the buffer and trigger the working of the buffer. Just make sure you start every cycle with a setTimeout(... to break the JS execution streak (not hogging the only cpu you have). - Just some thoughts.
-
• #34
@AkosLukacs Thanks, using onWrite in NRF.setServices seems to be what I was looking for. I am thinking about around 100ms update rate when the knobs for acceleration and steering are operated from joystick. Thats what I set the interval to on the webjoystick side. Like you say there is no big data payload. From what you are saying I dont need buffering. I can deal with it later once I test the setServices.
I guess I cant use the uart.js with default settings or at all on the web bluetooth side? Would be nice to see some example if you came across anything similar.@allObjects the heart beat is a good idea. I dont want the car to drive into walls full speed once it loses communication. That can be implemented easily. I will look into the Acknowledge on a later stage once I have basics working. Should be good idea for reliability.
-
• #35
something like this: https://play.google.com/store/apps/details?id=iyok.com.blejoystick&hl=en_US&gl=US
-
• #36
or for apple fan
-
• #37
There is few joystick apps around. I looked through them but usually they are rather simple button type, limited control. I am aiming at something with more accuracy. Here is my prototype (my web development skills are very limited and its a work in progress):
https://kristosb.github.io/WebJoystick/
Also I dont want to go HID way straight away. I will follow @AkosLukacs suggestion and handle onwrite event after setting up NRF.setServices with custom data frame.
Right now I am trying to figure out if on WebBluetooth side I can stil use puck.js/uart.js or I need to go to lower level. -
• #38
For a proportional joystick I used code derived from this https://create.arduino.cc/projecthub/iot_lover/arduino-web-based-joystick-02ca54
But your WebJoystick prototype looks cool so perhaps treat ^^^ just as an inspiration.
-
• #39
Thanks @opichals that looks cool and I didnt come across it. Right now I am focusing on bluetooth connection. Yesterday I had some luck making it work from both sides using custom services. A lot to learn.
Once I have the whole system going I will have to refactor a lot of things so keep the inspirations coming :) Scalable js buttons and gauges would be something I will be looking for. -
• #40
Need some help with reading characteristic. I have a custom service and characteristics for writing to my device and reading from it. Writing works perfect. Value from read I just load from a global (FuelLevel) that I update every second in a setInterval. I know its updating because I can log it in console. When I read it from WebBluetooth app I only get the initial value that the global was loaded from but no updates. I am pretty sure I am missing something in the setServices descriptor.
NRF.setServices({ 0xBCDE : { 0xABCD : { value : [0,0,0,0,0,0], writable : true, onWrite : function(evt) { bolidControl(evt); } }, 0xABCE: { // fuel readable : true, value : [FuelLevel,0xAA] } } },{ advertise: [ 'BCDE' ] });
-
• #41
Ok, I am getting closer. I was missing NRF.updateServices. Now I see the value changing. The thing is I added it in a setInterval which fires before the connection is establish causing an error. I suppose I need to detect if there is a connection and update only then.
Is there any example/tutorial for this custom services communication? -
• #42
You should not need to be connected to update the value. However it could still make sense to stop updating it if nobody is reading to save power (if you run from battery).
Maybe the setInterval fires already before you call NRF.setServices?
-
• #43
setInterval is the last thing I do in the program. The error I get is
in function called from system
Uncaught Error: Can't update services until BLE restartLast lines of code:
function bolidRdUpdate(){ NRF.updateServices({ 0xBCDE : { 0xABCE : { value : [FuelLevel] } } }); } setInterval( bolidRdUpdate, 1000);
After I disconnect WebIDE and connect WebBluetooth app it works fine. The errors pop up while connected to IDE on every interval.
I suppose the error explains it. BLE needs to be restarted so maybe thats how it should behave. -
• #44
After I disconnect WebIDE and connect WebBluetooth app it works fine.
And then after you disconnect app and connect IDE again the error reappears?
Maybe it needs restart only first time after you call setServices while you are still connected via IDE - as it probably cannot change service definition while still connected(?). -
• #45
After just disconnecting and reconnecting the IDE error goes away. Its described in the help for setServices. Now I even remember reading it. I forgot about it by the time I got to that problem :) Initially I spend a lot of time on just writing which doesnt require reset.
Note: The services on Espruino can only be modified when there is no device connected to it as it requires a restart of the Bluetooth stack
-
• #47
Saving power make sense. I can see the device is drawing around 40mA even when not connected. It would be nice to detect the connection. Then it could be kept in some lower power mode when nothing is connected to it.
-
• #48
device is drawing around 40mA even when not connected
Wow, that's a lot! Any idea why? Even when executing JS flat out it should only be drawing 4mA or so...
could that be a good reason to add a throw in the code?
Sorry, not sure I understand?
-
• #49
It seemed a lot. I will turn off everything else on the board and make sure its not coming from somewhere else. 4mA idle would be acceptable for now.
thanks @Gordon I have no experience with that. Do you think its possible to make it work with bangle watch? There is a joystick app for bangle.