tinygo-org / drivers

TinyGo drivers for sensors, displays, wireless adaptors, and other devices that use I2C, SPI, GPIO, ADC, and UART interfaces.
https://tinygo.org
BSD 3-Clause "New" or "Revised" License
587 stars 182 forks source link

WS2812 driver not working properly - array offset incorrect #495

Open mytechnotalent opened 1 year ago

mytechnotalent commented 1 year ago

Using the default example...

// Connects to an WS2812 RGB LED strip with 10 LEDS.
//
// See either the others.go or digispark.go files in this directory
// for the neopixels pin assignments.
package main

import (
    "image/color"
    "machine"
    "time"

    "tinygo.org/x/drivers/ws2812"
)

var neo machine.Pin = machine.GPIO3
var led = machine.LED
var leds [64]color.RGBA

func main() {
    led.Configure(machine.PinConfig{Mode: machine.PinOutput})

    neo.Configure(machine.PinConfig{Mode: machine.PinOutput})

    ws := ws2812.New(neo)
    // rg := false

    for {
        // rg = !rg
        // for i := range leds {
        //  rg = !rg
        //  if rg {
        //      // Alpha channel is not supported by WS2812 so we leave it out
        //      leds[i] = color.RGBA{R: 0xff, G: 0x00, B: 0x00}
        //  } else {
        //      leds[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00}
        //  }
        // }

        leds[0] = color.RGBA{R: 0x00, G: 0xff, B: 0x00}  // lights green as expected, if i do led[1] and add a value nothing happens

        leds[8] = color.RGBA{R: 0xff, G: 0x00, B: 0x00}  // lights green, unexpected, lesser value of green
        ws.WriteColors(leds[:])
        //led.Set(rg)
        time.Sleep(100 * time.Millisecond)
    }
}

I am using a WS2812B and I do not believe it is an RGBA however I would assume this driver has functionality for a WS2812B? If so is there something I need to tweak as I read the docs and did not see anything regarding a WS2812B. Thank you

aykevl commented 1 year ago

What kind of LED strip do you have? To see what's going wrong, can you set the first 8 or so LEDs to green and tell what the result is? That might give a better idea of what's going wrong.

mytechnotalent commented 1 year ago

@aykevl I am using a Raspberry Pi Pico here and have a 64 array WS2182B strip. This is NOT a RGBA I do not believe. When I set an array of 8 pixels and set to green the 0th or 1st neopixel in the array flashes between bright white and yellow at the speed of the onboard led.

// Connects to an WS2812 RGB LED strip with 10 LEDS.
//
// See either the others.go or digispark.go files in this directory
// for the neopixels pin assignments.
package main

import (
    "image/color"
    "machine"
    "time"

    "tinygo.org/x/drivers/ws2812"
)

var neo machine.Pin = machine.GPIO3
var led = machine.LED
var leds [8]color.RGBA

func main() {
    led.Configure(machine.PinConfig{Mode: machine.PinOutput})

    neo.Configure(machine.PinConfig{Mode: machine.PinOutput})

    ws := ws2812.New(neo)
    rg := false

    for {
        rg = !rg
        for i := range leds {
            rg = !rg
            if rg {
                // Alpha channel is not supported by WS2812 so we leave it out
                leds[i] = color.RGBA{R: 0xff, G: 0x00, B: 0x00}
            } else {
                leds[i] = color.RGBA{R: 0x00, G: 0xff, B: 0x00}
            }
        }

        ws.WriteColors(leds[:])
        led.Set(rg)
        time.Sleep(100 * time.Millisecond)
    }
}

When I try this code with a bluepill (it is default 8MHz nothing lights up. I suspect with the bluepill the timings are not matching up).

aykevl commented 1 year ago

flashes between bright white and yellow at the speed of the onboard led.

This could be a problem with the power supply. Can you:

  1. Check whether the power supply is strong enough for these LEDs?
  2. Try the same thing with Arduino/MicroPython/etc to see whether the LED strip is stable in that case?
mytechnotalent commented 1 year ago

@aykevl just tested with MicroPython and everything works perfectly as expected. The supply is a 3.3v which is also expected.

aykevl commented 1 year ago

Hmm, that's odd. I have been using WS2812 LEDs on a RP2040 just fine. I'm afraid it's difficult to help you much further. I've been using GPIO29, you could perhaps try that pin and see whether it makes any difference?

When I set an array of 8 pixels and set to green the 0th or 1st neopixel in the array flashes between bright white and yellow at the speed of the onboard led.

That's very odd. Normally I'd say that indicates a problem with the wires but if it works with MicroPython that's unlikely.

Gustavomurta commented 8 months ago

MyTechnoTalent, the minimum supply voltage for the WS2812B LED to work is 3.5V, according to the datasheet. I recommend that you power the LEDs with 5V. As DIN is an input of the WS281B, it does not pose a risk for a 3.3V MCU.

Power supply voltage VDD: +3.5~+5.3 https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf

I tested your second program on a Raspberry Pico and it worked correctly (LED VCC = 5V). But using another GPIO - 16. Testing GPIO 3 doesn't work. It could be some restriction from Pico, since GPIO3 can normally be used on I2C or SPI interfaces.

var neo machine.Pin = machine.GPIO16 // Raspberry Pico GPIO16 (pin 21) var led = machine.LED // Raspberry Pico LED = GPIO25 var leds [8]color.RGBA // number of LEDs must be divisible by 2

graugans commented 8 months ago

I am using a WS2812B and I do not believe it is an RGBA however I would assume this driver has functionality for a WS2812B? If so is there something I need to tweak as I read the docs and did not see anything regarding a WS2812B. Thank you

As stated in the comment of the example the A from RGBA is not supported by the LED so does the driver skip this part when writing to the device, see https://github.com/tinygo-org/drivers/blob/release/ws2812/ws2812.go#L38

@Gustavomurta I can not find any reference in the driver that the number of LEDs needs to be divisible by 2. For my Halloween project I have used 3 LEDs without an issue.

Gustavomurta commented 8 months ago

@Gustavomurta I can not find any reference in the driver that the number of LEDs needs to be divisible by 2. For my Halloween project I have used 3 LEDs without an issue.

Correcting my conclusion : I tested with 5 LEDs and it didn't work. So I concluded this. Tests with 6 and 8 leds were OK. I will have to test more options to reach an accurate conclusion. Thanks