Once you've finished setting up your Feather RP2040 Propmaker with CircuitPython, you can access the code and necessary libraries by downloading the Project Bundle.
To do this, click on the Download Project Bundle button in the window below. It will download to your computer as a zipped folder.
# SPDX-FileCopyrightText: 2017 Limor Fried for Adafruit Industries # # SPDX-License-Identifier: MIT # Dotstar POV Display! Can handle up to ~2300 pixel size image (e.g. 36 x 64) import gc import time from adafruit_motorkit import MotorKit import board import busio import digitalio kit = MotorKit(i2c=board.I2C()) FILENAME = "nyan-xmas.bmp" IMAGE_DELAY = 0.001 REPEAT = True BRIGHTNESS = 0.3 PIXEL_DELAY = 0.003 dotstar = busio.SPI(board.SCK, board.MOSI) while not dotstar.try_lock(): pass dotstar.configure(baudrate=44000000) # we'll resize this later databuf = bytearray(0) led = digitalio.DigitalInOut(board.D13) led.switch_to_output() def read_le(s): # as of this writting, int.from_bytes does not have LE support, DIY! result = 0 shift = 0 for byte in bytearray(s): result += byte << shift shift += 8 return result class BMPError(Exception): pass try: with open("/" + FILENAME, "rb") as f: print("File opened") if f.read(2) != b'BM': # check signature raise BMPError("Not BitMap file") bmpFileSize = read_le(f.read(4)) f.read(4) # Read & ignore creator bytes bmpImageoffset = read_le(f.read(4)) # Start of image data headerSize = read_le(f.read(4)) bmpWidth = read_le(f.read(4)) bmpHeight = read_le(f.read(4)) flip = True print("Size: %d\nImage offset: %d\nHeader size: %d" % (bmpFileSize, bmpImageoffset, headerSize)) print("Width: %d\nHeight: %d" % (bmpWidth, bmpHeight)) if read_le(f.read(2)) != 1: raise BMPError("Not singleplane") bmpDepth = read_le(f.read(2)) # bits per pixel print("Bit depth: %d" % (bmpDepth)) if bmpDepth != 24: raise BMPError("Not 24-bit") if read_le(f.read(2)) != 0: raise BMPError("Compressed file") print("Image OK!") rowSize = (bmpWidth * 3 + 3) & ~3 # 32-bit line boundary # its huge! but its also fast :) databuf = bytearray(bmpWidth * bmpHeight * 4) for row in range(bmpHeight): # For each scanline... if flip: # Bitmap is stored bottom-to-top order (normal BMP) pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize else: # Bitmap is stored top-to-bottom pos = bmpImageoffset + row * rowSize # print ("seek to %d" % pos) f.seek(pos) for col in range(bmpWidth): b, g, r = bytearray(f.read(3)) # BMP files store RGB in BGR # front load brightness, gamma and reordering here! order = [b, g, r] idx = (col * bmpHeight + (bmpHeight - row - 1)) * 4 databuf[idx] = 0xFF # first byte is 'brightness' idx += 1 for color in order: databuf[idx] = int( pow((color * BRIGHTNESS) / 255, 2.7) * 255 + 0.5) idx += 1 except BMPError as e: print("Failed to parse BMP: " + e.args[0]) gc.collect() print(gc.mem_free()) print("Ready to go!") kit.motor1.throttle = 1 while True: print("Draw!") index = 0 for col in range(bmpWidth): row = databuf[index:index + bmpHeight * 4] dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00])) dotstar.write(row) dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00])) index += bmpHeight * 4 time.sleep(PIXEL_DELAY) # clear it out dotstar.write(bytearray([0x00, 0x00, 0x00, 0x00])) for r in range(bmpHeight * 5): dotstar.write(bytearray([0xFF, 0x00, 0x00, 0x00])) dotstar.write(bytearray([0xff, 0xff, 0xff, 0xff])) gc.collect() if not REPEAT: break time.sleep(IMAGE_DELAY)
Upload the code, images and Libraries to the Feather RP2040
After downloading the Project Bundle, plug your Feather RP2040 into the computer's USB port with a known good USB data+power cable. You should see a new flash drive appear in the computer's File Explorer or Finder (depending on your operating system) called CIRCUITPY. Unzip the folder and copy the following items to the Feather RP2040's CIRCUITPY drive.
- lib folder
- code.py
- blinka.bmp
- sans.bmp
- dreidel.bmp
- nyan-xmas.bmp
- pipesky.bmp
- xmas.bmp
- xmastree.bmp
Your Feather RP2040 CIRCUITPY drive should look like this after copying the lib folder, images and the code.py file.
Adjusting Image
At the top of the code, there are some user configurable settings that you can edit.
-
FILENAME
is the title of the image the display will draw. Change this variable to the desired image name to display -
BRIGHTNESS
affects the overall brightness of the LEDs -
PIXEL_DELAY
affects how the image is scaled when in motion. If the image appears stretched, lower the number. If it appears squished, increase the number
FILENAME = "nyan-xmas.bmp" IMAGE_DELAY = 0.001 REPEAT = True BRIGHTNESS = 0.3 PIXEL_DELAY = 0.003
Page last edited January 22, 2025
Text editor powered by tinymce.