littlewire 0.9 → 0.9.2
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.
- data/examples/led pixel.rb +55 -0
- data/examples/ws2811 colors.rb +20 -0
- data/examples/ws2811 scan.rb +25 -0
- data/examples/ws2811.rb +39 -0
- data/lib/digital.rb +1 -1
- data/lib/littlewire.rb +32 -19
- data/lib/software-pwm.rb +11 -4
- data/lib/spi.rb +6 -4
- data/lib/ws2811.rb +52 -0
- data/readme.md +2 -2
- metadata +24 -3
@@ -0,0 +1,55 @@
|
|
1
|
+
# Connects to an LPD6803 LED Pixel of the type sold by ladyada, bliptronics, and alibaba
|
2
|
+
# and sends rgb info to the pixel. While these lights have worse colour reproduction than
|
3
|
+
# the PWM in Little Wire, they're chainable so you can run hundreds off one Little Wire!
|
4
|
+
#
|
5
|
+
# This sort: http://bliptronics.com/item.aspx?ItemID=113
|
6
|
+
#
|
7
|
+
# Note if you're running more than five or so from a littlewire you should power them
|
8
|
+
# with an external power supply instead of Little Wire's VCC pin
|
9
|
+
require '../lib/littlewire'
|
10
|
+
|
11
|
+
wire = LittleWire.connect
|
12
|
+
spi = wire.spi
|
13
|
+
|
14
|
+
wire.pin_mode :pin1 => :output, :pin3 => :output
|
15
|
+
|
16
|
+
def lpd6803_data red, green, blue
|
17
|
+
# TODO: could add some dithering here
|
18
|
+
bits = [green, blue, red].map { |v| (v * 31).round.to_s(2).rjust(5, '0') }
|
19
|
+
"1#{bits.join ''}".to_i(2)
|
20
|
+
end
|
21
|
+
|
22
|
+
$lights = [[1.0, 0.0, 1.0]] # just one light, with red, green, blue set to bright violet
|
23
|
+
def update_lights
|
24
|
+
new_sequence = $lights.map { |pix| lpd6803_data(*pix) }
|
25
|
+
new_sequence.unshift 0, 0 # add start frame
|
26
|
+
$data_sequence = new_sequence
|
27
|
+
end
|
28
|
+
|
29
|
+
update_lights
|
30
|
+
|
31
|
+
spi.delay = 10
|
32
|
+
|
33
|
+
$x = 0.0
|
34
|
+
|
35
|
+
require 'benchmark'
|
36
|
+
Benchmark.benchmark do
|
37
|
+
for i in 1..1000000
|
38
|
+
wire.digital_write pin1: true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
# loop do
|
42
|
+
# $data_sequence.each_slice(2) do |cells|
|
43
|
+
# spi.send cells.pack('S>*')
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# $lights = [[0.0, $x % 1.0, 0.0]]
|
47
|
+
# $x += 1.0/32.0
|
48
|
+
# update_lights
|
49
|
+
#
|
50
|
+
# # and now we use software pwm to run the light's clock for a little while
|
51
|
+
# wire.software_pwm_write(pin2: 127)
|
52
|
+
# sleep (1.0/32.0)
|
53
|
+
# wire.software_pwm_enabled = false
|
54
|
+
# end
|
55
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require '../lib/littlewire.rb'
|
2
|
+
wire = LittleWire.connect
|
3
|
+
pin = :pin1
|
4
|
+
speed = 1
|
5
|
+
num_leds = 64
|
6
|
+
|
7
|
+
loop do
|
8
|
+
puts "red"
|
9
|
+
wire.ws2811.colors = ['red'] * num_leds
|
10
|
+
wire.ws2811.output pin
|
11
|
+
sleep speed
|
12
|
+
puts "green"
|
13
|
+
wire.ws2811.colors = ['green'] * num_leds
|
14
|
+
wire.ws2811.output pin
|
15
|
+
sleep speed
|
16
|
+
puts "blue"
|
17
|
+
wire.ws2811.colors = ['blue'] * num_leds
|
18
|
+
wire.ws2811.output pin
|
19
|
+
sleep speed
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require '../lib/littlewire.rb'
|
2
|
+
wire = LittleWire.connect
|
3
|
+
num_pixels = ARGV.first.to_i
|
4
|
+
|
5
|
+
lit = 0
|
6
|
+
loop do
|
7
|
+
|
8
|
+
text_output = ['-'] * num_pixels
|
9
|
+
text_output[lit] = '*'
|
10
|
+
puts text_output.join
|
11
|
+
|
12
|
+
wire.ws2811.colors = num_pixels.times.map do |idx|
|
13
|
+
if idx == lit
|
14
|
+
'white'.to_color
|
15
|
+
else
|
16
|
+
'black'.to_color
|
17
|
+
end
|
18
|
+
end
|
19
|
+
wire.ws2811.output :pin1
|
20
|
+
|
21
|
+
lit += 1
|
22
|
+
lit %= num_pixels
|
23
|
+
|
24
|
+
sleep 0.01
|
25
|
+
end
|
data/examples/ws2811.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Send up to 64 colours to a string of WS2812 LEDs or 800khz (version 2) Adafruit Flora NeoPixels
|
2
|
+
# Any 800khz mode ws2811 pixels will work
|
3
|
+
require '../lib/littlewire.rb'
|
4
|
+
wire = LittleWire.connect
|
5
|
+
|
6
|
+
puts DATA.read # print out the little ascii art thing at the end of this file
|
7
|
+
puts "Which pin to use for data output?"
|
8
|
+
print "Enter pin number: "
|
9
|
+
output_pin = gets.gsub(/[^0-9]/, '').to_i
|
10
|
+
|
11
|
+
print "Enter 1st color: "
|
12
|
+
wire.ws2811.colors = [gets.strip.to_color]
|
13
|
+
wire.ws2811.output(output_pin) # output our first color
|
14
|
+
|
15
|
+
titles = ['1st', '2nd', '3rd']
|
16
|
+
|
17
|
+
63.times do |idx|
|
18
|
+
print "Enter #{titles[idx + 1] || "#{idx + 2}th"} color: "
|
19
|
+
gotten = gets.strip
|
20
|
+
break if gotten.empty?
|
21
|
+
# add colour to array
|
22
|
+
wire.ws2811.colors.push gotten.to_color
|
23
|
+
wire.ws2811.output(output_pin) # output the colours to the string
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "All done!"
|
27
|
+
|
28
|
+
__END__
|
29
|
+
LittleWire connector: | Digispark Board:
|
30
|
+
/-----\ | _________
|
31
|
+
pin_1 | o o | vcc | _____| o| ds5
|
32
|
+
pin_2 | o o | pin 4 | |----- o| (usb - not available)
|
33
|
+
pin_3 | o o | gnd | |----- o| (usb - not available)
|
34
|
+
\-----/ | |----- o| ds2
|
35
|
+
|----- o| ds1
|
36
|
+
|_o_o_o__o| ds0
|
37
|
+
5 g v
|
38
|
+
v n c
|
39
|
+
d c
|
data/lib/digital.rb
CHANGED
@@ -58,7 +58,7 @@ module LittleWire::Digital
|
|
58
58
|
# `sensor_a, sensor_b = my_wire.digital_read(:pin1, :pin2)` which reads both pins at
|
59
59
|
# the exact same instant in just one USB request, returning an array of the results
|
60
60
|
#
|
61
|
-
# digital_read
|
61
|
+
# digital_read works best when the pin is in :input mode. See also #pin_mode
|
62
62
|
def digital_read *args
|
63
63
|
raise "Incorrect Arguments" if args.length < 1
|
64
64
|
pins = args.flatten
|
data/lib/littlewire.rb
CHANGED
@@ -11,6 +11,7 @@ require_relative 'servo'
|
|
11
11
|
require_relative 'spi'
|
12
12
|
require_relative 'i2c'
|
13
13
|
require_relative 'one-wire'
|
14
|
+
require_relative 'ws2811'
|
14
15
|
|
15
16
|
# LittleWire class represents LittleWire's connected to your computer via USB
|
16
17
|
#
|
@@ -25,10 +26,10 @@ class LittleWire
|
|
25
26
|
|
26
27
|
# pin name to numeric internal code maps
|
27
28
|
DigitalPinMap = { # maps common names to bit positions in PORTB
|
28
|
-
pin1: 1, d1: 1, miso: 1, pwm_b: 1, pwm_2: 1,
|
29
|
-
pin2: 2, d2: 2, sck: 2,
|
30
|
-
pin3: 5, d3: 5, reset: 5,
|
31
|
-
pin4: 0, d4: 0, mosi: 0, pwm_a: 0, pwm_1: 0 }
|
29
|
+
pin1: 1, d1: 1, miso: 1, pwm_b: 1, pwm_2: 1, ds1: 1,
|
30
|
+
pin2: 2, d2: 2, sck: 2, ds2: 2,
|
31
|
+
pin3: 5, d3: 5, reset: 5, ds5: 5,
|
32
|
+
pin4: 0, d4: 0, mosi: 0, pwm_a: 0, pwm_1: 0, ds0: 0 }
|
32
33
|
AnalogPinMap = { # maps common names to switch index in littlewire firmware
|
33
34
|
a1: 0, adc_1: 0, reset: 0, pin3: 0, d3: 0,
|
34
35
|
a2: 1, adc_2: 1, sck: 1, pin2: 1, d2: 1,
|
@@ -37,9 +38,9 @@ class LittleWire
|
|
37
38
|
pwm_b: 1, pwm_1: 1, d1: 1, pin1: 1, miso: 1,
|
38
39
|
pwm_a: 0, pwm_2: 0, d4: 0, pin4: 0, mosi: 0 }
|
39
40
|
SoftwarePWMPinMap = { # TODO: figure out which pins these are
|
40
|
-
softpwm_1: 0, softpwm_a: 0,
|
41
|
-
softpwm_2: 1, softpwm_b: 1,
|
42
|
-
softpwm_3: 2, softpwm_c: 2 }
|
41
|
+
softpwm_1: 0, softpwm_a: 0, pin4: 0, d4: 0, mosi: 0, pwm_a: 0, pwm_1: 0,
|
42
|
+
softpwm_2: 1, softpwm_b: 1, pin1: 1, d1: 1, miso: 1, pwm_b: 1, pwm_2: 1,
|
43
|
+
softpwm_3: 2, softpwm_c: 2, pin2: 2, d2: 2, sck: 2 }
|
43
44
|
GenericPinMap = { # generic pinmap used by [] and []= methods to refer to anything
|
44
45
|
d1: [:digital, :pin1],
|
45
46
|
d2: [:digital, :pin2],
|
@@ -65,7 +66,7 @@ class LittleWire
|
|
65
66
|
softpwm_c: [:software_pwm, :softpwm_c],
|
66
67
|
}
|
67
68
|
|
68
|
-
SupportedVersions = ['1.1', '1.0'] # in order of newness. # TODO: Add version 1.0?
|
69
|
+
SupportedVersions = ['1.2', '1.1', '1.0'] # in order of newness. # TODO: Add version 1.0?
|
69
70
|
|
70
71
|
|
71
72
|
# An array of all unclaimed littlewires connected to computer via USB
|
@@ -120,11 +121,11 @@ class LittleWire
|
|
120
121
|
|
121
122
|
# implementations of littlewire functions
|
122
123
|
# - generic requests
|
123
|
-
def echo; control_transfer(function: :echo, dataIn: 8).unpack('S<*'); end # echo's usb request for testing
|
124
|
-
def read; control_transfer(function: :read, wIndex: 0, dataIn: 1); end
|
125
|
-
def write byte; control_transfer(function: :write, wIndex: 0, wValue: byte); end
|
126
|
-
def clear_bit bit; control_transfer(function: :clear_bit, wIndex: 0, wValue: bit); end
|
127
|
-
def set_bit bit; control_transfer(function: :set_bit, wIndex: 0, wValue: bit); end
|
124
|
+
#def echo; control_transfer(function: :echo, dataIn: 8).unpack('S<*'); end # echo's usb request for testing
|
125
|
+
#def read; control_transfer(function: :read, wIndex: 0, dataIn: 1); end
|
126
|
+
#def write byte; control_transfer(function: :write, wIndex: 0, wValue: byte); end
|
127
|
+
#def clear_bit bit; control_transfer(function: :clear_bit, wIndex: 0, wValue: bit); end
|
128
|
+
#def set_bit bit; control_transfer(function: :set_bit, wIndex: 0, wValue: bit); end
|
128
129
|
# - programming requests
|
129
130
|
#def power_up sck_period, reset; control_transfer(function: :power_up, wIndex: sck_period, wValue: reset ? 1 : 0); end
|
130
131
|
#def power_down; control_transfer(function: :power_down); end
|
@@ -151,12 +152,23 @@ class LittleWire
|
|
151
152
|
@i2c ||= I2C.new(self)
|
152
153
|
end
|
153
154
|
|
154
|
-
# get the 1wire interface (requires firmware 1.1 or newer
|
155
|
+
# get the 1wire interface (requires firmware 1.1 or newer)
|
155
156
|
def one_wire
|
156
157
|
raise "You need to update your LittleWire firmware to version 1.1 to use One Wire" unless version_hex >= 0x11
|
157
158
|
@one_wire ||= OneWire.new(self)
|
158
159
|
end
|
159
160
|
|
161
|
+
# get the ws2811 led strip interface (requires firmware 1.2 or newer)
|
162
|
+
# optionally call with pin number to preset it
|
163
|
+
def ws2811 pin = false
|
164
|
+
raise "You need to update your LittleWire firmware to version 1.2 to use One Wire" unless version_hex >= 0x12
|
165
|
+
@ws2811 ||= Array.new
|
166
|
+
@ws2811[pin || 0] ||= WS2811.new(self, pin)
|
167
|
+
return @ws2811[pin || 0]
|
168
|
+
end
|
169
|
+
|
170
|
+
alias_method :ws2812, :ws2811
|
171
|
+
|
160
172
|
|
161
173
|
|
162
174
|
# translate calls with arduino-style lowerCamelCase method names in to ruby-style underscored_method_names
|
@@ -259,7 +271,9 @@ class LittleWire
|
|
259
271
|
:onewire_read_bit, # 50
|
260
272
|
:onewire_write_bit, # 51
|
261
273
|
:pic_24f_programming, # 52 - experimental
|
262
|
-
:pic_24f_sendsix
|
274
|
+
:pic_24f_sendsix, # 53 - experimental
|
275
|
+
:ws2812_write, # 54 - experimental
|
276
|
+
:ws2812_preload # 55 - experimental
|
263
277
|
# special cases
|
264
278
|
# pic 24f send bytes - request = 0xD*
|
265
279
|
# i2c send multiple messages - request = 0xE* ### experimental ###
|
@@ -278,10 +292,9 @@ class LittleWire
|
|
278
292
|
|
279
293
|
# calculate usb request type
|
280
294
|
def usb_request_type opts #:nodoc:
|
281
|
-
|
282
|
-
value
|
283
|
-
value |=
|
284
|
-
value |= c::EndpointDirections[:ENDPOINT_IN] if opts.has_key? :dataIn
|
295
|
+
value = LIBUSB::REQUEST_TYPE_VENDOR | LIBUSB::RECIPIENT_DEVICE
|
296
|
+
value |= LIBUSB::ENDPOINT_OUT if opts.has_key? :dataOut
|
297
|
+
value |= LIBUSB::ENDPOINT_IN if opts.has_key? :dataIn
|
285
298
|
return value
|
286
299
|
end
|
287
300
|
|
data/lib/software-pwm.rb
CHANGED
@@ -34,10 +34,17 @@ module LittleWire::SoftwarePWM
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# Set the value of a single software pwm channel - value must be a number between 0 and 255 inclusive
|
37
|
-
def software_pwm_write
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
def software_pwm_write *args
|
38
|
+
if args.first.is_a? Hash
|
39
|
+
state = self.software_pwm
|
40
|
+
args.first.each do |channel, value|
|
41
|
+
state[get_pin(LittleWire::SoftwarePWMPinMap, channel)] = value
|
42
|
+
end
|
43
|
+
self.software_pwm = state
|
44
|
+
else
|
45
|
+
raise "Invalid Arguments" unless args.length == 2
|
46
|
+
self.software_pwm_write(args.first => args.last)
|
47
|
+
end
|
41
48
|
end
|
42
49
|
|
43
50
|
def is_software_pwm_available?
|
data/lib/spi.rb
CHANGED
@@ -6,12 +6,14 @@ class LittleWire::SPI
|
|
6
6
|
end
|
7
7
|
|
8
8
|
# send and receive a message of up to four bytes
|
9
|
-
def send send,
|
9
|
+
def send send, auto_chipselect = false
|
10
10
|
mode = auto_chipselect ? 1 : 0
|
11
|
+
bytes = send.bytes.to_a
|
11
12
|
@wire.control_transfer(
|
12
|
-
|
13
|
-
wValue:
|
14
|
-
wIndex:
|
13
|
+
bRequest: 0xF0 + send.length + (mode << 3),
|
14
|
+
wValue: bytes[1].to_i << 8 | bytes[0].to_i,
|
15
|
+
wIndex: bytes[3].to_i << 8 | bytes[2].to_i,
|
16
|
+
dataIn: bytes.length
|
15
17
|
)
|
16
18
|
end
|
17
19
|
|
data/lib/ws2811.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'colorist'
|
2
|
+
|
3
|
+
# Output colours to ws2812 strips and other 800khz ws2811 led devices
|
4
|
+
# To use, simply set colours in the 'colors' array property as css color strings
|
5
|
+
# or Colorist::Color objects, then call #output(pin) to send it on it's way
|
6
|
+
#
|
7
|
+
# Note that this requires firmware v1.2 which is not yet released and there is a
|
8
|
+
# maximum of 64 lights in the firmware at the time of writing
|
9
|
+
#
|
10
|
+
# Also note that you can connect 64 leds to each of the digital pins on the LittleWire
|
11
|
+
# or Digispark device, and this enables you a total of 64 * 4 = 256 lights! Neato!
|
12
|
+
class LittleWire::WS2811
|
13
|
+
attr_accessor :colors
|
14
|
+
attr_accessor :pin
|
15
|
+
|
16
|
+
|
17
|
+
def initialize wire, default_pin = false # :nodoc:
|
18
|
+
@wire = wire
|
19
|
+
@pin = default_pin
|
20
|
+
@colors = []
|
21
|
+
end
|
22
|
+
|
23
|
+
# send colours to strip, optionally specifying a pin if not specified via
|
24
|
+
# littlewire.ws2811(pin).output
|
25
|
+
def output pin = nil
|
26
|
+
colors_buffer = @colors.map { |i| i.is_a?(Colorist::Color) ? i : i.to_color }
|
27
|
+
output_pin = @wire.get_pin(LittleWire::DigitalPinMap, pin || @pin)
|
28
|
+
raise "Must specify output pin for ws2811 strip" unless output_pin.is_a? Integer
|
29
|
+
|
30
|
+
until colors_buffer.empty?
|
31
|
+
|
32
|
+
if colors_buffer.length > 1
|
33
|
+
color = colors_buffer.shift
|
34
|
+
|
35
|
+
@wire.control_transfer(
|
36
|
+
function: :ws2812_preload,
|
37
|
+
wIndex: color.b << 8 | color.r,
|
38
|
+
wValue: color.g << 8
|
39
|
+
)
|
40
|
+
elsif colors_buffer.length == 1
|
41
|
+
color = colors_buffer.shift
|
42
|
+
|
43
|
+
@wire.control_transfer(
|
44
|
+
function: :ws2812_write,
|
45
|
+
wIndex: color.b << 8 | color.r,
|
46
|
+
wValue: color.g << 8 | output_pin
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
data/readme.md
CHANGED
@@ -53,8 +53,8 @@ lights... whatever floats your boat really. The possabilities are not especially
|
|
53
53
|
limited. Most projects you might use an Arduino for can be done with a Little Wire
|
54
54
|
if you don't mind leaving a computer turned on connected to it, and with the advent
|
55
55
|
of Raspberry Pi, that's not all that bad of an idea. I use my Little Wire to quickly
|
56
|
-
test ideas before changing them to C and uploading them to cheaper
|
57
|
-
using the Little Wire to program them)
|
56
|
+
test ideas before changing them to C and uploading them to cheaper avr tiny chips
|
57
|
+
(also using the Little Wire to program them)
|
58
58
|
|
59
59
|
|
60
60
|
### a warning ###
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: littlewire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.9.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-05-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: libusb
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 0.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: colorist
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.0.2
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.0.2
|
30
46
|
description: A little library for a little wire. Providing a pure ruby interface (via
|
31
47
|
the nonpure libusb gem) to littlewire.cc's wonderful gadget. littlewire.rb provides
|
32
48
|
general purpose digital IO, pulse width modulation analog outputs, analog inputs,
|
@@ -46,10 +62,15 @@ files:
|
|
46
62
|
- lib/servo.rb
|
47
63
|
- lib/software-pwm.rb
|
48
64
|
- lib/spi.rb
|
65
|
+
- lib/ws2811.rb
|
49
66
|
- readme.md
|
50
67
|
- license.txt
|
51
68
|
- examples/blinky.rb
|
52
69
|
- examples/fadey.rb
|
70
|
+
- examples/led pixel.rb
|
71
|
+
- examples/ws2811 colors.rb
|
72
|
+
- examples/ws2811 scan.rb
|
73
|
+
- examples/ws2811.rb
|
53
74
|
homepage: http://creativepony.com/littlewire/
|
54
75
|
licenses: []
|
55
76
|
post_install_message:
|
@@ -72,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
93
|
version: '0'
|
73
94
|
requirements: []
|
74
95
|
rubyforge_project:
|
75
|
-
rubygems_version: 1.8.
|
96
|
+
rubygems_version: 1.8.23
|
76
97
|
signing_key:
|
77
98
|
specification_version: 3
|
78
99
|
summary: A tiny library for littlewire.cc usb devices
|