Install & Use the Demo
Click the Download Project Bundle button below to download the necessary libraries and the code.py file in a zip file. Extract the contents of the zip file, and copy the entire lib folder and the code.py file to your CIRCUITPY drive.
You will need to use a terminal program that understands ANSI escape codes such as screen
or tio
. Connect to your device using a compatible terminal program and you will see the image captured as lo-fi ASCII art.
If the live mode image is black, remove the lens cap from the camera.
# SPDX-FileCopyrightText: Copyright (c) 2023 Limor Fried for Adafruit Industries # # SPDX-License-Identifier: Unlicense """ This demo is designed for the Raspberry Pi Pico. It shows the camera image as ASCII art on the USB REPL. """ import sys import time import busio import board import digitalio import adafruit_ov5640 print("construct bus") bus = busio.I2C(board.GP9, board.GP8) print("construct camera") reset = digitalio.DigitalInOut(board.GP10) cam = adafruit_ov5640.OV5640( bus, data_pins=( board.GP12, board.GP13, board.GP14, board.GP15, board.GP16, board.GP17, board.GP18, board.GP19, ), clock=board.GP11, vsync=board.GP7, href=board.GP21, mclk=board.GP20, shutdown=None, reset=reset, size=adafruit_ov5640.OV5640_SIZE_QQVGA, ) print("print chip id") print(cam.chip_id) cam.colorspace = adafruit_ov5640.OV5640_COLOR_YUV cam.flip_y = True cam.flip_x = True cam.test_pattern = False buf = bytearray(cam.capture_buffer_size) chars = b" .':-+=*%$#" remap = [chars[i * (len(chars) - 1) // 255] for i in range(256)] width = cam.width row = bytearray(width) print("capturing") cam.capture(buf) print("capture complete") sys.stdout.write("\033[2J") while True: cam.capture(buf) for j in range(0, cam.height, 2): sys.stdout.write(f"\033[{j//2}H") for i in range(cam.width): row[i] = remap[buf[2 * (width * j + i)]] sys.stdout.write(row) sys.stdout.write("\033[K") sys.stdout.write("\033[J") time.sleep(0.1)
After code that is familiar from the LCD demo is the start of the code specific to the ASCIi art part of the program:
- "chars" holds the ASCII characters to use, arranged from darkest to lightest (the demo is intended to be run on a terminal with a dark background color).
- "remap" is a 256-element look-up table from the raw brightness value to a character
- "width" is just a short-hand way to refer to the camera's width property
- "row" contains one byte for every 2 characters across the image, which gives a width of 80 characters, a standard terminal width.
Finally, the whole screen is cleared.
chars = b" .:-=+*#%@" remap = [chars[i * (len(chars) - 1) // 255] for i in range(256)] width = cam.width row = bytearray(width//2) sys.stdout.write("\033[2J")
The forever loop grabs a fresh frame and then converts it to ASCII.
Every 5th row of the input image is used, giving 24 lines of height; every 2nd column is taken, given 80 characters of width.
First, an escape code is printed to move the cursor to the start of the correct line.
Then, the ASCII characters for the row are calculated by using the remap
array
Finally, the row is written, followed by an escape code indicating "clear to end of line".
When the whole thing is written, the remainder of the screen (if any) is cleared.
sys.stdout.write("\033[2J") while True: cam.capture(buf) for j in range(0, cam.height, 2): sys.stdout.write(f"\033[{j//2}H") for i in range(cam.width): row[i] = remap[buf[2 * (width * j + i)]] sys.stdout.write(row) sys.stdout.write("\033[K") sys.stdout.write("\033[J") time.sleep(0.1)
Text editor powered by tinymce.