dino 0.10.0 → 0.11.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +67 -0
- data/README.md +24 -8
- data/bin/dino +108 -0
- data/dino.gemspec +2 -1
- data/examples/button/button.rb +3 -2
- data/examples/ethernet.rb +15 -0
- data/examples/{ir_receiver.rb → ir_receiver/ir_receiver.rb} +3 -2
- data/examples/led/led.rb +3 -3
- data/examples/{potentiometer.rb → potentiometer/potentiometer.rb} +4 -6
- data/examples/{rgb_led.rb → rgb_led/rgb_led.rb} +4 -6
- data/examples/{sensor.rb → sensor/sensor.rb} +5 -6
- data/examples/ser2net.rb +31 -0
- data/examples/servo/servo.rb +16 -0
- data/examples/stepper/stepper.rb +3 -3
- data/lib/dino/board.rb +69 -59
- data/lib/dino/components/base_component.rb +8 -7
- data/lib/dino/components/rgb_led.rb +19 -17
- data/lib/dino/components/sensor.rb +2 -2
- data/lib/dino/components/servo.rb +8 -5
- data/lib/dino/components/stepper.rb +9 -9
- data/lib/dino/tx_rx.rb +5 -4
- data/lib/dino/tx_rx/base.rb +64 -0
- data/lib/dino/tx_rx/serial.rb +44 -0
- data/lib/dino/tx_rx/tcp.rb +23 -0
- data/lib/dino/version.rb +1 -1
- data/spec/lib/board_spec.rb +53 -39
- data/spec/lib/components/led_spec.rb +1 -1
- data/spec/lib/components/rgb_led_spec.rb +49 -4
- data/spec/lib/components/sensor_spec.rb +14 -10
- data/spec/lib/components/servo_spec.rb +9 -4
- data/spec/lib/components/stepper_spec.rb +2 -2
- data/spec/lib/tx_rx/serial_spec.rb +111 -0
- data/spec/lib/tx_rx/tcp_spec.rb +37 -0
- data/spec/spec_helper.rb +10 -1
- data/src/du/du.ino +19 -0
- data/src/du_ethernet/du_ethernet.ino +71 -0
- data/src/lib/Dino.cpp +257 -0
- data/src/lib/Dino.h +85 -0
- metadata +25 -17
- data/examples/servo.rb +0 -13
- data/examples/telnet.rb +0 -28
- data/lib/dino/tx_rx/telnet.rb +0 -53
- data/lib/dino/tx_rx/usb_serial.rb +0 -69
- data/spec/lib/tx_rx/telnet_spec.rb +0 -66
- data/spec/lib/tx_rx/usb_serial_spec.rb +0 -101
- data/src/du.ino +0 -251
@@ -1,12 +1,13 @@
|
|
1
1
|
module Dino
|
2
2
|
module Components
|
3
3
|
class BaseComponent
|
4
|
-
attr_reader :pin, :
|
4
|
+
attr_reader :board, :pin, :pullup
|
5
5
|
alias :pins :pin
|
6
6
|
|
7
7
|
def initialize(options={})
|
8
|
-
self.pin = options[:pin] || options[:pins]
|
9
8
|
self.board = options[:board]
|
9
|
+
self.pin = options[:pin] || options[:pins]
|
10
|
+
self.pullup = options[:pullup]
|
10
11
|
|
11
12
|
raise 'board and pin or pins are required for a component' if self.board.nil? || self.pin.nil?
|
12
13
|
after_initialize(options)
|
@@ -23,19 +24,19 @@ module Dino
|
|
23
24
|
|
24
25
|
protected
|
25
26
|
|
26
|
-
attr_writer :pin, :
|
27
|
+
attr_writer :board, :pin, :pullup
|
27
28
|
alias :pins= :pin=
|
28
29
|
|
29
|
-
def digital_write(
|
30
|
+
def digital_write(pin=self.pin, value)
|
30
31
|
self.board.digital_write(pin, value)
|
31
32
|
end
|
32
33
|
|
33
|
-
def analog_write(
|
34
|
+
def analog_write(pin=self.pin, value)
|
34
35
|
self.board.analog_write(pin, value)
|
35
36
|
end
|
36
37
|
|
37
|
-
def set_pin_mode(
|
38
|
-
self.board.set_pin_mode(pin, mode)
|
38
|
+
def set_pin_mode(pin=self.pin, mode)
|
39
|
+
self.board.set_pin_mode(pin, mode, pullup)
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
@@ -8,27 +8,29 @@ module Dino
|
|
8
8
|
raise 'missing pins[:blue] pin' unless self.pins[:blue]
|
9
9
|
|
10
10
|
pins.each do |color, pin|
|
11
|
-
set_pin_mode(:out
|
12
|
-
analog_write(Board::LOW
|
11
|
+
set_pin_mode(pin, :out)
|
12
|
+
analog_write(pin, Board::LOW)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
# Format: [R, G, B]
|
17
|
+
COLORS = {
|
18
|
+
red: [255, 000, 000],
|
19
|
+
green: [000, 255, 000],
|
20
|
+
blue: [000, 000, 255],
|
21
|
+
cyan: [000, 255, 255],
|
22
|
+
yellow: [255, 255, 000],
|
23
|
+
magenta: [255, 000, 255],
|
24
|
+
white: [255, 255, 255],
|
25
|
+
off: [000, 000, 000]
|
26
|
+
}
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
COLORS.each_key do |color|
|
29
|
+
define_method(color) do
|
30
|
+
analog_write(pins[:red], COLORS[color][0])
|
31
|
+
analog_write(pins[:green], COLORS[color][1])
|
32
|
+
analog_write(pins[:blue], COLORS[color][2])
|
33
|
+
end
|
32
34
|
end
|
33
35
|
|
34
36
|
def blinky
|
@@ -5,14 +5,17 @@ module Dino
|
|
5
5
|
|
6
6
|
def after_initialize(options={})
|
7
7
|
set_pin_mode(:out)
|
8
|
-
|
8
|
+
board.servo_toggle(pin, 1)
|
9
|
+
self.position = options[:position] || 0
|
9
10
|
end
|
10
11
|
|
11
|
-
def position=(
|
12
|
-
@position =
|
13
|
-
|
12
|
+
def position=(value)
|
13
|
+
board.servo_write(pin, @position = angle(value))
|
14
|
+
end
|
15
|
+
|
16
|
+
def angle(value)
|
17
|
+
value == 180 ? value : value % 180
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
18
|
-
|
@@ -6,21 +6,21 @@ module Dino
|
|
6
6
|
raise 'missing pins[:step] pin' unless self.pins[:step]
|
7
7
|
raise 'missing pins[:direction] pin' unless self.pins[:direction]
|
8
8
|
|
9
|
-
set_pin_mode(
|
10
|
-
set_pin_mode(
|
11
|
-
digital_write(
|
9
|
+
set_pin_mode(pins[:step], :out)
|
10
|
+
set_pin_mode(pins[:direction], :out)
|
11
|
+
digital_write(pins[:step], Board::LOW)
|
12
12
|
end
|
13
13
|
|
14
14
|
def step_cc
|
15
|
-
digital_write(
|
16
|
-
digital_write(
|
17
|
-
digital_write(
|
15
|
+
digital_write(self.pins[:direction], Board::HIGH)
|
16
|
+
digital_write(self.pins[:step], Board::HIGH)
|
17
|
+
digital_write(self.pins[:step], Board::LOW)
|
18
18
|
end
|
19
19
|
|
20
20
|
def step_cw
|
21
|
-
digital_write(
|
22
|
-
digital_write(
|
23
|
-
digital_write(
|
21
|
+
digital_write(self.pins[:direction], Board::LOW)
|
22
|
+
digital_write(self.pins[:step], Board::HIGH)
|
23
|
+
digital_write(self.pins[:step], Board::LOW)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/dino/tx_rx.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Dino
|
2
2
|
module TxRx
|
3
|
-
require 'dino/tx_rx/
|
4
|
-
require 'dino/tx_rx/
|
3
|
+
require 'dino/tx_rx/base'
|
4
|
+
require 'dino/tx_rx/serial'
|
5
|
+
require 'dino/tx_rx/tcp'
|
5
6
|
|
6
|
-
def self.new
|
7
|
-
self::
|
7
|
+
def self.new(options={})
|
8
|
+
self::Serial.new(options)
|
8
9
|
end
|
9
10
|
end
|
10
11
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'observer'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
module Dino
|
5
|
+
module TxRx
|
6
|
+
class Base
|
7
|
+
include Observable
|
8
|
+
|
9
|
+
def read
|
10
|
+
@thread ||= Thread.new do
|
11
|
+
loop do
|
12
|
+
line = gets
|
13
|
+
if line && line.match(/\A\d+:/)
|
14
|
+
pin, message = line.chop.split(/:/)
|
15
|
+
pin && message && changed && notify_observers(pin, message)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def close_read
|
22
|
+
return nil if @thread.nil?
|
23
|
+
Thread.kill(@thread)
|
24
|
+
@thread = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def write(message)
|
28
|
+
loop do
|
29
|
+
if IO.select(nil, [io], nil)
|
30
|
+
io.syswrite(message)
|
31
|
+
break
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def handshake
|
37
|
+
flush_read
|
38
|
+
100.times do
|
39
|
+
begin
|
40
|
+
write("!9000000.")
|
41
|
+
Timeout::timeout(0.1) do
|
42
|
+
line = gets.to_s
|
43
|
+
if line.match /ACK:/
|
44
|
+
flush_read
|
45
|
+
return line.chop.split(/:/)[1].to_i
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
raise BoardNotFound
|
53
|
+
end
|
54
|
+
|
55
|
+
def flush_read
|
56
|
+
gets until gets == nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def gets
|
60
|
+
IO.select([io], nil, nil, 0.005) && io.gets
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'serialport'
|
2
|
+
|
3
|
+
module Dino
|
4
|
+
module TxRx
|
5
|
+
class Serial < Base
|
6
|
+
BAUD = 115200
|
7
|
+
|
8
|
+
def initialize(options={})
|
9
|
+
@device = options[:device]
|
10
|
+
@baud = options[:baud] || BAUD
|
11
|
+
@first_write = true
|
12
|
+
end
|
13
|
+
|
14
|
+
def io
|
15
|
+
@io ||= connect
|
16
|
+
end
|
17
|
+
|
18
|
+
def handshake
|
19
|
+
if on_windows?
|
20
|
+
io; sleep 3
|
21
|
+
end
|
22
|
+
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def connect
|
29
|
+
tty_devices.each { |device| return SerialPort.new(device, @baud) rescue nil }
|
30
|
+
raise BoardNotFound
|
31
|
+
end
|
32
|
+
|
33
|
+
def tty_devices
|
34
|
+
return [@device] if @device
|
35
|
+
return (1..256).map { |n| "COM#{n}" } if on_windows?
|
36
|
+
`ls /dev`.split("\n").grep(/usb|ACM/i).map{ |d| "/dev/#{d}" }
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_windows?
|
40
|
+
RUBY_PLATFORM.match /mswin|mingw/i
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Dino
|
4
|
+
module TxRx
|
5
|
+
class TCP < Base
|
6
|
+
def initialize(host, port=3466)
|
7
|
+
@host, @port = host, port
|
8
|
+
end
|
9
|
+
|
10
|
+
def io
|
11
|
+
@io ||= connect
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def connect
|
17
|
+
Timeout::timeout(10) { TCPSocket.open(@host, @port) }
|
18
|
+
rescue
|
19
|
+
raise BoardNotFound
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/dino/version.rb
CHANGED
data/spec/lib/board_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module Dino
|
4
4
|
describe Dino::Board do
|
5
5
|
def io_mock(methods = {})
|
6
|
-
@io ||= mock(:io, {write: nil, add_observer: nil}.merge(methods))
|
6
|
+
@io ||= mock(:io, {write: nil, add_observer: nil, flush_read: nil, handshake: "14"}.merge(methods))
|
7
7
|
end
|
8
8
|
|
9
9
|
subject { Board.new(io_mock) }
|
@@ -20,14 +20,8 @@ module Dino
|
|
20
20
|
subject.send(:initialize, io_mock)
|
21
21
|
end
|
22
22
|
|
23
|
-
it 'should
|
24
|
-
io_mock.should_receive(:
|
25
|
-
subject.add_digital_hardware(mock(:part, pin: 12))
|
26
|
-
sleep 0.01
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should send clearing bytes to the io' do
|
30
|
-
io_mock.should_receive(:write).with("00000000")
|
23
|
+
it 'should initiate the handshake' do
|
24
|
+
io_mock.should_receive(:handshake)
|
31
25
|
subject
|
32
26
|
end
|
33
27
|
end
|
@@ -47,9 +41,9 @@ module Dino
|
|
47
41
|
|
48
42
|
context 'when the given pin connects to an digital hardware part' do
|
49
43
|
it 'should call update with the message on the part' do
|
50
|
-
part = mock(:part, pin: 5)
|
44
|
+
part = mock(:part, pin: 5, pullup: nil)
|
51
45
|
subject.add_digital_hardware(part)
|
52
|
-
other_part = mock(:part, pin: 11)
|
46
|
+
other_part = mock(:part, pin: 11, pullup: nil)
|
53
47
|
subject.add_digital_hardware(other_part)
|
54
48
|
|
55
49
|
part.should_receive(:update).with('wake up!')
|
@@ -82,21 +76,23 @@ module Dino
|
|
82
76
|
|
83
77
|
describe '#add_digital_hardware' do
|
84
78
|
it 'should add digital hardware to the board' do
|
85
|
-
subject.add_digital_hardware(mock1 = mock(:part1, pin: 12))
|
86
|
-
subject.add_digital_hardware(mock2 = mock(:part2, pin: 14))
|
79
|
+
subject.add_digital_hardware(mock1 = mock(:part1, pin: 12, pullup: nil))
|
80
|
+
subject.add_digital_hardware(mock2 = mock(:part2, pin: 14, pullup: nil))
|
87
81
|
subject.digital_hardware.should =~ [mock1, mock2]
|
88
82
|
end
|
89
83
|
|
90
|
-
it 'should set the mode for the given pin to "in"' do
|
84
|
+
it 'should set the mode for the given pin to "in" and add a digital listener' do
|
91
85
|
subject
|
92
|
-
subject.should_receive(:write).with("
|
93
|
-
subject.
|
86
|
+
subject.should_receive(:write).with("0012001")
|
87
|
+
subject.should_receive(:write).with("0112000")
|
88
|
+
subject.should_receive(:write).with("0512000")
|
89
|
+
subject.add_digital_hardware(mock1 = mock(:part1, pin: 12, pullup: nil))
|
94
90
|
end
|
95
91
|
end
|
96
92
|
|
97
93
|
describe '#remove_digital_hardware' do
|
98
94
|
it 'should remove the given part from the hardware of the board' do
|
99
|
-
mock = mock(:part1, pin: 12)
|
95
|
+
mock = mock(:part1, pin: 12, pullup: nil)
|
100
96
|
subject.add_digital_hardware(mock)
|
101
97
|
subject.remove_digital_hardware(mock)
|
102
98
|
subject.digital_hardware.should == []
|
@@ -105,21 +101,23 @@ module Dino
|
|
105
101
|
|
106
102
|
describe '#add_analog_hardware' do
|
107
103
|
it 'should add analog hardware to the board' do
|
108
|
-
subject.add_analog_hardware(mock1 = mock(:part1, pin: 12))
|
109
|
-
subject.add_analog_hardware(mock2 = mock(:part2, pin: 14))
|
104
|
+
subject.add_analog_hardware(mock1 = mock(:part1, pin: 12, pullup: nil))
|
105
|
+
subject.add_analog_hardware(mock2 = mock(:part2, pin: 14, pullup: nil))
|
110
106
|
subject.analog_hardware.should =~ [mock1, mock2]
|
111
107
|
end
|
112
108
|
|
113
|
-
it 'should set the mode for the given pin to "in"' do
|
109
|
+
it 'should set the mode for the given pin to "in" and add an analog listener' do
|
114
110
|
subject
|
115
|
-
subject.should_receive(:write).with("
|
116
|
-
subject.
|
111
|
+
subject.should_receive(:write).with("0012001")
|
112
|
+
subject.should_receive(:write).with("0112000")
|
113
|
+
subject.should_receive(:write).with("0612000")
|
114
|
+
subject.add_analog_hardware(mock1 = mock(:part1, pin: 12, pullup: nil))
|
117
115
|
end
|
118
116
|
end
|
119
117
|
|
120
118
|
describe '#remove_analog_hardware' do
|
121
119
|
it 'should remove the given part from the hardware of the board' do
|
122
|
-
mock = mock(:part1, pin: 12)
|
120
|
+
mock = mock(:part1, pin: 12, pullup: nil)
|
123
121
|
subject.add_analog_hardware(mock)
|
124
122
|
subject.remove_analog_hardware(mock)
|
125
123
|
subject.analog_hardware.should == []
|
@@ -167,7 +165,7 @@ module Dino
|
|
167
165
|
end
|
168
166
|
|
169
167
|
describe '#digital_read' do
|
170
|
-
it 'should tell the board to
|
168
|
+
it 'should tell the board to read once from the given pin' do
|
171
169
|
io_mock.should_receive(:write).with('!0213000.')
|
172
170
|
subject.digital_read(13)
|
173
171
|
end
|
@@ -181,33 +179,49 @@ module Dino
|
|
181
179
|
end
|
182
180
|
|
183
181
|
describe '#analog_read' do
|
184
|
-
it 'should tell the board to
|
182
|
+
it 'should tell the board to read once from the given pin' do
|
185
183
|
io_mock.should_receive(:write).with('!0413000.')
|
186
184
|
subject.analog_read(13)
|
187
185
|
end
|
188
186
|
end
|
189
187
|
|
188
|
+
describe '#digital_listen' do
|
189
|
+
it 'should tell the board to continuously read from the given pin' do
|
190
|
+
io_mock.should_receive(:write).with('!0513000.')
|
191
|
+
subject.digital_listen(13)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe '#analog_listen' do
|
196
|
+
it 'should tell the board to continuously read from the given pin' do
|
197
|
+
io_mock.should_receive(:write).with('!0613000.')
|
198
|
+
subject.analog_listen(13)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe '#stop_listener' do
|
203
|
+
it 'should tell the board to stop sending values for the given pin' do
|
204
|
+
io_mock.should_receive(:write).with('!0713000.')
|
205
|
+
subject.stop_listener(13)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
190
209
|
describe '#set_pin_mode' do
|
191
|
-
it 'should send a value of
|
192
|
-
io_mock.should_receive(:write).with('!
|
210
|
+
it 'should send a value of 0 if the pin mode is set to out' do
|
211
|
+
io_mock.should_receive(:write).with('!0013000.')
|
193
212
|
subject.set_pin_mode(13, :out)
|
194
213
|
end
|
195
214
|
|
196
|
-
it 'should send a value of
|
197
|
-
io_mock.should_receive(:write).with('!
|
215
|
+
it 'should send a value of 1 if the pin mode is set to in' do
|
216
|
+
io_mock.should_receive(:write).with('!0013001.')
|
198
217
|
subject.set_pin_mode(13, :in)
|
199
218
|
end
|
200
219
|
end
|
201
220
|
|
202
|
-
describe '#
|
203
|
-
it 'should
|
204
|
-
io_mock.should_receive(:
|
205
|
-
subject.
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'should set the boards debug off when passed off' do
|
209
|
-
io_mock.should_receive(:write).with('!9900000.')
|
210
|
-
subject.set_debug(:off)
|
221
|
+
describe '#handshake' do
|
222
|
+
it 'should tell the board to reset to defaults' do
|
223
|
+
io_mock.should_receive(:handshake)
|
224
|
+
subject.handshake
|
211
225
|
end
|
212
226
|
end
|
213
227
|
|
@@ -221,7 +235,7 @@ module Dino
|
|
221
235
|
end
|
222
236
|
|
223
237
|
it 'should raise if a number larger than two digits are given' do
|
224
|
-
expect { subject.normalize_pin(1000) }.to raise_exception '
|
238
|
+
expect { subject.normalize_pin(1000) }.to raise_exception 'pin number must be in 0-99'
|
225
239
|
end
|
226
240
|
end
|
227
241
|
|