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