|
| 1 | +# SPDX-FileCopyrightText: Copyright (c) 2023 Lady Ada for Adafruit Industries |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: Unlicense |
| 4 | + |
| 5 | +"""Capture an images from the camera and display on a ST7789 with |
| 6 | +displayio. |
| 7 | +
|
| 8 | +This demo is designed to run on the Raspberry Pi Pico, but you can adapt it |
| 9 | +to other boards by changing the constructors for `bus` and `cam` |
| 10 | +appropriately. |
| 11 | +
|
| 12 | +Remember to take the lens cap off! |
| 13 | +""" |
| 14 | +import time |
| 15 | +from adafruit_ov7670 import OV7670, OV7670_SIZE_DIV1, OV7670_SIZE_DIV16 |
| 16 | +from displayio import ( |
| 17 | + Bitmap, |
| 18 | + Group, |
| 19 | + TileGrid, |
| 20 | + FourWire, |
| 21 | + release_displays, |
| 22 | + ColorConverter, |
| 23 | + Colorspace, |
| 24 | +) |
| 25 | +from adafruit_st7789 import ST7789 |
| 26 | +import board |
| 27 | +import busio |
| 28 | +import digitalio |
| 29 | + |
| 30 | +# Set up the display (You must customize this block for your display!) |
| 31 | +release_displays() |
| 32 | +spi = busio.SPI(clock=board.GP2, MOSI=board.GP3) |
| 33 | +display_bus = FourWire(spi, command=board.GP0, chip_select=board.GP1, reset=None) |
| 34 | +display = ST7789(display_bus, width=240, height=240, rowstart=80, rotation=270) |
| 35 | + |
| 36 | + |
| 37 | +# Ensure the camera is shut down, so that it releases the SDA/SCL lines, |
| 38 | +# then create the configuration I2C bus |
| 39 | + |
| 40 | +with digitalio.DigitalInOut(board.GP10) as reset: |
| 41 | + reset.switch_to_output(False) |
| 42 | + time.sleep(0.001) |
| 43 | + bus = busio.I2C(board.GP9, board.GP8) |
| 44 | + |
| 45 | +# Set up the camera (you must customize this for your board!) |
| 46 | +cam = OV7670( |
| 47 | + bus, |
| 48 | + data0=board.GP12, # [16] [org] |
| 49 | + clock=board.GP11, # [15] [blk] |
| 50 | + vsync=board.GP7, # [10] [brn] |
| 51 | + href=board.GP21, # [27/o14] [red] |
| 52 | + mclk=board.GP20, # [16/o15] |
| 53 | + shutdown=None, |
| 54 | + reset=board.GP10, |
| 55 | +) # [14] |
| 56 | + |
| 57 | +width = display.width |
| 58 | +height = display.height |
| 59 | + |
| 60 | +# cam.test_pattern = OV7670_TEST_PATTERN_COLOR_BAR_FADE |
| 61 | +bitmap = None |
| 62 | +# Select the biggest size for which we can allocate a bitmap successfully, and |
| 63 | +# which is not bigger than the display |
| 64 | +for size in range(OV7670_SIZE_DIV1, OV7670_SIZE_DIV16 + 1): |
| 65 | + cam.size = size |
| 66 | + if cam.width > width: |
| 67 | + continue |
| 68 | + if cam.height > height: |
| 69 | + continue |
| 70 | + try: |
| 71 | + bitmap = Bitmap(cam.width, cam.height, 65535) |
| 72 | + break |
| 73 | + except MemoryError: |
| 74 | + continue |
| 75 | + |
| 76 | +print(width, height, cam.width, cam.height) |
| 77 | +if bitmap is None: |
| 78 | + raise SystemExit("Could not allocate a bitmap") |
| 79 | + |
| 80 | +g = Group(scale=1, x=(width - cam.width) // 2, y=(height - cam.height) // 2) |
| 81 | +tg = TileGrid( |
| 82 | + bitmap, pixel_shader=ColorConverter(input_colorspace=Colorspace.RGB565_SWAPPED) |
| 83 | +) |
| 84 | +g.append(tg) |
| 85 | +display.show(g) |
| 86 | + |
| 87 | +t0 = time.monotonic_ns() |
| 88 | +display.auto_refresh = False |
| 89 | +while True: |
| 90 | + cam.capture(bitmap) |
| 91 | + bitmap.dirty() |
| 92 | + display.refresh(minimum_frames_per_second=0) |
| 93 | + t1 = time.monotonic_ns() |
| 94 | + print("fps", 1e9 / (t1 - t0)) |
| 95 | + t0 = t1 |
0 commit comments