BBB 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
- - jruby-19mode
5
- - rbx-19mode
4
+ - 2.0.0
5
+ - rbx-2.2.1
6
6
  - ruby-head
7
7
  - jruby-head
data/Gemfile CHANGED
@@ -6,4 +6,6 @@ gem 'coveralls', require: false
6
6
 
7
7
  group :test do
8
8
  gem 'pry'
9
+ gem 'rubysl', :platform => :rbx
10
+ gem 'racc', :platform => :rbx
9
11
  end
@@ -0,0 +1,31 @@
1
+ require 'BBB'
2
+
3
+ ##
4
+ # Setup the AnalogPin Circuit
5
+ #
6
+ class Circuit < BBB::Circuit
7
+ def initialize
8
+ # Attach temperature sensor to pin P9_40
9
+ attach BBB::Components::Analog, pin: :P9_40, as: :thermometer
10
+ end
11
+ end
12
+
13
+ ##
14
+ # Setup the actual Applicaiton
15
+ #
16
+ class TemperatureExampleApp < BBB::Application
17
+ # Run this on the BeagleBoneBlack
18
+ board BBB::Board.new
19
+
20
+ # Connect the circuit to the board
21
+ circuit Circuit.new
22
+
23
+ # This is the basic run loop
24
+ def run
25
+ puts thermometer.read
26
+ end
27
+ end
28
+
29
+ # Initialize the app
30
+ app = TemperatureExampleApp.new
31
+ app.start
data/examples/led.rb CHANGED
@@ -17,7 +17,7 @@ class LedExampleApplication < BBB::Application
17
17
  # Run this on the BeableBoneBlack
18
18
  board BBB::Board.new
19
19
 
20
- # Connection the led circuit
20
+ # Connect the led circuit
21
21
  circuit Circuit.new
22
22
 
23
23
  # This is the basic run loop
data/examples/sketches.rb CHANGED
@@ -73,8 +73,8 @@ module Thunderball
73
73
 
74
74
  def Stabalizer
75
75
  def initialize(opts={})
76
- @escs = opts[:escs]
77
- @gyo = opts[:gyro]
76
+ @escs = opts[:escs]
77
+ @gyo = opts[:gyro]
78
78
  @accelerometer = opts[:accelerometer]
79
79
  end
80
80
 
@@ -0,0 +1,41 @@
1
+ module BBB
2
+ module ADC
3
+ class AnalogPin
4
+ attr_reader :position, :pin_map, :mock
5
+ attr_reader :file_handle
6
+
7
+ def initialize(position, opts={})
8
+ self.position = position
9
+ @mock = opts.fetch(:mock, false)
10
+ @file_handle = get_file_handle(mock)
11
+ end
12
+
13
+ def position=(position)
14
+ map = Board::PinMapper.map(position, :ain)
15
+ unless map.respond_to?(:ain) && !map.ain.nil?
16
+ raise ArgumentError, "#{position} is not a valid AIN pin position"
17
+ end
18
+
19
+ @pin_map = map
20
+ @position = position
21
+ end
22
+
23
+ def ain_path
24
+ "/sys/devices/ocp.3/helper.15/AIN#{pin_map.ain}"
25
+ end
26
+
27
+ def read
28
+ file_handle.read
29
+ end
30
+
31
+ def scale
32
+ pin_map.scale
33
+ end
34
+
35
+ def get_file_handle(mock=false)
36
+ mock ? StringIO.new : File.open(ain_path, "r")
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ module BBB
2
+ module ADC
3
+ def self.setup
4
+ check_if_kernel_module_is_loaded!
5
+ end
6
+
7
+ def self.check_if_kernel_module_is_loaded!
8
+ ains = `find /sys/ -name '*AIN*'`.split("\n")
9
+
10
+ if ains.size > 0
11
+ return true
12
+ else
13
+ raise ModuleNotLoadedException, "Is seems that the ADC module is not
14
+ loaded into the kernel. You might want to try: \n
15
+ sudo modprobe t1_tscadc or add it to the kernel on boot: \n
16
+ echo 't1_tscadc' >> /etc/modules.conf"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,45 @@
1
+ module BBB
2
+ module Board
3
+ ##
4
+ # Base class, designed and tested on BeagleBone Black Revision A5C
5
+ #
6
+ class Base
7
+ attr_reader :gpio, :pin_converter
8
+
9
+ def initialize(pin_converter=nil)
10
+ @pin_converter = pin_converter || self.class.pin_converter
11
+ @pins = {}
12
+ end
13
+
14
+ ##
15
+ # Define methods for a GPIO::PIN
16
+ #
17
+ def setup_pin(pin)
18
+ @pins[pin.position] = pin
19
+
20
+ metaclass = class << self; self; end
21
+ metaclass.class_eval do
22
+ define_method("p#{pin.position.to_s[1..-1]}") do
23
+ @pins[pin.position].read
24
+ end
25
+
26
+ define_method("p#{pin.position.to_s[1..-1]}=") do |value|
27
+ @pins[pin.position].write value
28
+ end if pin.mode == :output
29
+ end
30
+ end
31
+
32
+ def connect_io_pin(pin)
33
+ gpio_pin = pin_converter.convert(pin)
34
+ pin.pin_io = gpio_pin
35
+ setup_pin(pin)
36
+ end
37
+
38
+ private
39
+
40
+ def self.pin_converter
41
+ GPIO::PinConverter.new
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,203 @@
1
+ module BBB
2
+ module Board
3
+ ##
4
+ # This class provides a convenient way of mapping a JSON representation of the
5
+ # pins, taken from the bonescript sourcecode, into Ruby objects. After
6
+ # converting the json to ruby objects the "normal" PinMapper will take the
7
+ # object structure and provide the actual mapping from the pin header
8
+ # positions, like p8_3 to the correct GPIO, I2C or WPM endpoints.
9
+ #
10
+ # This class should not be used directly to provide these mappings it's simply
11
+ # a helper class to get from JSON to Ruby.
12
+ #
13
+ class JSONPinMapper
14
+ class PinMap < Struct.new(:pins, :uart, :i2c); end
15
+ class Pin < Struct.new(:name, :gpio, :led, :mux, :key, :mux_reg_offset,
16
+ :options, :eeprom, :pwm, :ain, :scale); end
17
+ class UART < Struct.new(:devicetree, :rx, :tx); end
18
+ class I2C < Struct.new(:devicetree, :path, :sda, :scl); end
19
+
20
+ attr_reader :data
21
+
22
+ ##
23
+ # Initialize a JSONPinMapper
24
+ #
25
+ # @param [Hash] hash Hash that was converted from json with the keys
26
+ # pinIndex, uart and i2c.
27
+ #
28
+ def initialize(hash)
29
+ @data = hash
30
+ end
31
+
32
+ ##
33
+ # Factor a new JSONPinMapper based on a json_file that get's parsed to a
34
+ # hash.
35
+ #
36
+ # @param [String] json_filename The file that contains the JSON object with
37
+ # pin information
38
+ #
39
+ # @return JSONPinMapper instance
40
+ #
41
+ def self.convert(json_filename)
42
+ file = File.open(json_filename, "r")
43
+ hash = JSON.parse(file.read)
44
+ new(hash).convert
45
+ end
46
+
47
+ ##
48
+ # Convert from a the data hash to ruby objects
49
+ #
50
+ # @return [Struct] with pins, uart and i2c as keys.
51
+ # pins has a
52
+ #
53
+ def convert
54
+ pins = convert_pins(data["pinIndex"])
55
+ uart = convert_uart(data["uarts"])
56
+ i2c = convert_i2c(data["i2c"])
57
+
58
+ PinMap.new(pins, uart, i2c)
59
+ end
60
+
61
+ ##
62
+ # Converts an array of pins into a hash with the pin key as a key and a Pin
63
+ # Struct as a value.
64
+ #
65
+ # Here is an example of a piece of the JSON code containing pin info:
66
+ #
67
+ # {
68
+ # "name": "USR0",
69
+ # "gpio": 53,
70
+ # "led": "usr0",
71
+ # "mux": "gpmc_a5",
72
+ # "key": "USR0",
73
+ # "muxRegOffset": "0x054",
74
+ # "options": [
75
+ # "gpmc_a5",
76
+ # "gmii2_txd0",
77
+ # "rgmii2_td0",
78
+ # "rmii2_txd0",
79
+ # "gpmc_a21",
80
+ # "pr1_mii1_rxd3",
81
+ # "eqep1b_in",
82
+ # "gpio1_21"
83
+ # ]
84
+ # }
85
+ #
86
+ # @param [Array<Hash>] array An array of Pin hashes
87
+ #
88
+ # @return [Hash] a hash with pin keys as keys and pin objects as values.
89
+ #
90
+ def convert_pins(array)
91
+ hash = {}
92
+
93
+ array.each do |pin_hash|
94
+ pin = Pin.new
95
+ pin_hash.each_pair do |key, value|
96
+ pin[underscore(key).to_sym] = value
97
+ end
98
+ hash[pin.key.upcase.to_sym] = pin
99
+ end
100
+
101
+ return hash
102
+ end
103
+
104
+ ##
105
+ # Convert a hash of uarts to a hash with the uart folder (e.g. /dev/tty00)
106
+ # as the key and an uart object as the value.
107
+ #
108
+ # Here is an example of an individual UART hash:
109
+ #
110
+ # "/dev/ttyO1": {
111
+ # "devicetree": "BB-UART1",
112
+ # "rx": "P9_26",
113
+ # "tx": "P9_24"
114
+ # }
115
+ #
116
+ # @param [Hash] data_hash with strings as keys and hashes as values
117
+ #
118
+ # @return [Hash] with strings of uart positions (e.g. /dev/tty00) as keys
119
+ # and uart objects as values
120
+ #
121
+ def convert_uart(data_hash)
122
+ convert_hash_with_hashes(data_hash, UART)
123
+ end
124
+
125
+ ##
126
+ # Convert a hash of I2Cs to a hash with the I2C folder as the key and a i2c
127
+ # object as the value
128
+ #
129
+ # Here is an example of an individual I2C hash:
130
+ #
131
+ # "/dev/i2c-1": {
132
+ # "devicetree": "BB-I2C1",
133
+ # "path": "/dev/i2c-2",
134
+ # "sda": "P9_18",
135
+ # "scl": "P9_17"
136
+ # }
137
+ #
138
+ # @param [Hash] data_hash with strings as keys and hashes as values
139
+ #
140
+ # @return [Hash] with strings of I2C folders as keys and I2C objects as
141
+ # values
142
+ #
143
+ def convert_i2c(data_hash)
144
+ convert_hash_with_hashes(data_hash, I2C)
145
+ end
146
+
147
+ private
148
+
149
+ ##
150
+ # @see #convert_uart
151
+ #
152
+ def convert_hash_with_hashes(data_hash, object)
153
+ hash = {}
154
+
155
+ data_hash.each_pair do |filesystem, info_hash|
156
+ instance = object.new
157
+ info_hash.each_pair do |key, value|
158
+ instance[key] = value
159
+ end
160
+
161
+ hash[filesystem] = instance
162
+ end
163
+
164
+ return hash
165
+ end
166
+
167
+ ##
168
+ # Makes an underscored, lowercase form from the expression in the string.
169
+ #
170
+ # Gracefully copied from ActiveSupport::Inflections
171
+ # http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore
172
+ #
173
+ # Changes '::' to '/' to convert namespaces to paths.
174
+ #
175
+ # 'ActiveModel'.underscore # => "active_model"
176
+ # 'ActiveModel::Errors'.underscore # => "active_model/errors"
177
+ #
178
+ # As a rule of thumb you can think of +underscore+ as the inverse of
179
+ # +camelize+, though there are cases where that does not hold:
180
+ #
181
+ # 'SSLError'.underscore.camelize # => "SslError"
182
+ def underscore(camel_cased_word)
183
+ word = camel_cased_word.to_s.dup
184
+ word.gsub!('::', '/')
185
+ word.gsub!(/(?:([A-Za-z\d])|^)(#{acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
186
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
187
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
188
+ word.tr!("-", "_")
189
+ word.downcase!
190
+ word
191
+ end
192
+
193
+ ##
194
+ # Specifies acronyms. This is a shortcut approach to the full acronym
195
+ # functionality of Rails. Which can be found here:
196
+ # https://github.com/rails/rails/blob/4e327225947b933d5434509e02e98226c581adc1/activesupport/lib/active_support/inflector/inflections.rb#L47
197
+ #
198
+ def acronym_regex
199
+ /#{%w(I2C UART GPIO).join("|")}/
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,19 @@
1
+ module BBB
2
+ module Board
3
+ class PinMapper
4
+ ##
5
+ # Thanks to BoneScript, see the resources/pin_mappings.json.comment
6
+ # for reference to the original BoneScript file.
7
+ #
8
+ MAP = JSONPinMapper.convert("resources/pin_mappings.json")
9
+
10
+ def self.map(pin_symbol, type=:gpio)
11
+ begin
12
+ MAP.pins.fetch(pin_symbol.upcase.to_sym)
13
+ rescue Exception => e
14
+ raise UnknownPinException, "Pin #{pin_symbol} could not be mapped"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ module BBB
2
+ module Board
3
+ class TestBoard < BBB::Board::Base
4
+
5
+ private
6
+
7
+ def self.pin_converter
8
+ GPIO::PinConverter.new(mock:true)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -2,5 +2,4 @@ module BBB
2
2
  class UnknownPinException < ArgumentError; end
3
3
  class UnknownPinModeException < ArgumentError; end
4
4
  class PinsDoNotMatchException < ArgumentError; end
5
- class NotImplementedError < ArgumentError; end
6
5
  end
data/lib/BBB/gpio/base.rb CHANGED
@@ -12,12 +12,12 @@ module BBB
12
12
  @mock = opts.fetch(:mock, false)
13
13
  self.position = pin_position
14
14
  @file_class = @mock ? StringIO : File
15
- export
15
+ export
16
16
  end
17
17
 
18
18
  def position=(position, mock=false)
19
19
  @position = position
20
- @converted_position = PinMapper.map(position)
20
+ @converted_position = Board::PinMapper.map(position).gpio
21
21
  end
22
22
 
23
23
  def gpio_path
@@ -0,0 +1,23 @@
1
+ module BBB
2
+ module IO
3
+ class AnalogPin
4
+ include Pinnable
5
+
6
+ attr_reader :pin_io, :position
7
+
8
+ def initialize(pin_io=nil, position=nil)
9
+ @pin_io = pin_io || MockPin.new
10
+ @position = position
11
+ end
12
+
13
+ def read
14
+ pin_io.read
15
+ end
16
+
17
+ def scale
18
+ pin_io.scale
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -36,11 +36,11 @@ module BBB
36
36
 
37
37
  # Reads digitally from the specified pin on initialize
38
38
  def read
39
- if mode == :input
40
- pin_io.read
41
- else
39
+ if mode == :input
40
+ pin_io.read
41
+ else
42
42
  status
43
- end
43
+ end
44
44
  end
45
45
 
46
46
  # Sets digital write for the pin to HIGH
data/lib/BBB/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module BBB
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/BBB.rb CHANGED
@@ -1,14 +1,22 @@
1
1
  require "BBB/version"
2
- require "BBB/board"
3
- require "BBB/test_board"
2
+
3
+ require "json"
4
+
5
+ require "BBB/board/base"
6
+ require "BBB/board/test_board"
7
+ require "BBB/board/json_pin_mapper"
8
+ require "BBB/board/pin_mapper"
9
+
4
10
  require "BBB/circuit"
5
- require "BBB/pin_mapper"
6
11
  require "BBB/exceptions"
7
12
 
8
13
  require "BBB/gpio/base"
9
14
  require "BBB/gpio/digital_pin"
10
15
  require "BBB/gpio/pin_converter"
11
16
 
17
+ require "BBB/adc/setup"
18
+ require "BBB/adc/analog_pin"
19
+
12
20
  require "BBB/io/pinnable"
13
21
  require "BBB/io/digital_pin"
14
22
  require "BBB/io/mock_pin"