Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Bob Hammell
Published © GPL3+

Personalized Digital Tree Ornament with Animated Icons

Build your own digital ornament that lights up your Christmas tree with animated face icons of your loved ones

BeginnerFull instructions provided4 hours54

Things used in this project

Hardware components

Adafruit Feather RP2040
×1
Adafruit 1.8" Color TFT LCD Display (ST7735R)
×1
Adafruit Lithium Ion Polymer Battery - 3.7V 350mAh
×1
Adafruit Pushbutton On/Off Toggle Switch
×1
M2.5x3 Machine Screw
×8

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)
Jumper Wire, Bundle
Jumper Wire, Bundle

Story

Read more

Custom parts and enclosures

Ornament case back

Sketchfab still processing.

Ornament case front

Sketchfab still processing.

Schematics

Ornament Circuit Diagram

Code

code.py

Python
Main Python script uploaded to the Feather RP2040
# Circuit
import time
import random
import board
import displayio
import pwmio
import adafruit_st7735r

# Initialze TFT display
displayio.release_displays()
spi = board.SPI()
tft_cs = board.D5
tft_dc = board.D6
display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=board.D9)
display = adafruit_st7735r.ST7735R(display_bus, width=128, height=160, rotation=0, bgr=True)
display.auto_refresh = False

# Change backlight brightness
brightness = 0.3
duty_cycle = int(brightness * 65535)
frequency = 500
backlight_pwm = pwmio.PWMOut(board.D10, duty_cycle=duty_cycle, frequency=frequency)

# Icon settings
icon_fname = 'img/face.bmp'
icon_height = 50
icon_width = 33

# Define bouncing icon class
class BouncingIcon:
    def __init__(self, fname, x, y, speed_x, speed_y):

        image = displayio.OnDiskBitmap(fname)
        image.pixel_shader.make_transparent(0)

        self.icon = displayio.TileGrid(
            image,
            pixel_shader=image.pixel_shader,
            x=x,
            y=y
        )
        main_group.append(self.icon)
        self.speed_x = speed_x
        self.speed_y = speed_y

# Create main display groups
main_group = displayio.Group()
display.root_group = main_group

# Create bouncing icon instances
icons = []
for i in range(3):
    icons.append(BouncingIcon(
        icon_fname,
        random.randint(0, display.width - icon_width),
        random.randint(0, display.height - icon_height),
        random.choice([-1, 1]),
        random.choice([-1, 1])
    ))

# Miain loop
while True:

    # Update icon positions
    for icon in icons:
        # Update x/y values
        icon.icon.x += icon.speed_x
        icon.icon.y += icon.speed_y

        # Bounce off the right and left edges
        if icon.icon.x + icon_width >= display.width or icon.icon.x <= 0:
            icon.speed_x = -icon.speed_x

        # Bounce off the bottom and top edges
        if icon.icon.y + icon_height >= display.height or icon.icon.y <= 0:
            icon.speed_y = -icon.speed_y

    # Refresh display
    display.refresh()

Credits

Bob Hammell

Bob Hammell

9 projects • 25 followers
Developer interested in Python, Arduino, & Matlab. Background in Image Processing and Remote Sensing.

Comments