pycom / pycom-libraries

MicroPython libraries and examples that work out of the box on Pycom's IoT modules
333 stars 375 forks source link

pycoproc 0.0.4 can't wake pytrack-2 on accel interrupt #132

Closed hgoldwire closed 3 years ago

hgoldwire commented 4 years ago

What are the steps to reproduce this issue?

  1. install 1.20.2.r1 on brand new GPy
  2. install GPy on brand new pytrack 2.0
  3. reformat filesystem with os.fsformat('/flash')
  4. clear nvram with pycom.nvs_erase_all()
  5. power cycle in attempt to guarantee there's no lingering data/config
  6. install contents of https://github.com/pycom/pycom-libraries/tree/master/pytrack-2/lib in /flash/lib, including pycoproc 0.0.4
  7. run the code below
  8. bash head against pytrack, in attempt to wake it up
from pytrack import Pytrack
from LIS2HH12 import LIS2HH12

py = Pytrack()
acc = LIS2HH12(py)

acc.enable_activity_interrupt(200, 200)     # this works before I go_to_sleep
py.setup_int_wake_up(rising=True, falling=False)       # attempt to wake on activity

py.setup_sleep(300)
py.go_to_sleep()

What happens?

before issuing py.go_to_sleep(), accelerometer generates activity and inactivity interrupts. After going to sleep, no amount of "accelerating" 😄 the pytrack will wake it--you must wait for the sleep timer or hit the button on the pytrack.

What were you expecting to happen?

I was expecting the accelerometer to generate an interrupt that wakes the pytrack from sleep, which would then boot the GPy.

Any other comments?

I also notice that get_wake_reason() and get_sleep_remaining() are removed in pycoproc 0.0.4. Is the library actually ready for use?

What versions of software are you using?

>>> py.read_hw_version()          
6
>>> py.read_fw_version()            
15
>>> py.read_product_id()
61459
>>> os.uname()     
(sysname='GPy', nodename='GPy', release='1.20.2.r1', version='v1.11-a5aa0b8 on 2020-09-09', machine='GPy with ESP32', pybytes='1.6.0')
JanBurkhardt commented 4 years ago

Yes, same problem to me. I manually added the missing functions, but they didn't work. Just confusion returns from the function. I also tested the Setup with an old Pytrack and the old lib's. Therefore the program runs as expected.

gijsio commented 3 years ago

Hi, We are working on the issue! There should be an update soon Best, Gijs

hgoldwire commented 3 years ago

Hi,

We are working on the issue! There should be an update soon

Best,

Gijs

Any progress? It's been a couple months and (to me at least) the add-on boards are still unusable 🙁

peter-pycom commented 3 years ago

Hi, the underlying problem is that the same method of sleep&wake-from-accelerometer that is used on version 1 of the board is not possible on version 2.

Please test the attached firmware and scripts:

With the attached files the Pycom module (Gpy, Fipy, etc) is not completely powered off, but instead put to deepsleep. This way it can wake from accelerometer interrupt. In my tests, this reaches 165uA with a supply of 3.75V on a pysense2 with a GPy. I have not actually tested this on a pytrack, but they use the same firmware and scripts, so it should work the same. Looking forward to your feedback.

For completeness, I also attach v15 of the firmware (pysense_app_v15.dfu). That's the one you have right now, in case you want to revert to this during testing.

[pysense-2-v16-zip.zip]()

UPDATE: Apologies, the previous zip file was wrong. uploaded the correct one: pysense-2-v16-zip-again.zip

jandleuven commented 3 years ago

Hi Peter,

I followed all instructions to upgrade the firmware of my pysense 2.0X to pysense2_v16.dfu. But this is what happens (and keeps on happening if I repeat it a few times):

`>> dfu-util-static.exe -D pysense2_v16.dfu dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. Copyright 2010-2016 Tormod Volden and Stefan Schmidt This program is Free Software and has ABSOLUTELY NO WARRANTY Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Match vendor ID from file: 04d8 Match product ID from file: f011 Opening DFU capable USB device... ID 04d8:f011 Run-time device DFU version 0100 Claiming USB DFU Runtime Interface... Determining device status: state = dfuIDLE, status = 0 WARNING: Runtime device already in DFU state ?!? Claiming USB DFU Interface... Setting Alternate Setting #0 ... Determining device status: state = dfuIDLE, status = 0 dfuIDLE, continuing DFU mode device DFU version 0100 Device returned transfer size 64 Copying data from PC to DFU device Download [======================== ] 96% 15808 bytesError sending completion packet`

So I cannot download 100% It stops long before the 7s window is closed. What to do now? I can also not revert to pysense_app_v15.dfu. Same problem.

Luckily after mounting my lopy4 on the pysense I can still connect to the module, and py.read_fw_version() gives me '15'. So it looks the old firmware is not replaced. But I need v16 because I want to keep the RTC running in deepsleep mode and I want to use a wakeup pin on the module.

I am running Windows 10 Enterprise.

peter-pycom commented 3 years ago

this is strange, it does get to 96% so initially it works. searching for "Error sending completion packet", I see some comments about access rights. That also sounds strange to me, but maybe worth a shot - can you run it with admin rights? Failing that, maybe the other usual dance, different usb cable, different usb port, different computer, different operating system ...

jandleuven commented 3 years ago

Hi Peter,

After updating the pysense 2.0X firmware to your new pysense2_v16.dfu version, I tried the command py.read_fw_version(), and the reply is 15. Does it mean that the update didn't work? Of is the fw version number not updated in the new firmware?

I was now able to do this firmware update on another laptop where I had full admin rights, and it worked immediately. I now immediately reached the 100% from the first try. Whether that is due to the admin rights is not sure. But I am worried with the '15' response.

jandleuven commented 3 years ago

Hi Peter,

What power consumption do you expect when the pic is gone to sleep (with wake_up enabled) and the lopy4 module is in deep sleep? I measure 1.2 mA @4V, which is far too much for a battery-powered IoT device. So something must still be wrong as a lopy4 in deepsleep rather consumes something like 33µA. Or do I need to also switch some of the pins on the lopy4 (with 'hold' for deep sleep)?
I used the standard pysense script at https://docs.pycom.io/tutorials/expansionboards/pysense2/ but with the following additions at the end:

`py.setup_sleep(60) py.go_to_sleep(pycom_module_off=False, wake_interrupt=True)

machine.deepsleep(30000)`

In this way the lopy4 weeks up after 30s, and next wakes up the pic (before its own sleep time of 60s expires). All that works. But the power consumption is the problem.

Or is this because of the fact that I am still using Pysense 2X firmware 15 (see my previous post)

peter-pycom commented 3 years ago

Hi Peter,

After updating the pysense 2.0X firmware to your new pysense2_v16.dfu version, I tried the command py.read_fw_version(), and the reply is 15.

That's definitely not right. I checked. This was my mistake. Seems I uploaded the wrong files. I've updated it above. Please try again.

What power consumption do you expect when the pic is gone to sleep (with wake_up enabled) and the lopy4 module is in deep sleep?

I measure 165uA on a Gpy with 3.75V

I used the standard pysense script at https://docs.pycom.io/tutorials/expansionboards/pysense2/ but with the following additions at the end:

With the updated dfu firmware and pycoproc that should work.

But please also see the scripts in the zip file above. It also contains some explanations. (Note, when I updated the archive just now, also the scripts have changed.)

jandleuven commented 3 years ago

@Peter,

Thanks very much. It now seems to be working with fw16 and with your scripts. I measure the following power consumption (which is similar as what you measured): In ultra low power mode (~11uA @3.9V) with all sensors, incl accelerometer and also pycom module (lopy4) off In low power mode (~227uA @3.9V) with accelerometer on, pycom module in deepsleep and wake from accelerometer interrupt

Since I do not need the accelerometer wakeup, I thought I could reduce the low power mode consumption further by specifying accelerometer_off=True in pycoproc.go_to_sleep(). But strange enough that increases power consumption during the deep sleep from (~227uA @3.9V) to (~750uA @3.9V). Why is that? How to power-off the accelerometer so power consumption goes down further?

And why is power consumption in low power mode still (~227uA @3.9V)?

In ultra low power mode, the pic only consumes (~11uA @3.9V). And a lopy4 in deepsleep only consumes about 33µA. If you add these up, we should stay under 50µA for the combination, which would be a lot better for battery-powered IoT applications.

I know that to get to the 33µA for the lopy4 you need to make sure no power is consumed by the I/O pins (by the pull-ups or by anything connected to it). May I assume that during deepsleep all the lopy4 pins can be put in a state that consumes no power. Any recommendations here? Without having the schematics it is difficult for me to understand what happens under the hood.

peter-pycom commented 3 years ago

If you don't need the accelerometer wake up, why not use the "11uA mode"?

jandleuven commented 3 years ago

I need the RTC to keep track of time, and need to wake up the module with the reed switch of a tipping bucket rain gauge. The pysense offers a number of interesting features for my application: an MicroSD unit that can be powered off, and an on-board temperature/RH sensor that can monitor conditions inside the enclosure in which the device will be placed to face the weather elements, and the possibility to read and power (and power off) an external sensor like e.g. a temperature sensor (via the external I/O header). So your pysense offers an alternative to designing your own PCB for other applications than just the on-board sensors or the pycom sensors (that are not yet for sale). For all that it is worthwhile to have more information and to be able to keep power consumption minimal.

mexx42 commented 3 years ago

@peter-pycom, can you please provide me with the firmware for the pytrack2 ?

i have the same issue here as the original poster ... issued same code with current pycom-libraries

>>> py = Pytrack()
>>> py.read_hw_version()          
6
>>> py.read_fw_version()            
15
>>> py.read_product_id()
61459
>>> import os
>>> os.uname()     
(sysname='LoPy4', nodename='LoPy4', release='1.20.2.r3', version='v1.11-a6eabf9fe on 2020-02-26', machine='LoPy4 with ESP32', lorawan='1.0.2', sigfox='1.0.1', pybytes='1.3.1')

i tried flashing the pysense2 firmware, but dfu-util refused because of not matching usb-ids ...

for my project i absolutely need the accel-wakeup function !

as i tried this late december and found this issue i wanted to order pytrack(v1) boards where this worked, but they are not available anymore :(

if i can help you with anything - even coding, i am here !!! as i really would need it in the next days ...

regards and thanks for all the hard work ! - your stuff is awesome !!!

peter-pycom commented 3 years ago

Hi @mexx42 I am attaching v16 fw for pytrack and an update of the python scripts. The scripts should now work for both pysense and pytrack. I have to admit I only did minimal testing, but sleep with and without accelerometer wake up should work. There seems to be a problem with waking up from MCLR button, but you can press reset on the module afterwards.

Please do let me know how it works for you.

pysense-pytrack-2.zip

pytrack_v16.zip

mexx42 commented 3 years ago

Hello Peter, thanks a lot for the Firmware and the Scripts - i have tried your main.py and it works!

However, the code you are using differs from the one in the documentation - which i want to mention here for the others:

instead of:

py = Pytrack()
acc = LIS2HH12()

py.setup_int_wake_up(True, True)
acc.enable_activity_interrupt(2000, 200)
py.go_to_sleep()

you now use:

wake_pins = [Pin('P13', mode=Pin.IN, pull=Pin.PULL_DOWN)]
machine.pin_sleep_wakeup(wake_pins, machine.WAKEUP_ANY_HIGH, True)
pycoproc.setup_sleep(sleep_time_s)
pycoproc.go_to_sleep(pycom_module_off=False, accelerometer_off=False, wake_interrupt=True)
machine.deepsleep(sleep_time_s * 1000)

when will these changes be "official" - including the new firmware ?

mexx42 commented 3 years ago

@peter-pycom strange things happen here when i strip down your code to the essentials:

import time
import pycom
from machine import Pin
from pycoproc import Pycoproc
import machine
from LIS2HH12 import LIS2HH12

sleep_time_s = 15
pycom.heartbeat(False)
pycom.rgbled(0x0a0a0a) # white

print (machine.wake_reason())

pycoproc = Pycoproc()
print("battery {:.2f} V".format(pycoproc.read_battery_voltage()))
print("sleep_remaining:",machine.remaining_sleep_time())
accelerometer_sensor = LIS2HH12(pysense = pycoproc)
accelerometer_sensor.enable_activity_interrupt(100, 200)

wake_pins = [Pin('P13', mode=Pin.IN, pull=Pin.PULL_DOWN)]
machine.pin_sleep_wakeup(wake_pins, machine.WAKEUP_ANY_HIGH, True)

pycoproc.setup_sleep(sleep_time_s)
pycoproc.go_to_sleep(pycom_module_off=False, accelerometer_off=False, wake_interrupt=True)
machine.deepsleep(sleep_time_s * 1000)

print("we never reach here!")

Under normal circumstances it has 0.22mA power consumption when in deep sleep. When it wakes up after sleep time, it stays at 0.22mA, When it wakes via accelerometer interrupt, it uses 0.44mA in deep sleep ...

This happens not always, but most often.

If you put in some sleeps here and there you can improve the situation but that's not really an option.

In my code i wish to wake up on accelerometer, increment a counter, store in in nvram and got to sleep as fast as possible - but its not really an option to have double the power consumption for this case ...

Do you have any clues what can i do ? and why this happens ? something with waking up the pic ?

Is there any documentation or source code for the pic firmware available ?

>>> os.uname ()
(sysname='LoPy4', nodename='LoPy4', release='1.20.0.rc13', version='v1.9.4-94bb382 on 2019-08-22', machine='LoPy4 with ESP32', lorawan='1.0.2', sigfox='1.0.1')

The same is happening with latest development firmware:

>>> os.uname ()
(sysname='LoPy4', nodename='LoPy4', release='1.20.3.b0', version='v1.11-db33be7 on 2020-07-01', machine='LoPy4 with ESP32', lorawan='1.0.2', sigfox='1.0.1', pybytes='1.5.0')
mexx42 commented 3 years ago

@robert-hh: sorry, i was not that clear. The current is meant in sleep mode. At runtime i have avg. 40 to 50 mA, but in sleep mode it consumes either 0.22mA or 0.44mA ... depending on either it woke up by timer or by interrupt ... not always, but most of the time ... and that is definitely strange.

peter-pycom commented 3 years ago

how much do you get with my main.py? and can you explain a bit more where/how you put in sleep()'s that help. It might give a lead as to what is going wrong... Also how are you supplying power? Voltage?

mexx42 commented 3 years ago

Hello peter, thanks for your answer !

i needed to strip down your main.py to not be interactive - removing this and all the nice debug output leads to the main.py i posted above.

sadly enough, i found no real correlation between putting sleeps in the code or not, i tried numerous combinations, but nothing really showed any deterministic behaviour - even sometimes it consumes twice the power when it awakes from timer ... but this is lets say 1:100, whereas wakeup by accel it is nearly every time, but sometimes also not ...

The board is powered by 4 eneloop cells, so approx. 4.8 to 5Volts.

are there any (test)points on the device where i can measure if something gets not powered down correctly ? - and thus find out what is causing this ?

laszlokarsai commented 3 years ago

@peter-pycom thank you for the v16 firmware, accelerometer interrupt works well. My application also requires GPS though, and I am getting an I2C bus error using L76GNSS.py with your new pycoproc.py script.

I call this in main.py: py = Pycoproc() l76 = L76GNSS(py, timeout=30, buffer=512)

Getting this error: Traceback (most recent call last): File "main.py", line 15, in <module> File "L76GNSS.py", line 35, in __init__ OSError: I2C bus error

This is line 35 in L76GNSS.py: self.i2c.writeto(GPS_I2CADDR, self.reg)

Would you be able to help troubleshoot this for me? I am not sure what changed in the new firmware and new pycoproc versions and I'm not experienced in I2C. I want to avoid downgrading the firmware of my Pytrack2 if possible. I am using a SiPy + Pytrack 2.0 with the latest firmwares and libraries. UPDATE: after testing, the error does not occur if I use the original pycoproc file from the pycom libraries, so it must be some change in there. Ideally I would be able to have the accelerometer and GPS working together.

peter-pycom commented 3 years ago

Oh, you're right. Sorry for this. Thanks for flagging! It is sufficient to take the gps_standby() function from the old pycoproc. That way you should get the right mix of accelerometer wake and GPS.

Is that sufficient for the moment? We're working on the public release for this. Otherwise I can send you a new zip. Let me know and let me know your results.

peter-pycom commented 3 years ago

Ok. New pysense/pytrack 2 dfu's and pycom-libraries have been released. It supports waking from accelerometer. So, I'm closing this one. If anyone here has some further/other issue, please open a new ticket