BBB 0.2.0 → 0.3.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 +8 -8
- data/examples/analog_pin.rb +4 -6
- data/examples/{led.rb → blinker.rb} +2 -3
- data/examples/ldr_light_switch.rb +16 -22
- data/examples/light_switch.rb +10 -33
- data/examples/{nunchuck.rb → nunchuck_websocket.rb} +13 -13
- data/examples/quadcopter.rb +77 -0
- data/examples/servo_ldr.rb +104 -14
- data/lib/BBB.rb +16 -2
- data/lib/BBB/application.rb +10 -4
- data/lib/BBB/attachable.rb +77 -0
- data/lib/BBB/circuit.rb +7 -47
- data/lib/BBB/components/button.rb +45 -5
- data/lib/BBB/components/esc.rb +1 -1
- data/lib/BBB/components/led.rb +19 -0
- data/lib/BBB/components/nunchuck.rb +0 -43
- data/lib/BBB/components/pinnable.rb +4 -1
- data/lib/BBB/components/wii_motion_plus.rb +4 -0
- data/lib/BBB/configuration.rb +14 -0
- data/lib/BBB/pins/pinnable.rb +1 -1
- data/lib/BBB/version.rb +1 -1
- data/spec/application_spec.rb +27 -5
- data/spec/bbb_spec.rb +23 -0
- data/spec/configuration_spec.rb +16 -0
- data/spec/examples/analog_pin_spec.rb +13 -0
- data/spec/examples/blinker_spec.rb +17 -0
- data/spec/examples/ldr_light_switch_spec.rb +38 -0
- data/spec/examples/light_switch_spec.rb +47 -0
- data/spec/examples/nunchuck_websocket_spec.rb +20 -0
- data/spec/examples/quadcopter_spec.rb +90 -0
- data/spec/examples/servo_ldr_spec.rb +95 -0
- data/spec/pins/pinnable_spec.rb +4 -2
- data/spec/spec_helper.rb +1 -0
- metadata +26 -7
- data/examples/sketches.rb +0 -86
- data/spec/examples/led_spec.rb +0 -40
data/lib/BBB.rb
CHANGED
@@ -2,12 +2,26 @@ require "json"
|
|
2
2
|
require "stringio"
|
3
3
|
|
4
4
|
require "BBB/version"
|
5
|
+
require "BBB/configuration"
|
5
6
|
|
6
|
-
require "BBB/circuit"
|
7
|
-
require "BBB/exceptions"
|
8
7
|
require "BBB/pins"
|
9
8
|
require "BBB/components"
|
9
|
+
require "BBB/attachable"
|
10
|
+
require "BBB/circuit"
|
11
|
+
require "BBB/exceptions"
|
10
12
|
require "BBB/application"
|
11
13
|
|
12
14
|
module BBB
|
15
|
+
|
16
|
+
def self.configuration
|
17
|
+
Configuration.instance
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.escape_test(&block)
|
21
|
+
old_mode = configuration.test_mode
|
22
|
+
configuration.test_mode = false
|
23
|
+
yield
|
24
|
+
configuration.test_mode = old_mode
|
25
|
+
end
|
26
|
+
|
13
27
|
end
|
data/lib/BBB/application.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
module BBB
|
2
2
|
class Application
|
3
3
|
include Attachable
|
4
|
+
include Components
|
4
5
|
|
6
|
+
##
|
7
|
+
# Start the application by activating the components and
|
8
|
+
# load the run loop.
|
9
|
+
#
|
5
10
|
def start
|
6
|
-
activate_components
|
7
11
|
loop do
|
8
12
|
run
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
##
|
17
|
+
# The run funciton gets called as part of the run loop on every iteration.
|
18
|
+
# This is where you put your main application code that needs to be
|
19
|
+
# evaluaded.
|
20
|
+
#
|
15
21
|
def run
|
16
22
|
raise NotImplementedError
|
17
23
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module BBB
|
2
|
+
module Attachable
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
def class_components
|
6
|
+
@class_components ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def class_component_groups
|
10
|
+
@class_component_groups ||= Hash.new { |hash, key| hash[key] = [] }
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Attach a component of a certain type to the circuit
|
15
|
+
#
|
16
|
+
# @param component [Class] The class of the object you # want to attach.
|
17
|
+
# @param opts [Hash] Hash of options that setup the component
|
18
|
+
#
|
19
|
+
# @option opts [Symbol] :pin The pin position for the component
|
20
|
+
# @option opts [Array<Symbol>] :pins The list of pin numbers used on the
|
21
|
+
# circuit.
|
22
|
+
# @options opts [Symbol] :as The name of the component
|
23
|
+
#
|
24
|
+
def attach(object, opts={})
|
25
|
+
name = opts.delete(:as)
|
26
|
+
group = opts.delete(:group)
|
27
|
+
|
28
|
+
class_components[name] = object
|
29
|
+
define_method_for_object(object, name, opts)
|
30
|
+
|
31
|
+
define_method_for_group(group)
|
32
|
+
add_to_group(name, group) if group
|
33
|
+
end
|
34
|
+
|
35
|
+
def define_method_for_object(component, name, opts)
|
36
|
+
define_method(name) do
|
37
|
+
value = components[name]
|
38
|
+
return value if value
|
39
|
+
|
40
|
+
object = self.class.class_components[name]
|
41
|
+
value = object.kind_of?(Class) ? object.new(opts) : object
|
42
|
+
components[name] = value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def define_method_for_group(group_name)
|
47
|
+
return if group_name.nil? || respond_to?(group_name)
|
48
|
+
define_method(group_name) do
|
49
|
+
if component_groups[group_name].empty?
|
50
|
+
component_groups[group_name] = self.class.class_component_groups[group_name]
|
51
|
+
end
|
52
|
+
|
53
|
+
component_groups[group_name].map do |component_name|
|
54
|
+
self.send(component_name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_to_group(component_name, group_name)
|
60
|
+
class_component_groups[group_name] << component_name
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.included(base)
|
66
|
+
base.extend(ClassMethods)
|
67
|
+
end
|
68
|
+
|
69
|
+
def components
|
70
|
+
@components ||= {}
|
71
|
+
end
|
72
|
+
|
73
|
+
def component_groups
|
74
|
+
@component_groups ||= Hash.new { |hash, key| hash[key] = [] }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/BBB/circuit.rb
CHANGED
@@ -1,51 +1,4 @@
|
|
1
1
|
module BBB
|
2
|
-
module Attachable
|
3
|
-
module ClassMethods
|
4
|
-
|
5
|
-
def class_components
|
6
|
-
@class_components ||= {}
|
7
|
-
end
|
8
|
-
|
9
|
-
##
|
10
|
-
# Attach a component of a certain type to the circuit
|
11
|
-
#
|
12
|
-
# @param component [Class] The class of the object you # want to attach.
|
13
|
-
# @param opts [Hash] Hash of options that setup the component
|
14
|
-
#
|
15
|
-
# @option opts [Symbol] :pin The pin position for the component
|
16
|
-
# @option opts [Array<Symbol>] :pins The list of pin numbers used on the
|
17
|
-
# circuit.
|
18
|
-
# @options opts [Symbol] :as The name of the component
|
19
|
-
#
|
20
|
-
def attach(object, opts={})
|
21
|
-
name = opts.delete(:as)
|
22
|
-
class_components[name] = object
|
23
|
-
define_method_for_object(object, name)
|
24
|
-
end
|
25
|
-
|
26
|
-
def define_method_for_object(component, name)
|
27
|
-
define_method(name) do
|
28
|
-
value = components[name]
|
29
|
-
return value if value
|
30
|
-
|
31
|
-
object = self.class.class_components[name]
|
32
|
-
value = object.kind_of?(Class) ? object.new : object
|
33
|
-
|
34
|
-
components[name] = value
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.included(base)
|
40
|
-
base.extend(ClassMethods)
|
41
|
-
end
|
42
|
-
|
43
|
-
def components
|
44
|
-
@components ||= {}
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
2
|
##
|
50
3
|
# The idea here is to attach a piece of equipment to a circuit.
|
51
4
|
#
|
@@ -59,6 +12,13 @@ module BBB
|
|
59
12
|
# boards. For example by mapping P8_3 on BBB to P1 on an Arduino.
|
60
13
|
#
|
61
14
|
class Circuit
|
15
|
+
attr_reader :options
|
16
|
+
|
62
17
|
include Attachable
|
18
|
+
include Components
|
19
|
+
|
20
|
+
def initialize(options={})
|
21
|
+
@options = options
|
22
|
+
end
|
63
23
|
end
|
64
24
|
end
|
@@ -1,10 +1,55 @@
|
|
1
1
|
module BBB
|
2
2
|
module Components
|
3
3
|
class Button
|
4
|
+
attr_reader :status
|
5
|
+
attr_accessor :release_callbacks, :press_callbacks
|
6
|
+
|
4
7
|
include Pinnable
|
5
8
|
|
6
9
|
uses BBB::Pins::DigitalInputPin
|
7
10
|
|
11
|
+
def initialize(options={})
|
12
|
+
@status = :released
|
13
|
+
@release_callbacks = []
|
14
|
+
@press_callbacks = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def pressed?
|
18
|
+
status == :pressed
|
19
|
+
end
|
20
|
+
|
21
|
+
def released?
|
22
|
+
!pressed
|
23
|
+
end
|
24
|
+
|
25
|
+
def press!
|
26
|
+
old_state = status
|
27
|
+
@status = :pressed
|
28
|
+
on_press if old_state != status
|
29
|
+
end
|
30
|
+
|
31
|
+
def release!
|
32
|
+
old_state = status
|
33
|
+
@status = :released
|
34
|
+
on_release if old_state != status
|
35
|
+
end
|
36
|
+
|
37
|
+
def update(value=pin.high?)
|
38
|
+
value == true ? press! : release!
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_release(&block)
|
42
|
+
@release_callbacks.each{ |c| c.call(status) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_press(&block)
|
46
|
+
if block_given?
|
47
|
+
@press_callbacks << block
|
48
|
+
else
|
49
|
+
@press_callbacks.each{ |c| c.call(status) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
8
53
|
def high?
|
9
54
|
pin.on?
|
10
55
|
end
|
@@ -14,11 +59,6 @@ module BBB
|
|
14
59
|
!high
|
15
60
|
end
|
16
61
|
alias_method :off?, :low?
|
17
|
-
|
18
|
-
def status
|
19
|
-
pin.status
|
20
|
-
end
|
21
|
-
alias_method :state, :status
|
22
62
|
end
|
23
63
|
end
|
24
64
|
end
|
data/lib/BBB/components/esc.rb
CHANGED
data/lib/BBB/components/led.rb
CHANGED
@@ -49,6 +49,25 @@ module BBB
|
|
49
49
|
pin.off?
|
50
50
|
end
|
51
51
|
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns the status of the current led
|
55
|
+
#
|
56
|
+
def status
|
57
|
+
on? ? :on : :off
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Toggle the led between on and off
|
62
|
+
#
|
63
|
+
def toggle!
|
64
|
+
if on?
|
65
|
+
off!
|
66
|
+
elsif off?
|
67
|
+
on!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
52
71
|
end
|
53
72
|
end
|
54
73
|
end
|
@@ -130,49 +130,6 @@ module BBB
|
|
130
130
|
@axis[:y].update(bytes[1])
|
131
131
|
end
|
132
132
|
|
133
|
-
class Button
|
134
|
-
attr_reader :status
|
135
|
-
attr_accessor :release_callbacks, :press_callbacks
|
136
|
-
|
137
|
-
def initialize
|
138
|
-
@status = :released
|
139
|
-
@release_callbacks = []
|
140
|
-
@press_callbacks = []
|
141
|
-
end
|
142
|
-
|
143
|
-
def pressed?
|
144
|
-
status == :pressed
|
145
|
-
end
|
146
|
-
|
147
|
-
def press!
|
148
|
-
@status = :pressed
|
149
|
-
on_press if old_state != status
|
150
|
-
end
|
151
|
-
|
152
|
-
def release!
|
153
|
-
old_state = status
|
154
|
-
@status = :released
|
155
|
-
on_release if old_state != status
|
156
|
-
end
|
157
|
-
|
158
|
-
def released?
|
159
|
-
!pressed
|
160
|
-
end
|
161
|
-
|
162
|
-
def update(value)
|
163
|
-
value == true ? release! : press!
|
164
|
-
end
|
165
|
-
|
166
|
-
def on_release
|
167
|
-
@release_callbacks.each{ |c| c.call(status) }
|
168
|
-
end
|
169
|
-
|
170
|
-
def on_press
|
171
|
-
@press_callbacks.each{ |c| c.call(status) }
|
172
|
-
end
|
173
|
-
|
174
|
-
end
|
175
|
-
|
176
133
|
class ControlAxis
|
177
134
|
attr_accessor :value
|
178
135
|
attr_accessor :change_callbacks
|
@@ -147,7 +147,10 @@ module BBB
|
|
147
147
|
# @param options [Hash]
|
148
148
|
#
|
149
149
|
def set_options(options)
|
150
|
-
@positions = [options
|
150
|
+
@positions = [options[:pin],
|
151
|
+
options[:pins],
|
152
|
+
options[:position],
|
153
|
+
options[:path]].flatten.compact
|
151
154
|
end
|
152
155
|
end
|
153
156
|
end
|
@@ -27,11 +27,15 @@ module BBB
|
|
27
27
|
|
28
28
|
attr_reader :gyro, :positions
|
29
29
|
|
30
|
+
##
|
31
|
+
# the WMP uses I2C pins, so you can give it a name like "I2C2_SDA"
|
32
|
+
#
|
30
33
|
def initialize(options = {})
|
31
34
|
@started = false
|
32
35
|
@calibrated = false
|
33
36
|
@gyro = Gyro.new
|
34
37
|
@positions = [options.fetch(:i2c, nil)].compact
|
38
|
+
@extension = options[:extension]
|
35
39
|
end
|
36
40
|
|
37
41
|
def start
|
data/lib/BBB/pins/pinnable.rb
CHANGED
data/lib/BBB/version.rb
CHANGED
data/spec/application_spec.rb
CHANGED
@@ -6,23 +6,45 @@ describe BBB::Application do
|
|
6
6
|
lambda { BBB::Application.new }.should_not raise_exception
|
7
7
|
end
|
8
8
|
|
9
|
+
it "it responds to start" do
|
10
|
+
BBB::Application.new.respond_to?(:start).should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "start calls run" do
|
14
|
+
app = BBB::Application.new
|
15
|
+
app.should_receive(:run).and_raise(StopIteration)
|
16
|
+
app.start
|
17
|
+
end
|
18
|
+
|
19
|
+
it "run raises NotImplementedError" do
|
20
|
+
app = BBB::Application.new
|
21
|
+
lambda { app.run }.should raise_error(NotImplementedError)
|
22
|
+
end
|
23
|
+
|
9
24
|
class TestLedCircuit < BBB::Circuit
|
10
|
-
attach
|
25
|
+
attach Led, as: :led
|
11
26
|
end
|
12
27
|
|
13
|
-
class
|
28
|
+
class TestCircuitConnectionApp < BBB::Application
|
14
29
|
attach TestLedCircuit, as: :circuit
|
15
30
|
end
|
16
31
|
|
17
32
|
it "attaches virtual pins to board pins" do
|
18
|
-
app =
|
33
|
+
app = TestCircuitConnectionApp.new
|
19
34
|
app.circuit.respond_to?(:led).should be_true
|
20
35
|
app.circuit.led.respond_to?(:on!).should be_true
|
21
36
|
end
|
22
37
|
|
23
|
-
class
|
24
|
-
attach
|
38
|
+
class TestBasicApp < BBB::Application
|
39
|
+
attach Led, as: :led
|
40
|
+
end
|
25
41
|
|
42
|
+
it "adds helper functions to applications" do
|
43
|
+
app = TestBasicApp.new
|
44
|
+
app.respond_to?(:led).should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
class FunctionsInApp < BBB::Application
|
26
48
|
def run
|
27
49
|
raise StopIteration
|
28
50
|
end
|