#I followed the `board.XXX` definitions

1 messages · Page 1 of 1 (latest)

shell kiln
#

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)

hexed coyote
#

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.

hexed coyote
shell kiln
# hexed coyote 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.
hexed coyote
shell kiln
hexed coyote
# shell kiln **Adafruit CircuitPython 10.0.0-beta.2 on 2025-07-31; Seeed Xiao ESP32-S3 Sense ...

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.

shell kiln
#

probably easier for me to switch to 10.0.3

shell kiln
#

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

hexed coyote
# shell kiln works for me with **Adafruit CircuitPython 10.0.3 on 2025-10-17; Seeed Xiao ESP3...

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()
shell kiln
#

if I remove the camera board I get RuntimeError: No pull up found on SDA or SCL; check your wiring

hexed coyote
#

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.

shell kiln
shell kiln
#

although I guess that's more critical for the main pins than the CAM_* pins on the fpc connector