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  }