pixel_pi 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c158234b67ccd01d55b48cf274c5ccb437ae77a
4
- data.tar.gz: 5125b6c0d47381ca23ba8fc942ac73d22f9f3bbb
3
+ metadata.gz: 688bc3e73f552b02b5dc0680b011b5bac6126e5b
4
+ data.tar.gz: 8834674338856c9c2cff5ade3a2e3bd965a861b1
5
5
  SHA512:
6
- metadata.gz: d010f3d8e722cb39aea7cd13cb78e92621628014799899bb08def77a0b0e1333dcf88362aa797f88ccdf2949b6d524f80bf23fa3302951e875e974fbf0e7a80b
7
- data.tar.gz: acdac849b6517a354918be99681e360592a8edb77ca18a77bc741aba66008c56b42a62a760500a9026f6bd41c7d6d1a7794d5085765e3a39fee56637ef8129e0
6
+ metadata.gz: 376b26eee53fd8a891d3592e7cdfd07abb335a4280033a28a7f6ee485ee1934739a01fa5ec7432dec92ed34046b3a255cd56631497423a2ab7a8b6ee55629686
7
+ data.tar.gz: af41e39b37c563710b2d3066fb7673864d0c6bb0af707fb7a4a588335ef641a44bde725106150fca0774b7868873e94f475e354335383413442e2eb31521526e
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  *.gem
2
2
  tmp
3
+ pkg
4
+ vendor
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Tim Pease
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/Rakefile CHANGED
@@ -6,7 +6,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
 
7
7
  spec = Gem::Specification.load("pixel_pi.gemspec")
8
8
 
9
- Gem::PackageTask.new(spec)
9
+ Gem::PackageTask.new(spec) do |pkg|
10
+ pkg.need_zip = false
11
+ pkg.need_tar = false
12
+ end
10
13
 
11
14
  Rake::ExtensionTask.new("pixel_pi", spec) do |ext|
12
15
  ext.name = "leds"
@@ -145,7 +145,6 @@ module StrandTest
145
145
 
146
146
  self
147
147
  end
148
-
149
148
  end
150
149
 
151
150
 
@@ -154,7 +153,8 @@ strip = PixelPi::Leds.new \
154
153
  :frequency => LED_FREQ_HZ,
155
154
  :dma => LED_DMA,
156
155
  :brightness => LED_BRIGHTNESS,
157
- :invert => LED_INVERT
156
+ :invert => LED_INVERT,
157
+ :debug => true
158
158
 
159
159
  strip.extend StrandTest
160
160
 
@@ -1,18 +1,36 @@
1
1
  require 'mkmf'
2
+ require 'rbconfig'
2
3
 
3
4
  pixel_pi_path = File.expand_path("../", __FILE__)
4
5
  ws2811_path = File.expand_path("../../ws2811", __FILE__)
5
- ws2811_files = %w[
6
- clk.h
7
- dma.h
8
- gpio.h
9
- pwm.h
10
- ws2811.h
11
- dma.c
12
- pwm.c
13
- ws2811.c
14
- ]
15
- ws2811_files.map! { |name| "#{ws2811_path}/#{name}" }
16
- FileUtils.cp(ws2811_files, pixel_pi_path)
17
6
 
18
- create_makefile("pixel_pi/leds")
7
+ if RbConfig::CONFIG["arch"].to_s =~ /\Aarm-linux/i
8
+ ws2811_files = %w[
9
+ clk.h
10
+ dma.h
11
+ gpio.h
12
+ pwm.h
13
+ ws2811.h
14
+ dma.c
15
+ pwm.c
16
+ ws2811.c
17
+ ]
18
+ ws2811_files.map! { |name| "#{ws2811_path}/#{name}" }
19
+ FileUtils.cp(ws2811_files, pixel_pi_path)
20
+
21
+ create_makefile("pixel_pi/leds")
22
+ else
23
+ File.open("#{pixel_pi_path}/Makefile", "w") do |fd|
24
+ fd.write <<-MAKEFILE
25
+ all: ;
26
+ install: ;
27
+ static: ;
28
+ install-so: ;
29
+ install-rb: ;
30
+ clean: ;
31
+ clean-so: ;
32
+ clean-static: ;
33
+ clean-rb: ;
34
+ MAKEFILE
35
+ end
36
+ end
@@ -0,0 +1,210 @@
1
+ require "forwardable"
2
+
3
+ module PixelPi
4
+
5
+ # Given a set of RGB values return a single 24-bit color value. The RGB values
6
+ # are nubmers in the range 0..255.
7
+ #
8
+ # Returns a 24-bit RGB color value.
9
+ def self.Color( red, green, blue )
10
+ ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF)
11
+ end
12
+
13
+ # PixelPi::Error class
14
+ Error = StandardError.new
15
+
16
+ class Leds
17
+ extend Forwardable
18
+
19
+ # call-seq:
20
+ # PixelPi::Leds.new( length, gpio, options = {} )
21
+ #
22
+ # Create a new PixelPi::Leds instance that can be used to control a string of
23
+ # NeoPixels from a RaspberryPi. The length of the pixel string must be given as
24
+ # well as the GPIO pin number used to control the string. The remaining options
25
+ # have sensible defaults.
26
+ #
27
+ # length - the nubmer of leds in the string
28
+ # gpio - the GPIO pin number
29
+ # options - Hash of arguments
30
+ # :dma - DMA channel defaults to 5
31
+ # :frequency - output frequency defaults to 800,000 Hz
32
+ # :invert - defaults to `false`
33
+ # :brightness - defaults to 255
34
+ #
35
+ def initialize( length, gpio, options = {} )
36
+ @leds = [0] * length
37
+ @gpio = gpio
38
+ @dma = options.fetch(:dma, 5)
39
+ @frequency = options.fetch(:frequency, 800_000)
40
+ @invert = options.fetch(:invert, false)
41
+ @brightness = options.fetch(:brightness, 255)
42
+ @debug = options.fetch(:debug, false)
43
+
44
+ if @debug
45
+ require "rainbow"
46
+ @debug = "◉ " unless @debug.is_a?(String) && !@debug.empty?
47
+ end
48
+ end
49
+
50
+ attr_reader :gpio, :dma, :frequency, :invert, :brightness
51
+
52
+ def_delegators :@leds, :length, :[]
53
+
54
+ # Set the pixel brightness. This is a value between 0 and 255. All pixels will
55
+ # be scaled by this value. The hue is not affected; only the luminosity is
56
+ # affected.
57
+ #
58
+ # Returns the new brightness.
59
+ def brightness=( value )
60
+ @brightness = Integer(value) & 0xFF;
61
+ end
62
+
63
+ # Update the display with the data from the LED buffer. This is a noop method
64
+ # for the fake LEDs.
65
+ def show
66
+ closed!
67
+ if @debug
68
+ ary = @leds.map { |value| Rainbow(@debug).color(*to_rgb(value)) }
69
+ $stdout.print "\r#{ary.join}"
70
+ end
71
+ self
72
+ end
73
+
74
+ # Clear the display. This will set all values in the LED buffer to zero, and
75
+ # then update the display. All pixels will be turned off by this method.
76
+ def clear
77
+ closed!
78
+ @leds.fill 0
79
+ self
80
+ end
81
+
82
+ # Shutdown the NeoPixels connected to the DMA / PWM channel. After this method
83
+ # the current PixelPi::Leds instance will no longer be usable; a new instance
84
+ # will need to be created. This method is automatically invoked when the
85
+ # instance is deallcoated by the Ruby garbage collector. It does not need to be
86
+ # explicitly invoked.
87
+ #
88
+ # Returns `nil`.
89
+ def close
90
+ $stdout.puts if @debug
91
+ @leds = nil
92
+ end
93
+
94
+ # Set the LED at position `num` to the provided 24-bit RGB color value.
95
+ #
96
+ # Returns the 24-bit RGB color value.
97
+ def []=( num, value )
98
+ closed!
99
+ if (num < 0 || num >= @leds.length)
100
+ raise IndexError, "index #{num} is outside of LED range: 0...#{@leds.length-1}"
101
+ end
102
+ @leds[num] = to_color(value)
103
+ end
104
+
105
+ # Set the LED at position `num` to the given color. The color can be a single
106
+ # 24-bit RGB `color` value or three separate color values - one for `red`, one
107
+ # for `green`, and one for `blue`.
108
+ #
109
+ # Returns this PixelPi::Leds instance.
110
+ def set_pixel( num, *args )
111
+ self[num] = to_color(*args)
112
+ self
113
+ end
114
+
115
+ # Takes the current list of 24-bit RGB values stored in the LED strings and
116
+ # returns them as an Array. These colors might not be actively displayed; it
117
+ # all depends if `show` has been called on the PixelPi::Leds instance.
118
+ #
119
+ # Returns an Array of 24-bit RGB values.
120
+ def to_a
121
+ closed!
122
+ @leds.dup
123
+ end
124
+
125
+ # Replace the LED colors with the 24-bit RGB color values found in the `ary`.
126
+ # If the `ary` is longer than the LED string then the extra color values will
127
+ # be ignored. If the `ary` is shorter than the LED string then only the LEDS
128
+ # up to `ary.length` will be changed.
129
+ #
130
+ # You must call `show` for the new colors to be displayed.
131
+ #
132
+ # Returns this PixelPi::Leds instance.
133
+ def replace( ary )
134
+ closed!
135
+ @leds.length.times do |ii|
136
+ @leds[ii] = Integer(ary[ii])
137
+ end
138
+ self
139
+ end
140
+
141
+ # Reverse the order of the LED colors.
142
+ #
143
+ # Returns this PixelPi::Leds instance.
144
+ def reverse
145
+ closed!
146
+ @leds.reverse!
147
+ self
148
+ end
149
+
150
+ # Rotates the LED colors in place so that the color at `count` comes first. If
151
+ # `count` is negative then it rotates in the opposite direction, starting from
152
+ # the end of the LEDs where -1 is the last LED.
153
+ #
154
+ # Returns this PixelPi::Leds instance.
155
+ def rotate( *args )
156
+ closed!
157
+ @leds.rotate!(*args)
158
+ self
159
+ end
160
+
161
+ # Set the selected LEDs to the given `color`. The `color` msut be given as a
162
+ # 24-bit RGB value. You can also supply a block that receives an LED index and
163
+ # returns a 24-bit RGB color.
164
+ #
165
+ # Examples:
166
+ # leds.fill( 0x00FF00 )
167
+ # leds.fill( 0xFF0000, 2, 2 )
168
+ # leds.fill( 0x0000FF, (4...8) )
169
+ # leds.fill { |i| 256 << i }
170
+ #
171
+ # Returns this PixelPi::Leds instance.
172
+ def fill( *args )
173
+ closed!
174
+ if block_given?
175
+ @leds.fill do |ii|
176
+ value = yield(ii)
177
+ to_color(value)
178
+ end
179
+ else
180
+ value = to_color(args.shift)
181
+ @leds.fill(value, *args)
182
+ end
183
+ self
184
+ end
185
+
186
+ private
187
+
188
+ def to_color( *args )
189
+ case args.length
190
+ when 1; Integer(args.first) & 0xFFFFFF
191
+ when 3; PixelPi::Color(*args)
192
+ else
193
+ raise ArgumentError, "expecting either 1 or 3 arguments: #{args.length}"
194
+ end
195
+ end
196
+
197
+ def to_rgb( color )
198
+ scale = (brightness & 0xFF) + 1
199
+ [
200
+ (((color >> 16) & 0xFF) * scale) >> 8,
201
+ (((color >> 8) & 0xFF) * scale) >> 8,
202
+ (( color & 0xFF) * scale) >> 8
203
+ ]
204
+ end
205
+
206
+ def closed!
207
+ raise(::PixelPi::Error, "Leds are not initialized") if @leds.nil?
208
+ end
209
+ end
210
+ end
@@ -1,3 +1,3 @@
1
1
  module PixelPi
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/pixel_pi.rb CHANGED
@@ -1,2 +1,9 @@
1
- require "pixel_pi/leds"
2
1
  require "pixel_pi/version"
2
+
3
+ begin
4
+ require "pixel_pi/leds"
5
+ rescue LoadError
6
+ $stderr.puts "C extension is not configured."
7
+ $stderr.puts "Using fake LEDs instead."
8
+ require "pixel_pi/fake_leds"
9
+ end
data/pixel_pi.gemspec CHANGED
@@ -19,5 +19,5 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = %w{lib}
20
20
 
21
21
  spec.add_development_dependency "rake-compiler", "~> 0.9"
22
+ spec.add_development_dependency "rainbow", "~> 2.0"
22
23
  end
23
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixel_pi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Pease
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-22 00:00:00.000000000 Z
11
+ date: 2015-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rainbow
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
27
41
  description: NeoPixels are fun! Ruby is fun! RaspberryPi is fun! FUN^3
28
42
  email:
29
43
  - tim.pease@gmail.com
@@ -33,6 +47,7 @@ extensions:
33
47
  extra_rdoc_files: []
34
48
  files:
35
49
  - ".gitignore"
50
+ - LICENSE
36
51
  - README.md
37
52
  - Rakefile
38
53
  - examples/strandtest.rb
@@ -48,6 +63,7 @@ files:
48
63
  - ext/ws2811/ws2811.c
49
64
  - ext/ws2811/ws2811.h
50
65
  - lib/pixel_pi.rb
66
+ - lib/pixel_pi/fake_leds.rb
51
67
  - lib/pixel_pi/version.rb
52
68
  - pixel_pi.gemspec
53
69
  homepage: https://github.com/TwP/pixel_pi
@@ -70,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
86
  version: '0'
71
87
  requirements: []
72
88
  rubyforge_project:
73
- rubygems_version: 2.2.2
89
+ rubygems_version: 2.2.3
74
90
  signing_key:
75
91
  specification_version: 4
76
92
  summary: A library for controlling NeoPixels via Ruby on the RaspberryPi