A LED Christmas Tree controlled by Rust. Contribute your own renderers!

Overview

Rusty Christmas Tree

This is code that draws on the LED Christmas Tree made by @aidancrowther. You can see his 3D design files and Pi Pico setup code on his project OpenPixelTree.

Adding your own renderer

If any of this doesn't make sense, write an issue and I'll try to make it more clear πŸ‘

This should get you started with making something to display on the tree. There is a Nannou visualizer included so you can see what it will look like before making a PR. You'll be able to run this with make visualize from the root.

To write your own code to run on the tree, you need to implement a "renderer". A renderer is just a Rust module that implements a draw function, and returns a TreeCanvas. You can find the renderers in this folder. Here is an example of what you'll implement:

pub fn draw(tick: u64) -> TreeCanvas {
    let mut canvas = TreeCanvas::new();

    for y in 0..75 {
        for x in 0..20 {
            let this_pixel = Pixel {
                r: (
                    (tick as f64) // Start by converting the tick to a 64 bit float
                    .sin() // The sin will be between -1 and 1
                    .abs() // Get the absolute value so we are between 0 and 1
                    * 150.0 // Multiply by 150 to get a number between 0 and 150
                    + 100.0
                    // ^^ Add 100 to get a number between 100 and 250
                ) as u8, // Convert the float to an 8 bit integer
                g: 0,
                b: 0,
            };
            canvas.set_pixel(x, y, this_pixel)
        }
    }
    canvas
}

To add a new renderer, start by duplicating the template folder and giving it a new name. You'll then have to add code in several different places in the project:

  • First, add your module here.
  • Second, add a new enum variant here.
  • Next, we'll have to add this new variant to several match statements here, here, and here.
  • Finally, set the default vizualizer renderer to your new renderer here.

Hopefully I get some time to fix this eventually, but I don't know how right now. Now, you can start working in the mod.rs file in the new renderer folder.

At this point, you should also be able to run the visualizer and see your renderer in action.

make visualize

Once you have something cool, make a pull request!

Other Make Commands

build: build tree-writer for the Raspberry Pi (requires Docker and cargo-cross)
deploy: scp the binary to the Pi
run: (build + deploy) build tree-writer for the Raspberry Pi and scp the binary to the Pi
visualize: run the Nannou visualizer
setup-web: install the prerequisites for the frontend
frontend: serve the frontend
frontend-release: serve the frontend in release mode

Architecture

The plan for this project is to have many renderers implemented that show off different displays (tree-writer). There will be a web server running (tree-backend) that allows you to change what is currently being displayed on the tree. A simple web frontend (tree-frontend) will display all the options of renderers and allow you to pick one to display.

On the Raspberry Pi, there will be a process (tree-deploy) that runs the main process (tree-writer). The first process will look for new releases from Github periodically. If there is a new release, it will update the and restart the main process.

While you're developing, you can run the visualizer (tree-visualizer) to see what your renderer will look like on the tree.

Physical Tree

The physical tree is running on a Raspberry Pi Pico. There are 20 (actually 19) strips running, creating 19x75 LED grid. You send data to the LED strings using spidev, and send 4500 8-bit numbers for each frame. Up to 33 frames can be drawn per second. The light indexes on the tree are as follows:

3 4 9
2 5 8
1 6 7

tree-writer

This crate is where the different "renderers" are implemented. A renderer is just a module that implements a draw function, and returns a TreeCanvas. In this function, you can set any Pixel{r: u8, g: u8, b: u8} on the TreeCanvas.

tree-visualizer

This crate uses Nannou to visualize different renderers. It renders at the same speed (I think ℒ️ ) and orientation that will be displayed on the tree.

tree-backend

This crate uses Warp to serve a basic web server. It allows you to change the renderer that is currently being displayed on the tree. The tree-writer will ping this server about once a second to see if there is a new renderer to switch to.

tree-frontend

This crate uses Yew to create a basic frontend for the tree-backend. It will just have a list of buttons.

tree-script

This was an attempt to use the Mun scripting language as the backend for drawing to the canvas. Currently, this isn't working, but if an MVP is made, then it could be easier to write with, and hot reloadable as well.

You might also like...
Shuttle.rs Christmas Code Hunt 2023

πŸš€ Shuttle.rs Christmas Code Hunt 2023 Submissions πŸŽ„ These are my submissions for the Christmas Code Hunt hosted by shuttle.rs This is using a custom

Some tools for streaming frames to rpi-rgb-led-matrix using ZeroMQ, written in Rust.

led_matrix_zmq Some tools for streaming frames to rpi-rgb-led-matrix using ZeroMQ, written in Rust. This repository includes: Rust client and server l

A blinking LED program written in Rust for the AVR

blink A small Hello World Rust application for the AVR. The program itself toggles a LED on PORTB periodically. Designed for the ATmega328p. The AVR-R

IR Remote Controller for WS2812(or analog) LED Strip
IR Remote Controller for WS2812(or analog) LED Strip

ir-smart-led-controller IR Remote Controller for WS2812(or analog) LED Strip. Resources Schematics Gerber files BOM License Licensed under either of A

A command-line tool for extensible LED matrix control with Raspberry Pi devices.

Matricks "Teach an old matrix new tricks..." Matricks is a WASM-based extensible LED matrix control tool intended for use on Raspberry Pi devices. LED

Count your code by tokens, types of syntax tree nodes, and patterns in the syntax tree. A tokei/scc/cloc alternative.

tcount (pronounced "tee-count") Count your code by tokens, types of syntax tree nodes, and patterns in the syntax tree. Quick Start Simply run tcount

Procedural engine sound generator controlled via GUI or CLI
Procedural engine sound generator controlled via GUI or CLI

enginesound GUI Application used to generate purely synthetic engine sounds with advanced options written in Rust loosely based on this paper Reading

Distributed, version controlled, SQL database with cryptographically verifiable storage, queries and results. Think git for postgres.

SDB - SignatureDB Distributed, version controlled, SQL database with cryptographically verifiable storage, queries and results. Think git for postgres

This contract is to provide vesting account feature for the both cw20 and native tokens, which is controlled by a master address

Token Vesting This contract is to provide vesting account feature for the both cw20 and native tokens, which is controlled by a master address. Instan

MIDI-controlled stereo-preserving granular-synthesizer LV2 plugin

Stereog "Stereog" rhymes with "hairy dog." Stereog is a MIDI-controlled stereo-preserving granular synthesizer LV2 plugin. It is experimental software

Minimal server (with maximal security) for turning off an X10-controlled fan over HTTP

"Fan Remote" A self-contained Rust binary to expose a single X10 command (turn off that fan) as an HTML form button. In its current form, it's highly

Play videos on IT8951-controlled e-paper displays

it8951-video Play videos on IT8951-controlled e-paper displays via USB. This has been tested with a Waveshare 7.8inch e-Paper HAT display. Design This

Minimalist multi-track audio recorder which may be controlled via OSC or MIDI.
Minimalist multi-track audio recorder which may be controlled via OSC or MIDI.

smrec Minimalist multi-track audio recorder which may be controlled via OSC or MIDI. I did this because I needed a simple multi-track audio recorder w

Traversal of tree-sitter Trees and any arbitrary tree with a TreeCursor-like interface

tree-sitter-traversal Traversal of tree-sitter Trees and any arbitrary tree with a TreeCursor-like interface. Using cursors, iteration over the tree c

As-tree - Print a list of paths as a tree of paths 🌳

as-tree Print a list of paths as a tree of paths. For example, given: dir1/foo.txt dir1/bar.txt dir2/qux.txt it will print: . β”œβ”€β”€ dir1 β”‚ β”œβ”€β”€ foo.tx

Nearest neighbor search algorithms including a ball tree and a vantage point tree.

petal-neighbors Nearest neighbor search algorithms including a ball tree and a vantage point tree. Examples The following example shows how to find tw

Untree converts tree diagrams produced by tree back into directory file structures.
Untree converts tree diagrams produced by tree back into directory file structures.

Untree: Undoing tree for fun and profit Untree converts tree diagrams produced by tree back into directory file structures. Let's say you have the fol

A sparse merkle tree lib focused on efficient on-chain proofs. Enforces ordering within the merkle tree.

sparse-merkle-tree The merkle tree functions are located in sparse.ak. Currently the supported functionality is: Verifying a new root with an added me

miette is a diagnostic library for Rust. It includes a series of traits/protocols that allow you to hook into its error reporting facilities, and even write your own error reports!
miette is a diagnostic library for Rust. It includes a series of traits/protocols that allow you to hook into its error reporting facilities, and even write your own error reports!

miette is a diagnostic library for Rust. It includes a series of traits/protocols that allow you to hook into its error reporting facilities, and even write your own error reports!

Comments
  • Re-licensing under MIT/Apache 2

    Re-licensing under MIT/Apache 2

    @ApprenticeofEnder @EliasJRH @ayyEve I forgot to add a license originally, so we get to do a re-license :tada:

    To agree to have your code re-licensed under the dual MIT/Apache-2.0 license, reply to this issue with the comment below :+1: (if you don't agree to the re-license, commend that and I'll remove your code from the repo)

    I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to choose either at their option.
    
    opened by AngelOnFira 4
  • Consider adding a license

    Consider adding a license

    Hello, thanks for sharing this awesome project!

    I noticed the repository doesn't contain any license. This makes it legally impossible to use or contribute to the repo. GitHub lets you add the most common ones from the Insights -> Community tab I believe.

    Thanks for considering! πŸŽ„

    opened by torkleyy 1
  • Bump regex from 1.5.4 to 1.5.6

    Bump regex from 1.5.4 to 1.5.6

    Bumps regex from 1.5.4 to 1.5.6.

    Changelog

    Sourced from regex's changelog.

    1.5.6 (2022-05-20)

    This release includes a few bug fixes, including a bug that produced incorrect matches when a non-greedy ? operator was used.

    1.5.5 (2022-03-08)

    This releases fixes a security bug in the regex compiler. This bug permits a vector for a denial-of-service attack in cases where the regex being compiled is untrusted. There are no known problems where the regex is itself trusted, including in cases of untrusted haystacks.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Releases(v1.0.1)
  • v1.0.1(Dec 26, 2021)

    • Moved request to check current renderer off main thread, preventing stuttering each second

    Full Changelog: https://github.com/AngelOnFira/rusty-christmas-tree/compare/v1.0.0...v1.0.1

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Dec 25, 2021)

    What's Changed

    • add snowflakes by @ayyEve in https://github.com/AngelOnFira/rusty-christmas-tree/pull/1
    • add ender's logo + waaaaaaves by @ApprenticeofEnder in https://github.com/AngelOnFira/rusty-christmas-tree/pull/2
    • Create rainbow wave tick pattern by @EliasJRH in https://github.com/AngelOnFira/rusty-christmas-tree/pull/4
    • Add Space Fight by @ayyEve in https://github.com/AngelOnFira/rusty-christmas-tree/pull/5
    • added jwst by @zacchaeusliang in https://github.com/AngelOnFira/rusty-christmas-tree/pull/8

    New Contributors

    • @ayyEve made their first contribution in https://github.com/AngelOnFira/rusty-christmas-tree/pull/1
    • @ApprenticeofEnder made their first contribution in https://github.com/AngelOnFira/rusty-christmas-tree/pull/2
    • @EliasJRH made their first contribution in https://github.com/AngelOnFira/rusty-christmas-tree/pull/4
    • @zacchaeusliang made their first contribution in https://github.com/AngelOnFira/rusty-christmas-tree/pull/8

    Full Changelog: https://github.com/AngelOnFira/rusty-christmas-tree/compare/v0.1.0...v1.0.0

    Source code(tar.gz)
    Source code(zip)
Owner
Forest Anderson
GitHub Campus Expert, core dev of @Veloren, Rust Gamedev WG member & CTCFT team lead, host of the Rust Gamedev meetup, CTO @ Timsle πŸ¦€
Forest Anderson
Everything you need to know about cross compiling Rust programs!

rust-cross Everything you need to know about cross compiling Rust programs! If you want to set up your Rust toolchain as a cross compiler, you have co

Jorge Aparicio 2.3k Jan 2, 2023
[OUTDATED] Instructions for how to cross compile Rust projects for the Raspberry Pi

Cross Compiling for Raspberry Pi This guide will show how Rust programs can be cross compiled for the Raspberry Pi using Cargo. These instructions may

Erik Hedvall 297 Jul 22, 2022
Operating System development tutorials in Rust on the Raspberry Pi

Operating System development tutorials in Rust on the Raspberry Pi

Rust Embedded 10k Jan 9, 2023
Vue's template compiler reimplemented in Rust!

vue template compiler in Rust https://github.com/vuejs/rfcs/discussions/369#discussioncomment-1192421 Maybe in the long run we want the whole transfor

Herrington Darkholme 687 Jan 1, 2023
A Brainheck compiler written in Rust.

Brainhecc A compiler for Brain[hecc] programs, written in Rust with Cranelift. It compiles any valid Brainhecc program into an executable binary. Inst

Zack 1 Oct 28, 2021
Raspberry PI library for Rust. GPIO controller, L298N motors, sockets and "i2clib" integrated

raslib Raspberry PI library for Rust. GPIO controller, L298N motors, sockets and "i2clib" integrated All tests are made on Raspberry PI 4B+ on Raspbia

AnΡ‚o 5 Apr 12, 2022
My own image file format created for fun! Install the "hif_opener.exe" to open hif files. clone the repo and compile to make your own hif file

Why am i creating this? I wanted to create my own image format since I was 12 years old using Windows 7, tryna modify GTA San Andreas. That day, when

hiftie 3 Dec 17, 2023
Very simple Rust binary that can turn on/off a TP-Link L920 led light strip in your local network

TP-Link L920 on/off script This is a (very) simple Rust binary that can turn on/off a TP-Link L920 led light strip in your local network. Installation

Luciano Mammino 3 Aug 21, 2023
A fun rust terminal program so you can make Christmas trees!

Xmastree 2021 A fun christmas tree where you can add ornaments! Then, you can export the file into either: a rust file a txt file About Taking a break

Junhao 2 Dec 21, 2021
The Dutch secret service (AIVD) has a yearly puzzle challenge around Christmas

AIVD kerstpuzzel 2021 18 solver The Dutch secret service (AIVD) has a yearly puzzle challenge around Christmas, called the 'AIVD kerstpuzzel'. This re

Tim VisΓ©e 2 Mar 7, 2022