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.
@@ -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
@@ -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
@@ -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 tends to work best when the pin in :input mode. See also #pin_mode
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
@@ -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 # 53 - experimental
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
- c = LIBUSB::Call
282
- value = c::RequestTypes[:REQUEST_TYPE_VENDOR] | c::RequestRecipients[:RECIPIENT_DEVICE]
283
- value |= c::EndpointDirections[:ENDPOINT_OUT] if opts.has_key? :dataOut
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
 
@@ -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 channel, value
38
- state = self.software_pwm
39
- state[get_pin(LittleWire::SoftwarePWMPinMap, channel)] = value
40
- self.software_pwm = state
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, receive, auto_chipselect = false
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
- wRequest: 0xF0 + send.length + (mode << 3),
13
- wValue: send.bytes[1] << 8 | send.bytes[0],
14
- wIndex: send.bytes[3] << 8 | send.bytes[0]
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
 
@@ -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 attiny chips (also
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: '0.9'
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: 2012-09-20 00:00:00.000000000 Z
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.21
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