1package led
 2
 3import (
 4	"fmt"
 5	"image/color"
 6	"machine"
 7	"time"
 8
 9	"tinygo.org/x/drivers/ws2812"
10)
11
12var ledDevice ws2812.Device
13
14func Init(pin machine.Pin) {
15	pin.Configure(machine.PinConfig{Mode: machine.PinOutput})
16	ledDevice = ws2812.New(pin)
17}
18
19type RGB struct {
20	R, G, B float64
21}
22
23type HSL struct {
24	H, S, L float64
25}
26
27func hueToRGB(v1, v2, h float64) float64 {
28	if h < 0 {
29		h += 1
30	}
31	if h > 1 {
32		h -= 1
33	}
34	switch {
35	case 6*h < 1:
36		return (v1 + (v2-v1)*6*h)
37	case 2*h < 1:
38		return v2
39	case 3*h < 2:
40		return v1 + (v2-v1)*((2.0/3.0)-h)*6
41	}
42	return v1
43}
44
45func (c HSL) ToRGB() RGB {
46	h := c.H
47	s := c.S
48	l := c.L
49
50	if s == 0 {
51		// it's gray
52		return RGB{l, l, l}
53	}
54
55	var v1, v2 float64
56	if l < 0.5 {
57		v2 = l * (1 + s)
58	} else {
59		v2 = (l + s) - (s * l)
60	}
61
62	v1 = 2*l - v2
63
64	r := hueToRGB(v1, v2, h+(1.0/3.0))
65	g := hueToRGB(v1, v2, h)
66	b := hueToRGB(v1, v2, h-(1.0/3.0))
67
68	return RGB{r, g, b}
69}
70
71func RainbowLED(sleep time.Duration, incr float64, startingHue float64) {
72	hue := startingHue
73	for true {
74		rgb := HSL{hue, 1, 0.5}.ToRGB()
75		fmt.Println(uint8(rgb.R*255), uint8(rgb.G*255), uint8(rgb.B*255))
76		WriteColor(color.RGBA{uint8(rgb.R * 255), uint8(rgb.G * 255), uint8(rgb.B * 255), 255})
77		hue += incr
78		if hue >= 1 {
79			hue -= 1
80		}
81		time.Sleep(sleep)
82	}
83}
84
85func WriteColor(colorToWrite color.RGBA) {
86	ledDevice.WriteColors([]color.RGBA{colorToWrite})
87}