-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Quoting from #9535 (comment):
I'm having a very similar issue with I2C on QT-PY-ESP32-S2. I've come at it all kinds of ways, with one or multiple I2C devices and varying the I2C bus speed from 10_000 to 400_000.
With these i2c devices:
-
adafruit_ssd1306
-
adafruit_seesaw (rotaryio: product number 4991)
When I do a i2c.scan() it never shows any devices, but I can "speak" to the rotaryio. When I enable the ssd1306, I get:
main.py output:
sys.implementation=(name='circuitpython', version=(9, 1, 1), _machine='Adafruit QT Py ESP32S2 with ESP32S2', _mpy=262)
I2C_FREQ : 100000
I2C_DO_SCAN : True
I2C_USE_SSD1306: True
I2C_USE_SEESAW : True
Scanning I2C addresses: []
Position: 0
cnt_loops = 16 / sec
Traceback (most recent call last):
File "main.py", line 69, in <module>
File "adafruit_ssd1306.py", line 219, in show
File "adafruit_ssd1306.py", line 287, in write_framebuf
OSError: [Errno 116] ETIMEDOUT
If I never do the i2c.scan(), seesaw-rotaryio and ssd1306 appear to work fine (I've tried different instances of ssd1306 hardware).
In the case where I use only the seesaw-rotaryio and do i2c.scan(), the scan still shows no devices, I can communicate with the seesaw-rotario and my code speed decreases dramatically, e.g. 100+ loops/second becomes ~15 loops/second.
Code below. Can anyone shed some light on this?
Thanks,
Casa
# ==============================================================================
#
from micropython import const
import busio
import board
import sys
from adafruit_ticks import ticks_ms, ticks_add, ticks_less
I2C_FREQ = const(100_000)
I2C_DO_SCAN: bool = True
I2C_USE_SSD1306: bool = True
I2C_USE_SEESAW: bool = True
MS_ONE_SECOND = const(1000)
# ------------------------------------------------------------------------------
print(f"{sys.implementation=}")
print(f"I2C_FREQ : {I2C_FREQ:6d}")
print(f"I2C_DO_SCAN : {I2C_DO_SCAN}")
print(f"I2C_USE_SSD1306: {I2C_USE_SSD1306}")
print(f"I2C_USE_SEESAW : {I2C_USE_SEESAW}")
# ------------------------------------------------------------------------------
def print_I2C_Scan(i2c: busio.i2c) -> None:
while not i2c.try_lock():
pass
print("Scanning I2C addresses:", [hex(i).upper() for i in i2c.scan()])
i2c.unlock()
# ------------------------------------------------------------------------------
# Set up i2c0, OLED, seesaw rotaryio
#
i2c0 = busio.I2C(board.SCL, board.SDA, frequency=I2C_FREQ)
if I2C_USE_SSD1306:
import adafruit_ssd1306
ADDR = const(0x3C)
WIDTH = const(128)
HEIGHT = const(64)
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c0, addr=ADDR)
if I2C_USE_SEESAW:
from adafruit_seesaw import seesaw, rotaryio #, digitalio
seesaw = seesaw.Seesaw(i2c0, 0x36)
encoder = rotaryio.IncrementalEncoder(seesaw)
last_position = None
# ------------------------------------------------------------------------------
if I2C_DO_SCAN:
print_I2C_Scan(i2c0) # PROBLEM HERE
# ------------------------------------------------------------------------------
cnt_loops: int = 0
cnt_printed: int = 0
ms_target: int = ticks_add(ticks_ms(), MS_ONE_SECOND)
try:
while True:
cnt_loops += 1
if not ticks_less(ticks_ms(), ms_target):
ms_target = ticks_add(ticks_ms(), MS_ONE_SECOND)
if cnt_printed < 10:
cnt_printed += 1
print(f"cnt_loops = {cnt_loops} / sec")
cnt_loops = 0
if I2C_USE_SSD1306:
oled.fill(0)
oled.show()
# oled.line(X_MAX, Y_MAX, X_MIN, Y_MIN, 1)
oled.vline(WIDTH // 2, 0, HEIGHT, 1)
oled.show()
if I2C_USE_SEESAW:
if (position := -encoder.position) != last_position:
last_position = position
print("Position: {}".format(position))
except KeyboardInterrupt:
print("Caught KeyboardInterrupt, exiting")
Originally posted by @Casa-Machinalia in #9535 (comment)