
A Rust no-std no-alloc LED control library.
For 1D, 2D, and 3D layouts.
layout in 1D, 2D, or 3D spacepattern (effect), or choose from our built-in patterns librarydriver] to send each frame of colors to your [leds]If you want help to support a new LED chipset, make an issue!
If you want help to port a pattern from FastLED / WLED to Rust, make an issue!
Clocked LED support (e.g. APA102):
| Micro | HAL | Blinksy | Recommended Driver | Backup Driver |
|---|---|---|---|---|
| ALL | embedded-hal | blinksy | Spi | Delay |
Clockless LED support (e.g. WS2812)
| Micro | HAL | Blinksy | Recommended Driver | Backup Driver |
|---|---|---|---|---|
| ALL | embedded-hal | blinksy | - | TODO Spi #12 |
| ESP32 | esp-hal | blinksy-esp | Rmt | - |
| RP (2040 or 2350) | rp-hal | TODO | TODO #36 | - |
| STM32 | stm32-hal | TODO | TODO #78 | - |
| nRF | nrf-hal | TODO | TODO #77 | - |
| atsamd | atsamd | TODO | TODO #67 | - |
| AVR (Arduino) | avr-hal | TODO | TODO #79 | - |
| CH32 | ch32-hal | TODO | TODO #80 | - |
| ??? | - | - | - | - |
If you want help to support a new microcontroller family, make an issue!
These are ready-to-go LED controllers with board support crates to make things even easier:
If you want help to support a new target, make an issue!
To quickstart a project, see:
To start using the library, see control.
blinksy : blinksy-desktop : blinksy-esp : gledopto : For all examples, see:
./blinksy-desktop/examples./esp/gledopto/exampleshttps://github.com/user-attachments/assets/36a2c6ad-7ae6-4498-85b3-ed76d0b62264
Click to see code
#![no_std]
#![no_main]
use blinksy::{
layout::{Layout3d, Shape3d, Vec3},
layout3d,
leds::Ws2812,
patterns::noise::{noise_fns, Noise3d, NoiseParams},
ControlBuilder,
};
use gledopto::{board, bootloader, elapsed, main, ws2812};
bootloader!();
#[main]
fn main() -> ! {
let p = board!();
layout3d!(
Layout,
[
// bottom face
Shape3d::Grid {
start: Vec3::new(1., -1., 1.), // right bottom front
horizontal_end: Vec3::new(-1., -1., 1.), // left bottom front
vertical_end: Vec3::new(1., -1., -1.), // right bottom back
horizontal_pixel_count: 16,
vertical_pixel_count: 16,
serpentine: true,
},
// back face
Shape3d::Grid {
start: Vec3::new(-1., -1., -1.), // left bottom back
horizontal_end: Vec3::new(-1., 1., -1.), // left top back
vertical_end: Vec3::new(1., -1., -1.), // right bottom back
horizontal_pixel_count: 16,
vertical_pixel_count: 16,
serpentine: true,
},
// right face
Shape3d::Grid {
start: Vec3::new(1., 1., -1.), // right top back
horizontal_end: Vec3::new(1., 1., 1.), // right top front
vertical_end: Vec3::new(1., -1., -1.), // right bottom back
horizontal_pixel_count: 16,
vertical_pixel_count: 16,
serpentine: true,
},
// front face
Shape3d::Grid {
start: Vec3::new(-1., -1., 1.), // left bottom front
horizontal_end: Vec3::new(1., -1., 1.), // right bottom front
vertical_end: Vec3::new(-1., 1., 1.), // left top front
horizontal_pixel_count: 16,
vertical_pixel_count: 16,
serpentine: true,
},
// left face
Shape3d::Grid {
start: Vec3::new(-1., 1., -1.), // left top back
horizontal_end: Vec3::new(-1., -1., -1.), // left bottom back
vertical_end: Vec3::new(-1., 1., 1.), // left top front
horizontal_pixel_count: 16,
vertical_pixel_count: 16,
serpentine: true,
},
// top face
Shape3d::Grid {
start: Vec3::new(1., 1., 1.), // right top front
horizontal_end: Vec3::new(1., 1., -1.), // right top back
vertical_end: Vec3::new(-1., 1., 1.), // left top front
horizontal_pixel_count: 16,
vertical_pixel_count: 16,
serpentine: true,
}
]
);
let mut control = ControlBuilder::new_3d()
.with_layout::<Layout, { Layout::PIXEL_COUNT }>()
.with_pattern::<Noise3d<noise_fns::Perlin>>(NoiseParams {
..Default::default()
})
.with_driver(ws2812!(p, Layout::PIXEL_COUNT))
.with_frame_buffer_size::<{ Ws2812::frame_buffer_size(Layout::PIXEL_COUNT) }>()
.build();
control.set_brightness(0.2);
loop {
let elapsed_in_ms = elapsed().as_millis();
control.tick(elapsed_in_ms).unwrap();
}
}
https://github.com/user-attachments/assets/22f388d0-189e-44bd-acbf-186a142b956d
Click to see code
```rust use blinksy::{ layout::{Layout2d, Shape2d, Vec2}, layout2d, patterns::noise::{noise_fns, Noise2d, NoiseParams}, ControlBuilder, }; use blinksy_desktop::{ driver::{Desktop, DesktopError}, time::elapsed_in_ms, }; use std::{thread::sleep, time::Duration};
layout2d!( PanelLayout, [Shape2d::Grid { start: Vec2::new(-1., -1.), horizontal_end: Vec2::new(1., -1.), vertical_end: Vec2::new(-1., 1.), horizontal_pixel_count: 16, vertical_pixel_count: 16, serpentine: true, }] );
fn main() { Desktop::new_2d::().start(|driver| { let mut control = ControlBuilder::new_2d() .with_layout::() .with_pattern::>(NoiseParams { ..Default::default() })
$ claude mcp add blinksy \
-- python -m otcore.mcp_server <graph>