Class: Denko::LED::APA102

Inherits:
Object
  • Object
show all
Includes:
Behaviors::BusPeripheral, Behaviors::Lifecycle
Defined in:
lib/denko/led/apa102.rb

Constant Summary

Constants included from Behaviors::Lifecycle

Behaviors::Lifecycle::CALLBACK_METHODS

Instance Attribute Summary collapse

Attributes included from Behaviors::Component

#board, #params

Attributes included from Behaviors::State

#state

Instance Method Summary collapse

Methods included from Behaviors::Lifecycle

included

Methods included from Behaviors::BusPeripheral

#atomically

Methods included from Behaviors::Component

#initialize, #micro_delay

Methods included from Behaviors::State

#update_state

Instance Attribute Details

#bufferObject



33
34
35
# File 'lib/denko/led/apa102.rb', line 33

def buffer
  @buffer ||= Array.new(length * bpp) { 0 }
end

Instance Method Details

#[]=(index, array) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/denko/led/apa102.rb', line 66

def []=(index, array)
  # Per-pixel brightness control, as optional 3rd indexed element of array.
  if array[3]
    buffer[index*bpp+0] = 0b11100000 | array[3]
  end

  # APA102 uses BGR ordering.
  buffer[index*bpp+1] = array[2]
  buffer[index*bpp+2] = array[1]
  buffer[index*bpp+3] = array[0]
end

#all_onObject



78
79
80
81
82
# File 'lib/denko/led/apa102.rb', line 78

def all_on
  self.brightness = 31
  self.buffer     = buffer.each_slice(bpp).map { [@masked_brightness,255,255,255] }.flatten
  show
end

#bppObject

This is BYTES per pixel, not bits per pixel. 0th byte is per-pixel brightness (PWM applied to all 3 colors).



29
30
31
# File 'lib/denko/led/apa102.rb', line 29

def bpp
  @bpp ||= 4
end

#brightness=(value) ⇒ Object

Global (per-strip) brightness control.



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/denko/led/apa102.rb', line 52

def brightness=(value)
  value = 31 if value > 31
  value = 0 if value < 0
  @brightness = value

  # @masked_brightness needs to set the 3 bits above the 5 used.
  @masked_brightness = 0b11100000 | @brightness

  # Set brightness for all pixels.
  (0..length-1).each do |index|
    buffer[index*bpp+0] = @masked_brightness
  end
end

#clearObject



89
90
91
# File 'lib/denko/led/apa102.rb', line 89

def clear
  self.buffer = buffer.each_slice(bpp).map { [@masked_brightness,0,0,0] }.flatten
end

#end_frameObject



16
17
18
19
20
21
22
23
24
25
# File 'lib/denko/led/apa102.rb', line 16

def end_frame
  return @end_frame if @end_frame

  # End frame must be at least length/2 bits long, and 32 bits (4 bytes) minimum.
  end_frame_bytes = (length / 16.0).ceil
  end_frame_bytes = 4 if end_frame_bytes < 4

  # Use all 0's for end frame instead of 1's. Prevents extra pixel when using partial strip.
  @end_frame = Array.new(end_frame_bytes) { 0 }
end

#lengthObject



7
8
9
# File 'lib/denko/led/apa102.rb', line 7

def length
  @length ||= params[:length] || 1
end

#offObject



84
85
86
87
# File 'lib/denko/led/apa102.rb', line 84

def off
  clear
  show
end

#showObject



93
94
95
96
# File 'lib/denko/led/apa102.rb', line 93

def show
  data = start_frame + buffer + end_frame
  bus.transfer(nil, write: data)
end

#start_frameObject

Start frame is always 32 0-bits (4 bytes).



12
13
14
# File 'lib/denko/led/apa102.rb', line 12

def start_frame
  @start_frame ||= Array.new(4) { 0 }
end