Install & Use the Demo
First, make sure you can see the Kaluga CIRCUITPY drive and connect to the REPL. Open the REPL and double check that import espcamera
works without showing an error. Then, copy the correct bundle to your device. It will automatically reload and start displaying the image from the camera on the serial REPL as lo-fi ASCII art.
By clicking the BOOT button you can swap the camera between live mode & test pattern mode.
You will need to use a terminal program that understands ANSI escape codes such as screen or tio.
If the live mode image is black, remove the lens cap from the camera.
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.
# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries # # SPDX-License-Identifier: Unlicense """ This demo is designed for the Kaluga development kit version 1.3. To fix the MemoryError when creating a Camera object, Place the line ```toml CIRCUITPY_RESERVED_PSRAM=1048576 ``` in the file **CIRCUITPY/settings.toml** and restart. """ import sys import board import keypad import displayio import espcamera import espidf # The demo runs very slowly if the LCD display is enabled! # It's intended to be viewed on the REPL on a host computer displayio.release_displays() if espidf.get_reserved_psram() < 1047586: print("""Place the following line in CIRCUITPY/settings.toml, then hard-reset the board: CIRCUITPY_RESERVED_PSRAM=1048576 """) raise SystemExit print("Initializing camera") cam = espcamera.Camera( data_pins=board.CAMERA_DATA, external_clock_pin=board.CAMERA_XCLK, pixel_clock_pin=board.CAMERA_PCLK, vsync_pin=board.CAMERA_VSYNC, href_pin=board.CAMERA_HREF, pixel_format=espcamera.PixelFormat.GRAYSCALE, frame_size=espcamera.FrameSize.QQVGA, i2c=board.I2C(), external_clock_frequency=20_000_000, framebuffer_count=2) print("initialized") k = keypad.Keys([board.IO0], value_when_pressed=False) 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") while True: if (e := k.events.get()) is not None and e.pressed: cam.colorbar = not cam.colorbar frame = cam.take(1) for j in range(0, cam.height, 5): sys.stdout.write(f"\033[{j//5}H") for i in range(cam.width // 2): row[i] = remap[frame[width * j + 2 * i]] sys.stdout.write(row) sys.stdout.write("\033[K") sys.stdout.write("\033[J")

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 shorthand 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.
while True: if (e := k.events.get()) is not None and e.pressed: cam.colorbar = not cam.colorbar frame = cam.take(1) for j in range(0, cam.height, 5): sys.stdout.write(f"\033[{j//5}H") for i in range(cam.width // 2): row[i] = remap[frame[width * j + 2 * i]] sys.stdout.write(row) sys.stdout.write("\033[K") sys.stdout.write("\033[J")


Page last edited January 22, 2025
Text editor powered by tinymce.