Class: Ws2812::Basic

Inherits:
Object
  • Object
show all
Includes:
Lowlevel
Defined in:
lib/ws2812/basic.rb

Overview

Provides basic interface for so called NeoPixels (ws2812 RGB LED chips)

This library internally uses C (and SWIG) extension from Richard Hirst’s version of Jeremy Garff’s rpi_ws281x library.

And this particular class is heavily inspired by the included neopixel.py Python class within these projects.

See:

jgarff

github.com/jgarff/rpi_ws281x

richardghirst

github.com/richardghirst/rpi_ws281x

pimoroni

github.com/pimoroni/unicorn-hat/tree/master/python/rpi-ws281x

Instance Method Summary collapse

Constructor Details

#initialize(num, pin, brightness = 50, options = {}) ⇒ Basic

Initializes the basic ws2812 driver for num leds at given pin, with initial brightness (0..255)

The options hash can contain various additional options (all keys as symbols):

freq

frequency (Hz) to communicate at, defaults to 800_000

dma

dma channel to use, defaults to 5

invert

use inverted logic, defaults to false

channel

which channel to use, defaults to 0 (permissible 0, 1)



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/ws2812/basic.rb', line 32

def initialize(num, pin, brightness = 50, options = {})

  freq = options.fetch(:freq) { 800_000 }
  dma = options.fetch(:dma) { 5 }
  invert = options.fetch(:invert) { false }
  channel = options.fetch(:channel) { 0 }

  @leds = Ws2811_t.new
  @leds.freq = freq
  @leds.dmanum = dma

  @channel = ws2811_channel_get(@leds, channel)
  @channel.count = num
  @channel.gpionum = pin
  @channel.invert = invert ? 1 : 0
  @channel.brightness = brightness

  @count = num

  at_exit { self.close }

  @open = false
end

Instance Method Details

#[](index) ⇒ Object

Return Color of led located at given index

Indexed from 0 upto #count - 1



169
170
171
172
173
174
175
176
177
178
179
# File 'lib/ws2812/basic.rb', line 169

def [](index)
  if index.respond_to?(:to_a)
    index.to_a.map do |i|
      check_index(i)
      Color.from_i(ws2811_led_get(@channel, i))
    end
  else
    check_index(index)
    Color.from_i(ws2811_led_get(@channel, index))
  end
end

#[]=(index, color) ⇒ Object

Set given pixel identified by index to color

See set for a method that takes individual r, g, b components



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ws2812/basic.rb', line 116

def []=(index, color)
  if index.respond_to?(:to_a)
    index.to_a.each do |i|
      check_index(i)
      ws2811_led_set(@channel, i, color.to_i)
    end
  else
    check_index(index)
    ws2811_led_set(@channel, index, color.to_i)
  end
end

#brightnessObject

Return brightness used for all pixels

The value is from 0 to 255 and is internally used as a scaler for all colors values that are supplied via []=



152
153
154
# File 'lib/ws2812/basic.rb', line 152

def brightness
  @channel.brightness
end

#brightness=(val) ⇒ Object

Set brightness used for all pixels

The value is from 0 to 255 and is internally used as a scaler for all colors values that are supplied via []=



143
144
145
# File 'lib/ws2812/basic.rb', line 143

def brightness=(val)
  @channel.brightness = val
end

#closeObject

Closes (deinitializes) communication with the LED strand

Can be called on already closed device just fine



89
90
91
92
93
94
95
96
97
98
# File 'lib/ws2812/basic.rb', line 89

def close
  if @open && @leds
    @open = false
    ws2811_fini(@leds)
    @channel = nil # will GC the memory
    @leds = nil
    # Note: ws2811_fini will free mem used by led_data internally
  end
  self
end

#countObject

Number of leds it’s initialized for

Method actually passes to low-level implementation for this value; it doesn’t use the parameter passed during construction



161
162
163
# File 'lib/ws2812/basic.rb', line 161

def count
  @channel.count
end

#direct=(value) ⇒ Object

Instruct lowlevel driver to bypass gamma correction (brightness) and use the color values straight as they are given



65
66
67
# File 'lib/ws2812/basic.rb', line 65

def direct=(value)
  Ws2812::Lowlevel.ws2811_direct_colors = !!value ? 1 : 0
end

#direct?Boolean

Is gamma correction (brightness) bypassed?

Returns:

  • (Boolean)


58
59
60
# File 'lib/ws2812/basic.rb', line 58

def direct?
  !Ws2812::Lowlevel.ws2811_direct_colors.zero?
end

#openObject

Actually opens (initializes) communication with the LED strand

Raises an exception when the initialization fails.

Failure is usually because you don’t have root permissions which are needed to access /dev/mem and to create special devices.



77
78
79
80
81
82
83
# File 'lib/ws2812/basic.rb', line 77

def open
  return nil if @open
  resp = ws2811_init(@leds)
  fail "init failed with code: " + resp.to_s + ", perhaps you need to run as root?" unless resp.zero?
  @open = true
  self
end

#set(index, r, g, b) ⇒ Object

Set given pixel identified by index to r, g, b

See []= for a method that takes Color instance instead of individual components



133
134
135
136
# File 'lib/ws2812/basic.rb', line 133

def set(index, r, g, b)
  check_index(index)
  self[index] = Color.new(r, g, b)
end

#showObject

Apply all changes since last show

This method renders all changes (brightness, pixels) done to the strand since last show



106
107
108
109
# File 'lib/ws2812/basic.rb', line 106

def show
  resp = ws2811_render(@leds)
  fail "show failed with code: " + resp.to_s unless resp.zero?
end