gobot.io/x/gobot@v1.16.0/drivers/spi/apa102.go (about) 1 package spi 2 3 import ( 4 "image/color" 5 "math" 6 7 "gobot.io/x/gobot" 8 ) 9 10 // APA102Driver is a driver for the APA102 programmable RGB LEDs. 11 type APA102Driver struct { 12 name string 13 connector Connector 14 connection Connection 15 Config 16 gobot.Commander 17 18 vals []color.RGBA 19 brightness uint8 20 } 21 22 // NewAPA102Driver creates a new Gobot Driver for APA102 RGB LEDs. 23 // 24 // Params: 25 // a *Adaptor - the Adaptor to use with this Driver. 26 // count int - how many LEDs are in the array controlled by this driver. 27 // bright - the default brightness to apply for all LEDs (must be between 0 and 31). 28 // 29 // Optional params: 30 // spi.WithBus(int): bus to use with this driver. 31 // spi.WithChip(int): chip to use with this driver. 32 // spi.WithMode(int): mode to use with this driver. 33 // spi.WithBits(int): number of bits to use with this driver. 34 // spi.WithSpeed(int64): speed in Hz to use with this driver. 35 // 36 func NewAPA102Driver(a Connector, count int, bright uint8, options ...func(Config)) *APA102Driver { 37 d := &APA102Driver{ 38 name: gobot.DefaultName("APA102"), 39 connector: a, 40 vals: make([]color.RGBA, count), 41 brightness: uint8(math.Min(float64(bright), 31)), 42 Config: NewConfig(), 43 } 44 for _, option := range options { 45 option(d) 46 } 47 return d 48 } 49 50 // Name returns the name of the device. 51 func (d *APA102Driver) Name() string { return d.name } 52 53 // SetName sets the name of the device. 54 func (d *APA102Driver) SetName(n string) { d.name = n } 55 56 // Connection returns the Connection of the device. 57 func (d *APA102Driver) Connection() gobot.Connection { return d.connection.(gobot.Connection) } 58 59 // Start initializes the driver. 60 func (d *APA102Driver) Start() (err error) { 61 bus := d.GetBusOrDefault(d.connector.GetSpiDefaultBus()) 62 chip := d.GetChipOrDefault(d.connector.GetSpiDefaultChip()) 63 mode := d.GetModeOrDefault(d.connector.GetSpiDefaultMode()) 64 bits := d.GetBitsOrDefault(d.connector.GetSpiDefaultBits()) 65 maxSpeed := d.GetSpeedOrDefault(d.connector.GetSpiDefaultMaxSpeed()) 66 67 d.connection, err = d.connector.GetSpiConnection(bus, chip, mode, bits, maxSpeed) 68 if err != nil { 69 return err 70 } 71 return nil 72 } 73 74 // Halt stops the driver. 75 func (d *APA102Driver) Halt() (err error) { 76 return 77 } 78 79 // SetRGBA sets the ith LED's color to the given RGBA value. 80 // A subsequent call to Draw is required to transmit values 81 // to the LED strip. 82 func (d *APA102Driver) SetRGBA(i int, v color.RGBA) { 83 d.vals[i] = v 84 } 85 86 // SetBrightness sets the ith LED's brightness to the given value. 87 // Must be between 0 and 31. 88 func (d *APA102Driver) SetBrightness(i uint8) { 89 d.brightness = uint8(math.Min(float64(i), 31)) 90 } 91 92 // Brightness return driver brightness value. 93 func (d *APA102Driver) Brightness() uint8 { 94 return d.brightness 95 } 96 97 // Draw displays the RGBA values set on the actual LED strip. 98 func (d *APA102Driver) Draw() error { 99 // TODO(jbd): dotstar allows other RGBA alignments, support those layouts. 100 n := len(d.vals) 101 102 tx := make([]byte, 4*(n+1)+(n/2+1)) 103 tx[0] = 0x00 104 tx[1] = 0x00 105 tx[2] = 0x00 106 tx[3] = 0x00 107 108 for i, c := range d.vals { 109 j := (i + 1) * 4 110 if c.A != 0 { 111 tx[j] = 0xe0 + byte(math.Min(float64(c.A), 31)) 112 } else { 113 tx[j] = 0xe0 + byte(d.brightness) 114 } 115 tx[j+1] = c.B 116 tx[j+2] = c.G 117 tx[j+3] = c.R 118 } 119 120 // end frame with at least n/2 0xff vals 121 for i := (n + 1) * 4; i < len(tx); i++ { 122 tx[i] = 0xff 123 } 124 125 return d.connection.Tx(tx, nil) 126 }