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
617 stars 195 forks source link

RGBW leds #51

Open directionless opened 5 years ago

directionless commented 5 years ago

I was playing with rgbw leds, using the existing ws2812 driver. It turned out to be quite easy, instead of writing the GRB bytes, I needed to write a 4th W byte. So, what might support for this look like?

I imagine there's some benefit to using the existing color.RGBA type. Does adding an optional parameter for the white array make sense?

deadprogram commented 5 years ago

I just wonder if in this case, we should use the alpha channel for that? Your typical WS2812 does not support which is why WriteColors() currently ignores that data. Seems like the easiest thing to do, probably, would be to add an additional member to the struct type like HasWhite bool which would control if 3 or 4 bytes are sent.

What do you think?

aykevl commented 5 years ago

Perhaps even better: an enum to describe the color model (or however this should be called):

Some (older) strips do not follow the GRB order and it would be useful to add support for those without breaking the API.

deadprogram commented 5 years ago

That's a much better idea.

aykevl commented 5 years ago

Still, I wonder how we can best pass the white channel in this API. We could (ab)use the alpha channel for that, but I think that's wrong. Maybe we should define a new color type for that, for RGBW? Passing the white channel as a separate slice also seems wrong somehow, it makes working with RGBW colors needlessly difficult.

Come to think of it, I suspect the APA102 uses the wrong color format. I think it should use NRGBA instead of RGBA because it essentially does the alpha calculation inside the LED.

directionless commented 5 years ago

I have some partially implemented code using functional parameters and an enum. It's pretty clean, but https://github.com/tinygo-org/tinygo/issues/320. I'll look back and put up some kind of PR for it all.

I was thinking the alpha channel felt like a good fit for brightness. (https://github.com/tinygo-org/drivers/issues/52)

But I'm still baffled about how to pass the data. I wonder if we should chat with image/color and see what their thoughts are.

syoder commented 4 years ago

I have a 5x8 Neopixel RGBW panel that I was trying to get working and ran into this issue. And my initial thought was maybe it's not completely crazy to use the alpha channel for white. But if we want to avoid that, we could keep it simple and do something like this:

type RGBW struct {
    color.RGBA
    W uint8
}

func (d Device) WriteColorsRGBW(buf []RGBW) error {
    for _, color := range buf {
        d.WriteByte(color.G) // green
        d.WriteByte(color.R) // red
        d.WriteByte(color.B) // blue
        d.WriteByte(color.W) // white
    }
    return nil
}

That would leave the existing WriteColors as-is so that we wouldn't break it.

Thoughts? I'm happy to throw together a PR if there is some consensus on how to support RGBW.