Skip to content

Commit f8bbe61

Browse files
authored
Merge pull request #2416 from adafruit/ov5640-more-demos
Ov5640 more demos
2 parents e0a0722 + f450e77 commit f8bbe61

File tree

5 files changed

+366
-3
lines changed
  • OV5640_Breakout
    • CircuitPython_Kaluga-ascii-mirror
    • CircuitPython_Kaluga-jpeg
    • CircuitPython_Kaluga-lcd-mirror
    • CircuitPython_Pico-ascii-mirror
    • CircuitPython_Pico-lcd-mirror

5 files changed

+366
-3
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
"""
6+
This demo is designed for the Kaluga development kit version 1.3.
7+
8+
To fix the MemoryError when creating a Camera object, Place the line
9+
```toml
10+
CIRCUITPY_RESERVED_PSRAM=1048576
11+
```
12+
in the file **CIRCUITPY/settings.toml** and restart.
13+
"""
14+
15+
import sys
16+
17+
import board
18+
import keypad
19+
import displayio
20+
import espcamera
21+
import espidf
22+
23+
# The demo runs very slowly if the LCD display is enabled!
24+
# It's intended to be viewed on the REPL on a host computer
25+
displayio.release_displays()
26+
27+
if espidf.get_reserved_psram() < 1047586:
28+
print("""Place the following line in CIRCUITPY/settings.toml, then hard-reset the board:
29+
CIRCUITPY_RESERVED_PSRAM=1048576
30+
""")
31+
raise SystemExit
32+
33+
print("Initializing camera")
34+
cam = espcamera.Camera(
35+
data_pins=board.CAMERA_DATA,
36+
external_clock_pin=board.CAMERA_XCLK,
37+
pixel_clock_pin=board.CAMERA_PCLK,
38+
vsync_pin=board.CAMERA_VSYNC,
39+
href_pin=board.CAMERA_HREF,
40+
pixel_format=espcamera.PixelFormat.GRAYSCALE,
41+
frame_size=espcamera.FrameSize.QQVGA,
42+
i2c=board.I2C(),
43+
external_clock_frequency=20_000_000,
44+
framebuffer_count=2)
45+
print("initialized")
46+
47+
k = keypad.Keys([board.IO0], value_when_pressed=False)
48+
49+
chars = b" .:-=+*#%@"
50+
remap = [chars[i * (len(chars) - 1) // 255] for i in range(256)]
51+
width = cam.width
52+
row = bytearray(width//2)
53+
54+
sys.stdout.write("\033[2J")
55+
56+
while True:
57+
if (e := k.events.get()) is not None and e.pressed:
58+
cam.colorbar = not cam.colorbar
59+
60+
frame = cam.take(1)
61+
62+
for j in range(0, cam.height, 5):
63+
sys.stdout.write(f"\033[{j//5}H")
64+
for i in range(cam.width // 2):
65+
row[i] = remap[frame[width * j + 2 * i]]
66+
sys.stdout.write(row)
67+
sys.stdout.write("\033[K")
68+
sys.stdout.write("\033[J")
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023 Jeff Epler for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
"""
6+
This demo is designed for the Kaluga development kit version 1.3 with the
7+
ILI9341 display. It requires CircuitPython 8.
8+
9+
This demo needs reserved psram properly configured in settings.toml:
10+
CIRCUITPY_RESERVED_PSRAM=1048576
11+
12+
This example also requires an SD card breakout wired as follows:
13+
* IO18: SD Clock Input
14+
* IO17: SD Serial Output (MISO)
15+
* IO14: SD Serial Input (MOSI)
16+
* IO12: SD Chip Select
17+
18+
Insert a CircuitPython-compatible SD card before powering on the Kaluga.
19+
Press the "BOOT" button to take a photo in BMP format.
20+
"""
21+
22+
import os
23+
import struct
24+
25+
import board
26+
import busio
27+
import displayio
28+
import espcamera
29+
import espidf
30+
import keypad
31+
import sdcardio
32+
import storage
33+
34+
print("Initializing display")
35+
displayio.release_displays()
36+
spi = busio.SPI(MOSI=board.LCD_MOSI, clock=board.LCD_CLK)
37+
display_bus = displayio.FourWire(
38+
spi,
39+
command=board.LCD_D_C,
40+
chip_select=board.LCD_CS,
41+
reset=board.LCD_RST,
42+
baudrate=80_000_000,
43+
)
44+
_INIT_SEQUENCE = (
45+
b"\x01\x80\x80" # Software reset then delay 0x80 (128ms)
46+
b"\xEF\x03\x03\x80\x02"
47+
b"\xCF\x03\x00\xC1\x30"
48+
b"\xED\x04\x64\x03\x12\x81"
49+
b"\xE8\x03\x85\x00\x78"
50+
b"\xCB\x05\x39\x2C\x00\x34\x02"
51+
b"\xF7\x01\x20"
52+
b"\xEA\x02\x00\x00"
53+
b"\xc0\x01\x23" # Power control VRH[5:0]
54+
b"\xc1\x01\x10" # Power control SAP[2:0];BT[3:0]
55+
b"\xc5\x02\x3e\x28" # VCM control
56+
b"\xc7\x01\x86" # VCM control2
57+
b"\x36\x01\x40" # Memory Access Control
58+
b"\x37\x01\x00" # Vertical scroll zero
59+
b"\x3a\x01\x55" # COLMOD: Pixel Format Set
60+
b"\xb1\x02\x00\x18" # Frame Rate Control (In Normal Mode/Full Colors)
61+
b"\xb6\x03\x08\x82\x27" # Display Function Control
62+
b"\xF2\x01\x00" # 3Gamma Function Disable
63+
b"\x26\x01\x01" # Gamma curve selected
64+
b"\xe0\x0f\x0F\x31\x2B\x0C\x0E\x08\x4E\xF1\x37\x07\x10\x03\x0E\x09\x00" # Set Gamma
65+
b"\xe1\x0f\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F" # Set Gamma
66+
b"\x11\x80\x78" # Exit Sleep then delay 0x78 (120ms)
67+
b"\x29\x80\x78" # Display on then delay 0x78 (120ms)
68+
)
69+
70+
display = displayio.Display(display_bus, _INIT_SEQUENCE, width=320, height=240)
71+
72+
if espidf.get_reserved_psram() < 1047586:
73+
print("""Place the following line in CIRCUITPY/settings.toml, then hard-reset the board:
74+
CIRCUITPY_RESERVED_PSRAM=1048576
75+
""")
76+
raise SystemExit
77+
78+
print("Initializing SD card")
79+
sd_spi = busio.SPI(clock=board.IO18, MOSI=board.IO14, MISO=board.IO17)
80+
sd_cs = board.IO12
81+
sdcard = sdcardio.SDCard(sd_spi, sd_cs)
82+
vfs = storage.VfsFat(sdcard)
83+
storage.mount(vfs, "/sd")
84+
85+
print("Initializing camera")
86+
cam = espcamera.Camera(
87+
data_pins=board.CAMERA_DATA,
88+
external_clock_pin=board.CAMERA_XCLK,
89+
pixel_clock_pin=board.CAMERA_PCLK,
90+
vsync_pin=board.CAMERA_VSYNC,
91+
href_pin=board.CAMERA_HREF,
92+
pixel_format=espcamera.PixelFormat.RGB565,
93+
frame_size=espcamera.FrameSize.QVGA,
94+
i2c=board.I2C(),
95+
external_clock_frequency=20_000_000,
96+
framebuffer_count=1)
97+
print("initialized")
98+
display.auto_refresh = False
99+
100+
def exists(filename):
101+
try:
102+
os.stat(filename)
103+
return True
104+
except OSError:
105+
return False
106+
107+
108+
_image_counter = 0
109+
110+
111+
def open_next_image(extension="jpg"):
112+
global _image_counter # pylint: disable=global-statement
113+
while True:
114+
filename = f"/sd/img{_image_counter:04d}.{extension}"
115+
_image_counter += 1
116+
if exists(filename):
117+
continue
118+
print("#", filename)
119+
return open(filename, "wb")
120+
121+
ow = (display.width - cam.width) // 2
122+
oh = (display.height - cam.height) // 2
123+
124+
k = keypad.Keys([board.IO0], value_when_pressed=False)
125+
126+
while True:
127+
frame = cam.take(1)
128+
display_bus.send(42, struct.pack(">hh", ow, cam.width + ow - 1))
129+
display_bus.send(43, struct.pack(">hh", oh, cam.height + ow - 1))
130+
display_bus.send(44, frame)
131+
if (e := k.events.get()) is not None and e.pressed:
132+
cam.reconfigure(
133+
pixel_format=espcamera.PixelFormat.JPEG,
134+
frame_size=espcamera.FrameSize.SVGA,
135+
)
136+
frame = cam.take(1)
137+
if isinstance(frame, memoryview):
138+
jpeg = frame
139+
print(f"Captured {len(jpeg)} bytes of jpeg data")
140+
141+
with open_next_image() as f:
142+
f.write(jpeg)
143+
cam.reconfigure(
144+
pixel_format=espcamera.PixelFormat.RGB565,
145+
frame_size=espcamera.FrameSize.QVGA,
146+
)

OV5640_Breakout/CircuitPython_Kaluga/code.py renamed to OV5640_Breakout/CircuitPython_Kaluga-lcd-mirror/code.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@
6262

6363
if espidf.get_reserved_psram() < 1047586:
6464
print("""Place the following line in CIRCUITPY/settings.toml, then hard-reset the board:
65-
```
66-
CIRCUITPY_RESERVED_PSRAM
67-
```
65+
CIRCUITPY_RESERVED_PSRAM=1048576
6866
""")
6967
raise SystemExit
7068

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023 Limor Fried for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
"""
5+
This demo is designed for the Raspberry Pi Pico.
6+
7+
It shows the camera image as ASCII art on the USB REPL.
8+
"""
9+
10+
11+
import sys
12+
import time
13+
import busio
14+
import board
15+
import digitalio
16+
import adafruit_ov5640
17+
18+
print("construct bus")
19+
bus = busio.I2C(board.GP9, board.GP8)
20+
print("construct camera")
21+
reset = digitalio.DigitalInOut(board.GP10)
22+
cam = adafruit_ov5640.OV5640(
23+
bus,
24+
data_pins=(
25+
board.GP12,
26+
board.GP13,
27+
board.GP14,
28+
board.GP15,
29+
board.GP16,
30+
board.GP17,
31+
board.GP18,
32+
board.GP19,
33+
),
34+
clock=board.GP11,
35+
vsync=board.GP7,
36+
href=board.GP21,
37+
mclk=board.GP20,
38+
shutdown=None,
39+
reset=reset,
40+
size=adafruit_ov5640.OV5640_SIZE_QQVGA,
41+
)
42+
print("print chip id")
43+
print(cam.chip_id)
44+
45+
46+
cam.colorspace = adafruit_ov5640.OV5640_COLOR_YUV
47+
cam.flip_y = True
48+
cam.flip_x = True
49+
cam.test_pattern = False
50+
51+
buf = bytearray(cam.capture_buffer_size)
52+
chars = b" .':-+=*%$#"
53+
remap = [chars[i * (len(chars) - 1) // 255] for i in range(256)]
54+
55+
width = cam.width
56+
row = bytearray(width)
57+
58+
print("capturing")
59+
cam.capture(buf)
60+
print("capture complete")
61+
62+
sys.stdout.write("\033[2J")
63+
while True:
64+
cam.capture(buf)
65+
for j in range(0, cam.height, 2):
66+
sys.stdout.write(f"\033[{j//2}H")
67+
for i in range(cam.width):
68+
row[i] = remap[buf[2 * (width * j + i)]]
69+
sys.stdout.write(row)
70+
sys.stdout.write("\033[K")
71+
sys.stdout.write("\033[J")
72+
time.sleep(0.1)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023 Limor Fried for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
"""
5+
This demo is designed for the Raspberry Pi Pico. with 240x240 SPI TFT display
6+
7+
It shows the camera image on the LCD
8+
"""
9+
import time
10+
import busio
11+
import board
12+
import digitalio
13+
import adafruit_ov5640
14+
import adafruit_st7789
15+
import displayio
16+
17+
# Set up the display (You must customize this block for your display!)
18+
displayio.release_displays()
19+
spi = busio.SPI(clock=board.GP2, MOSI=board.GP3)
20+
display_bus = displayio.FourWire(spi, command=board.GP0, chip_select=board.GP1, reset=None)
21+
display = adafruit_st7789.ST7789(display_bus, width=240, height=240, rowstart=80, rotation=0)
22+
23+
print("construct bus")
24+
bus = busio.I2C(board.GP9, board.GP8)
25+
print("construct camera")
26+
reset = digitalio.DigitalInOut(board.GP10)
27+
cam = adafruit_ov5640.OV5640(
28+
bus,
29+
data_pins=(
30+
board.GP12,
31+
board.GP13,
32+
board.GP14,
33+
board.GP15,
34+
board.GP16,
35+
board.GP17,
36+
board.GP18,
37+
board.GP19,
38+
),
39+
clock=board.GP11,
40+
vsync=board.GP7,
41+
href=board.GP21,
42+
mclk=board.GP20,
43+
shutdown=None,
44+
reset=reset,
45+
size=adafruit_ov5640.OV5640_SIZE_240X240,
46+
)
47+
print("print chip id")
48+
print(cam.chip_id)
49+
50+
cam.colorspace = adafruit_ov5640.OV5640_COLOR_RGB
51+
cam.flip_y = False
52+
cam.flip_x = False
53+
cam.test_pattern = False
54+
55+
width = display.width
56+
height = display.height
57+
58+
#cam.test_pattern = OV7670_TEST_PATTERN_COLOR_BAR_FADE
59+
bitmap = displayio.Bitmap(cam.width, cam.height, 65535)
60+
print(width, height, cam.width, cam.height)
61+
if bitmap is None:
62+
raise SystemExit("Could not allocate a bitmap")
63+
64+
g = displayio.Group(scale=1, x=(width-cam.width)//2, y=(height-cam.height)//2)
65+
tg = displayio.TileGrid(bitmap,
66+
pixel_shader=displayio.ColorConverter(input_colorspace=displayio.Colorspace.RGB565_SWAPPED)
67+
)
68+
g.append(tg)
69+
display.show(g)
70+
71+
t0 = time.monotonic_ns()
72+
display.auto_refresh = False
73+
while True:
74+
cam.capture(bitmap)
75+
bitmap.dirty()
76+
display.refresh(minimum_frames_per_second=0)
77+
t1 = time.monotonic_ns()
78+
print("fps", 1e9 / (t1 - t0))
79+
t0 = t1

0 commit comments

Comments
 (0)