Documentation ¶
Overview ¶
Example ¶
package main import ( "bufio" "fmt" "image/color" "log" "math" "os" "sync" "time" "github.com/cgxeiji/ring" ) func main() { // Initialize the ring. r, err := ring.New(&ring.Options{ LedCount: 12, // adjust this to the number of LEDs you have MaxBrightness: 180, // value from 0 to 255 }) r.Offset(-math.Pi / 3) // you can set a rotation offset for the ring if err != nil { log.Fatal(err) } // Make sure to properly close the ring. defer r.Close() // Create a new layer. This will be a static white background. bg, err := ring.NewLayer(&ring.LayerOptions{ Resolution: 1, // set to 1 pixel because it is a uniform color background ContentMode: ring.ContentScale, // this scales the pixel to the whole ring }) if err != nil { log.Fatal(err) } // Set all pixels of the layer to white. bg.SetAll(color.White) // Add the layer to the ring. r.AddLayer(bg) // Create a mask layer. This will fade the background. bgMask, err := ring.NewLayer(&ring.LayerOptions{ Resolution: 1, // set to 1 pixel because it is a uniform mask }) if err != nil { log.Fatal(err) } r.AddLayer(bgMask) // Render the ring. if err := r.Render(); err != nil { log.Fatal(err) } // Wait for 1 second to see the beauty of the freshly rendered layer. time.Sleep(1 * time.Second) // Create another layer. This will set 3 pixels to red, green and blue, // and a hidden purple pixel with transparency of 200, that rotate // counter-clockwise. triRotate, err := ring.NewLayer(&ring.LayerOptions{ Resolution: 48, }) if err != nil { log.Fatal(err) } // We can immediately add the layer to the ring. By default, new layers // are initialized with transparent pixels. The new layer is added on top // of the previous layers. r.AddLayer(triRotate) // Set the colors. triRotate.SetPixel(0, color.NRGBA{128, 0, 0, 200}) // dark red triRotate.SetPixel(3, color.NRGBA{0, 128, 0, 200}) // dark green triRotate.SetPixel(6, color.NRGBA{0, 0, 128, 200}) // dark blue triRotate.SetPixel(24, color.NRGBA{128, 0, 255, 200}) // purple // Render the ring. if err := r.Render(); err != nil { log.Fatal(err) } // Wait for 1 second to see the beauty of both layers. time.Sleep(1 * time.Second) // Create another layer. This will set a pixel that will blink every 500ms. blink, err := ring.NewLayer(&ring.LayerOptions{ Resolution: 3, // we are going to set the 3rd pixel (index: 2) to blink ContentMode: ring.ContentCrop, // this crops the layer to avoid repetition }) if err != nil { log.Fatal(err) } // Add the layer to the ring. This will be on top of the previous two // layers. r.AddLayer(blink) // Set the color. We can use any variable that implements the color.Color // interface. blink.SetPixel(2, color.CMYK{255, 0, 0, 0}) // Render the ring. if err := r.Render(); err != nil { log.Fatal(err) } // Wait for 1 second and enjoy the view. time.Sleep(1 * time.Second) /* ANIMATION SETUP */ done := make(chan struct{}) // this will cancel all animations render := make(chan struct{}) // this will request a concurrent-safe render var ws sync.WaitGroup // this makes sure we close all goroutines /* render goroutine */ ws.Add(1) go func() { defer ws.Done() for { select { case <-done: return case <-render: if err := r.Render(); err != nil { log.Fatal(err) } } } }() /* fading goroutine */ ws.Add(1) go func() { defer ws.Done() c := color.NRGBA{0, 0, 0, 0} step := uint8(5) for { for a := uint8(0); a < 255; a += step { c.A = a bgMask.SetAll(c) select { case <-done: return case render <- struct{}{}: } time.Sleep(20 * time.Millisecond) } for a := uint8(255); a > 0; a -= step { c.A = a bgMask.SetAll(c) select { case <-done: return case render <- struct{}{}: } time.Sleep(20 * time.Millisecond) } } }() /* rotation goroutine */ ws.Add(1) go func() { defer ws.Done() for { for a := 0.0; a < math.Pi*2; a += 0.01 { triRotate.Rotate(a) select { case <-done: return case render <- struct{}{}: } time.Sleep(20 * time.Millisecond) } } }() /* blinking goroutine */ ws.Add(1) go func() { defer ws.Done() c := color.CMYK{255, 0, 0, 0} timer := time.NewTicker(500 * time.Millisecond) on := true for { select { case <-done: return case <-timer.C: if on { blink.SetPixel(2, color.Transparent) on = false } else { blink.SetPixel(2, c) on = true } select { case <-done: return case render <- struct{}{}: } } } }() fmt.Println("Press [ENTER] to exit") stdin := bufio.NewReader(os.Stdin) stdin.ReadString('\n') // Stop all animations close(done) // Wait for goroutines to exit ws.Wait() // Remember that we called a defer `r.Close()` at the beginning of the // code. This will turn off the LEDs and clean up the resources used by the // ring before exiting. Otherwise, the ring will stay on with the latest // render. }
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ContentMode ¶
type ContentMode uint8
ContentMode defines how the layer will be rendered.
const ( // ContentTile sets the layer to crop its content if it is larger that the ring // and to repeat the content. ContentTile ContentMode = iota // ContentCrop sets the layer to crop its content if it is larger than the ring // and does not repeat the content. ContentCrop // ContentScale sets the layer to scale up or down its content to fit the ring. ContentScale )
type Layer ¶
type Layer struct {
// contains filtered or unexported fields
}
Layer represents a drawable layer of the LED ring.
func NewLayer ¶
func NewLayer(options *LayerOptions) (*Layer, error)
NewLayer creates a new drawable layer.
func (*Layer) Rotate ¶
Rotate sets the rotation of the layer. A positive angle makes a counter-clockwise rotation.
type LayerOptions ¶
type LayerOptions struct { // Resolution sets the number of pixels a layer has. Usually, this is set // to the same number of LEDs the ring has. Resolution int // ContentMode sets how the layer will be rendered (default: Tile). ContentMode ContentMode }
LayerOptions is the list of options of a layer.
type Options ¶
type Options struct { // LedCount is the number of LEDs in the ring. LedCount int // MinBrightness is the minimum output of the LED> Goes from 0 to 255 // (default: 0). // MaxBrightness is the maximum output of the LED. Goes from 0 to 255 // (default: 64). // // The color will be scaled to these values. For example, color.RGBA{255, // 255, 255, 255} will output led(R: 128, G: 128, B: 128) if MaxBrightness // is set to 128, and color.RGBA(0, 0, 0, 0) will output led(R: 10, G: 10, // B: 10) if MinBrightness is set to 10. MinBrightness, MaxBrightness int // GpioPin is the GPIO pin on the Raspberry Pi with PWM output (default: // GPIO 18). *Do not confuse with the physical pin number* GpioPin int }
Options is the list of ring options.
type Ring ¶
type Ring struct {
// contains filtered or unexported fields
}
Ring represents the WS2811 LED device.
Click to show internal directories.
Click to hide internal directories.