Wake up using accelerometer
Is there a way of waking up the device from
machine.sleep()if the accelerometer value exceeds 2.8G or is less than 0.45G? I have seen a post on how it exceeds a threshold using
acc.enable_activity_interrupt(2000, 200)but I would like to make it to where if it is less than 0.45G, it wakes the device too. After the device wakes up, I would like to print GPS coordinates and then enter
machine.deepsleep(). Is there a way? I would like to keep battery life high on this device and the only trigger I require is the accelerometer. Ideally I would also send an sms to a number using the lte module but I do not have a sim atm.
Device = Pytrack 2.0X + GPy
Any help is appreciated thanks :)
rcolistete last edited by rcolistete
See 'machine.pin.hold()' :
"Get or set the pin hold. You can apply a hold to a pin by passing True (or clear it by passing False). When a pin is held, its value cannot be changed by using Pin.value() or Pin.toggle() until the hold is released. This Can be used to retain the pin state through a core reset and system reset triggered by watchdog time-out or Deep-sleep events. Only pins in the RTC power domain can retain their value through deep sleep or reset.
These are: P2, P3, P4, P6, P8, P9, P10, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23"
Yes, I was talking about
machine.deepsleep(). Using the Pytrack-controlled deep sleep will cut the power to the GPy, decreasing the power even further. The controller on the Pytrack is also put in a low power state and will keep track of the time and when to wake up.
I believe it is indeed possible to keep pin-states in deepsleep(), but I am not too sure of the exact pins, pullup or pulldown and how that would work in the end, you'll have to do some more research there..
@Gijs Just for completeness, this is the case during "native" deep sleep (
machine.deepsleep), not during Pytrack-controlled deep-sleep: in that case, the full ESP32 is powered off.
Also, in native deep sleep I believe at least some of the pins can be made to keep their state.
I think the best alternative for me is to calculate the composite acceleration value and then compare it to my thresholds. However, is there any way of waking up the Pycom on command? Like machine.wake() or something? I just need everything but the accelerometer to be sleeping and when I need to, I will wake the GPS and GSM modules, send data, and then enter machine.deepsleep().
You can set a wake-up time (like
machine.deepsleep(1000)will wake up after 1 second of sleeping.) a wake up interrupt pin (like the accelerometer uses) or touch button (using the ULP coprocessor). Next to that, the device will wake after pressing the reset button. Unfortunately, you cannot wake up on a command like
machine.wake(). More about the sleep and wake methods is discussed on this page: http://docs.pycom.io/firmwareapi/pycom/machine/
Just a sidenote, During deepsleep, the RTC timer and ULP coprocessor remain active (to keep track of the wake up time and touch buttons respectively), other than that, all pins states are left floating(?) and the main cores and WiFi radio are shut off. I believe it is technically possible to program the ULP coprocessor to do more, but that is outside the scope of our micropython firmware.
@jcaron Thanks! I think the best alternative for me is to calculate the composite acceleration value and then compare it to my thresholds. However, is there any way of waking up the Pycom on command? Like
machine.wake()or something? I just need everything but the accelerometer to be sleeping and when I need to, I will wake the GPS and GSM modules, send data, and then enter
@Akul9092 I believe this should be possible.
The LIS2HH12 has two interrupt generators (IGs), which can both trigger any of INT1 and/or INT2. Each IG can have its own threshold, and be set to interrupt on low or high. You can also pick which axes to monitor. Note however that I don't think you can monitor the "composite" acceleration vector, only each of the 3 axes.
The LIS2HH12 also has a high-pass filter, so that after a stable period the output signal is 0, and you can then monitor deviation from that instead of the actual acceleration. So after a steady state you can monitor acceleration up or down for instance.
Note that the data sheet of the chip is not very communicative of its abilities. You'll learn a lot more in this application note: https://www.st.com/resource/en/application_note/dm00165265-lis2hh12-mems-digital-output-motion-sensor-ultralowpower-highperformance-3axis-pico-accelerometer-stmicroelectronics.pdf
However, note that there are a few errors in there (and/or in the data sheet, I don't remember), so take it all with a grain of salt.
Disclaimer: I haven't actually tested any of them, I just report my understanding of the specs of the accelerometer.
Not sure if that has been addressed in the Pytrack 2.0, but in my experience switching on the accelerometer on the Pysense 1.0 resulted in a relatively large current draw (> 300 µA IIRC), which rendered sleep-and-wait-for-accelerometer-interrupt quite bit incompatible with good battery life.
Also there seems to be quite some confusion in your posts between
machine.deepsleepand more. The only way to achieve any decent battery life (if the above issue has been fixed) is deep sleep, either the GPy's, native deep sleep (
machine.deepsleep) or the Pytrack-controlled sleep (
pytrack.go_to_sleep). Anything else will result in current draw in mA, not µA, as far as I know.
Thanks for your help. That seems unfortunate. Also, the purpose of my device is fall detection — it detects a fall, tracks GPS coords and sends an SMS with coords to emergency contacts — so battery life is essential. A fall can occur by exceeding an upper threshold or lower threshold (which is 0.45 in this case) which explains the low value.
I made an attempt but it isn't as efficient. Could you have a look and see if it could be made more efficient or if I am making an error?
acc is the acceleration module
while True: machine.idle() sv = calculateSV(acc.acceleration()) #calculates by vector sum if sv > 2.8 or sv < 0.45: pycom.rgbled(0xff0000) #red print(getCoords(py)) pycom.rgbled(0xffff00) #yellow time.sleep(1000) #would send SMS rn but don't have SIM card atm machine.deepsleep() #user would have to click the reset button for it to switch back on
Also, is there a way of basically switching off the device on demand? Like using the reset button as an ON/OFF switch?
Currently it is only possible to choose one interrupt. I checked the datasheet of the accelerometer, and it is possible to set 2 interrupts in hardware. However, you will have to do some (quite hard) hardware modification to attach the second interrupt pin of the accelerometer (LIS2HH12) to a GPIO pin and write some new functions to be able to use it (Moreover, I believe it is not possible to set an interrupt for movement less than 0.45G). I would rethink your strategy (also, wake up if acceleration is less than 0.45G seems like an unusual usecase to me as then your device would always be moving?)