adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
MIT License
3.98k stars 1.17k forks source link

ItsyBitsy M4 Express deep sleep with external wakeup #7902

Open jdswope opened 1 year ago

jdswope commented 1 year ago

CircuitPython version

Adafruit CircuitPython 8.0.5; 4/23/2023 using IstyBitsy M4 Express

Code/REPL

import gc
import board
import adafruit_ssd1306
import adafruit_tca9548a
import alarm
import time
import digitalio

gc.collect()  # Garbage Collector to free up residual space

# Create the TCA9548A object and give it the I2C bus
tca = adafruit_tca9548a.TCA9548A(board.I2C())

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

led.value = True
time.sleep(1)
# led.value = False  No need to turn LED off, deep sleep will do it.

# For each sensor, create it using the TCA9548A channel instead of the I2C object
oled1 = adafruit_ssd1306.SSD1306_I2C(128, 64, tca[2])
oled2 = adafruit_ssd1306.SSD1306_I2C(128, 64, tca[3])
oled3 = adafruit_ssd1306.SSD1306_I2C(128, 64, tca[4])

# After initial setup, can just use sensors as normal.
oled1.fill(0)
oled1.text('Hello There', 0, 0, 1)
oled1.text('World', 0, 10, 1)
oled1.show()

oled2.fill(0)
oled2.text('Hi There!', 0, 0, 1)
oled2.text('How is the world?', 0, 10, 1)
oled2.show()

oled3.fill(0)
oled3.text('Hey!', 0, 0, 1)
oled3.text('What in the World?', 0, 10, 1)
oled3.show()

# Create a an alarm that will trigger 20 seconds from now.
#time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 20)
# digitalio.DigitalInOut(board.D11).deinit()
pin_alarm = alarm.pin.PinAlarm(pin=board.D11, value=False, pull=True)
# Exit the program, and then deep sleep until the alarm wakes us.
#alarm.exit_and_deep_sleep_until_alarms(time_alarm)
# Does not return, so we never get here.

# Exit the program, and then deep sleep until the alarm wakes us.
alarm.exit_and_deep_sleep_until_alarms(pin_alarm)

# Does not return, so we never get here.

Behavior

soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable. code.py output: Traceback (most recent call last): File "code.py", line 51, in ValueError: Invalid pin

Code done running.

Red LED starts blinking twice in succession every 5 seconds or so.

Description

Only happens when using the alarm.exit_and_deep_sleep_until_alarms(pin_alarm). Ir will let me use the time_alatm and works fine but, not the pin_alarm.

It even lets me set the pin_alarm to D11 (tor basically any other pin) but errors out on the pin_alarm.

Additional information

No response

raquo commented 3 months ago

This is marked as a bug, but... is it really a bug?

According to https://github.com/adafruit/circuitpython/pull/5425 the only pins that can be used for PinAlarm are "IN0:PB00; IN1:PB02; IN2:PA02; IN3:PC00; IN4:PC01". Of those, it seems that only the PA02 pin is brought out on ItsyBitsy m4 – according to the pinout chart, it is the A0 pin.

PinAlarm does in fact work on my ItsyBitsy m4's A0 pin with this code:

import alarm
import time
import board
import digitalio

ledPin = digitalio.DigitalInOut(board.D13)
ledPin.direction = digitalio.Direction.OUTPUT

ledPin.value = True

time.sleep(1)

pin_alarm = alarm.pin.PinAlarm(pin=board.A0, value=True, pull=True)

alarm.exit_and_deep_sleep_until_alarms(pin_alarm)

I haven't tested power consumption, but this code lights the LED for one second every time I connect A0 pin to the 3V pin, which is what I would expect from this PinAlarm.


I would be great if ItsyBitsy's doc page mentioned that A0 is the pin that can do PinAlarm, since this is a useful feature that appears to not work... unless you dig quite deep and find out that of all the pins, only A0 works.


I am guessing the same probably applies to the Feather m4 board, assuming that its CPU (which is a slightly different model number IIRC) has the same TAMPER pins as the one in ItsyBitsty m4 – on the Feather, PA02 pin is also mapped to A0. I haven't tested this on the Feather.

tannewt commented 3 months ago

Thanks for the info @raquo. I think you are right.

IIRC, we don't raise the issue from PinAlarm because it make work with light sleep just fine.

@jdswope You'll need to pick a different pin for deep sleep.