Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPI display goes black when running camera mirror example on Pico 2 #9662

Open
BlitzCityDIY opened this issue Sep 25, 2024 · 2 comments
Open
Assignees
Labels
Milestone

Comments

@BlitzCityDIY
Copy link

CircuitPython version

Adafruit CircuitPython 9.2.0-beta.0-12-gcd5c9d2632 on 2024-09-25; Raspberry Pi Pico 2 with rp2350a

Code/REPL

import board
import busio
import terminalio
import displayio
import adafruit_ov5640
import digitalio
import time
import adafruit_st7789

# Support both 8.x.x and 9.x.x. Change when 8.x.x is discontinued as a stable release.
try:
    from fourwire import FourWire
except ImportError:
    from displayio import FourWire

# Release any resources currently in use for the displays
displayio.release_displays()
spi = busio.SPI(clock=board.GP18, MOSI=board.GP19, MISO=board.GP16)
tft_cs = board.GP21
tft_dc = board.GP20
display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=None)
display = adafruit_st7789.ST7789(display_bus, width=240, height=240, rowstart=80, rotation=0)
print(spi.frequency)
freq = spi.frequency
spi.try_lock()
spi.configure(baudrate=int(freq / 2))
spi.unlock()
print(spi.frequency)
print("construct bus")
i2c = busio.I2C(board.GP5, board.GP4)
print("construct camera")
reset = digitalio.DigitalInOut(board.GP14)
cam = adafruit_ov5640.OV5640(
    i2c,
    data_pins=(
        board.GP6,
        board.GP7,
        board.GP8,
        board.GP9,
        board.GP10,
        board.GP11,
        board.GP12,
        board.GP13,
    ),
    clock=board.GP3,
    vsync=board.GP0,
    href=board.GP2,
    mclk=None,
    shutdown=None,
    reset=reset,
    size=adafruit_ov5640.OV5640_SIZE_240X240,
)
print("print chip id")
print(cam.chip_id)

cam.colorspace = adafruit_ov5640.OV5640_COLOR_RGB
cam.flip_y = False
cam.flip_x = False
cam.test_pattern = False

width = display.width
height = display.height

try:
    bitmap = displayio.Bitmap(cam.width, cam.height, 65535)
except MemoryError:
    print("Oops, 240x240 is a little too big, trying 240x176..")
    cam.size = adafruit_ov5640.OV5640_SIZE_QCIF
    bitmap = displayio.Bitmap(cam.width, cam.height, 65535)
print(width, height, cam.width, cam.height)
if bitmap is None:
    raise SystemExit("Could not allocate a bitmap")

g = displayio.Group(scale=1, x=(width-cam.width)//2, y=(height-cam.height)//2)
tg = displayio.TileGrid(bitmap,
    pixel_shader=displayio.ColorConverter(input_colorspace=displayio.Colorspace.RGB565_SWAPPED)
)
g.append(tg)
display.root_group = g

t0 = time.monotonic_ns()
display.auto_refresh = False
while True:
    cam.capture(bitmap)
    bitmap.dirty()
    display.refresh(minimum_frames_per_second=0)
    t1 = time.monotonic_ns()
    print("fps", 1e9 / (t1 - t0))
    t0 = t1

Behavior

The preview for the camera will show correctly on the display for a while, but then the colors will either invert or the display will go black. The code is still running because the camera FPS is still printing to the serial console. The hardware setup I'm using is with a Pico 2, PiCowbell Camera and a PiCowbell Tripler. The display is connected via the EYESPI connector. I've tried a 1.54" ST7789 240x240 display and a 2.8" ILI9341 240x320 display.

I have tried setting the camera size to OV5640_SIZE_QCIF, OV5640_SIZE_HQVGA, OV5640_SIZE_240X240 and OV5640_SIZE_QVGA (QVGA only when using the 240x320 display)

Description

I have tried reducing the SPI frequency, which previously I didn't have to do for this example with the Pico. However, the issue still persists. I was trying increasingly lower frequencies all the way down to spi.configure(baudrate=1000) (which is an actual frequency of 2288 when I print it to the console) and that seemed to keep the display alive for the longest. The default SPI frequency prints as 18750000 and half of that prints as 9375000.

Additional information

I have not been able to recreate the issue using a Pico RP2040. When displaying the REPL the display does not go out.

@BlitzCityDIY
Copy link
Author

testing with display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=None, baudrate = 9375000) instead of spi.configure(frequency=) and that actually affects display speed. display is staying up but the bottom 1/3 pixels on 240x240 disappear and show the REPL

@jepler jepler added this to the 9.2.0 milestone Sep 25, 2024
@jepler
Copy link
Member

jepler commented Sep 25, 2024

I'm trying to reproduce this with a similar setup:

PXL_20240925_220249882

clock for code.py for my setup
import board
import busio
import terminalio
import displayio
import adafruit_ov5640
import digitalio
import time
import adafruit_st7789

# Support both 8.x.x and 9.x.x. Change when 8.x.x is discontinued as a stable release.
try:
    from fourwire import FourWire
except ImportError:
    from displayio import FourWire

# Release any resources currently in use for the displays
displayio.release_displays()
spi = busio.SPI(clock=board.GP18, MOSI=board.GP19, MISO=board.GP16)
tft_cs = board.GP21
tft_dc = board.GP20
display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=None)
#display = adafruit_st7789.ST7789(display_bus, width=240, height=240, rowstart=80, rotation=0)
display = adafruit_st7789.ST7789(display_bus, height=320, width=170, colstart=35)
print(spi.frequency)
freq = spi.frequency
spi.try_lock()
spi.configure(baudrate=int(freq / 2))
spi.unlock()
print(spi.frequency)
print("construct bus")
i2c = busio.I2C(board.GP5, board.GP4)
print("construct camera")
reset = digitalio.DigitalInOut(board.GP14)
cam = adafruit_ov5640.OV5640(
    i2c,
    data_pins=(
        board.GP6,
        board.GP7,
        board.GP8,
        board.GP9,
        board.GP10,
        board.GP11,
        board.GP12,
        board.GP13,
    ),
    clock=board.GP3,
    vsync=board.GP0,
    href=board.GP2,
    mclk=None,
    shutdown=None,
    reset=reset,
    size=adafruit_ov5640.OV5640_SIZE_240X240,
)
print("print chip id")
print(cam.chip_id)

cam.colorspace = adafruit_ov5640.OV5640_COLOR_RGB
cam.flip_y = False
cam.flip_x = False
cam.test_pattern = False

width = display.width
height = display.height

try:
    bitmap = displayio.Bitmap(cam.width, cam.height, 65535)
except MemoryError:
    print("Oops, 240x240 is a little too big, trying 240x176..")
    cam.size = adafruit_ov5640.OV5640_SIZE_QCIF
    bitmap = displayio.Bitmap(cam.width, cam.height, 65535)
print(width, height, cam.width, cam.height)
if bitmap is None:
    raise SystemExit("Could not allocate a bitmap")

g = displayio.Group(scale=1, x=(width-cam.width)//2, y=(height-cam.height)//2)
tg = displayio.TileGrid(bitmap,
    pixel_shader=displayio.ColorConverter(input_colorspace=displayio.Colorspace.RGB565_SWAPPED)
)
g.append(tg)
display.root_group = g

t0 = time.monotonic_ns()
display.auto_refresh = False
while True:
    cam.capture(bitmap)
    bitmap.dirty()
    display.refresh(minimum_frames_per_second=0)
    t1 = time.monotonic_ns()
    print("fps", 1e9 / (t1 - t0))
    t0 = t1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants