smart-leds-rs / ws2812-spi-rs

Use ws2812 on rust with embedded-hal spi
Apache License 2.0
64 stars 23 forks source link

Implement embedded_hal v1.0.0 #32

Closed BRA1L0R closed 2 months ago

BRA1L0R commented 7 months ago

embedded_hal recently had it's 1.0 release. Every crate is adopting it finally and since i am using esp-idf-hal (which has already been upgraded) i cannot use this crate with it yet.

david-sawatzke commented 7 months ago

The new embedded_hal has no equivalent to the features we're currently using (we introduce a deliberate offset to ensure the bytes are transmitted after each other), but the write method could work, but it's even more implementation defined so we'd need to check if/how it works on most HALs first. I threw something together that might work, if you want you can try it and report back: https://github.com/smart-leds-rs/ws2812-spi-rs/pull/33

ic3man5 commented 5 months ago

I think I'm getting hit by this but I'm not exactly sure as I'm new to esp, rust and this crate.

source:

#![no_std]
#![no_main]

use esp_backtrace as _;
use esp_hal::{
    clock::ClockControl,
    gpio::NO_PIN,
    peripherals::Peripherals,
    prelude::*,
    spi::{master::Spi, SpiMode},
    Delay, IO,
};
use esp_println::println;
use smart_leds::{gamma, hsv::hsv2rgb, hsv::Hsv, RGB8};
use smart_leds::SmartLedsWrite;
use ws2812_spi::Ws2812;

#[entry]
fn main() -> ! {
    let peripherals = Peripherals::take();
    let system = peripherals.SYSTEM.split();

    let clocks = ClockControl::max(system.clock_control).freeze();
    let mut delay = Delay::new(&clocks);

    let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
    let mut led = io.pins.gpio7.into_push_pull_output();
    let button = io.pins.gpio9.into_pull_up_input();

    let mosi = io.pins.gpio2;

    let mut spi = Spi::new(peripherals.SPI2, 3000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
        NO_PIN, //sclk,
        Some(mosi),
        NO_PIN, //miso,
        NO_PIN, //cs,
    );

    let mut ws = Ws2812::new(spi);

    println!("Hello world!");
    loop {
        if button.is_input_high() {
            led.set_low().unwrap();
        } else {
            led.set_high().unwrap();
        }
        //delay.delay_ms(1u32);
        const LED_NUM: usize = 1;
        let mut data = [RGB8::default(); LED_NUM];

        loop {
            for j in 0..256 {
                for i in 0..LED_NUM {
                    // rainbow cycle using HSV, where hue goes through all colors in circle
                    // value sets the brightness
                    let hsv = Hsv {
                        hue: ((i * 3 + j) % 256) as u8,
                        sat: 255,
                        val: 100,
                    };

                    data[i] = hsv2rgb(hsv);
                }
                // before writing, apply gamma correction for nicer rainbow
                ws.write(gamma(data.iter().cloned())).unwrap();
                delay.delay_ms(10u8);
            }
        }
    }
}

compiler errors:


$ cargo build
   Compiling esp32c3rust v0.1.0 (/home/drebbe/dev/esp32c3rust)
error[E0599]: the method `write` exists for struct `Ws2812<Spi<'_, SPI2, FullDuplexMode>>`, but its trait bounds were not satisfied
  --> src/main.rs:66:20
   |
66 |                 ws.write(gamma(data.iter().cloned())).unwrap();
   |                    ^^^^^ method cannot be called on `Ws2812<Spi<'_, SPI2, FullDuplexMode>>` due to unsatisfied trait bounds
   |
  ::: /home/drebbe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ws2812-spi-0.4.0/src/lib.rs:42:1
   |
42 | pub struct Ws2812<SPI, DEVICE = devices::Ws2812> {
   | ------------------------------------------------ doesn't satisfy `_: Default<_>` or `_: _embedded_hal_blocking_spi_Write<_>`
   |
   = note: the following trait bounds were not satisfied:
           `ws2812_spi::Ws2812<esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>>: embedded_hal::blocking::spi::write::Default<_>`
           which is required by `ws2812_spi::Ws2812<esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>>: esp_hal::prelude::_embedded_hal_blocking_spi_Write<_>`
   = help: items from traits can only be used if the trait is in scope
help: trait `SmartLedsWrite` which provides `write` is implemented but not in scope; perhaps you want to import it
   |
4  + use smart_leds_trait::SmartLedsWrite;
   |

warning: unused import: `smart_leds::SmartLedsWrite`
  --> src/main.rs:15:5
   |
15 | use smart_leds::SmartLedsWrite;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

For more information about this error, try `rustc --explain E0599`.
warning: `esp32c3rust` (bin "esp32c3rust") generated 1 warning
error: could not compile `esp32c3rust` (bin "esp32c3rust") due to 1 previous error; 1 warning emitted

cargo.toml:


[dependencies]
esp-backtrace = { version = "0.11.0", features = [
    "esp32c3",
    "exception-handler",
    "panic-handler",
    "println",
] }
esp-hal = { version = "0.16.0", features = [ "esp32c3" ] }
esp-println = { version = "0.9.0", features = ["esp32c3"] }
smart-leds = "0.4.0"
smart-leds-trait = "0.3.0"
ws2812-spi = "0.4.0"
ic3man5 commented 5 months ago

I changed my dependencies to the PR #33 and it doesn't seem to have fixed my particular issue.

    Updating git repository `https://github.com/smart-leds-rs/ws2812-spi-rs.git`
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on package cache
   Compiling ws2812-spi v0.4.0 (https://github.com/smart-leds-rs/ws2812-spi-rs.git?branch=eh10#42d348f3)

ws2812-spi = { git = "https://github.com/smart-leds-rs/ws2812-spi-rs.git", branch = "eh10" }

new error message:


error[E0277]: the trait bound `esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>: embedded_hal::spi::SpiBus` is not satisfied
  --> src/main.rs:39:30
   |
39 |     let mut ws = Ws2812::new(spi);
   |                  ----------- ^^^ the trait `embedded_hal::spi::SpiBus` is not implemented for `esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>`
   |                  |
   |                  required by a bound introduced by this call
   |
   = help: the trait `embedded_hal::spi::SpiBus<Word>` is implemented for `&mut T`
note: required by a bound in `ws2812_spi::Ws2812::<SPI>::new`
  --> /home/drebbe/.cargo/git/checkouts/ws2812-spi-rs-1693b0ecf9b2bdab/42d348f/src/lib.rs:47:10
   |
47 |     SPI: SpiBus<u8, Error = E>,
   |          ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Ws2812::<SPI>::new`
...
57 |     pub fn new(spi: SPI) -> Self {
   |            --- required by a bound in this associated function

error[E0599]: the method `write` exists for struct `Ws2812<Spi<'_, SPI2, FullDuplexMode>>`, but its trait bounds were not satisfied
   --> src/main.rs:66:20
    |
66  |                 ws.write(gamma(data.iter().cloned())).unwrap();
    |                    ^^^^^ method cannot be called on `Ws2812<Spi<'_, SPI2, FullDuplexMode>>` due to unsatisfied trait bounds
    |
   ::: /home/drebbe/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-hal-0.16.1/src/spi/master.rs:378:1
    |
378 | pub struct Spi<'d, T, M> {
    | ------------------------ doesn't satisfy `<_ as ErrorType>::Error = _` or `_: SpiBus`
    |
   ::: /home/drebbe/.cargo/git/checkouts/ws2812-spi-rs-1693b0ecf9b2bdab/42d348f/src/lib.rs:40:1
    |
40  | pub struct Ws2812<SPI, DEVICE = devices::Ws2812> {
    | ------------------------------------------------ doesn't satisfy `_: Default<_>`, `_: SmartLedsWrite` or `_: _embedded_hal_blocking_spi_Write<_>`
    |
    = note: the following trait bounds were not satisfied:
            `<esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode> as embedded_hal::spi::ErrorType>::Error = _`
            which is required by `ws2812_spi::Ws2812<esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>>: SmartLedsWrite`
            `esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>: embedded_hal::spi::SpiBus`
            which is required by `ws2812_spi::Ws2812<esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>>: SmartLedsWrite`
            `ws2812_spi::Ws2812<esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>>: embedded_hal::blocking::spi::write::Default<_>`
            which is required by `ws2812_spi::Ws2812<esp_hal::spi::master::Spi<'_, esp_hal::peripherals::SPI2, FullDuplexMode>>: esp_hal::prelude::_embedded_hal_blocking_spi_Write<_>`

warning: unused import: `smart_leds::SmartLedsWrite`
  --> src/main.rs:15:5
   |
15 | use smart_leds::SmartLedsWrite;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(unused_imports)]` on by default

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
warning: `esp32c3rust` (bin "esp32c3rust") generated 1 warning
error: could not compile `esp32c3rust` (bin "esp32c3rust") due to 2 previous errors; 1 warning emitted
ic3man5 commented 5 months ago

Digging a little deeper this might be related: https://github.com/esp-rs/esp-idf-hal/issues/3