//! 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 = TxRmtDriver::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) }