BBB 0.0.1 → 0.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +7 -0
- data/Gemfile +5 -0
- data/README.md +31 -0
- data/Rakefile +4 -0
- data/examples/led.rb +34 -0
- data/examples/sketches.rb +86 -0
- data/lib/BBB.rb +18 -1
- data/lib/BBB/application.rb +44 -0
- data/lib/BBB/board.rb +41 -0
- data/lib/BBB/circuit.rb +72 -0
- data/lib/BBB/components/led.rb +33 -0
- data/lib/BBB/components/pinnable.rb +15 -0
- data/lib/BBB/exceptions.rb +5 -0
- data/lib/BBB/gpio/base.rb +56 -0
- data/lib/BBB/gpio/digital_pin.rb +69 -0
- data/lib/BBB/gpio/pin_converter.rb +22 -0
- data/lib/BBB/io/digital_pin.rb +67 -0
- data/lib/BBB/io/mock_pin.rb +8 -0
- data/lib/BBB/io/pinnable.rb +12 -0
- data/lib/BBB/pin_mapper.rb +84 -0
- data/lib/BBB/test_board.rb +11 -0
- data/lib/BBB/version.rb +1 -1
- data/spec/application_spec.rb +53 -0
- data/spec/board_spec.rb +49 -0
- data/spec/circuit_spec.rb +47 -0
- data/spec/components/led_spec.rb +45 -0
- data/spec/components/pinnable_spec.rb +19 -0
- data/spec/gpio/base_spec.rb +48 -0
- data/spec/gpio/digital_pin_spec.rb +100 -0
- data/spec/gpio/pin_converter_spec.rb +19 -0
- data/spec/io/digital_pin_spec.rb +14 -0
- data/spec/io/mock_pin_spec.rb +13 -0
- data/spec/io/pinnable_spec.rb +13 -0
- data/spec/pin_mapper_spec.rb +17 -0
- data/spec/spec_helper.rb +4 -0
- metadata +46 -4
- data/LICENSE.txt +0 -22
@@ -0,0 +1,56 @@
|
|
1
|
+
module BBB
|
2
|
+
module GPIO
|
3
|
+
class Base
|
4
|
+
attr_reader :position, :converted_position
|
5
|
+
attr_reader :file_class
|
6
|
+
|
7
|
+
def initialize(position=nil, opts={})
|
8
|
+
initialize_base(position, opts)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_base(pin_position, opts)
|
12
|
+
@mock = opts.fetch(:mock, false)
|
13
|
+
self.position = pin_position
|
14
|
+
@file_class = @mock ? StringIO : File
|
15
|
+
export
|
16
|
+
end
|
17
|
+
|
18
|
+
def position=(position, mock=false)
|
19
|
+
@position = position
|
20
|
+
@converted_position = PinMapper.map(position)
|
21
|
+
end
|
22
|
+
|
23
|
+
def gpio_path
|
24
|
+
"/sys/class/gpio"
|
25
|
+
end
|
26
|
+
|
27
|
+
def export_path
|
28
|
+
gpio_path + "/export"
|
29
|
+
end
|
30
|
+
|
31
|
+
def unexport_path
|
32
|
+
gpio_path + "/unexport"
|
33
|
+
end
|
34
|
+
|
35
|
+
def gpio_direction_input
|
36
|
+
"in"
|
37
|
+
end
|
38
|
+
|
39
|
+
def gpio_direction_output
|
40
|
+
"out"
|
41
|
+
end
|
42
|
+
|
43
|
+
def gpio_pin_dir
|
44
|
+
"#{gpio_path}/gpio#{converted_position}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def export
|
48
|
+
file_class.open(export_path, "w") { |f| f.write("#{ converted_position }") }
|
49
|
+
end
|
50
|
+
|
51
|
+
def unexport
|
52
|
+
file_class.open(unexport_path, "w") { |f| f.write("#{converted_position}") }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module BBB
|
2
|
+
module GPIO
|
3
|
+
class DigitalPin < Base
|
4
|
+
attr_reader :mode, :io
|
5
|
+
|
6
|
+
def initialize(position, mode, opts={})
|
7
|
+
initialize_base(position, opts)
|
8
|
+
@mode = validate_mode(mode)
|
9
|
+
set_mode
|
10
|
+
end
|
11
|
+
|
12
|
+
def direction
|
13
|
+
case mode
|
14
|
+
when :input
|
15
|
+
gpio_direction_input
|
16
|
+
when :output
|
17
|
+
gpio_direction_output
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def file_mode
|
22
|
+
case mode
|
23
|
+
when :input
|
24
|
+
"r"
|
25
|
+
when :output
|
26
|
+
"w+"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_mode
|
31
|
+
direction_file = gpio_pin_dir + "/direction"
|
32
|
+
file_class.open(direction_file, "w") {|f| f.write(direction); f.flush}
|
33
|
+
end
|
34
|
+
|
35
|
+
def io
|
36
|
+
return @io unless @io.nil?
|
37
|
+
|
38
|
+
value_file = gpio_pin_dir + "/value"
|
39
|
+
@io = file_class.open(value_file, file_mode)
|
40
|
+
end
|
41
|
+
|
42
|
+
def write(value)
|
43
|
+
io.rewind
|
44
|
+
io.write value_map[value]
|
45
|
+
io.flush
|
46
|
+
end
|
47
|
+
|
48
|
+
def read
|
49
|
+
io.rewind
|
50
|
+
value_map[io.read]
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def validate_mode(mode)
|
56
|
+
if [:input, :output].include?(mode)
|
57
|
+
return mode
|
58
|
+
else
|
59
|
+
raise UnknownPinModeException, "Pin mode: #{mode} is now known"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def value_map
|
64
|
+
@value_map ||= {:high=>1, :low=>0, 1=>:high, 0=>:low}
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module BBB
|
2
|
+
module GPIO
|
3
|
+
class PinConverter
|
4
|
+
attr_reader :mock
|
5
|
+
|
6
|
+
def initialize(opts={})
|
7
|
+
@mock = opts.fetch(:mock, false)
|
8
|
+
end
|
9
|
+
|
10
|
+
##
|
11
|
+
# Currently only converts IO::DigitalPins
|
12
|
+
#
|
13
|
+
def convert(pin, opts={})
|
14
|
+
base_class = pin.class.to_s.split("::").last
|
15
|
+
klass = GPIO::const_get(base_class.to_sym)
|
16
|
+
opts = {:mock=>mock}.merge(opts)
|
17
|
+
return klass.new(pin.position, pin.mode, opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module BBB
|
2
|
+
module IO
|
3
|
+
##
|
4
|
+
# Credit goes to the great work done at the Artoo framework
|
5
|
+
# The original idea for this class came from them.
|
6
|
+
# https://github.com/hybridgroup/artoo/blob/master/lib/artoo/adaptors/io/digital_pin.rb
|
7
|
+
#
|
8
|
+
class DigitalPin
|
9
|
+
include Pinnable
|
10
|
+
attr_reader :mode, :status
|
11
|
+
attr_accessor :pin_io
|
12
|
+
|
13
|
+
##
|
14
|
+
# Digital pin which is abstracted away from any kind of IO.
|
15
|
+
# This has the benefit of being able to write a generic application
|
16
|
+
# that you can then easily port to a BBB, Pi or Arduino
|
17
|
+
#
|
18
|
+
# @param pin_num [Symbol]
|
19
|
+
# @param mode [Symbol, nil] the mode of the pin, :input or :output. Defaults
|
20
|
+
# to :input
|
21
|
+
# @pin_io [IO, nil] the IO object
|
22
|
+
#
|
23
|
+
def initialize(mode=:input, pin_io=nil, position=nil)
|
24
|
+
@pin_io = pin_io || MockPin.new
|
25
|
+
@mode = mode
|
26
|
+
@position = position
|
27
|
+
end
|
28
|
+
|
29
|
+
# Writes to the specified pin Digitally
|
30
|
+
# accepts values :high or :low
|
31
|
+
def write(value)
|
32
|
+
raise ArgumentError unless [:high, :low].include?(value)
|
33
|
+
@status = value
|
34
|
+
@pin_io.write(value)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Reads digitally from the specified pin on initialize
|
38
|
+
def read
|
39
|
+
if mode == :input
|
40
|
+
pin_io.read
|
41
|
+
else
|
42
|
+
status
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Sets digital write for the pin to HIGH
|
47
|
+
def on!
|
48
|
+
write(:high)
|
49
|
+
end
|
50
|
+
#
|
51
|
+
# Sets digital write for the pin to LOW
|
52
|
+
#
|
53
|
+
def off!
|
54
|
+
write(:low)
|
55
|
+
end
|
56
|
+
|
57
|
+
def on?
|
58
|
+
(status == :high) ? true : false
|
59
|
+
end
|
60
|
+
|
61
|
+
def off?
|
62
|
+
!self.on?
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module BBB
|
2
|
+
class PinMapper
|
3
|
+
##
|
4
|
+
# Thanks to artoo-beaglebone
|
5
|
+
# https://github.com/hybridgroup/artoo-beaglebone/blob/master/lib/artoo/adaptors/beaglebone.rb
|
6
|
+
#
|
7
|
+
PINS = {
|
8
|
+
:P8_3 => 38,
|
9
|
+
:P8_4 => 39,
|
10
|
+
:P8_5 => 34,
|
11
|
+
:P8_6 => 35,
|
12
|
+
:P8_7 => 66,
|
13
|
+
:P8_8 => 67,
|
14
|
+
:P8_9 => 69,
|
15
|
+
:P8_10 => 68,
|
16
|
+
:P8_11 => 45,
|
17
|
+
:P8_12 => 44,
|
18
|
+
:P8_13 => 23,
|
19
|
+
:P8_14 => 26,
|
20
|
+
:P8_15 => 47,
|
21
|
+
:P8_16 => 46,
|
22
|
+
:P8_17 => 27,
|
23
|
+
:P8_18 => 65,
|
24
|
+
:P8_19 => 22,
|
25
|
+
:P8_20 => 63,
|
26
|
+
:P8_21 => 62,
|
27
|
+
:P8_22 => 37,
|
28
|
+
:P8_23 => 36,
|
29
|
+
:P8_24 => 33,
|
30
|
+
:P8_25 => 32,
|
31
|
+
:P8_26 => 61,
|
32
|
+
:P8_27 => 86,
|
33
|
+
:P8_28 => 88,
|
34
|
+
:P8_29 => 87,
|
35
|
+
:P8_30 => 89,
|
36
|
+
:P8_31 => 10,
|
37
|
+
:P8_32 => 11,
|
38
|
+
:P8_33 => 9,
|
39
|
+
:P8_34 => 81,
|
40
|
+
:P8_35 => 8,
|
41
|
+
:P8_36 => 80,
|
42
|
+
:P8_37 => 78,
|
43
|
+
:P8_38 => 79,
|
44
|
+
:P8_39 => 76,
|
45
|
+
:P8_40 => 77,
|
46
|
+
:P8_41 => 74,
|
47
|
+
:P8_42 => 75,
|
48
|
+
:P8_43 => 72,
|
49
|
+
:P8_44 => 73,
|
50
|
+
:P8_45 => 70,
|
51
|
+
:P8_46 => 71,
|
52
|
+
:P9_11 => 30,
|
53
|
+
:P9_12 => 60,
|
54
|
+
:P9_13 => 31,
|
55
|
+
:P9_14 => 50,
|
56
|
+
:P9_15 => 48,
|
57
|
+
:P9_16 => 51,
|
58
|
+
:P9_17 => 5,
|
59
|
+
:P9_18 => 4,
|
60
|
+
:P9_19 => 13,
|
61
|
+
:P9_20 => 12,
|
62
|
+
:P9_21 => 3,
|
63
|
+
:P9_22 => 2,
|
64
|
+
:P9_23 => 49,
|
65
|
+
:P9_24 => 15,
|
66
|
+
:P9_25 => 117,
|
67
|
+
:P9_26 => 14,
|
68
|
+
:P9_27 => 115,
|
69
|
+
:P9_28 => 113,
|
70
|
+
:P9_29 => 111,
|
71
|
+
:P9_30 => 112,
|
72
|
+
:P9_31 => 110
|
73
|
+
}
|
74
|
+
attr_reader :pins
|
75
|
+
|
76
|
+
def self.map(pin_symbol)
|
77
|
+
begin
|
78
|
+
PINS.fetch(pin_symbol.upcase.to_sym)
|
79
|
+
rescue Exception => e
|
80
|
+
raise UnknownPinException, "Pin #{pin_symbol} could not be mapped"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/BBB/version.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBB::Application do
|
4
|
+
|
5
|
+
it "initializes" do
|
6
|
+
lambda { BBB::Application.new }.should_not raise_exception
|
7
|
+
end
|
8
|
+
|
9
|
+
class MockCircuit
|
10
|
+
def components; {}; end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestBoardApp < BBB::Application
|
14
|
+
board "board"
|
15
|
+
circuit MockCircuit.new
|
16
|
+
end
|
17
|
+
|
18
|
+
it "defaults board to class variable board" do
|
19
|
+
TestBoardApp.instance_variable_get('@_board').should eql("board")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "sets the board as an instance variable" do
|
23
|
+
app = TestBoardApp.new
|
24
|
+
app.board.should eql("board")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "sets a circuit" do
|
28
|
+
app = TestBoardApp.new
|
29
|
+
app.circuit.class.should eql(MockCircuit)
|
30
|
+
end
|
31
|
+
|
32
|
+
class TestLedCircuit < BBB::Circuit
|
33
|
+
def initialize
|
34
|
+
attach BBB::Components::Led, pin: :P8_3, as: :led
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class TestConnectionApp < BBB::Application
|
39
|
+
board BBB::TestBoard.new
|
40
|
+
circuit TestLedCircuit.new
|
41
|
+
end
|
42
|
+
|
43
|
+
it "attaches virtual pins to board pins" do
|
44
|
+
app = TestConnectionApp.new
|
45
|
+
|
46
|
+
app.circuit.respond_to?(:led).should be_true
|
47
|
+
app.circuit.led.should_receive(:on!)
|
48
|
+
app.led.should eql(app.circuit.led)
|
49
|
+
|
50
|
+
app.led.on!
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/spec/board_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BBB::Board do
|
4
|
+
let(:bbb) {BBB::TestBoard.new}
|
5
|
+
|
6
|
+
it "initializes with a converter" do
|
7
|
+
BBB::Board.should_not_receive(:pin_converter)
|
8
|
+
converter = "SomeConverter"
|
9
|
+
board = BBB::Board.new(converter)
|
10
|
+
board.pin_converter.should eql(converter)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "initializes with a default configuration" do
|
14
|
+
BBB::Board.should_receive(:pin_converter) { 'Default Config' }
|
15
|
+
board = BBB::Board.new
|
16
|
+
end
|
17
|
+
|
18
|
+
context "setting pins" do
|
19
|
+
Pin = BBB::IO::DigitalPin
|
20
|
+
|
21
|
+
it "defines input function for input pin" do
|
22
|
+
pin = Pin.new(:input, nil, :P8_3)
|
23
|
+
bbb.setup_pin(pin)
|
24
|
+
bbb.respond_to?("p8_3").should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "defines output function for input pin" do
|
28
|
+
pin = Pin.new(:output, nil, :P8_3)
|
29
|
+
bbb.setup_pin(pin)
|
30
|
+
bbb.respond_to?("p8_3=").should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "enables output function for output pin" do
|
34
|
+
pin = Pin.new(:output, nil, :P8_3)
|
35
|
+
bbb.setup_pin(pin)
|
36
|
+
bbb.p8_3=:low
|
37
|
+
pin.status.should eql(:low)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should keep the reference to the pin" do
|
41
|
+
pin = Pin.new(:output, nil, :P8_4)
|
42
|
+
bbb.connect_io_pin(pin)
|
43
|
+
pin.write :high
|
44
|
+
bbb.p8_4.should eql(:high)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|