The previous post descripted how to install CircuitPython 7.0.0 and Library Bundle on nanoESP32-S2, and and
SPI ST7789 LCD. This exercise capture image from ov7670 camera module and display it on
ST7789 SPI LCD.
Libraries
adafruit_ov7670 and adafruit_st7789. How to download and install Adafruit
Library, refer to the previous post.
Connection between nanoESP32-S2 and ov7670 cam module/ST7789 SPI TFT
ov7670 header
+-----------+
3V3 |3V3 DGND| GND
IO7 |SCL* SDA*| IO8
IO9 |VS HS | IO10
IO11 |PLK XLK | IO12
IO40 |D7 D6 | IO39
IO38 |D5 D4 | IO37
IO36 |D3 D2 | IO35
IO34 |D1 D0 | IO33
IO13 |RET PWDN|
+-----------+
*cam.SCL/SDA are I2C control pin, pull-up resistors are needed.
I use 2K ohm resistor for it.
ST7789 +-------------------------------+
----- | |
GND | -----+ +-------------------+ |
VCC | -------- | 3V3 GND | ------+
SCL | -------- | 0 RST |
SDA | -------- | 1 46 |
RES | -------- | 2 45 |
DC | -------- | 3 44 |
CS | -------- | 4 43 |
BLK | -------- | 5 42 |
----- | 6 41 |
cam.scl | 7 40 | cam.D7
cam.sda | 8 39 | cam.D6
cam.VS | 9 38 | cam.D5
cam.HS | 10 37 | cam.D4
cam.PLK | 11 36 | cam.D3
cam.XLK | 12 35 | cam.D2
cam.RET | 13 34 | cam.D1
| 14 33 | cam.D0
| 15 26 |
| 16 21 |
| 17 20 |
| 5V0 19 |
| GND 18 |
+-------------------+
nanoESP32-S2
Exercise code
"""
CircuitPython (7.0.0) exercise run on nanoESP32-S2,
capture image from ov7670 camera module and
display it on ST7789 SPI LCD.
Modified from ov7670_displayio_pico_st7789_2in.py example
in CircuitPython Bundle for Version 7.x
"""
import time
from displayio import (
Bitmap,
Group,
TileGrid,
FourWire,
release_displays,
ColorConverter,
Colorspace,
)
import adafruit_st7789
import board
import busio
import digitalio
import adafruit_ov7670
import gc
print(adafruit_ov7670.__name__, ":", adafruit_ov7670.__version__)
print(adafruit_st7789.__name__, ":", adafruit_st7789.__version__)
print()
time.sleep(1)
gc.collect()
print("free mem@power up", gc.mem_free()) # print free memory
# Set up the display (You must customize this block for your display!)
release_displays()
#assign pins for nanoESP32-S2
tft_blk = board.IO5
tft_cs = board.IO4
tft_dc = board.IO3
tft_res = board.IO2
spi_mosi = board.IO1
spi_clk = board.IO0
pin_blk = digitalio.DigitalInOut(tft_blk)
pin_blk.direction = digitalio.Direction.OUTPUT
pin_blk.value = True
spi = busio.SPI(spi_clk, MOSI=spi_mosi)
display_bus = FourWire(
spi, command=tft_dc, chip_select=tft_cs, reset=tft_res
)
#for 240x320
display = adafruit_st7789.ST7789(display_bus,
width=320, height=240, rotation=90)
cam_scl = board.IO7
cam_sda = board.IO8
cam_reset = board.IO13
# Ensure the camera is shut down, so that it releases the SDA/SCL lines,
# then create the configuration I2C bus
with digitalio.DigitalInOut(cam_reset ) as reset:
reset.switch_to_output(False)
time.sleep(0.001)
bus = busio.I2C(scl=cam_scl, sda=cam_sda)
# Set up the camera (you must customize this for your board!)
cam = adafruit_ov7670.OV7670(
bus,
data_pins=[
board.IO33,
board.IO34,
board.IO35,
board.IO36,
board.IO37,
board.IO38,
board.IO39,
board.IO40,
],
clock=board.IO11, #PLK
vsync=board.IO9, #VS
href=board.IO10, #HS
mclk=board.IO12, #XLK
shutdown=None,
reset=cam_reset ,
) # [14]
width = display.width
height = display.height
# cam.test_pattern = OV7670_TEST_PATTERN_COLOR_BAR
bitmap = None
# Select the biggest size for which we can allocate a bitmap successfully, and
# which is not bigger than the display
#
# *** Remark by Erik: due to limited memory for bitmap,
# *** OV7670_SIZE_DIV8 (80x60) is selected.
#
gc.collect()
print("free mem@before bitmap", gc.mem_free()) # print free memory
for size in range(adafruit_ov7670.OV7670_SIZE_DIV1,
adafruit_ov7670.OV7670_SIZE_DIV16 + 1):
cam.size = size
if cam.width > width:
continue
if cam.height > height:
continue
try:
bitmap = Bitmap(cam.width, cam.height, 65536)
break
except MemoryError:
print("MemoryError in allocate bitmap", cam.width, " x ", cam.height)
continue
"""
# Erik: to use fixed cam.size
cam.size = adafruit_ov7670.OV7670_SIZE_DIV8
bitmap = Bitmap(cam.width, cam.height, 65536)
"""
print("free mem@after bitmap", gc.mem_free()) # print free memory
print(width, height, cam.width, cam.height)
print()
if bitmap is None:
raise SystemExit("Could not allocate a bitmap")
# Erik: change gScale to enlarge image on screen
gScale = 1
g = Group(scale=gScale,
x=(width - (gScale*cam.width)) // 2,
y=(height - (gScale*cam.height)) // 2)
tg = TileGrid(
bitmap, pixel_shader=ColorConverter(input_colorspace=Colorspace.RGB565_SWAPPED)
)
g.append(tg)
display.show(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
In my test, due to limited memory, I can create bitmap of 80x60 only!
No comments:
Post a Comment