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
@@ -5,7 +5,7 @@ module Dino
|
|
5
5
|
describe RgbLed do
|
6
6
|
let(:board) { mock(:board, analog_write: true, set_pin_mode: true) }
|
7
7
|
let(:pins) { {red: 1, green: 2, blue: 3} }
|
8
|
-
let
|
8
|
+
let(:rgb) { RgbLed.new(pins: pins, board: board)}
|
9
9
|
|
10
10
|
describe '#initialize' do
|
11
11
|
it 'should raise if it does not receive a pin' do
|
@@ -21,9 +21,9 @@ module Dino
|
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should set the pin to out' do
|
24
|
-
board.should_receive(:set_pin_mode).with(1, :out)
|
25
|
-
board.should_receive(:set_pin_mode).with(2, :out)
|
26
|
-
board.should_receive(:set_pin_mode).with(3, :out)
|
24
|
+
board.should_receive(:set_pin_mode).with(1, :out, nil)
|
25
|
+
board.should_receive(:set_pin_mode).with(2, :out, nil)
|
26
|
+
board.should_receive(:set_pin_mode).with(3, :out, nil)
|
27
27
|
|
28
28
|
RgbLed.new(pins: pins, board: board)
|
29
29
|
end
|
@@ -64,6 +64,51 @@ module Dino
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
describe '#cyan' do
|
68
|
+
it 'should set blue and green to high, red to low' do
|
69
|
+
board.should_receive(:analog_write).with(1, Board::LOW)
|
70
|
+
board.should_receive(:analog_write).with(2, Board::HIGH)
|
71
|
+
board.should_receive(:analog_write).with(3, Board::HIGH)
|
72
|
+
rgb.cyan
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#yellow' do
|
77
|
+
it 'should set red and green to high, blue to low' do
|
78
|
+
board.should_receive(:analog_write).with(1, Board::HIGH)
|
79
|
+
board.should_receive(:analog_write).with(2, Board::HIGH)
|
80
|
+
board.should_receive(:analog_write).with(3, Board::LOW)
|
81
|
+
rgb.yellow
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#magenta' do
|
86
|
+
it 'should set red and blue to high, green to low' do
|
87
|
+
board.should_receive(:analog_write).with(1, Board::HIGH)
|
88
|
+
board.should_receive(:analog_write).with(2, Board::LOW)
|
89
|
+
board.should_receive(:analog_write).with(3, Board::HIGH)
|
90
|
+
rgb.magenta
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#white' do
|
95
|
+
it 'should set all to high' do
|
96
|
+
board.should_receive(:analog_write).with(1, Board::HIGH)
|
97
|
+
board.should_receive(:analog_write).with(2, Board::HIGH)
|
98
|
+
board.should_receive(:analog_write).with(3, Board::HIGH)
|
99
|
+
rgb.white
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#off' do
|
104
|
+
it 'should set all to low' do
|
105
|
+
board.should_receive(:analog_write).with(1, Board::LOW)
|
106
|
+
board.should_receive(:analog_write).with(2, Board::LOW)
|
107
|
+
board.should_receive(:analog_write).with(3, Board::LOW)
|
108
|
+
rgb.off
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
67
112
|
describe '#blinky' do
|
68
113
|
it 'should set blue to high, red and green to low' do
|
69
114
|
Array.any_instance.should_receive(:cycle).and_yield(:red).and_yield(:green).and_yield(:blue)
|
@@ -32,25 +32,29 @@ module Dino
|
|
32
32
|
end
|
33
33
|
|
34
34
|
describe '#when_data_received' do
|
35
|
-
|
35
|
+
|
36
|
+
it "should add a callback to the list of callbacks" do
|
36
37
|
sensor = Sensor.new(board: board, pin: 'a pin')
|
37
|
-
sensor.when_data_received
|
38
|
-
sensor.instance_variable_get(:@data_callbacks).
|
38
|
+
sensor.when_data_received { "this is a block" }
|
39
|
+
sensor.instance_variable_get(:@data_callbacks).should_not be_empty
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
43
|
describe '#update' do
|
43
44
|
it 'should call all callbacks passing in the given data' do
|
44
|
-
first_callback, second_callback = mock, mock
|
45
|
-
first_callback.should_receive(:call).with('Some data')
|
46
|
-
second_callback.should_receive(:call).with('Some data')
|
47
|
-
|
48
45
|
sensor = Sensor.new(board: board, pin: 'a pin')
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
|
47
|
+
first_block_data = nil
|
48
|
+
second_block_data = nil
|
49
|
+
sensor.when_data_received do |data|
|
50
|
+
first_block_data = data
|
51
|
+
end
|
52
|
+
sensor.when_data_received do |data|
|
53
|
+
second_block_data = data
|
54
|
+
end
|
52
55
|
|
53
56
|
sensor.update('Some data')
|
57
|
+
[first_block_data, second_block_data].each { |block_data| block_data.should == "Some data" }
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module Dino
|
4
4
|
module Components
|
5
5
|
describe Servo do
|
6
|
-
let(:board) { mock(:board, analog_write: true, set_pin_mode: true) }
|
6
|
+
let(:board) { mock(:board, analog_write: true, set_pin_mode: true, servo_toggle: true, servo_write: true) }
|
7
7
|
|
8
8
|
describe '#initialize' do
|
9
9
|
it 'should raise if it does not receive a pin' do
|
@@ -19,7 +19,7 @@ module Dino
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'should set the pins to out' do
|
22
|
-
board.should_receive(:set_pin_mode).with(13, :out)
|
22
|
+
board.should_receive(:set_pin_mode).with(13, :out, nil)
|
23
23
|
Servo.new(pin: 13, board: board)
|
24
24
|
end
|
25
25
|
|
@@ -37,13 +37,18 @@ module Dino
|
|
37
37
|
servo.instance_variable_get(:@position).should == 90
|
38
38
|
end
|
39
39
|
|
40
|
-
it 'should
|
40
|
+
it 'should let you write up to 180' do
|
41
|
+
servo.position = 180
|
42
|
+
servo.instance_variable_get(:@position).should == 180
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should modulate when position > 180' do
|
41
46
|
servo.position = 190
|
42
47
|
servo.instance_variable_get(:@position).should == 10
|
43
48
|
end
|
44
49
|
|
45
50
|
it 'should write the new position to the board' do
|
46
|
-
|
51
|
+
board.should_receive(:servo_write).with(13, 10)
|
47
52
|
servo.position = 190
|
48
53
|
end
|
49
54
|
end
|
@@ -25,8 +25,8 @@ module Dino
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should set the pins to out' do
|
28
|
-
board.should_receive(:set_pin_mode).with(13, :out)
|
29
|
-
board.should_receive(:set_pin_mode).with(12, :out)
|
28
|
+
board.should_receive(:set_pin_mode).with(13, :out, nil)
|
29
|
+
board.should_receive(:set_pin_mode).with(12, :out, nil)
|
30
30
|
Stepper.new(pins: {step: 13, direction: 12}, board: board)
|
31
31
|
end
|
32
32
|
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dino
|
4
|
+
describe TxRx::Serial do
|
5
|
+
it { should be }
|
6
|
+
|
7
|
+
describe '#initialize' do
|
8
|
+
it 'should set first_write to true' do
|
9
|
+
TxRx::Serial.new.instance_variable_get(:@first_write).should == true
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should set the device and buad if specified' do
|
13
|
+
txrx = TxRx::Serial.new({device: "/dev/ttyACM0", baud: 9600})
|
14
|
+
txrx.instance_variable_get(:@baud).should == 9600
|
15
|
+
txrx.instance_variable_get(:@device).should == "/dev/ttyACM0"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#io' do
|
20
|
+
context "on windows" do
|
21
|
+
it 'should instantiate a new SerialPort for the first available tty device' do
|
22
|
+
original_platform = RUBY_PLATFORM
|
23
|
+
Constants.redefine(:RUBY_PLATFORM, "mswin", :on => Object)
|
24
|
+
subject.should_receive(:tty_devices).and_return(["COM1", "COM2", "COM3"])
|
25
|
+
|
26
|
+
# COM2 is chosen as available for this test.
|
27
|
+
SerialPort.should_receive(:new).with("COM1", TxRx::Serial::BAUD).and_raise
|
28
|
+
SerialPort.should_receive(:new).with("COM2", TxRx::Serial::BAUD).and_return(mock_serial = mock)
|
29
|
+
SerialPort.should_not_receive(:new).with("COM3", TxRx::Serial::BAUD)
|
30
|
+
|
31
|
+
subject.io.should == mock_serial
|
32
|
+
Constants.redefine(:RUBY_PLATFORM, original_platform, :on => Object)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "on unix" do
|
37
|
+
it 'should instantiate a new SerialPort for the first available tty device' do
|
38
|
+
subject.should_receive(:tty_devices).and_return(['/dev/ttyACM0', '/dev/tty.usbmodem1'])
|
39
|
+
|
40
|
+
# /dev/ttyACM0 is chosen as available for this test.
|
41
|
+
SerialPort.should_receive(:new).with('/dev/ttyACM0', TxRx::Serial::BAUD).and_return(mock_serial = mock)
|
42
|
+
SerialPort.should_not_receive(:new).with('/dev/tty.usbmodem1', TxRx::Serial::BAUD)
|
43
|
+
|
44
|
+
subject.io.should == mock_serial
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should connect to the specified device at the specified baud rate' do
|
49
|
+
subject.should_receive(:tty_devices).and_return(["/dev/ttyACM0"])
|
50
|
+
SerialPort.should_receive(:new).with('/dev/ttyACM0', 9600).and_return(mock_serial = mock)
|
51
|
+
|
52
|
+
subject.instance_variable_set(:@device, "/dev/ttyACM0")
|
53
|
+
subject.instance_variable_set(:@baud, 9600)
|
54
|
+
|
55
|
+
subject.io.should == mock_serial
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should use the existing io instance if set' do
|
59
|
+
subject.should_receive(:tty_devices).once.and_return(['/dev/tty.ACM0', '/dev/tty.usbmodem1'])
|
60
|
+
SerialPort.stub(:new).and_return(mock_serial = mock)
|
61
|
+
|
62
|
+
3.times { subject.io }
|
63
|
+
subject.io.should == mock_serial
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should raise a BoardNotFound exception if there is no board connected' do
|
67
|
+
SerialPort.stub(:new).and_raise
|
68
|
+
expect { subject.io }.to raise_exception BoardNotFound
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#read' do
|
73
|
+
it 'should create a new thread' do
|
74
|
+
Thread.should_receive :new
|
75
|
+
subject.read
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should get messages from the device' do
|
79
|
+
subject.stub(:io).and_return(mock_serial = mock)
|
80
|
+
|
81
|
+
IO.should_receive(:select).and_return(true)
|
82
|
+
Thread.should_receive(:new).and_yield
|
83
|
+
subject.should_receive(:loop).and_yield
|
84
|
+
mock_serial.should_receive(:gets).and_return("02:00\n")
|
85
|
+
subject.should_receive(:changed).and_return(true)
|
86
|
+
subject.should_receive(:notify_observers).with('02','00')
|
87
|
+
|
88
|
+
subject.read
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#close_read' do
|
93
|
+
it 'should kill the reading thread' do
|
94
|
+
subject.instance_variable_set(:@thread, mock_thread = mock)
|
95
|
+
Thread.should_receive(:kill).with(mock_thread)
|
96
|
+
subject.read
|
97
|
+
subject.close_read
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#write' do
|
102
|
+
it 'should write to the device' do
|
103
|
+
IO.should_receive(:select).and_return(true)
|
104
|
+
|
105
|
+
subject.stub(:io).and_return(mock_serial = mock)
|
106
|
+
mock_serial.should_receive(:syswrite).with('a message')
|
107
|
+
subject.write('a message')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dino
|
4
|
+
describe TxRx::TCP do
|
5
|
+
before :each do
|
6
|
+
@host = "127.0.0.1"
|
7
|
+
@port = 3466
|
8
|
+
@instance = TxRx::TCP.new(@host, @port)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#connect" do
|
12
|
+
it 'should raise a BoardNotFound exception if it cannot connect to the server' do
|
13
|
+
expect { @instance.io }.to raise_exception BoardNotFound
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should return the TCPSocket if connected' do
|
17
|
+
@server = TCPServer.new 3466
|
18
|
+
@instance.io.should be_a TCPSocket
|
19
|
+
@server.close
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#io' do
|
24
|
+
it 'should set io to a new TCPSocket with the specified host and port' do
|
25
|
+
TCPSocket.should_receive(:open).with(@host, @port)
|
26
|
+
@instance.io
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should use the existing io instance if set' do
|
30
|
+
@server = TCPServer.new 3466
|
31
|
+
socket = @instance.io
|
32
|
+
@instance.io.should be socket
|
33
|
+
@server.close
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
|
3
|
-
require File.expand_path(File.join('../..', 'lib/dino'), __FILE__)
|
3
|
+
require File.expand_path(File.join('../..', 'lib/dino'), __FILE__)
|
4
|
+
|
5
|
+
# Nice little helper module to redefine constants quietly.
|
6
|
+
module Constants
|
7
|
+
def self.redefine(const, value, opts={})
|
8
|
+
opts = {:on => self.class}.merge(opts)
|
9
|
+
opts[:on].send(:remove_const, const) if self.class.const_defined?(const)
|
10
|
+
opts[:on].const_set(const, value)
|
11
|
+
end
|
12
|
+
end
|
data/src/du/du.ino
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "Dino.h"
|
2
|
+
#include <Servo.h>
|
3
|
+
Dino dino;
|
4
|
+
|
5
|
+
// Dino.h doesn't handle TXRX. Setup a function to tell it to write to Serial.
|
6
|
+
void writeResponse(char *response) { Serial.print(response); Serial.print("\n"); }
|
7
|
+
void (*writeCallback)(char *str) = writeResponse;
|
8
|
+
|
9
|
+
void setup() {
|
10
|
+
Serial.begin(115200);
|
11
|
+
dino.setupWrite(writeCallback);
|
12
|
+
}
|
13
|
+
|
14
|
+
void loop() {
|
15
|
+
while(Serial.available() > 0) dino.parse(Serial.read());
|
16
|
+
dino.updateListeners();
|
17
|
+
Serial.flush();
|
18
|
+
}
|
19
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#include "Dino.h"
|
2
|
+
#include <SPI.h>
|
3
|
+
#include <Ethernet.h>
|
4
|
+
#include <Servo.h>
|
5
|
+
|
6
|
+
// Configure your MAC address, IP address, and HTTP port here.
|
7
|
+
byte mac[] = { 0xDE, 0xAD, 0xBE, 0x30, 0x31, 0x32 };
|
8
|
+
IPAddress ip(192,168,0,77);
|
9
|
+
int port = 3466;
|
10
|
+
|
11
|
+
Dino dino;
|
12
|
+
EthernetServer server(port);
|
13
|
+
EthernetClient client;
|
14
|
+
char responseBuffer[65];
|
15
|
+
|
16
|
+
|
17
|
+
// Dino.h doesn't handle TXRX. Setup a callback to receive the responses and buffer them.
|
18
|
+
void bufferResponse(char *response) {
|
19
|
+
if (strlen(responseBuffer) > 56 ) {
|
20
|
+
writeResponses();
|
21
|
+
strcpy(responseBuffer, response);
|
22
|
+
} else {
|
23
|
+
strcat(responseBuffer, response);
|
24
|
+
}
|
25
|
+
strcat(responseBuffer, "\n");
|
26
|
+
}
|
27
|
+
void (*writeCallback)(char *str) = bufferResponse;
|
28
|
+
|
29
|
+
// Write the buffered responses to the client.
|
30
|
+
void writeResponses() {
|
31
|
+
if (responseBuffer[0] != '\0')
|
32
|
+
client.write(responseBuffer);
|
33
|
+
responseBuffer[0] = '\0';
|
34
|
+
}
|
35
|
+
|
36
|
+
|
37
|
+
void setup() {
|
38
|
+
// Explicitly disable the SD card.
|
39
|
+
pinMode(4,OUTPUT);
|
40
|
+
digitalWrite(4,HIGH);
|
41
|
+
|
42
|
+
// Start up the network connection and server.
|
43
|
+
Ethernet.begin(mac, ip);
|
44
|
+
server.begin();
|
45
|
+
|
46
|
+
// Start serial for debugging.
|
47
|
+
Serial.begin(9600);
|
48
|
+
Serial.print("Dino::TCP started at ");
|
49
|
+
Serial.print(Ethernet.localIP());
|
50
|
+
Serial.print(" on port ");
|
51
|
+
Serial.println(port);
|
52
|
+
|
53
|
+
// Attach the write callback.
|
54
|
+
dino.setupWrite(writeCallback);
|
55
|
+
}
|
56
|
+
|
57
|
+
void loop() {
|
58
|
+
// Listen for connections.
|
59
|
+
client = server.available();
|
60
|
+
|
61
|
+
// Handle a connection.
|
62
|
+
if (client) {
|
63
|
+
while (client.connected()) {
|
64
|
+
while (client.available()) dino.parse(client.read());
|
65
|
+
dino.updateListeners();
|
66
|
+
writeResponses();
|
67
|
+
}
|
68
|
+
}
|
69
|
+
client.stop();
|
70
|
+
}
|
71
|
+
|
data/src/lib/Dino.cpp
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
/*
|
2
|
+
Library for dino ruby gem.
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "Arduino.h"
|
6
|
+
#include "Dino.h"
|
7
|
+
|
8
|
+
Dino::Dino(){
|
9
|
+
reset();
|
10
|
+
}
|
11
|
+
|
12
|
+
void Dino::parse(char c) {
|
13
|
+
if (c == '!') index = 0; // Reset request
|
14
|
+
else if (c == '.') process(); // End request and process
|
15
|
+
else request[index++] = c; // Append to request
|
16
|
+
}
|
17
|
+
|
18
|
+
void Dino::process() {
|
19
|
+
response[0] = '\0';
|
20
|
+
|
21
|
+
// Parse the request.
|
22
|
+
strncpy(cmdStr, request, 2); cmdStr[2] = '\0';
|
23
|
+
strncpy(pinStr, request + 2, 2); pinStr[2] = '\0';
|
24
|
+
strncpy(valStr, request + 4, 3); valStr[3] = '\0';
|
25
|
+
cmd = atoi(cmdStr);
|
26
|
+
pin = atoi(pinStr);
|
27
|
+
val = atoi(valStr);
|
28
|
+
|
29
|
+
#ifdef debug
|
30
|
+
Serial.print("Received request - "); Serial.println(request);
|
31
|
+
Serial.print("Command - "); Serial.println(cmdStr);
|
32
|
+
Serial.print("Pin - "); Serial.println(pinStr);
|
33
|
+
Serial.print("Value - "); Serial.println(valStr);
|
34
|
+
#endif
|
35
|
+
|
36
|
+
// Call the command.
|
37
|
+
switch(cmd) {
|
38
|
+
case 0: setMode (); break;
|
39
|
+
case 1: dWrite (); break;
|
40
|
+
case 2: dRead (); break;
|
41
|
+
case 3: aWrite (); break;
|
42
|
+
case 4: aRead (); break;
|
43
|
+
case 5: addDigitalListener (); break;
|
44
|
+
case 6: addAnalogListener (); break;
|
45
|
+
case 7: removeListener (); break;
|
46
|
+
case 8: servoToggle (); break;
|
47
|
+
case 9: servoWrite (); break;
|
48
|
+
case 90: reset (); break;
|
49
|
+
case 97: setAnalogDivider (); break;
|
50
|
+
case 98: setHeartRate (); break;
|
51
|
+
default: break;
|
52
|
+
}
|
53
|
+
|
54
|
+
// Write the response.
|
55
|
+
if (response[0] != '\0') writeResponse();
|
56
|
+
|
57
|
+
#ifdef debug
|
58
|
+
Serial.print("Responded with - "); Serial.println(response);
|
59
|
+
Serial.println();
|
60
|
+
#endif
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
// WRITE CALLBACK
|
66
|
+
void Dino::setupWrite(void (*writeCallback)(char *str)) {
|
67
|
+
_writeCallback = writeCallback;
|
68
|
+
}
|
69
|
+
void Dino::writeResponse() {
|
70
|
+
_writeCallback(response);
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
// LISTNENERS
|
76
|
+
void Dino::updateListeners() {
|
77
|
+
if (timeSince(lastUpdate) > heartRate || timeSince(lastUpdate) < 0) {
|
78
|
+
lastUpdate = micros();
|
79
|
+
loopCount++;
|
80
|
+
updateDigitalListeners();
|
81
|
+
if (loopCount % analogDivider == 0) updateAnalogListeners();
|
82
|
+
}
|
83
|
+
}
|
84
|
+
void Dino::updateDigitalListeners() {
|
85
|
+
for (int i = 0; i < 22; i++) {
|
86
|
+
if (digitalListeners[i]) {
|
87
|
+
pin = i;
|
88
|
+
dRead();
|
89
|
+
if (rval != digitalListenerValues[i]) {
|
90
|
+
digitalListenerValues[i] = rval;
|
91
|
+
writeResponse();
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
void Dino::updateAnalogListeners() {
|
97
|
+
for (int i = 0; i < 22; i++) {
|
98
|
+
if (analogListeners[i]) {
|
99
|
+
pin = i;
|
100
|
+
aRead();
|
101
|
+
writeResponse();
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
long Dino::timeSince(long event) {
|
106
|
+
long time = micros() - event;
|
107
|
+
return time;
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
// API FUNCTIONS
|
113
|
+
// CMD = 00 // Pin Mode
|
114
|
+
void Dino::setMode() {
|
115
|
+
if (val == 0) {
|
116
|
+
removeListener();
|
117
|
+
pinMode(pin, OUTPUT);
|
118
|
+
#ifdef debug
|
119
|
+
Serial.print("Set pin "); Serial.print(pin); Serial.print(" to "); Serial.println("OUTPUT mode");
|
120
|
+
#endif
|
121
|
+
}
|
122
|
+
else {
|
123
|
+
pinMode(pin, INPUT);
|
124
|
+
#ifdef debug
|
125
|
+
Serial.print("Set pin "); Serial.print(pin); Serial.print(" to "); Serial.println("INPTUT mode");
|
126
|
+
#endif
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
// CMD = 01 // Digital Write
|
131
|
+
void Dino::dWrite() {
|
132
|
+
if (val == 0) {
|
133
|
+
digitalWrite(pin, LOW);
|
134
|
+
#ifdef debug
|
135
|
+
Serial.print("Digital write "); Serial.print(LOW); Serial.print(" to pin "); Serial.println(pin);
|
136
|
+
#endif
|
137
|
+
}
|
138
|
+
else {
|
139
|
+
digitalWrite(pin, HIGH);
|
140
|
+
#ifdef debug
|
141
|
+
Serial.print("Digital write "); Serial.print(HIGH); Serial.print(" to pin "); Serial.println(pin);
|
142
|
+
#endif
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
// CMD = 02 // Digital Read
|
147
|
+
void Dino::dRead() {
|
148
|
+
rval = digitalRead(pin);
|
149
|
+
sprintf(response, "%02d:%02d", pin, rval);
|
150
|
+
}
|
151
|
+
|
152
|
+
// CMD = 03 // Analog (PWM) Write
|
153
|
+
void Dino::aWrite() {
|
154
|
+
analogWrite(pin,val);
|
155
|
+
#ifdef debug
|
156
|
+
Serial.print("Analog write "); Serial.print(val); Serial.print(" to pin "); Serial.println(pin);
|
157
|
+
#endif
|
158
|
+
}
|
159
|
+
|
160
|
+
// CMD = 04 // Analog Read
|
161
|
+
void Dino::aRead() {
|
162
|
+
rval = analogRead(pin);
|
163
|
+
sprintf(response, "%02d:%02d", pin, rval);
|
164
|
+
}
|
165
|
+
|
166
|
+
// CMD = 05
|
167
|
+
// Listen for a digital signal on any pin.
|
168
|
+
void Dino::addDigitalListener() {
|
169
|
+
removeListener();
|
170
|
+
digitalListeners[pin] = true;
|
171
|
+
digitalListenerValues[pin] = 2;
|
172
|
+
#ifdef debug
|
173
|
+
Serial.print("Added digital listener on pin "); Serial.println(pin);
|
174
|
+
#endif
|
175
|
+
}
|
176
|
+
|
177
|
+
// CMD = 06
|
178
|
+
// Listen for an analog signal on analog pins only.
|
179
|
+
void Dino::addAnalogListener() {
|
180
|
+
removeListener();
|
181
|
+
analogListeners[pin] = true;
|
182
|
+
#ifdef debug
|
183
|
+
Serial.print("Added analog listener on pin "); Serial.println(pin);
|
184
|
+
#endif
|
185
|
+
}
|
186
|
+
|
187
|
+
// CMD = 07
|
188
|
+
// Remove analog and digital listeners from any pin.
|
189
|
+
void Dino::removeListener() {
|
190
|
+
analogListeners[pin] = false;
|
191
|
+
digitalListeners[pin] = false;
|
192
|
+
#ifdef debug
|
193
|
+
Serial.print("Removed listeners on pin "); Serial.println(pin);
|
194
|
+
#endif
|
195
|
+
}
|
196
|
+
|
197
|
+
// CMD = 08
|
198
|
+
// Attach the servo object to pin or detach it.
|
199
|
+
void Dino::servoToggle() {
|
200
|
+
if (val == 0) {
|
201
|
+
#ifdef debug
|
202
|
+
Serial.print("Detaching servo"); Serial.print(" on pin "); Serial.println(pin);
|
203
|
+
#endif
|
204
|
+
servos[pin - SERVO_OFFSET].detach();
|
205
|
+
}
|
206
|
+
else {
|
207
|
+
#ifdef debug
|
208
|
+
Serial.print("Attaching servo"); Serial.print(" on pin "); Serial.println(pin);
|
209
|
+
#endif
|
210
|
+
servos[pin - SERVO_OFFSET].attach(pin);
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
// CMD = 09
|
215
|
+
// Write a value to the servo object.
|
216
|
+
void Dino::servoWrite() {
|
217
|
+
#ifdef debug
|
218
|
+
Serial.print("Servo write "); Serial.print(val); Serial.print(" to pin "); Serial.println(pin);
|
219
|
+
#endif
|
220
|
+
servos[pin - SERVO_OFFSET].write(val);
|
221
|
+
}
|
222
|
+
|
223
|
+
// CMD = 90
|
224
|
+
void Dino::reset() {
|
225
|
+
heartRate = 4000; // Default heartRate is ~4ms.
|
226
|
+
loopCount = 0;
|
227
|
+
analogDivider = 4; // Update analog listeners every ~16ms.
|
228
|
+
for (int i = 0; i < 22; i++) digitalListeners[i] = false;
|
229
|
+
for (int i = 0; i < 22; i++) digitalListenerValues[i] = 2;
|
230
|
+
for (int i = 0; i < 22; i++) analogListeners[i] = false;
|
231
|
+
lastUpdate = micros();
|
232
|
+
index = 0;
|
233
|
+
#ifdef debug
|
234
|
+
Serial.println("Reset the board to defaults. pin ");
|
235
|
+
#endif
|
236
|
+
sprintf(response, "ACK:%02d", A0);
|
237
|
+
}
|
238
|
+
|
239
|
+
// CMD = 97
|
240
|
+
// Set the analog divider. Powers of 2 up to 128 are valid.
|
241
|
+
void Dino::setAnalogDivider() {
|
242
|
+
analogDivider = val;
|
243
|
+
#ifdef debug
|
244
|
+
Serial.print("Analog divider set to "); Serial.println(analogDivider);
|
245
|
+
#endif
|
246
|
+
}
|
247
|
+
|
248
|
+
// CMD = 98
|
249
|
+
// Set the heart rate in milliseconds. Store it in microseconds.
|
250
|
+
void Dino::setHeartRate() {
|
251
|
+
int rate = val;
|
252
|
+
heartRate = (rate * 1000);
|
253
|
+
#ifdef debug
|
254
|
+
Serial.print("Heart rate set to "); Serial.print(heartRate); Serial.println(" microseconds");
|
255
|
+
#endif
|
256
|
+
}
|
257
|
+
|