puck.js - Improve long delay advertising

Posted on
  • I am using the puck.js button to turn on my hue lights.
    basically the button press is advertised and pickup by EspruinoHub then diverted through nodered to turn off the light. this unfortunately can take some time with delays around 8 secs.

    can this delay be improved, i understand the battery can take the hit but willing to try different scenarios.

    any help please

  • So you're using standard Bluetooth Advertising pretty much like is done here? http://www.espruino.com/Puck.js+Node-RED­

    You could try adding a debug node in NodeRed to see when the various events are getting fired and so where the delay is?

    The actual Bluetooth advertisement part should get sent out in around 300ms after the button press, so I'd be surprised if that was the slow part.

    The only other thing I could think is that the signal strength from the Puck was so low only a few of the advertising packets were getting through?

    To work around that you could:

    • Try and get the distance between the Puck and EspruinoHub down
    • Use NRF.setTxPower(4) to use the most powerful transmit power
    • Transmit more often (specify an interval in NRF.setAdvertising) so even if less are getting through, you hopefully stand a better chance of getting one.

    Hope that helps! 8 secs sure seems like a lot though? It may be on the Hue side of things

  • NRF.setTxPower(4) did the trick :)
    much better, some delays at times but way better.
    although i want it to be better. like the flic button.
    any suggestions please?

    the nordered flow i have is straightforward, i.e.

    [{"id":"597ae332.73aaa4","type":"mqtt in","z":"99c290d2.1b2068","name":"","top­ic":"/ble/advertise/d8:19:e7:5b:3a:57/ff­ff","qos":"2","broker":"21fe8cb3.438fcc"­,"x":160,"y":440,"wires":[["2b1d98d6.76c­7b","d47b84a0.1d40e8"]]},{"id":"2b1d98d6­.76c7b","type":"debug","z":"99c290d2.1b2­068","name":"","active":true,"tosidebar"­:true,"console":false,"tostatus":false,"­complete":"payload","x":410,"y":360,"wir­es":[]},{"id":"9efb6c2e.9426b","type":"h­ue-group","z":"99c290d2.1b2068","name":"­Living Room","bridge":"fe3415a5.63152","groupid­":"24","colornamer":true,"x":810,"y":500­,"wires":[["1c68d506.5a4eb3"]]},{"id":"8­a84c118.fdbae","type":"function","z":"99­c290d2.1b2068","name":"On/Off","func":"v­ar liv_light_bool = global.get(\"liv_light_bool\"); \nconst msg1 = {}\n\n \nif(!liv_light_bool){\n\n msg.payload={\n \t\"on\":[true],\n \t\"brightness\":[100],\n \t\"rgb\":[255,255,255],\n \t\"transitionTime\":[3],\n \t//\"colorloop\":[10],\n };\n \n}\n\nelse\n{\n msg.payload={\n \t\"on\":[false],\n \t\"brightness\":[0],\n };\n \n \n}\n\n\nmsg1.payload =\"digitalPulse(LED1, 1, 50);\";\n\nreturn [ msg, msg1];","outputs":2,"noerr":0,"x":530,"y­":440,"wires":[["9efb6c2e.9426b"],["1660­958b.f84e62","73e8e8a3.ba5848"]]},{"id":­"1c68d506.5a4eb3","type":"function","z":­"99c290d2.1b2068","name":"Set Global var","func":"global.set(\"liv_light_bool­\",msg.payload.on); \nnode.status({fill:\"red\",shape:\"ring­\",text:msg.payload.on});","outputs":1,"­noerr":0,"x":1060,"y":500,"wires":[[]]},­{"id":"1660958b.f84e62","type":"debug","­z":"99c290d2.1b2068","name":"","active":­false,"tosidebar":true,"console":false,"­tostatus":false,"complete":"true","x":67­0,"y":360,"wires":[]},{"id":"d47b84a0.1d­40e8","type":"rbe","z":"99c290d2.1b2068"­,"name":"","func":"rbe","gap":"","start"­:"","inout":"out","property":"payload","­x":390,"y":440,"wires":[["8a84c118.fdbae­"]]},{"id":"21fe8cb3.438fcc","type":"mqt­t-broker","z":"","name":"Localhost","bro­ker":"localhost","port":"1883","clientid­":"","usetls":false,"compatmode":true,"k­eepalive":"60","cleansession":true,"birt­hTopic":"","birthQos":"0","birthRetain":­"false","birthPayload":"","closeTopic":"­","closeQos":"0","closeRetain":"false","­closePayload":"","willTopic":"","willQos­":"0","willRetain":"false","willPayload"­:""},{"id":"fe3415a5.63152","type":"hue-­bridge","z":"","name":"Philips hue","bridge":"","key":"vvB2­GXGT15E6qEaaGTWzRwZVKoBXTcHYCnN25sGo","i­nterval":"1500"}]

  • Do you have a screenshot of the flow? It's a bit easier to see that way.

    Honestly if TX power fixed it then it's more of a physical problem than a software one. It's literally just that the signal isn't getting through very reliably to the Pi that is trying to receive it.

    If you're using WiFi on the Pi then you could try using Ethernet instead - that can help since the same aerial is used for both WiFi and Bluetooth, so WiFi traffic can make it harder to read from bluetooth.

  • i am standing 3 meters away from the rpi3 unit. i have disabled wifi as well same thing, still having 7 secs day at some times. please help, i like the puck.js and want to replace my flic buttons at home but flic so far is instantaneous. the flic is using a similar flow but fast..

    1 Attachment

    • Screen Shot 2018-10-09 at 7.38.30 pm.png
  • Ok, and you're saying that clicking on the timestamp inject button is basically instant as well?

    You can do this on the Puck:

    var pressCount = 0;
    setWatch(function() {
        0xFFFF : [pressCount]
    }, BTN, { edge:"rising", repeat:true, debounce:50 });

    Which will really raise the advertising interval so more packets get through (but it'll drain the battery faster unless you lower it again a while after the click).

    What happens if you do mosquitto_sub -v -t "/ble/advertise/de:70:d9:0c:eb:86/ffff" at the terminal on the Pi? You'll need to change the address to yours.

    I just tried it here from about 10 metres away and through 2 walls, and the response is almost instant.

  • lucky you you get this fast response. I really wish

    when clicking on timestamp the light turns on instantaneous

    i uploaded your code. tried it and was kinda quick. but then after restarting the machine it got slow like before. i am unable to turn off the red led from my flow,

    after doing the mosquito command, i get this,
    it seems to be skipping button counts if a press on button say 5 times i.e. one 1 press a second. see log. but if i press once and wait, it eventually prints it but after a while

    /ble/advertise/d8:19:e7:5b:3a:57/ffff [37]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [39]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [43]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [45]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [45]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [46]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [48]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [49]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [50]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [51]
    /ble/advertise/d8:19:e7:5b:3a:57/ffff [52]

    my machine uptime is as follow, i am not running anything besides nodered

    21:39:17 up 1:02, 2 users, load average: 0.21, 0.15, 0.10

  • reinstalled fresh raspbian copy, and seems to be quick now

  • Ahh, I think I see your problem.

    You are using nus_tx to write to the Puck as well to signal the button press?

    To write to the Puck a connection has to be opened (and it's kept open for a few (10?) seconds after the write in case another write comes along), but while that connection is open the Puck isn't advertising, so you don't receive any data from it.

    So after the initial button press, there's then 10 sec of not receiving anything.

    So you have two options:

    • Don't write to Puck.js (you could still make the Puck blink itself)
    • Switch the way you transfer data so that you always keep an open connection.

    You can do the second option by:

    • Program the Puck just to do Bluetooth.write("PRESS\r\n") (no setAdvertising) when the button is pressed
    • In your NodeRed flow, make sure you send a MQTT packet to /ble/notify/DEVICE/nux/nus_rx every 5 seconds
    • Listen on /ble/data/DEVICE/nus/nus_rx for data
    • To send commands to the Puck, send to /ble/data/DEVICE/nus/nus_tx as before

    The only problem with that approach is you can't also scan for advertising packets with EspruinoHub at the same time as holding open a connection.

    There's a third option which is to stop EspruinoHub from holding the connection open, but right now that's not something available in the config so would need a code change

  • thanks, found the culprit.
    so what is the best solution, quickest and best for battery please?

  • Well, a super-quick fix is to modify CONNECTION_TIMEOUT in EspruinoHub/lib/connect.js here: https://github.com/espruino/EspruinoHub/­blob/master/lib/connect.js#L20

    To be maybe just 1.

    Now after writing to the Puck, disconnect will happen after 1 second.

    So normally, changing light state should be almost instant, however if you click twice quickly then you'll be limited to roughly a 1 second delay on the second tap - which is probably ok?

  • thanks, that should solve the problem, which brings me to the next question, i rarely am able to program the puck through the espruino hub, i generally resort to the direct connection.... how can this be solved please

    When i go to the espruino hub, i can mot of the time locate the puck when i try to connect i get "connection failed"

  • Without more information I can't be much help - you're definitely using it from the Chrome Web Browser?

    Maybe you could start a new issue and post up the logs from the Chrome developer console, as well as the results of running sudo journalctl -f -u EspruinoHub on the Pi while trying to connect.

  • thanks gordon, you are a god send.
    appreciate your help. i am at the moment very comfortable with he button
    I would like to know 1 last thing, which of the options above is best to save battery


  • On 1v99 firmware and earlier, Bluetooth.write("PRESS\r\n") would use quite a lot of power, but on the cutting edge builds it is fine.

    I'd say NRF.setAdvertising is better though, if only because it deals better with intermittent signal (if you press the button while out of range, then come into range, it'll remember there was a press).


puck.js - Improve long delay advertising

Posted by Avatar for Ossama @Ossama