dino 0.10.0 → 0.11.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.
- 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
|
+
|