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.
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!
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
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.
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
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
.
This crate uses Nannou to visualize different renderers
. It renders at the
same speed (I think:tm:) and orientation that will be displayed on the tree.
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.
This crate uses Yew to create a basic frontend for the tree-backend
. It will
just have a list of buttons.
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.
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.