mirror of
https://github.com/esp-rs/esp-idf-hal.git
synced 2025-09-28 21:01:26 +00:00
54 lines
2.0 KiB
Rust
54 lines
2.0 KiB
Rust
//! A simple example to change colours of a WS2812/NeoPixel compatible LED.
|
|
//!
|
|
//! It is set to pin 18 which some dev boards have connected to a compatible LED.
|
|
//!
|
|
//! This example demonstrates the use of [`FixedLengthSignal`][crate::rmt::FixedLengthSignal] which
|
|
//! lives on the stack and requires a known length before creating it.
|
|
//!
|
|
//! There is a similar implementation in the esp-idf project:
|
|
//! https://github.com/espressif/esp-idf/tree/20847eeb96/examples/peripherals/rmt/led_strip
|
|
//!
|
|
//! Datasheet (PDF) for a WS2812, which explains how the pulses are to be sent:
|
|
//! https://cdn-shop.adafruit.com/datasheets/WS2812.pdf
|
|
|
|
use core::time::Duration;
|
|
|
|
use esp_idf_hal::delay::Ets;
|
|
use esp_idf_hal::peripherals::Peripherals;
|
|
use esp_idf_hal::rmt::config::TransmitConfig;
|
|
use esp_idf_hal::rmt::*;
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
esp_idf_sys::link_patches();
|
|
|
|
let peripherals = Peripherals::take().unwrap();
|
|
let led = peripherals.pins.gpio18;
|
|
let channel = peripherals.rmt.channel0;
|
|
let config = TransmitConfig::new().clock_divider(1);
|
|
let mut tx = RmtDriver::new(channel, led, &config)?;
|
|
|
|
let rgbs = [0xff0000, 0xffff00, 0x00ffff, 0x00ff00, 0xa000ff];
|
|
loop {
|
|
for rgb in rgbs {
|
|
let ticks_hz = tx.counter_clock()?;
|
|
let t0h = Pulse::new_with_duration(ticks_hz, PinState::High, &ns(350))?;
|
|
let t0l = Pulse::new_with_duration(ticks_hz, PinState::Low, &ns(800))?;
|
|
let t1h = Pulse::new_with_duration(ticks_hz, PinState::High, &ns(700))?;
|
|
let t1l = Pulse::new_with_duration(ticks_hz, PinState::Low, &ns(600))?;
|
|
|
|
let mut signal = FixedLengthSignal::<24>::new();
|
|
for i in 0..24 {
|
|
let bit = 2_u32.pow(i) & rgb != 0;
|
|
let (high_pulse, low_pulse) = if bit { (t1h, t1l) } else { (t0h, t0l) };
|
|
signal.set(i as usize, &(high_pulse, low_pulse))?;
|
|
}
|
|
tx.start_blocking(&signal)?;
|
|
Ets::delay_ms(1000);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn ns(nanos: u64) -> Duration {
|
|
Duration::from_nanos(nanos)
|
|
}
|