BBB 0.0.10 → 0.1.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.
- data/lib/BBB.rb +13 -17
- data/lib/BBB/application.rb +4 -21
- data/lib/BBB/circuit.rb +18 -33
- data/lib/BBB/components/analog_component.rb +29 -6
- data/lib/BBB/components/led.rb +39 -9
- data/lib/BBB/components/pinnable.rb +90 -4
- data/lib/BBB/components/servo.rb +43 -0
- data/lib/BBB/pins/analog_pin.rb +39 -0
- data/lib/BBB/pins/digital_pin.rb +106 -0
- data/lib/BBB/pins/io/ain.rb +58 -0
- data/lib/BBB/pins/io/gpio.rb +77 -0
- data/lib/BBB/pins/io/mapped.rb +39 -0
- data/lib/BBB/pins/io/pin_mapper.rb +224 -0
- data/lib/BBB/pins/io/pwm.rb +61 -0
- data/lib/BBB/pins/pinnable.rb +78 -0
- data/lib/BBB/pins/pwm_pin.rb +43 -0
- data/lib/BBB/version.rb +1 -1
- data/spec/application_spec.rb +1 -26
- data/spec/circuit_spec.rb +0 -1
- data/spec/components/analog_component_spec.rb +36 -0
- data/spec/components/led_spec.rb +14 -19
- data/spec/components/pinnable_spec.rb +73 -8
- data/spec/components/servo_spec.rb +6 -0
- data/spec/pins/analog_pin_spec.rb +33 -0
- data/spec/pins/digital_input_pin_spec.rb +13 -0
- data/spec/pins/digital_output_pin_spec.rb +14 -0
- data/spec/pins/digital_pin_spec.rb +66 -0
- data/spec/pins/io/mapped_spec.rb +41 -0
- data/spec/{board → pins/io}/pin_mapper_spec.rb +2 -2
- data/spec/pins/pinnable_spec.rb +68 -0
- data/spec/pins/pwm_pin_spec.rb +29 -0
- metadata +34 -37
- data/lib/BBB/adc/analog_pin.rb +0 -42
- data/lib/BBB/adc/setup.rb +0 -20
- data/lib/BBB/board/base.rb +0 -45
- data/lib/BBB/board/json_pin_mapper.rb +0 -203
- data/lib/BBB/board/pin_mapper.rb +0 -20
- data/lib/BBB/board/test_board.rb +0 -12
- data/lib/BBB/gpio/base.rb +0 -56
- data/lib/BBB/gpio/digital_pin.rb +0 -69
- data/lib/BBB/gpio/pin_converter.rb +0 -28
- data/lib/BBB/io/analog_pin.rb +0 -24
- data/lib/BBB/io/digital_pin.rb +0 -67
- data/lib/BBB/io/mock_pin.rb +0 -8
- data/lib/BBB/io/pinnable.rb +0 -12
- data/spec/adc/analog_pin_spec.rb +0 -100
- data/spec/adc/setup_spec.rb +0 -9
- data/spec/board/board_spec.rb +0 -49
- data/spec/gpio/base_spec.rb +0 -48
- data/spec/gpio/digital_pin_spec.rb +0 -100
- data/spec/gpio/pin_converter_spec.rb +0 -19
- data/spec/io/digital_pin_spec.rb +0 -14
- data/spec/io/mock_pin_spec.rb +0 -13
- data/spec/io/pinnable_spec.rb +0 -13
data/lib/BBB.rb
CHANGED
@@ -1,30 +1,26 @@
|
|
1
|
-
require "BBB/version"
|
2
|
-
|
3
1
|
require "json"
|
2
|
+
require "stringio"
|
4
3
|
|
5
|
-
require "BBB/
|
6
|
-
require "BBB/board/test_board"
|
7
|
-
require "BBB/board/json_pin_mapper"
|
8
|
-
require "BBB/board/pin_mapper"
|
4
|
+
require "BBB/version"
|
9
5
|
|
10
6
|
require "BBB/circuit"
|
11
7
|
require "BBB/exceptions"
|
12
8
|
|
13
|
-
require "BBB/
|
14
|
-
require "BBB/
|
15
|
-
require "BBB/
|
9
|
+
require "BBB/pins/io/pin_mapper"
|
10
|
+
require "BBB/pins/io/mapped"
|
11
|
+
require "BBB/pins/io/ain"
|
12
|
+
require "BBB/pins/io/gpio"
|
13
|
+
require "BBB/pins/io/pwm"
|
16
14
|
|
17
|
-
require "BBB/
|
18
|
-
require "BBB/
|
19
|
-
|
20
|
-
require "BBB/
|
21
|
-
require "BBB/io/digital_pin"
|
22
|
-
require "BBB/io/analog_pin"
|
23
|
-
require "BBB/io/mock_pin"
|
15
|
+
require "BBB/pins/pinnable"
|
16
|
+
require "BBB/pins/digital_pin"
|
17
|
+
require "BBB/pins/analog_pin"
|
18
|
+
require "BBB/pins/pwm_pin"
|
24
19
|
|
25
20
|
require "BBB/components/pinnable"
|
26
|
-
require "BBB/components/led"
|
27
21
|
require "BBB/components/analog_component"
|
22
|
+
require "BBB/components/led"
|
23
|
+
require "BBB/components/servo"
|
28
24
|
|
29
25
|
require "BBB/application"
|
30
26
|
|
data/lib/BBB/application.rb
CHANGED
@@ -1,42 +1,25 @@
|
|
1
1
|
module BBB
|
2
2
|
class Application
|
3
3
|
|
4
|
-
def self.board(board)
|
5
|
-
@_board = board
|
6
|
-
connect unless @_circuit.nil?
|
7
|
-
end
|
8
|
-
|
9
4
|
def self.circuit(circuit)
|
10
5
|
@_circuit = circuit
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
def self._board
|
15
|
-
@_board
|
6
|
+
define_convenience_methods(circuit)
|
16
7
|
end
|
17
8
|
|
18
9
|
def self._circuit
|
19
10
|
@_circuit
|
20
11
|
end
|
21
12
|
|
22
|
-
def self.
|
23
|
-
|
24
|
-
component.pins.each do |pin|
|
25
|
-
@_board.connect_io_pin(pin)
|
26
|
-
end
|
27
|
-
|
13
|
+
def self.define_convenience_methods(c)
|
14
|
+
c.components.keys.each do |name|
|
28
15
|
define_method(name) do
|
29
16
|
circuit.send(name)
|
30
17
|
end
|
31
18
|
end
|
32
19
|
end
|
33
20
|
|
34
|
-
def board
|
35
|
-
@board ||= self.class._board
|
36
|
-
end
|
37
|
-
|
38
21
|
def circuit
|
39
|
-
|
22
|
+
self.class._circuit
|
40
23
|
end
|
41
24
|
|
42
25
|
def start
|
data/lib/BBB/circuit.rb
CHANGED
@@ -1,56 +1,49 @@
|
|
1
1
|
module BBB
|
2
2
|
##
|
3
|
-
# The idea here is to attach a piece of equipment to a circuit.
|
4
|
-
# will later be connected to a board.
|
3
|
+
# The idea here is to attach a piece of equipment to a circuit.
|
5
4
|
#
|
6
5
|
# A component (e.g. Led or Servo) will define generic pins, like
|
7
|
-
# DigitalInput or AnalogOutput. And then, when the
|
8
|
-
# the
|
9
|
-
# on the board.
|
10
|
-
#
|
11
|
-
# This allows you to develop generic circuits that can be attached to any
|
12
|
-
# board. At least, in theory :-)
|
6
|
+
# DigitalInput or AnalogOutput. And then, when the component gets attached to
|
7
|
+
# the circuit those pins will be initialized using the file system.
|
13
8
|
#
|
14
9
|
# For now the attachment will be made onto specific pin numbers. For the BBB
|
15
10
|
# this might for example be :P8_3, however, the plan is to, in a future
|
16
11
|
# release, make sure that there are converters between the different kind of
|
17
12
|
# boards. For example by mapping P8_3 on BBB to P1 on an Arduino.
|
18
13
|
#
|
19
|
-
# As of now, the act of "attaching" something onto the circuit equals
|
20
|
-
# setting up a component with generic pins.
|
21
|
-
#
|
22
14
|
class Circuit
|
23
|
-
attr_reader :components
|
15
|
+
attr_reader :components, :mock
|
24
16
|
|
25
17
|
def components
|
26
18
|
@components ||= {}
|
27
19
|
end
|
28
20
|
|
21
|
+
def mock?
|
22
|
+
@mock == true
|
23
|
+
end
|
24
|
+
|
29
25
|
##
|
30
26
|
# Attach a component of a certain type to the circuit
|
31
27
|
#
|
32
28
|
# @param component [Class] The class of the object you # want to attach.
|
33
29
|
# @param opts [Hash] Hash of options that setup the component
|
34
30
|
#
|
31
|
+
# @option opts [Symbol] :pin The pin position for the component
|
35
32
|
# @option opts [Array<Symbol>] :pins The list of pin numbers used on the
|
36
|
-
#
|
33
|
+
# circuit.
|
34
|
+
# @options opts [Symbol] :as The name of the component
|
37
35
|
#
|
38
36
|
def attach(component, opts={})
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
name = opts.delete(:as)
|
38
|
+
component = component.new if component.kind_of?(Class)
|
39
|
+
pin_positions = opts.delete(:pins) || [opts.delete(:pin)]
|
40
|
+
pin_options = {:mock=>self.mock?}.merge!(opts)
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
verify_pin_argument_count(component_pins.count, pin_positions.count)
|
46
|
-
component.register_pin_positions(pin_positions)
|
47
|
-
end
|
48
|
-
|
49
|
-
name = opts.fetch(:as)
|
50
|
-
register_component(component, name)
|
42
|
+
component.initialize_pins(pin_positions, pin_options)
|
43
|
+
define_method_for_component(component, name)
|
51
44
|
end
|
52
45
|
|
53
|
-
def
|
46
|
+
def define_method_for_component(component, name)
|
54
47
|
components[name] = component
|
55
48
|
eigenclass = class << self; self; end
|
56
49
|
eigenclass.class_eval do
|
@@ -60,13 +53,5 @@ module BBB
|
|
60
53
|
end
|
61
54
|
end
|
62
55
|
|
63
|
-
def verify_pin_argument_count(type_count, position_count)
|
64
|
-
if type_count != position_count
|
65
|
-
raise PinsDoNotMatchException,
|
66
|
-
"#{object.to_s} requires #{types_count} but received #{position_count} pin arguments."
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
56
|
end
|
72
57
|
end
|
@@ -1,22 +1,45 @@
|
|
1
1
|
module BBB
|
2
2
|
module Components
|
3
|
+
##
|
4
|
+
# An AnalogComponent is a component that reads from an analog input (AIN) on
|
5
|
+
# the board. You can use a generic analog component for, for example,
|
6
|
+
# temperature or light sensors.
|
7
|
+
#
|
8
|
+
# The BeagleBoneBlack has 12 bit (4096) AIN pins. So the expected value of
|
9
|
+
# an analog pin is between 0 and 4096.
|
10
|
+
#
|
3
11
|
class AnalogComponent
|
4
12
|
include Pinnable
|
5
13
|
|
6
|
-
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@pin = BBB::IO::AnalogPin.new
|
10
|
-
@pins = [@pin]
|
11
|
-
end
|
14
|
+
uses BBB::Pins::AnalogPin
|
12
15
|
|
16
|
+
##
|
17
|
+
# Read from an initialized pin, if the pins have not been initialized yet,
|
18
|
+
# this method might actually raise an exception.
|
19
|
+
#
|
20
|
+
# @raise MethodNotFoundException
|
21
|
+
#
|
22
|
+
# @return Integer
|
23
|
+
#
|
13
24
|
def read
|
14
25
|
pin.read
|
15
26
|
end
|
16
27
|
|
28
|
+
##
|
29
|
+
# @see #read
|
30
|
+
#
|
17
31
|
def value
|
18
32
|
read
|
19
33
|
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Convenience method to grab the first pin in the pins array
|
37
|
+
#
|
38
|
+
# @return BBB::Pins::AnalogPin
|
39
|
+
#
|
40
|
+
def pin
|
41
|
+
pins.first
|
42
|
+
end
|
20
43
|
end
|
21
44
|
end
|
22
45
|
end
|
data/lib/BBB/components/led.rb
CHANGED
@@ -1,31 +1,61 @@
|
|
1
1
|
module BBB
|
2
2
|
module Components
|
3
|
+
##
|
4
|
+
# The LED class is the component interface into a digital pin. In a way it's
|
5
|
+
# nothing more than a straight forward port of a digital pin. You can use a
|
6
|
+
# led component when you want to use digital pins, or simply define your own
|
7
|
+
# class and extend it from the LED.
|
8
|
+
#
|
9
|
+
# The Led class does not perform any sort of caching or smart calls, it
|
10
|
+
# forwards everything to the pin. In your own applications you might want to
|
11
|
+
# tune this behavior by adding some kind of caching.
|
12
|
+
#
|
3
13
|
class Led
|
4
14
|
include Pinnable
|
5
|
-
attr_reader :state, :pin
|
6
15
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
16
|
+
uses BBB::Pins::DigitalOutputPin
|
17
|
+
|
18
|
+
##
|
19
|
+
# Convenience method to grab the first pin in the pins array
|
20
|
+
#
|
21
|
+
# @return BBB::Pins::DigitalOutputPin
|
22
|
+
#
|
23
|
+
def pin
|
24
|
+
pins.first
|
11
25
|
end
|
12
26
|
|
27
|
+
##
|
28
|
+
# Turns on the LED
|
29
|
+
# @return void
|
30
|
+
#
|
13
31
|
def on!
|
14
32
|
pin.on!
|
15
|
-
@state = :high
|
16
33
|
end
|
17
34
|
|
35
|
+
##
|
36
|
+
# Turns off the LED
|
37
|
+
# @return void
|
38
|
+
#
|
18
39
|
def off!
|
19
40
|
pin.off!
|
20
|
-
@state = :low
|
21
41
|
end
|
22
42
|
|
43
|
+
##
|
44
|
+
# Checks if the LED is turned on.
|
45
|
+
#
|
46
|
+
# @return Boolean
|
47
|
+
#
|
23
48
|
def on?
|
24
|
-
|
49
|
+
pin.on?
|
25
50
|
end
|
26
51
|
|
52
|
+
##
|
53
|
+
# Checks if the LED is turned off.
|
54
|
+
#
|
55
|
+
# @return Boolean
|
56
|
+
#
|
27
57
|
def off?
|
28
|
-
|
58
|
+
pin.off?
|
29
59
|
end
|
30
60
|
|
31
61
|
end
|
@@ -3,13 +3,99 @@ module BBB
|
|
3
3
|
module Pinnable
|
4
4
|
attr_reader :pins
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
pins.
|
9
|
-
|
6
|
+
module ClassMethods
|
7
|
+
##
|
8
|
+
# Register the use of classes of pins to a class. These classes will be
|
9
|
+
# initialized upon #initialize_pins
|
10
|
+
#
|
11
|
+
# @param pin_classes [Array<Class>] the classes to register on class
|
12
|
+
# level.
|
13
|
+
#
|
14
|
+
def uses(*pin_classes)
|
15
|
+
pins.concat(pin_classes)
|
10
16
|
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Attribute reader to the class level @pins
|
20
|
+
#
|
21
|
+
# @return Array<Class>
|
22
|
+
#
|
23
|
+
def pins
|
24
|
+
@pins ||= []
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.included(base)
|
29
|
+
base.extend(ClassMethods)
|
11
30
|
end
|
12
31
|
|
32
|
+
##
|
33
|
+
# Initialize the pin classes with their positions and options. Turning
|
34
|
+
# them from their Classes into working pin instances.
|
35
|
+
#
|
36
|
+
# The argument list of the methods is a bit odd. Since it's not
|
37
|
+
# possible to have both a splat and an option array as arguments, the
|
38
|
+
# method signature only shows a splat of positions. The options are then
|
39
|
+
# taken out of the positions, if the last position is actually a Hash as
|
40
|
+
# opposed to a Symbol. If the last element of the positions list is not
|
41
|
+
# a Hash, the options are set to an empty hash.
|
42
|
+
#
|
43
|
+
# @param positions [Array<Symbol>] positions the pins should be
|
44
|
+
# initialized with.
|
45
|
+
# @param opts [Hash] Options to pass along to the pins during
|
46
|
+
# initialization.
|
47
|
+
#
|
48
|
+
# @return Array[Pins]
|
49
|
+
#
|
50
|
+
def initialize_pins(*positions)
|
51
|
+
opts = positions.last.kind_of?(Hash) ? positions.pop : {}
|
52
|
+
|
53
|
+
verify_pin_position_count(positions)
|
54
|
+
|
55
|
+
@pins = []
|
56
|
+
self.class.pins.each_with_index do |pin, index|
|
57
|
+
@pins << pin.new(positions[index], opts)
|
58
|
+
end
|
59
|
+
after_pin_initialization
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Verifies if the number of pins registered in the @pins array match with
|
64
|
+
# the number of pins provided as an argument to the method. This function
|
65
|
+
# normally gets called as part of the initialize pins method to verify if
|
66
|
+
# the positions given to the initialize_pins method matches the number of
|
67
|
+
# registered pins.
|
68
|
+
#
|
69
|
+
# @param positions [Array<Symbol>] The array of positions
|
70
|
+
#
|
71
|
+
# @raise [PinsDoNotMatchException] If the pin counts between the positions
|
72
|
+
# provided as an argument and the pins in the pins array do not match,
|
73
|
+
# this exception gets raised, to prevent hard to debug situations later
|
74
|
+
# on in the lifecycle of an application.
|
75
|
+
#
|
76
|
+
# @return Void
|
77
|
+
def verify_pin_position_count(positions)
|
78
|
+
if self.class.pins.count != positions.count
|
79
|
+
raise PinsDoNotMatchException,
|
80
|
+
"#{self.class.to_s} requires #{self.class.pins.count} but received #{positions.count} pin position."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Method which classes can overwrite to hook into the after pin
|
86
|
+
# initialization
|
87
|
+
#
|
88
|
+
def after_pin_initialization
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Method that is used in the test suite to test if the pinnable module is
|
93
|
+
# included in an object
|
94
|
+
#
|
95
|
+
# @return true
|
96
|
+
def pinnable?
|
97
|
+
true
|
98
|
+
end
|
13
99
|
end
|
14
100
|
end
|
15
101
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module BBB
|
2
|
+
module Components
|
3
|
+
class Servo
|
4
|
+
include Pinnable
|
5
|
+
#uses Pins::PWMPin
|
6
|
+
attr_reader :min_duty, :max_duty, :period
|
7
|
+
|
8
|
+
def initialize(period=17e6, min_duty=14.6e6, max_duty=16.6e6)
|
9
|
+
@period = period
|
10
|
+
@min_duty = min_duty
|
11
|
+
@max_duty = max_duty
|
12
|
+
end
|
13
|
+
|
14
|
+
def after_pin_initialization
|
15
|
+
pin.period = 17e6
|
16
|
+
pin.duty = (min_duty + duty_range / 2)
|
17
|
+
pin.run = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def angle(degrees)
|
21
|
+
value = degrees / 180.to_f * duty_range + min_duty
|
22
|
+
pin.duty = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def activate!
|
26
|
+
pin.run = 1
|
27
|
+
end
|
28
|
+
|
29
|
+
def deactivate!
|
30
|
+
pin.run = 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def pin
|
34
|
+
pins.first
|
35
|
+
end
|
36
|
+
|
37
|
+
def duty_range
|
38
|
+
max_duty - min_duty
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|