concertina

Elecronic concertina
git clone https://git.woozle.org/neale/concertina.git

concertina / pkg / led
Neale Pickett  ·  2026-02-12

led.go

 1package led
 2
 3import "image/color"
 4import "context"
 5import "time"
 6
 7type LED interface {
 8	// Enable the LED. This must be called before doing any LED operations.
 9	// This may increase power use by some boards.
10	Enable() error
11
12	// Disable the LED. This may reduce power use by some boards.
13	Disable()
14
15	// Set the LED color as close as possible to c.
16	// On single-color LEDs (eg. Arduino Uno), this will only change the PWM duty cycle (brightness).
17	// Setting the color to black will make the LED stop emitting light,
18	// but if the LED requires a third power line (eg. ws2812), that will still be high.
19	// Use Disable() to shut off all power to the LED.
20	SetColor(c color.Color)
21}
22
23// Red enables l and sets is color as close as possible to red, with
24// brightness b. b=255 is full brightness.
25//
26// If your LED only emits one color, "as close as possible" means
27// whatever color your LED emits :)
28func Red(l LED, b uint8) {
29	l.Enable()
30	l.SetColor(color.RGBA{b, 0, 0, 0})
31}
32
33// On is a shortcut to Red(l, 0xff)
34func On(l LED) {
35	Red(l, 0xff)
36}
37
38// Off is a shortcut to Red(l, 0)
39func Off(l LED) {
40	Red(l, 0)
41}
42
43// Flash l until ctx is done.
44//
45// You can use this to asynchronously flash:
46//
47//    ctx, _ := context.WithTimeout(context.Background(), 5 * time.Second)
48//    blink := 500 * Millisecond
49//    go Flash(ctx, Builtin, blink, blink)
50//
51// Or you could flash forever, possibly to signal an error:
52//
53//    blink := 500 * Millisecond
54//    Flash(context.Background(), Builtin, blink, blink)
55func Flash(ctx context.Context, l LED, on time.Duration, off time.Duration) {
56	ledOn := false
57	var delay time.Duration
58
59	for {
60		ledOn = !ledOn
61		if ledOn {
62			delay = on
63			On(l)
64		} else {
65			delay = off
66			Off(l)
67		}
68
69		// Wait for something to happen
70		select {
71		case <-ctx.Done():
72			Off(l)
73			return
74		case <-time.After(delay):
75			continue
76		}
77	}
78}