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.
@@ -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,8 @@
1
+ require 'stringio'
2
+
3
+ module BBB
4
+ module IO
5
+ class MockPin < StringIO
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ module BBB
2
+ module IO
3
+ module Pinnable
4
+ attr_reader :position
5
+
6
+ def position=(position)
7
+ @position = position
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -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
@@ -0,0 +1,11 @@
1
+ module BBB
2
+ class TestBoard < BBB::Board
3
+
4
+ private
5
+
6
+ def self.pin_converter
7
+ GPIO::PinConverter.new(mock:true)
8
+ end
9
+ end
10
+ end
11
+
data/lib/BBB/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module BBB
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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
@@ -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