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
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
M2UxNTgxNGM3ZDIxMDdiZTZlYTdlZWYyOTBlZmRjMjI2MzI1NDBkMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YTM1M2M0MWJiOWY3Nzk3NTliYjkyZTI5ODIzZDcyNDAzNDJkZjEyNw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NzQ5Mjg0MWMwZmYyZmFmMzBlYTc5NmM5NjMyNTY3ZGI3Mzg1NDI0ZjI2Y2Y4
|
10
|
+
YjBhODgwZDQ5NmQ0ZjA1ZDVlZTM4NjE0ZGNjMDYyZmUzZjIzZDVkOWY5OWZm
|
11
|
+
NDM2ODViN2Y4MGYyZDU2ZTMxMTc2N2I0ZjA4YmU0OGEwZDgwYmQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZDg3ZmNjNzU3YTNmNWRjOGNmOTk0YmJmMGQ5ZjMwZTNhNmE3YTk3N2ZjNzQ1
|
14
|
+
ZGY4MDFhNTFjMjAwNTM5Zjc3YjNiMmQ5MjA5YTgwNTBmZDRhNTU3YjJjNzM4
|
15
|
+
MWVhZDE0NmZiMzQ4M2MzMWNjMmMxNjQ3M2VlYmIxNzcwM2FjYzY=
|
data/examples/analog_pin.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
#
|
2
1
|
# To run this example do this first:
|
3
2
|
#
|
4
3
|
# Make sure you run as root
|
5
4
|
# > sudo su
|
6
5
|
#
|
7
|
-
# Install BBB gem
|
6
|
+
# Install BBB gem
|
8
7
|
# > gem install BBB
|
9
8
|
#
|
10
9
|
# Then activate the ADC using the cape
|
@@ -23,8 +22,8 @@ require 'BBB'
|
|
23
22
|
##
|
24
23
|
# Setup the actual Applicaiton
|
25
24
|
#
|
26
|
-
class
|
27
|
-
attach
|
25
|
+
class Thermometer < BBB::Application
|
26
|
+
attach AnalogComponent, as: :thermometer
|
28
27
|
|
29
28
|
def initialize
|
30
29
|
thermometer.connect(:P9_40)
|
@@ -37,5 +36,4 @@ class TemperatureExampleApp < BBB::Application
|
|
37
36
|
end
|
38
37
|
|
39
38
|
# Initialize the app
|
40
|
-
|
41
|
-
app.start
|
39
|
+
TemperatureExampleApp.new.start if __FILE__ == $0
|
@@ -3,7 +3,7 @@ require 'BBB'
|
|
3
3
|
##
|
4
4
|
# Setup the actual Application
|
5
5
|
#
|
6
|
-
class
|
6
|
+
class Blinker < BBB::Application
|
7
7
|
# Connect the led
|
8
8
|
attach BBB::Components::Led, as: :led
|
9
9
|
|
@@ -21,5 +21,4 @@ class LedExampleApplication < BBB::Application
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# Initialize and run the LedExampleApplication
|
24
|
-
|
25
|
-
app.start
|
24
|
+
Blinker.new.start if __FILE__ == $0
|
@@ -1,16 +1,15 @@
|
|
1
|
-
#
|
2
1
|
# To run this example do this first:
|
3
2
|
#
|
4
3
|
# Make sure you run as root
|
5
4
|
# > sudo su
|
6
5
|
#
|
7
|
-
# Install BBB gem
|
6
|
+
# Install BBB gem
|
8
7
|
# > gem install BBB
|
9
8
|
#
|
10
9
|
# Then activate the ADC using the cape
|
11
10
|
# > echo cape-bone-iio > /sys/devices/bone_capemgr.*/slots
|
12
11
|
#
|
13
|
-
#
|
12
|
+
# Now open up an IRB console and copy paste in this code
|
14
13
|
# > irb
|
15
14
|
#
|
16
15
|
# BE CAREFUL:
|
@@ -20,30 +19,26 @@
|
|
20
19
|
#
|
21
20
|
require 'BBB'
|
22
21
|
|
23
|
-
##
|
24
|
-
# Setup the AnalogPin Circuit
|
25
|
-
#
|
26
|
-
class Circuit < BBB::Circuit
|
27
|
-
def initialize
|
28
|
-
# Attach temperature sensor to pin P9_40
|
29
|
-
attach BBB::Components::AnalogComponent, pin: :P9_40, as: :ldr
|
30
|
-
attach BBB::Components::Led, pin: :P8_10, as: :led
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
22
|
##
|
35
23
|
# Setup the actual Applicaiton
|
36
24
|
#
|
37
|
-
class
|
38
|
-
|
39
|
-
|
25
|
+
class LDRLightSwitch < BBB::Application
|
26
|
+
attr_accessor :threshold
|
27
|
+
|
28
|
+
attach AnalogComponent, as: :ldr
|
29
|
+
attach Led, as: :led
|
40
30
|
|
41
|
-
|
42
|
-
|
31
|
+
def initialize
|
32
|
+
threshold = 70
|
33
|
+
|
34
|
+
ldr.connect(:P9_40)
|
35
|
+
led.connect(:P8_10)
|
36
|
+
led.off!
|
37
|
+
end
|
43
38
|
|
44
39
|
# This is the basic run loop
|
45
40
|
def run
|
46
|
-
if ldr.read <
|
41
|
+
if ldr.read < threshold
|
47
42
|
led.on!
|
48
43
|
else
|
49
44
|
led.off!
|
@@ -52,5 +47,4 @@ class LightSwitch < BBB::Application
|
|
52
47
|
end
|
53
48
|
|
54
49
|
# Initialize the app
|
55
|
-
|
56
|
-
app.start
|
50
|
+
LDRLightSwitch.new.start if __FILE__ == $0
|
data/examples/light_switch.rb
CHANGED
@@ -1,51 +1,28 @@
|
|
1
1
|
require_relative '../lib/BBB'
|
2
2
|
|
3
3
|
class LightSwitch < BBB::Application
|
4
|
-
attach
|
5
|
-
attach
|
4
|
+
attach Led, as: :led
|
5
|
+
attach Button, as: :button
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
led.connect(:P8_10)
|
9
9
|
button.connect(:P8_19)
|
10
10
|
|
11
|
-
puts "Press the button to switch the light"
|
12
11
|
led.on!
|
13
|
-
read_button_state
|
14
|
-
end
|
15
|
-
|
16
|
-
def run
|
17
|
-
read_button_state
|
18
12
|
|
19
|
-
|
20
|
-
|
21
|
-
if led.on?
|
22
|
-
led.off!
|
23
|
-
else
|
24
|
-
led.on!
|
25
|
-
end
|
26
|
-
end
|
27
|
-
store_button_state
|
13
|
+
button.on_press do
|
14
|
+
led.toggle!
|
28
15
|
end
|
29
16
|
end
|
30
17
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@button_state = button.state
|
35
|
-
end
|
36
|
-
|
37
|
-
def current_button_state
|
38
|
-
@button_state
|
39
|
-
end
|
40
|
-
|
41
|
-
def last_button_state
|
42
|
-
@last_button_state
|
18
|
+
def start
|
19
|
+
puts "Press the button to switch the light"
|
20
|
+
super
|
43
21
|
end
|
44
22
|
|
45
|
-
def
|
46
|
-
|
23
|
+
def run
|
24
|
+
button.update
|
47
25
|
end
|
48
26
|
end
|
49
27
|
|
50
|
-
LightSwitch.new.start
|
51
|
-
|
28
|
+
LightSwitch.new.start if __FILE__==$0
|
@@ -3,14 +3,12 @@ require 'sinatra-websocket'
|
|
3
3
|
|
4
4
|
require 'BBB'
|
5
5
|
|
6
|
-
class
|
6
|
+
class NunchuckService < BBB::Application
|
7
|
+
attach Nunchuck, as: :nunchuck
|
8
|
+
|
7
9
|
def initialize
|
8
|
-
|
10
|
+
nunchuck.connect("/dev/i2c-2")
|
9
11
|
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class NunchuckService < BBB::Application
|
13
|
-
circuit Circuit.new
|
14
12
|
|
15
13
|
def start
|
16
14
|
Thread.new do
|
@@ -18,15 +16,17 @@ class NunchuckService < BBB::Application
|
|
18
16
|
nunchuck.update
|
19
17
|
end
|
20
18
|
end
|
21
|
-
self
|
19
|
+
return self
|
22
20
|
end
|
23
21
|
|
24
22
|
def add_socket(socket)
|
25
|
-
|
26
|
-
|
23
|
+
nunchuck.c.on_release do
|
24
|
+
socket.send("{c: 'released'}")
|
25
|
+
end
|
27
26
|
|
28
|
-
nunchuck.c.
|
29
|
-
|
27
|
+
nunchuck.c.on_press do
|
28
|
+
socket.send("{c: 'pressed'}")
|
29
|
+
end
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
@@ -34,7 +34,7 @@ end
|
|
34
34
|
class NunchuckServer < Sinatra::Base
|
35
35
|
set :server, 'thin'
|
36
36
|
set :sockets, []
|
37
|
-
set :nunchuck, NunchuckService.new
|
37
|
+
set :nunchuck, NunchuckService.new
|
38
38
|
enable :inline_templates
|
39
39
|
|
40
40
|
get '/' do
|
@@ -50,7 +50,7 @@ class NunchuckServer < Sinatra::Base
|
|
50
50
|
end
|
51
51
|
|
52
52
|
ws.onclose do
|
53
|
-
warn("
|
53
|
+
warn("websocket closed")
|
54
54
|
settings.sockets.delete(ws)
|
55
55
|
end
|
56
56
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'bbb'
|
2
|
+
|
3
|
+
##
|
4
|
+
# This is merely a design file. It doesn't work this way yet and functions
|
5
|
+
# merely as a way to sketch out how it should work
|
6
|
+
#
|
7
|
+
class Quadcopter < BBB::Application
|
8
|
+
|
9
|
+
##
|
10
|
+
# Load 4 ESCs, left-front (lf), right-front (rf), left-back (lb) and
|
11
|
+
# right-back(rb).
|
12
|
+
#
|
13
|
+
# We define them in clockwise order starting front-left, in order to have the
|
14
|
+
# array of escs constructed in a way that we can find them later on.
|
15
|
+
#
|
16
|
+
attach ESC, pins: [:P8_13, :P9_3], as: :esc_lf, group: :escs
|
17
|
+
attach ESC, pins: [:P9_14, :P9_2], as: :esc_rf, group: :escs
|
18
|
+
attach ESC, pins: [:P9_42, :P9_2], as: :esc_rb, group: :escs
|
19
|
+
attach ESC, pins: [:P9_21, :P9_2], as: :esc_lb, group: :escs
|
20
|
+
|
21
|
+
attach Led, pin: :P8_6, as: :power_indicator
|
22
|
+
|
23
|
+
##
|
24
|
+
# Connect the WMP with the nunchuck as extension
|
25
|
+
#
|
26
|
+
attach WMP, i2c: "BB-I2C1", as: :wmp, extension: "nunchuck"
|
27
|
+
|
28
|
+
attr_reader :stabilizer
|
29
|
+
|
30
|
+
def initialize
|
31
|
+
@stabilizer = Stabilizer.new(escs: escs,
|
32
|
+
gyro: gyro,
|
33
|
+
accelerometer: acc)
|
34
|
+
end
|
35
|
+
|
36
|
+
def gyro
|
37
|
+
wmp.gyro
|
38
|
+
end
|
39
|
+
|
40
|
+
def acc
|
41
|
+
#wmp.nunchuck.accelerometer
|
42
|
+
end
|
43
|
+
|
44
|
+
def fly_mode
|
45
|
+
stabilizer.mode
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Once start is called the run function will be called in a loop
|
50
|
+
#
|
51
|
+
def run
|
52
|
+
stabilizer.update
|
53
|
+
end
|
54
|
+
end # Copter
|
55
|
+
|
56
|
+
class Stabilizer
|
57
|
+
attr_reader :escs, :gyro, :accelerometer
|
58
|
+
attr_reader :mode
|
59
|
+
|
60
|
+
def initialize(opts={})
|
61
|
+
@escs = opts[:escs]
|
62
|
+
@gyro = opts[:gyro]
|
63
|
+
@accelerometer = opts[:accelerometer]
|
64
|
+
@mode = :hover
|
65
|
+
end
|
66
|
+
|
67
|
+
def hover
|
68
|
+
@mode = :hover
|
69
|
+
end
|
70
|
+
|
71
|
+
def update
|
72
|
+
# Do someting complex with all the components
|
73
|
+
# and update all values
|
74
|
+
end
|
75
|
+
end #Stabilizer
|
76
|
+
|
77
|
+
Quadcopter.new.start if __FILE__ == $0
|
data/examples/servo_ldr.rb
CHANGED
@@ -1,35 +1,125 @@
|
|
1
1
|
require 'BBB'
|
2
2
|
|
3
|
+
##
|
4
|
+
# An application where you mount an LDR to a servo. The servo will then turn
|
5
|
+
# towards the light. The idea for this application is that you, for example, use
|
6
|
+
# a servo to steer a small robot. When you then mount an LDR to the front of the
|
7
|
+
# robot, it will drive towards the light.
|
8
|
+
#
|
9
|
+
# The light finding algorithm could be much more sophisticaded, using several
|
10
|
+
# past measurements etc. etc. But you probably get the gist. Try for example to
|
11
|
+
# implement changes in the step_size over time.
|
12
|
+
#
|
13
|
+
#
|
3
14
|
class LDRServo < BBB::Application
|
4
|
-
attr_accessor :
|
15
|
+
attr_accessor :angle
|
16
|
+
attr_writer :previous_value
|
17
|
+
|
18
|
+
attr_reader :direction
|
5
19
|
|
6
20
|
attach Servo, as: :servo
|
7
21
|
attach AnalogComponent, as: :ldr
|
8
22
|
|
9
|
-
def initialize
|
10
|
-
@min = min
|
11
|
-
@max = max
|
12
|
-
end
|
13
|
-
|
14
|
-
def activate_components
|
23
|
+
def initialize
|
15
24
|
servo.connect(:P8_13)
|
16
25
|
ldr.connect(:P9_40)
|
17
26
|
end
|
18
27
|
|
19
28
|
def run
|
20
|
-
|
29
|
+
current_value = ldr.read
|
30
|
+
|
31
|
+
##
|
32
|
+
# This means we're moving away from the lightest point.
|
33
|
+
# So reverse.
|
34
|
+
#
|
35
|
+
if current_value < previous_value
|
36
|
+
reverse_direction
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# If the previous value is identical to the current_value we actually
|
41
|
+
# might've found the brightest spot, so keep on going where you're going.
|
42
|
+
# However, let's say the robot is in a dark room, and you turn on the lights
|
43
|
+
# above, and the whole room has equal light. If at that moment, the servo is
|
44
|
+
# positioned at an angle, it'll keep on making rounds.
|
45
|
+
#
|
46
|
+
# If you use this example to drive a robot, you're most probably driving at
|
47
|
+
# an angle, which means the value will change and the robot will start
|
48
|
+
# correcting itself. Reducing the angle, untill you're driving straigt to
|
49
|
+
# the light. (or at least a local optimum)
|
50
|
+
#
|
51
|
+
#require 'pry'; binding.pry
|
52
|
+
unless current_value == previous_value
|
53
|
+
self.angle = angle + (step * direction)
|
54
|
+
servo.angle(angle)
|
55
|
+
end
|
56
|
+
|
57
|
+
previous_value = current_value
|
58
|
+
|
59
|
+
return nil
|
21
60
|
end
|
22
61
|
|
23
|
-
|
24
|
-
|
62
|
+
|
63
|
+
##
|
64
|
+
# In this example we use a static step of 2 degrees. Which allows for smooth
|
65
|
+
# movement when making small adjustment, and still it's quite fast when having
|
66
|
+
# to make large adjustments.
|
67
|
+
#
|
68
|
+
# It could be interesting to play with the step size depending op previous
|
69
|
+
# measurements.
|
70
|
+
#
|
71
|
+
def step
|
72
|
+
2
|
25
73
|
end
|
26
74
|
|
75
|
+
##
|
76
|
+
# Basic servo's can move about 120 degrees. So we'll initialize the angle to
|
77
|
+
# 60 degrees. Which is probably straight ahead on a moving robot.
|
78
|
+
#
|
27
79
|
def angle
|
28
|
-
|
80
|
+
@angle ||= 60
|
29
81
|
end
|
30
82
|
|
31
|
-
|
83
|
+
##
|
84
|
+
# Make sure the angle doesn't go out of the servo range. If it does, set it to
|
85
|
+
# the minimum (0) or the maximum (120)
|
86
|
+
#
|
87
|
+
def angle=(value)
|
88
|
+
if(0..120).include?(value)
|
89
|
+
@angle = value
|
90
|
+
else
|
91
|
+
@angle = value > 0 ? max_servo_angle : min_servo_angle
|
92
|
+
end
|
93
|
+
end
|
32
94
|
|
33
|
-
|
34
|
-
|
95
|
+
##
|
96
|
+
# We define 1 as going to the right, and -1 as going to the left.
|
97
|
+
# Combined with a positive step this means that if the direction is 1, we're
|
98
|
+
# moving more towards the right, and -1 we're moving more towards the left.
|
99
|
+
#
|
100
|
+
# (you can also read up/ down here instead of left / right, it all depends on
|
101
|
+
# the way you mount your servo)
|
102
|
+
#
|
103
|
+
def direction
|
104
|
+
@direction ||= 1
|
105
|
+
end
|
106
|
+
|
107
|
+
def reverse_direction
|
108
|
+
@direction = direction * -1
|
109
|
+
end
|
110
|
+
|
111
|
+
def previous_value
|
112
|
+
@previous_value ||= ldr.read
|
113
|
+
end
|
114
|
+
|
115
|
+
def min_servo_angle
|
116
|
+
@min_servo_angle ||= 0
|
117
|
+
end
|
118
|
+
|
119
|
+
def max_servo_angle
|
120
|
+
@max_servo_angle ||= 120
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
35
124
|
|
125
|
+
LDRServo.new.start if __FILE__ == $0
|