-
@Gordon your movement detector using magnetometer works really well.
-
And I added a count-down timer that resets ever movement trigger.
Maybe set the timer for 1 hr and if no motion within the hour then trigger. I'll need to disable this alarm during evening hours.By the way, for those who think this is creepy spying..... just wait until you have a 90 some year old person who wants independence and living alone!
The real reason for the lack of movement timer is to determine if the puck is still sitting on the night stand and not being worn.
-
I added the psudo motion detector that was explained by Gordon and am using both that and the RSSI as a way to detect motion of the puck (any motion is good in this use-case).
For now, I am testing on my lab unit in my house so that I can tweak the threshold for magnetometer triggering and see if there is any noticeable patterns in RSSI as I move from room to room. Not much data in the charts yet...
-
I'd really like to combine two values, but it seems like each topic is triggered separately.
It would be cleaner from the SMS reader's point of view for the message to be:
printf("Alert, the button was pressed. This is press %d since powered up. Battery level is %d.", msg1.payload, msg2.payload)
but it isn't clear to me how to do this graphically in Node-Red.
-
I have my project working fine from an engineer's perspective but I need to tidy it up a bit.
When my Puck.js detects a button press, the Espruino-Hub/Node-Red servers send an SMS using Twilio. In Node-Red it finds the msg-payload value which is the cumulative number of button presses since power cycle.
The problem I am having is my lack of understanding of how to work in Node-Red with messages.
In many programming languages I wand something like
printf("Alert, the button was pressed. This is the %d press since power cycle." msg.payload)
Does anyone know how to do this in Node-Red?
Thanks
-
-
I use Twilio for a bunch of my tech tinkering. It is a programmable SMS and Voice service. The service lets you get a phone number for $1/month and each SMS is like 0.7 cents.
Once you get an account on Twilio and create a number, you can access the service a number of ways. The easiest in this case was to just install the Node-Red Twilio node and put my account credentials in.
https://flows.nodered.org/node/node-red-node-twilio
I have the Espruino/Node-Red servers running on as Raspberry Pi Zero W which cost $10. Not including the power adapter but I have a ton of low power plugs laying around.
-
The goal here is for her to maybe tuck the Puck.js into her bra strap of something. Sounds weird but evidently women use their bra straps as a sort of pocket :-)
Core principle.. on an alert, use the Espruino Hub to convert the BLE advertisement of the alert to MQTT and use Node-Red to take action on that button press with a Twilio webhook to send the kids a SMS.
First draft - the button sends the alert right away. But then I thought it might be good to have a cancel feature for x seconds.
Second draft - button sets the red LED flashing for 10 seconds during which time the whole shooting match can be cancelled. If not cancelled, send the alert.
var pressCount = 0; var batt = 0; var alertQueued = 0; digitalWrite([LED3,LED2,LED1], 0); var flasherID; var timeoutID; function showAlert() { pressCount++; batt = Puck.getBatteryPercentage(); clearInterval(flasherID); alertQueued=0; NRF.setAdvertising({ 0x1812 : [pressCount], 0x180f : batt, }); LED1.write(1); } function delayedAlert() { timeoutID = setTimeout(showAlert, 10000); alertQueued=1; } function clearAlert() { clearTimeout(timeoutID); clearInterval(flasherID); alertQueued=0; LED1.write(0); } setWatch(function() { if (alertQueued) { clearAlert(); } else { delayedAlert(); flasherID = setInterval("digitalWrite(LED1,redLEDOn=!redLEDOn);",200); } }, BTN, { edge:"rising", repeat:true, debounce:50 });
The LED will stay on after the alert is set. To clear it, just cycle it again but cancel during the delay.
Next Steps -
I tried to get the gyro/accel to help me determine a fall.I tried the tilt>35 interrupt and I could get that to work on its own but not in conjunction with the button press.
Even if I did get them to work together it seems like there would need to be a LOT of tuning to get it right. The detector seems like by default it tests all axis. So turning left or right is no different than falling flat.
Maybe one of the other detection mechanisms could work. But she is nearly 90 so her baseline activity level is pretty slow.
-
Looking at the tilt library it seems to be using INT1.
The setWatch(button) isn't clear on which interrupt it is using.
Each of these two separate tests work independently but when I combine them they must conflict.
var pressCount = 0; var tiltCount = 0; var batt = 0; var redLEDOn = false; var greenLEDOn = false; var blueLEDOn = false; function swapBlue() { blueLEDOn = !blueLEDOn; LED3.write(blueLEDOn); } function swapGreen() { greenLEDOn = !greenLEDOn; LED2.write(greenLEDOn); } # Tilt detection works by itself, fails when combined with Button watching. require("puckjsv2-accel-tilt").on(); Puck.on('accel',function() { batt = Puck.getBatteryPercentage(); tiltCount++; swapGreen(); NRF.setAdvertising({ 0x1821 : [tiltCount], 0x180f : batt, }); } ); # Button watching works by itself but fails when combined with tilt detection. setWatch(function() { batt = Puck.getBatteryPercentage(); pressCount++; swapBlue(); NRF.setAdvertising({ 0x1812 : [pressCount], 0x180f : batt, }); }, BTN, { edge:"rising", repeat:true, debounce:50 });
-
-
-
Here is my code for the puck v2. The idea is that when the button is pressed, it sends info (the button count, the battery level and the z-axis value) to Node-Red so that Node-Red can react to the event.
var pressCount = 0; var batt = 0; setWatch(function() { batt = Puck.getBatteryPercentage(); var acc_gyro = Puck.accel(); pressCount++; NRF.setAdvertising({ 0x1812 : [pressCount], 0x180f : batt, 0x1821 : acc_gyro.gyro.z }); }, BTN, { edge:"rising", repeat:true, debounce:50 });
So, kind of works, but then it keeps sending
Here is the first batch of three data points (button count, power and z-axis):
9/17/2020, 8:01:08 PMnode: b0afda13.2a2f68 /ble/advertise/e9:1d:0b:37:51:d3/1812 : msg : Object object topic: "/ble/advertise/e9:1d:0b:37:51:d3/1812" payload: "[2]" qos: 0 retain: false _topic: "/ble/advertise/e9:1d:0b:37:51:d3/1812" _msgid: "6c9a4099.d4036" 9/17/2020, 8:01:32 PMnode: b0afda13.2a2f68 /ble/advertise/e9:1d:0b:37:51:d3/180f : msg : Object object topic: "/ble/advertise/e9:1d:0b:37:51:d3/180f" payload: "[100]" qos: 0 retain: false _topic: "/ble/advertise/e9:1d:0b:37:51:d3/180f" _msgid: "78d1d1f2.a0fc7" 9/17/2020, 8:01:32 PMnode: b0afda13.2a2f68 /ble/advertise/e9:1d:0b:37:51:d3/1821 : msg : Object object topic: "/ble/advertise/e9:1d:0b:37:51:d3/1821" payload: array[1] qos: 0 retain: false _topic: "/ble/advertise/e9:1d:0b:37:51:d3/1821" _msgid: "99cb3105.e5c77"
Here is the next batch exactly one minute later.
9/17/2020, 8:02:08 PMnode: b0afda13.2a2f68 /ble/advertise/e9:1d:0b:37:51:d3/1812 : msg : Object object topic: "/ble/advertise/e9:1d:0b:37:51:d3/1812" payload: "[2]" qos: 0 retain: false _topic: "/ble/advertise/e9:1d:0b:37:51:d3/1812" _msgid: "ab42bd04.966bc" 9/17/2020, 8:02:32 PMnode: b0afda13.2a2f68 /ble/advertise/e9:1d:0b:37:51:d3/180f : msg : Object object topic: "/ble/advertise/e9:1d:0b:37:51:d3/180f" payload: "[100]" qos: 0 retain: false _topic: "/ble/advertise/e9:1d:0b:37:51:d3/180f" _msgid: "bf8ee39f.9ff23" 9/17/2020, 8:02:32 PMnode: b0afda13.2a2f68 /ble/advertise/e9:1d:0b:37:51:d3/1821 : msg : Object object topic: "/ble/advertise/e9:1d:0b:37:51:d3/1821" payload: array[1] qos: 0 retain: false _topic: "/ble/advertise/e9:1d:0b:37:51:d3/1821" _msgid: "f303b855.f82eb8"
Am I missing something with this? I thought the puck would sleep until the next press.
On a side note... it seems like there are RSSI messages very frequently. Do they use just a small bit of power?
Awesome! Now I know how to format message payloads. Thank you @Gordon , this works perfectly as you suggested. The method for referring to Message-A from Message-B is going to be useful in the future.
I also used this formatting function to not only format my lack of motion alerts, but also limit them to waking hours only.