#I followed the `board.XXX` definitions
1 messages · Page 1 of 1 (latest)
So.... the "retry loop" is a problem, and was probably (definitely on my system) responsible for the ValueError: CAM_D0 in use error. Adding a break before the except, i.e.
for _ in range(3):
try:
cam = espcamera.Camera( ... )
break
except OSError as e:
print(f"retrying, error={errno.errorcode[e.errno]}")
fixed it for me
Also, dropping the lock
i2c = busio.I2C(scl=board.CAM_SCL, sda=board.CAM_SDA)
#while not i2c.try_lock():
# time.sleep(0.1)
solved the EAGIN error
The **CAM_D0 ** in use came from the second attempt to initialize the camera, because it was used in the first attempt (and not properly released on the exception from trying to used the locked i2c or succeeded but ran again without break)
OK, removed the retry and the i2c lock. Still not working, as I'm getting this not supported error:
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
['.Spotlight-V100', '.fseventsd', 'test.txt']
Traceback (most recent call last):
File "code.py", line 31, in <module>
espidf.IDFError: Operation or feature not supported
Code done running.
My code:
import os
import espcamera
import board
import sdcardio
import storage
import time
import busio
import errno
sd = sdcardio.SDCard(board.SPI(), board.SDCS)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
print(os.listdir('/sd'))
# OV5640 Camera can do 1600x1200 (UXGA)
FRAME_SIZE = espcamera.FrameSize.VGA
# FRAME_SIZE = espcamera.FrameSize.UXGA
i2c = busio.I2C(board.CAM_SCL, board.CAM_SDA)
cam = espcamera.Camera(
data_pins=board.CAM_DATA,
external_clock_pin=board.CAM_XCLK,
pixel_clock_pin=board.CAM_PCLK,
vsync_pin=board.CAM_VSYNC,
href_pin=board.CAM_HREF,
pixel_format=espcamera.PixelFormat.JPEG,
frame_size=FRAME_SIZE,
i2c=i2c,
external_clock_frequency=20_000_000,
grab_mode=espcamera.GrabMode.WHEN_EMPTY,
framebuffer_count=2,
jpeg_quality=10)
cam.vflip = True
jpeg = cam.take(1)
if jpeg is not None:
with open('/sd/test.jpg', 'wb') as f:
f.write(jpeg)
print(os.listdir('/sd'))
del cam
storage.umount('/sd')
Line 31 is the contructor call. Does this actually run on your board?
Thanks for the clue with EAGAIN. Apparently the attempted second lock attempt by the constructor resulted in that error.
Were you able to run this on your board?
this code (above modified to make sd card optional)
#//from LumensalisCP.Bench.GCTests.GC_ArgsKwds import GC_ArgsKwds
import os
import espcamera
import board
import sdcardio
import storage
import time
import busio
import errno
sd = None
try:
sd = sdcardio.SDCard(board.SPI(), board.SDCS)
vfs = storage.VfsFat(sd)
storage.mount(vfs, '/sd')
print(os.listdir('/sd'))
except Exception as e:
print(f"SD card mount failed: {e}")
# OV5640 Camera can do 1600x1200 (UXGA)
FRAME_SIZE = espcamera.FrameSize.VGA
# FRAME_SIZE = espcamera.FrameSize.UXGA
i2c = busio.I2C(board.CAM_SCL, board.CAM_SDA)
cam = espcamera.Camera(
data_pins=board.CAM_DATA,
external_clock_pin=board.CAM_XCLK,
pixel_clock_pin=board.CAM_PCLK,
vsync_pin=board.CAM_VSYNC,
href_pin=board.CAM_HREF,
pixel_format=espcamera.PixelFormat.JPEG,
frame_size=FRAME_SIZE,
i2c=i2c,
external_clock_frequency=20_000_000,
grab_mode=espcamera.GrabMode.WHEN_EMPTY,
framebuffer_count=2,
jpeg_quality=10)
cam.vflip = True
jpeg = cam.take(1)
if jpeg is not None:
print(f"Captured JPEG of length {len(jpeg)}")
if sd is not None:
if jpeg is not None:
with open('/sd/test.jpg', 'wb') as f:
f.write(jpeg)
print(os.listdir('/sd'))
storage.umount('/sd')
del cam
results in
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
SD card mount failed: no SD card
Captured JPEG of length 13241
Code done running.
Press any key to enter the REPL. Use CTRL-D to reload.
James, thank you! I'll try it. What version of CircuitPython are you running? I grabbed the latest 10.1 build.
Adafruit CircuitPython 10.0.0-beta.2 on 2025-07-31; Seeed Xiao ESP32-S3 Sense with ESP32S3
OK, I tried with 10.0.3 on two boards and got the same error:
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
['.Spotlight-V100', '.fseventsd', 'test.txt']
Traceback (most recent call last):
File "code.py", line 35, in <module>
espidf.IDFError: Operation or feature not supported
Code done running.
Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 10.0.3 on 2025-10-17; Seeed Xiao ESP32-S3 Sense with ESP32S3
I will try to find the version of CP that you're using to see if there's been a regression.
probably easier for me to switch to 10.0.3
works for me with Adafruit CircuitPython 10.0.3 on 2025-10-17; Seeed Xiao ESP32-S3 Sense with ESP32S3 :
Adafruit CircuitPython 10.0.3 on 2025-10-17; Seeed Xiao ESP32-S3 Sense with ESP32S3
>>>
soft reboot
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
Hello World!
SD card mount failed: no SD card
Captured JPEG of length 15017
Code done running.
maybe try taking the SDCard out, just to remove one more variable?
also, how do you get these things into UF2 bootloader mode? I ended up doing a full re-install (hold BOOT, press/release RESET, release BOOT). Double clicking RESET just gives me the CIRCUITPY drive - nothing I tried would pull up the UF2 (XIABOOT ???) drive
I've tried with and without the SD card. Perhaps the boards are a bit different?
My experience with the bootloader access was the same: I had to re-install the bootloader (and then the BOOT drive appeared), then copied the CPy UF2 to the BOOT drive. But I can't get back to the bootloader either. When I do the hold BOOT, hit RESET I just get the JTAG/serial debug unit as expected. However, pressing RESET a second time during the yellow blink should put it into bootloader mode. I've even tried entering the bootloader using this code, and it didn't work:
import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()
if I remove the camera board I get RuntimeError: No pull up found on SDA or SCL; check your wiring
Yes, the pullups are on the camera board.
I haven't had the opportunity/need to get into the debugger in CPy; maybe this is the time. I'll dig into it on Monday.
yeah, I'd be surprised to find pullups on any XIAO controller because you won't always need I2C, in which case you probably want those pins for something else pretty badly...
although I guess that's more critical for the main pins than the CAM_* pins on the fpc connector