-
Notifications
You must be signed in to change notification settings - Fork 776
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2937 from adafruit/motor-pov-display
adding code for motorized pov display project
- Loading branch information
Showing
7 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# 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) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.