BBB 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|