-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
CircuitPython version and board name
Adafruit CircuitPython 10.0.3 on 2025-10-17; Adafruit Feather ESP32S3 4MB Flash 2MB PSRAM with ESP32S3Code/REPL
#
# i2c_power test
# 2026-01-27
#
# Test to see if i2c_power can be toggled before/after deep sleep and maintain setting through deep sleep
#
import board
import busio
import time
import digitalio
import adafruit_ens160
import alarm
print("\nESP32-S3 i2c_power test")
# Enable i2c_power pin to turn-on i2c power after sleep
i2c_power = digitalio.DigitalInOut(board.I2C_POWER)
i2c_power.direction = digitalio.Direction.OUTPUT
i2c_power.value = True
print('i2c power should be back on...')
def mox():
# ENS161 measurement
moxnap = 3
print('Sleep for ',moxnap,' seconds to allow MOX to get ready')
time.sleep(moxnap) # Allow sensor to get ready after power-up
print("AQI (1-5):", ens161.AQI)
print("TVOC (ppb):", ens161.TVOC)
print("eCO2 (ppm):", ens161.eCO2)
# Enable i2c
#i2c = board.STEMMA_I2C()
i2c = busio.I2C(board.SCL, board.SDA, frequency=100000) # Must use 100kHz frequency for i2c bus
# when PM2.5 sensor included
# ENS161 setup
# NOTE: i2c address conflict with LTR390 (both default to 0x53). Had to enable ENS161 to use 0x52 (see learn gu
ide)
ens161 = adafruit_ens160.ENS160(i2c,0x52)
measurement_time = 30 # Send measurement to Gamera every measurement_time
time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + measurement_time)
print("alarm.wake_alarm: ",alarm.wake_alarm)
if isinstance(alarm.wake_alarm, alarm.time.TimeAlarm):
print('Woke from ',alarm.wake_alarm)
mox()
print('Power off...')
i2c_power.value = False
time.sleep(5)
print('Power back on...')
i2c_power.value = True
time.sleep(5)
# Turn-off power to i2c devices before going to sleep
print('i2c power should turn off now...')
i2c_power.value = False # Set to False to turn-off i2c power during sleep
nap = 5
print('Sleep for ',nap,' to see i2c power go off...')
time.sleep(nap) # So I can see i2c power go off
print('Going to sleep for ',measurement_time,' seconds')
#alarm.exit_and_deep_sleep_until_alarms(time_alarm,preserve_dios=[i2c_power])
alarm.exit_and_deep_sleep_until_alarms(time_alarm)Behavior
With the final line of code as entered above (with no preserve_dios setting), the code will:
(1) Turn-off I2C bus power for 5 seconds (the wake timer has not been set yet, so the isinstance statement is not executed)
(2) Turn-on I2C bus power for the duration of the deep sleep (30 seconds)
(3) Upon wake from deep sleep due to wake timer, I2C power will
(3a) Come back on
(3b) Perform a MOX sensor measurement
(3c) Turn-off I2C bus power for 5 seconds
(3d) Turn-on I2C bus power for 5 seconds
(3e) Turn-off I2C bus power for 5 seconds
(4) Turn-on I2C bus power when board enters deep sleep
When I un-comment the alarm.exit_and_deep_sleep_until_alarms(time_alarm,preserve_dios=[i2c_power]) line and comment-out the alarm.exit_and_deep_sleep_until_alarms(time_alarm), thus enabling preservation of the I2C_POWER pin state through deep sleep, I see the following behaviour:
(1) Turn-off I2C bus power for 5 seconds (the wake timer has not been set yet, so the isinstance statement is not executed)
(2) Turn-off I2C bus power for the duration of the deep sleep (30 seconds)
(3) Upon wake from deep sleep due to wake timer, I2C power does not come back on. When the i2c initialization statement i2c = busio.I2C(board.SCL, board.SDA, frequency=100000) is reached, I get the error in the Repl:
RuntimeError: No pull up found on SDA or SCL; check your wiringIn all instanced where I say that I2C power is on or off, this is based on seeing the green LED on my I2C sensor (ENS161) either on or off, respectively. I should note also that this test is a stripped-down version of a much more complex system with a total of four I2C sensors connected via STEMMA. Testing with those other devices connected results in the same outcomes.
Description
- Using I2C_POWER pin to control power to I2C devices via STEMMA
- Can control I2C_POWER (turn I2C devices on and off at-will) when NOT using
preserve_dios=[i2c_power]inalarm.exit_and_deep_sleep_until_alarms - If
preserve_dios=[i2c_power]inalarm.exit_and_deep_sleep_until_alarmsis used, I2C_POWER does turn-off power to I2C devices during deep sleep, but I2C power does not come back on after time alarm wake from deep sleep.
Additional information
- Tested also with CircuitPython 9.2.9. Same behaviour as with 10.0.3.
- Hardware configuration includes an Adafruit LoRa Radio Featherwing RFM95W and several analog devices connected with a breadboard, but none of these devices are enabled for these tests. Tested by removing ESP32-S3+Radio Featherwing from breadboard (thus removing analog devices from system) and encountered same behaviour.