-
I can't find a way to write to a custom service/characteristic exposed on the Puck from Node-RED through EspruinoHub.
However:
- Writing from Node-RED to
/ble/write/puck/nus/nus_tx
through EspruinoHub works - Writing to the custom service/characteristic using nRF Connect app on an Android phone works
The problem only appears when writing to the custom characteristic through EspruinoHub.
It seems it's not related to Node-RED since the same problem appears also when the MQTT message is published usingmosquitto_pub
.Following the guidance in https://www.espruino.com/Puck.js+Node-RED ...:
The format is /ble/write/de:vi:ce:ad:dr/service/characteristic, so you don't have to write to the Nordic UART on Puck.js. You can define your own services and write directly to those.
...and the guidance in http://www.espruino.com/Reference#l_NRF_setServices, this is the code I have on the Puck (first part unrelated (?), but adding for completeness):
setInterval(() => NRF.setAdvertising({ 0xFFFF: String(Math.round(Puck.light() * 1000) / 1000).split(""), 0xFFFE: String(E.getTemperature()).split(""), 0xFFFD: String(Puck.getBatteryPercentage()).split("") }, { interval: 5000 }), 60000 ); NRF.setServices({ 0xAAAA: { 0xAAA0: { writable: true, onWrite: function (evt) { LED1.set(); } } } });
And publishing to
/ble/write/puck/0000aaaa00001000800000805f9b34fb/0000aaa000001000800000805f9b34fb
yields:<Connect> de:vi:ce:ad:dr: Getting Service... <Connect> de:vi:ce:ad:dr: Disconnecting due to lack of use (after 30 secs) <Connect> de:vi:ce:ad:dr: Disconnecting. <Connect> de:vi:ce:ad:dr: Disconnected
Even extending the
CONNECTION_TIMEOUT
to 30s and the "getting services" timeout to 15s didn't help.Any ideas?
Is there some interplay between
setAdvertising
andsetServices
?
Am I using the wrong format for specifying service/characteristic ID? (Tried shortaaaa
, long0000aaaa00001000800000805f9b34fb
, hex0xaaaa
, capitalized, non-capitalized, etc.).Environment:
- Puck.js 1v90
- EspruinoHub up to date
- Node-RED 0.15.2
- MQTT Broker is hbmqtt built into Home Assistant
- All running on the same Raspberry Pi 3
- Writing from Node-RED to
-
-
@hansamann Great idea!
There's no accelerometer though, only magnetometer. That could still be used for fall detection with lower reliability, through sudden changes in rotation. Perhaps a machine learning algorithm could distinguish a fall from noise.
For location detection, maybe you could reverse the logic - have logic on the hub scan for Pucks, not the other way around. It would save the battery, and not add any extra hardware, since for your original scenario, you already need hubs spread around for the Pucks to connect to as proxies.
See e.g.
https://developers.redhat.com/blog/2015/07/31/behind-the-internet-of-things-middleware-demo-at-red-hat-summit/
https://github.com/starksm64/NativeRaspberryPiBeaconParserWhat sucks with NFC API now is that the only type of content that can be set is a URL, but that still works.
-
@Gordon
I think it's not worth increasing base energy consumption just to handle this case.That snippet does indeed provide some reliability, but still - I think in that situation it's more appropriate to "restore reliability" rather by replacing the battery than repeatedly restarting the magnetometer.
To clarify - I'm not looking for a hack around this particular problem, but rather trying to clarify (in documentation) expectations of reliability and/or make the API more reliable.
If you agree, I'd try to make some PRs to add detail to
Puck.mag
,Puck.magOn
, andPuck.light
in https://www.espruino.com/Reference.Do you think such detail (the "unreliable" behaviour of
mag
,light
) is appropriate for Reference and/or some other place? Or is this something you'd reckon most folks come expecting? -
You're right that the battery level affects the readings, but I wouldn't call the situation better, just different. Fresh battery yields:
Average light at 0.5 Hz: 0.61942668876 Average light at 1 Hz: 0.61750315656 Average light at 10 Hz: 0.63999368686 Average light at 25 Hz: 0.69513494318 Average light at 100 Hz: 0.74657709911
The curve is quite different than at low battery, but there still is a curve - a side effect I didn't expect.
The 1 kHz was just an experiment (there's a 200 Hz theoretical maximum anyway).
Anyway, no big deal, just the same realization as in the magnetometer/battery post: the Espruino API is a very thin wrapper around low level calls, and doesn't provide much of a reliability layer.
That is not a problem, just something that perhaps should be acknowledged.I'm perhaps in the minority, but I'm not too interested in tinkering with low level electronics, but rather using Puck as an HCI device. Use cases in that sphere are somewhat limited by the "unreliable" nature of electronics (unless handled and accounted for).
One example use case: I intended to implement a variable-rate light detection as a power-saving measure for my Proximity module.
-
Thanks for the details. I'm looking for any way to make the behaviour more reliable.
Currently, the magnetometer basically can't be depended on for continuous operation.When the spontaneous magnetometer reset happens,
Puck.magOn
says the magnetometer is on, even though it isn't. Can we detect inmagOn
that the reset has happened and warn about it?A battery level of 38% isn't something I would have guessed to be "low" or "critical". Having individual components fail at different battery/voltage/load levels is an unexpected behaviour in my opinion. Would be nice to mention this caveat somewhere.
For newcomers like myself, it's easy to see Puck as a nice little "black box" with a nice deterministic dependable API, and forget that the API is just a very thin layer over low level electronics.
-
I noticed the following behaviour:
- set a listener using
Puck.on("mag", lsnr)
- start magnetometer reporting with
Puck.magOn(5)
lsnr
is called only about 5 times and no more
To be clear:
Puck.magOff
is not called anywhere in between.This happened with
Puck.getBatteryPercentage()
at 38. After replacing the battery with a new one, it all works fine again.I suppose this should be added to documentation, or handled on a lower level - e.g. throw an error from
Puck.magOn
when battery voltage is below some level... - set a listener using
-
@catmapper Yes, light is detected by the red LED, that's confirmed in documentation.
That still doesn't explain the behaviour though.I also noticed the readings "lag" behind the actual lighting conditions. If you rapidly reduce/increase light (e.g. turn on/off a lamp), you're gonna see gradually increasing/decreasing readings over several Puck.light calls, not an immediate spike.
I suppose those behaviours (frequency-dependent values and lagging) are somehow related, but my understanding of physical/electronic principles is very limited, so I'm looking for some layman's explanation...
-
The subject says it all - I get different light sensor readings depending on how frequently I call
Puck.light()
.These are measured in constant lighting conditions:
Average light at 0.5 Hz: 0.60877327967 Average light at 1 Hz: 0.61237373737 Average light at 10 Hz: 0.34283262310 Average light at 25 Hz: 0.39304174558 Average light at 100 Hz: 0.46682646780 Average light at 1000 Hz: 0.50218986742
The values seem to be roughly:
- at a maximum when below 1 Hz,
- at a minimum at ~10 Hz,
- rising (up to some limit) when above 10 Hz.
Using the following code:
ITER=10; var experiment = function(dly) { var arr = []; var f = function(c) { arr[c] = Puck.light(); if (c<ITER) setTimeout(f,dly,c+1); }; setTimeout(()=>console.log("Average light at " + Math.round(100000/dly)/100+ " Hz: "+E.sum(arr)/arr.length),(ITER)*dly+50); f(0); }; experiment(100); // set the argument to number of milliseconds between readings
Any ideas why this is happening?
- at a maximum when below 1 Hz,
-
@CanyonCasa Thanks, good point! Fixed.
-
@tc You just beat me to posting this :) I had a similar idea I've been building in the recent days, especially rotation for volume control.
Mine's here: https://github.com/rsmeral/puck.js/
I modularized it into these
Button - emits events for single/double/long/multi press
Button.on("double", ()=>console.log("I got double clicked!"));
Proximity - emits "far" and "close" events, emulating a proximity sensor (based on light)
Prox.on("close", ()=>console.log("close")); Prox.on("far", ()=>console.log("far"));
Scroll Wheel - emits "plus", "minus" and "notch", based on magnetometer
Knob.on("plus", hid.volumeUp); Knob.on("minus", hid.volumeDown); Knob.start();
Lights - (WIP - works, but needs tweaks) - pretty API to control the LEDs
Lights.pulsing().color(Lights.BLUE).when(Button, "down").until(Button, "up"); Lights.blip(Lights.CYAN, 500); Lights.steady().rainbow().now().for(5000);
The VolumePlayPause demo is quite fat (especially due to Lights being fat) - when I load it through the Web IDE, it gives me Out of memory error, but when loaded through CLI, it works OK. Most likely the difference is in minification.
-
Hi all, I'm seeing this:
var Util = { foo:x=>x.forEach(e=>console.log(e.length)) };
This is valid ES6 code (https://repl.it/EyUS/0), yet:
Uncaught SyntaxError: Got ID:console expected ',' at line 3 col 23 foo:(x)=>x.forEach(e=>console.log(e.length)) ^ at line 3 col 25 foo:(x)=>x.forEach(e=>console.log(e.length)) ^
Am I misunderstanding something, or is this a bug in the interpreter?
-
@allObjects @thedamos
Sad to hear about the light sensor readings after blinking a LED - I intended to fake a proximity sensor by detecting light while still keeping the ability for signalling with LEDs.I think the problem could be related to the fact that the light sensor is (in? on?) the red LED, according to the reference: https://www.espruino.com/Reference#l_Puck_light:
Read a light value based on the light the red LED is seeing
I'll post my projects soon - I'm working on a module for using the Puck as an interface: a scroll wheel, e.g. to control volume through BLE HID (works already), and a simple API to control the LEDs, e.g.:
Lights.pulse().color(Lights.CYAN).when(Button,"press").until(Button,"long");
This mostly works too, but I'm seeing some strange bugs related to the event emitter that I haven't cracked yet.
Thanks for the tips. Finally figured it out – turning off the WiFi module of the Raspberry Pi (putting
dtoverlay=pi3-disable-wifi
into/boot/config.txt
) has helped big time, basically resolved the issue. I saw the advice somewhere else before, not sure where, but tried it only now.Now it works nicely most of the time. It just occasionally times out with:
Is this expected? Do you see the same behaviour? Any ideas how to achieve more reliability, apart from maintaining a persistent connection?