CircuitPython on my DIY Pico Cam: Raspberry Pi Pico 2 + OV5640 camera sensor

CircuitPython 9.2.4 exercise run on my DIY Pico Cam: Raspberry Pi Pico 2 + Waveshare OV5640 Camera Board, display on 240x240 ST7789 display/240x240 GC9A01 round display.


cpy_pico2_cam.py
"""
Raspberry Pi Pico 2/CircuitPython 9.2.4
+ Waveshare OV5640 Camera Board (adafruit_ov5640)
+ 1.54" 240x240 ST7789 SPI IPS  (adafruit_st7789) or
  1.28" 240x240 Round GC9A01 SPI IPS (gc9a01)

CircuitPython Libraries Bundle for Version 9.x needed:
(https://circuitpython.org/libraries)
- adafruit_ov5640 folder
- adafruit_st7789.mpy (optional for st7789 display)
- gc9a01.mpy (optional for gc9a01 display)

or install using circup:
circup install adafruit_ov5640, adafruit_st7789, gc9a01
For Installing and using CircUp, read:
https://coxxect.blogspot.com/2024/12/install-and-using-circup-circuitpython.html

ref of adafruit_ov5640:
https://docs.circuitpython.org/projects/ov5640/en/latest/
"""
import sys, os
import board
import busio
from displayio import (
    Bitmap,
    Group,
    TileGrid,
    FourWire,
    release_displays,
    ColorConverter,
    Colorspace,
    FourWire,
)

import time
import digitalio

import adafruit_ov5640

disp_sck  = board.GP2
disp_mosi = board.GP3
disp_res  = board.GP4
disp_dc   = board.GP0
disp_cs   = board.GP1
disp_blk  = board.GP28
disp_width = 240
disp_height = 240
disp_rowstart= 80    # depends on your display

#ov_5640 IO
#I use the name of the cam module for better reference for connection
ov_SIOC = board.GP7
ov_SIOD = board.GP6
ov_VSYNC = board.GP18
ov_HREF = board.GP21
ov_PCLK = board.GP17
ov_XCLK = board.GP20
ov_D9 = board.GP15
ov_D8 = board.GP14
ov_D7 = board.GP13
ov_D6 = board.GP12
ov_D5 = board.GP11
ov_D4 = board.GP10
ov_D3 = board.GP9
ov_D2 = board.GP8
ov_RST = board.GP16

# In my test,
# with shutdown=ov_PWDN will raise error of:
# AttributeError: 'Pin' object has no attribute 'switch_to_output'
# So I set it None.
ov_PWDN = None #board.GP19   

# Release any resources currently in use for the displays
release_displays()

sys_info_text = sys.implementation[0] + " " + os.uname()[3] +\
                "\nrun on " + os.uname()[4] +\
                "\n" + adafruit_ov5640.__name__ + " " + adafruit_ov5640.__version__
print("====================================")
print(sys_info_text)
print("====================================")
print()

disp_spi = busio.SPI(clock=disp_sck, MOSI=disp_mosi)

display_bus = FourWire(spi_bus=disp_spi,
                                 command=disp_dc,
                                 chip_select=disp_cs,
                                 reset=disp_res)

# for st7789 display
import adafruit_st7789
display = adafruit_st7789.ST7789(display_bus,
                                 width=disp_width,
                                 height=disp_height,
                                 rowstart=disp_rowstart,
                                 backlight_pin=disp_blk)
"""
# for gc9a01 display
import gc9a01
display = gc9a01.GC9A01(display_bus,
                        width=240,
                        height=240,
                        rotation=180,
                        backlight_pin=disp_blk)
"""

print("display setup finished")

print("construct bus")
ov_i2c_bus = busio.I2C(ov_SIOC, ov_SIOD)
print("construct camera")
ov_reset = digitalio.DigitalInOut(ov_RST)
# Set up the camera (you must customize this for your board!)
cam = adafruit_ov5640.OV5640(
    ov_i2c_bus,
    data_pins=[    # A list of 8 data pins, in order.
        ov_D2,
        ov_D3,
        ov_D4,
        ov_D5,
        ov_D6,
        ov_D7,
        ov_D8,
        ov_D9,
    ],
    clock=ov_PCLK,
    vsync=ov_VSYNC,
    href=ov_HREF,
    mclk=ov_XCLK,
    shutdown=ov_PWDN,
    reset=ov_reset,
    
    size=adafruit_ov5640.OV5640_SIZE_240X240,
    #size=adafruit_ov5640.OV5640_SIZE_QQVGA,
)

print("chip_id:", cam.chip_id)

#cam.test_pattern = True
bitmap = Bitmap(cam.width, cam.height, 65536)

print(cam.width, "x", cam.height)

if bitmap is None:
    raise SystemExit("Could not allocate a bitmap")

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

display.root_group = g

display.auto_refresh = False
while True:
    cam.capture(bitmap)
    bitmap.dirty()
    display.refresh(minimum_frames_per_second=0)


To install Circup and install modules using Circup, read:
https://coxxect.blogspot.com/2024/12/install-and-using-circup-circuitpython.html


Comments

Popular posts from this blog

480x320 TFT/ILI9488 SPI wih EP32C3 (arduino-esp32) using Arduino_GFX Library

my dev.tools - FNIRSI 2C23T 3-in-1 Dual Channel Oscilloscope/Multimeter/Signal Generator