Electric Longboard Remote Help

Posted on
  • I am in the final stages of the creation of my Esk8 remote. I've built the hardware, created a simple UI, and now I need to write the bluetooth communication.

    I need some advice on how to create a bonded connection. I understand how promises work and the basic syntax of using nrf.connect().then.... to get the gatt and services/characteristics.

    Is there an easy way to read/write a value of characteristic without using that long syntax? Can I go through the pairing/bonding process, save the characteristic object to a variable (i.e. char = characteristic returned) and just call char.writeValue(data) to update the characteristic?

    Additionally, what is the reccomened transmitter/reciever setup? Should the reciever read a changing characteristic on the remote or should the remote(transmitter) write a value to a characteristic/service on the reciever?

    To give more detail, the remote uses a hall effect sensor to detect the throttle position and I need to send a value to the reciever and then send a pwm signal to the ESC based on the throttles position.

    Any help with this project would be appreciated.


    4 Attachments

    • 20190116_191509.jpg
    • 20190116_175509.jpg
    • 20190116_215111.jpg
    • IMG_20190203_210318_420.jpg
  • Wow, that looks awesome! I love the way you got an OLED display in there as well. It'd be great if you could post something up when you're done :)

    Bonding

    That should be fine. New firmwares (cutting edge, and 2v02 when it comes out) actually have the ability to set a passkey (http://www.espruino.com/Puck.js+Security#passkey-pin-pairing) which might be a good way of locking it down.

    Can I go through the pairing/bonding process, save the characteristic object to a variable (i.e. char = characteristic returned) and just call char.writeValue(data) to update the characteristic?

    There isn't a shorter way at the moment (I have plans to make a module to hide some of it), but you can re-use the service and characteristic.

    For instance:

    NRF.requestDevice({ filters: [{ namePrefix: 'Pixl.js' }] }).then(function(device) {
      return device.gatt.connect();
    }).then(function(g) {
      gatt = g;
      return service||gatt.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
    }).then(function(s) {
      service = s;
      return characteristic||service.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
    }).then(function(c) {
      characteristic = c;
      return characteristic.writeValue("LED1.toggle()\n");
    }).then(function() {
      gatt.disconnect();
      console.log("Done!");
    });
    

    Will make the connection next time quite a bit faster.

    Although for what you want, you want to stay connected - so you can just delete everything after characteristic = c; and then when you get a reading you want to transmit, do if (gatt && gatt.connected && characteristic) characteristic.writeValue([throttle_0_to_255]);.

    Should the reciever read a changing characteristic on the remote or should the remote(transmitter) write a value to a characteristic/service on the reciever?

    I'd say the latter. Make the board itself the peripheral, and make the controller connect to it. That's what most other stuff tends to do and then you could conceivably also use your phone to control it via Web Bluetooth - although god knows why you'd want to when the remote looks so cool :)

    I ought to cover it in more detail, but it's best to do it with a random 128 bit UUID (there are online generators available), then replace the second group of 4 numbers with 0001 for the service, then 0002/etc for the characteristics. Eg, ea1abd0133fc087275554a522b8f56c4 changes to ea1a000133fc087275554a522b8f56c4.

    That's a nice efficient way of doing it as the same basic 128 bit UUID gets re-used.

    You probably also want to add NRF.setConnectionInterval(7.5) on the longboard, to force it to use the fastest Bluetooth speed so you get the lowest latency. It also means you probably want to send the updates from the remote control at no more than 100Hz.

  • I just wrote up some examples on how to send data over a connection, so this might be some help for you: http://www.espruino.com/BLE+Communications#streaming-data

  • Wow, thank you gordon! I really appreciate your help. I will look over this code tonight and then get back to you with a few more questions.

    My end goal is to create a repo in Github, release the STl for the remote body (on thingiverse), and then create a build video on YouTube. You will also find a build post on the electric skateboard builders forum.

    Would you reccomend that flash the new v2.0 firmware before I continue? I'm currently using v1.99 I believe

  • @Shane.au.wade , what circuitry did you use to ensure safety for the MDBT42Q Bluetooth Module (<=3.6V) from the LiPo (up to 4.2V) - in the bottom of the remote?

    Are you right-handed?

    The remote looks really great!

  • https://www.adafruit.com/product/2124

    Here is the charging board that I am using. It is very small, and charges at 500ma. That isn't very fast, but you shouldn't need to charge it very often due to lower power consumption paired with a large battery. (2800mah samsung cell)
    If you need a small lipo/lion charger, that breakout board seems to be a good option.

    The MDBT42q has built in power management. it can be powered using 2.5 -> 16v. With the charge board and power management circuity it should be fine. The bare nrf52832 soc can only be powered with <=3.6v.

    I am right handed, yes.

    I worked hard on the remotes design. I wanted it to look slick.

  • ...and it payed of...

    The right-handed question was triggered by the position of display and button... to make the remote available thinking about how to us it with the other hand or both and till git from it what have designed is worth a thought - may be too version that at least support both preferences. I'n not a boarder and also do not know now often the display would have to be consulted or would be nice to be easily consulted while racing / cruising. UX things are quite a factor of acceptance.

    --- I guess you have to brand it with saw in elegant letters (and just drop the flattened O as goes with the pouch ;/* )

  • That's great! Please could you post a link up here when you do put stuff online?

    I'd say installing a 'cutting edge' build might be a good plan. There are some changes that really improve power consumption which might be useful, but also there's the Passkey pairing stuff which might be good security-wise?

  • I will update my two boards this week then.

    @Gordon I uploaded your code and made a few modifications and EUREKA! It works. I took my first test ride today and it seemed to perform well. Of course there is still a ton of testing and programming left to do but this is an excellent milestone.

    Here is a forum post!

    https://www.electric-skateboard.builders/t/no-name-yet-diy-esk8-remote/84639

  • Nice!

  • @Gordon

    I am working on increasing the security and efficiency of my remote. If you have sometime, I'd really like your feedback on what I have written so far. The next step is implementing the pair with passkey method.


    1 Attachment

  • It looks good to me. Do you have control over what's in the receiver, or is that someone else's?

    The easiest thing by far for security is to make your remote non-connectable with NRF.setAdvertising({}, { connectable:false }); and maybe even disable the UART with NRF.setServices(undefined, { uart : false});.

    Obviously that then means you wouldn't be able to connect to it to debug/do anything (you'd have to restart it with the button held down to get access). You could run the code in a timeout 30 seconds after boot to make it a bit easier I guess, or as it seems like even disconnecting the battery is tricky maybe you could make it so a really long press (30 sec?) of the button you added to D29 could re-enable it?

  • Actually, some other thoughts:

    • You might want to detect disconnect and try and automatically reconnect?
    • You can now add images 'in-line' as ascii with http://www.espruino.com/Graphics#images-bitmaps. What you've done is fine but having images as text makes them much easier to tweak if you need to later on.
  • I do have full control over the receiver as well. The receiver is another MDBT42Q with a female servo header soldered to it. Attaches is a photo.

    It is fairly easy to open up the remote and press the reset button so I might consider locking it down fully once I have tested it extensively.

    receiver.js :

    global.LED2=D2;
    
    var on = false;
    
    function onInit()
    {
    
    }
    
    NRF.setServices({
      "3e440001-f5bb-357d-719d-179272e4d4d9": {
        "3e440002-f5bb-357d-719d-179272e4d4d9": {
          value : [0],
          maxLen : 1,
          writable : true,
          //description: "PWM Throttle Input",
          onWrite : function(evt) {
            // Data comes in as a byte, make it 0..1 range
            var n = evt.data[0] / 255;
            // Send data directly to servo as PWM
            analogWrite(D7, ((1.2 + n*0.8)/10)*0.5, {freq:50});
          }
        }
      }
    }, { uart : true });
    
    
    NRF.setAdvertising({}, {name:"RxFlag"});
    
    
    
     // analogWrite(D7, pwmValue);
    
    //on disconnect return to a neutral state
    NRF.on('disconnect', function() {
      digitalWrite(D7,0.5);
      digitalWrite(LED, false);
    });
    
    NRF.on('connect', function() {
      digitalWrite(LED, true);
    });
    
    
     digitalWrite(LED2, true);
    

    Is there an event that occurs when the board detects a "powering off" state? I would like to send a neutral state of 0.5 to the receiver as soon as the remote disconnects form the board.

    Is it preferable to use the startBonding method of connection or is just using bluetoothdevice.connect() is fine/similar/the same?

    So far, at max tx power and lowest connection internal the performance has been very good. I am hoping that the connection is stable even in less than ideal connections (I.E. downtown SF where there is a lot of random RF everywhere.)


    1 Attachment

    • photo_2019-02-21_18-01-25.jpg
  • Is there an event that occurs when the board detects a "powering off" state?

    Not sure I understand. There's NRF.on('disconnect' but you're already handling that?

    Is it preferable to use the startBonding method of connection or is just using bluetoothdevice.connect() is fine/similar/the same?

    startBonding should try and set up a secure connection between the two devices, otherwise someone could 'spy' on the traffic between the two devices with a suitable radio. In practise very few people use encrypted links and it's not like you really care if anyone knows how far you pressed the trigger down - personally I'd say don't bother.

    I am hoping that the connection is stable even in less than ideal connections (I.E. downtown SF where there is a lot of random RF everywhere.)

    Only way is to test, but I think it should be pretty good.

    I've done stuff with them in some ridiculously bad areas - like 300 people in one room, each of which has at least 2 bluetooth LE devices, and everything is still pretty solid.

    Advertising can be a bit more touch a go (still not bad) but once you've got a connection it frequency hops and does seem to be very resilient.

  • ...I'm usually not thinking safety first... but in this case it seems to matter a bit...

    What is the behavior when you drop the remote?

    What is the behavior when the remote looses power for what ever reason?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Electric Longboard Remote Help

Posted by Avatar for Shane.au.wade @Shane.au.wade

Actions