pan_tilt 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p392
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fuci.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Dave Jachimiak
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Pan and Tilt
2
+
3
+ Pan and tilt your Arduino connected servos
data/bin/pan_tilt ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pan_tilt'
3
+
4
+ PanTilt.run
data/lib/du/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
+
data/lib/du/Dino.h ADDED
@@ -0,0 +1,85 @@
1
+ /*
2
+ Library for dino ruby gem.
3
+ */
4
+
5
+ #ifndef Dino_h
6
+ #define Dino_h
7
+
8
+ #include "Arduino.h"
9
+ #include <Servo.h>
10
+
11
+ // Allocate listener storage based on what board we're running.
12
+ #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
13
+ # define PIN_COUNT 70
14
+ # define SERVO_OFFSET 22
15
+ #else
16
+ # define PIN_COUNT 22
17
+ # define SERVO_OFFSET 2
18
+ #endif
19
+
20
+ // Uncomment this line to enable debugging mode.
21
+ // #define debug true
22
+
23
+ class Dino {
24
+ public:
25
+ Dino();
26
+ void setupWrite(void (*writeCallback)(char *str));
27
+ void parse(char c);
28
+ void process();
29
+ void updateListeners();
30
+
31
+ private:
32
+ // Manage heartbeat and listeners.
33
+ long heartRate;
34
+ long lastUpdate;
35
+ unsigned int loopCount;
36
+ unsigned int analogDivider;
37
+
38
+ // Storage for enough analog and digital listeners for UNO or Nano board.
39
+ // Correspond to raw pin number by array index, and store boolean. false == disabled.
40
+ boolean analogListeners[PIN_COUNT];
41
+ boolean digitalListeners[PIN_COUNT];
42
+
43
+ // Keep track of the last read values for digital listeners. Only write responses when changed.
44
+ byte digitalListenerValues[PIN_COUNT];
45
+
46
+ // Request storage.
47
+ char request[8];
48
+ int index;
49
+ char cmdStr[3];
50
+ byte cmd;
51
+ char pinStr[3];
52
+ byte pin;
53
+ char valStr[4];
54
+ int val;
55
+
56
+ // Value and response storage.
57
+ int rval;
58
+ char response[8];
59
+ void (*_writeCallback)(char *str);
60
+ void writeResponse();
61
+
62
+ Servo servos[12];
63
+
64
+ // API-accessible functions.
65
+ void setMode ();
66
+ void dWrite ();
67
+ void dRead ();
68
+ void aWrite ();
69
+ void aRead ();
70
+ void addDigitalListener ();
71
+ void addAnalogListener ();
72
+ void removeListener ();
73
+ void servoToggle ();
74
+ void servoWrite ();
75
+ void reset ();
76
+ void setAnalogDivider ();
77
+ void setHeartRate ();
78
+
79
+ // Internal functions.
80
+ long timeSince (long event);
81
+ void updateDigitalListeners ();
82
+ void updateAnalogListeners ();
83
+ };
84
+
85
+ #endif
data/lib/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,3 @@
1
+ module PanTilt
2
+ VERSION = "0.0.1"
3
+ end
data/lib/pan_tilt.rb ADDED
@@ -0,0 +1,55 @@
1
+ require "pan_tilt/version"
2
+
3
+ require 'bundler/setup'
4
+ require 'dino'
5
+ require 'io/console'
6
+
7
+ module PanTilt
8
+ ESCAPE = 'e'
9
+ LEFT_ARROW = 'h'
10
+ RIGHT_ARROW = 'l'
11
+ UP_ARROW = 'k'
12
+ DOWN_ARROW = 'j'
13
+ MAX_TILT_ANGLE = 135
14
+ MAX_PAN_ANGLE = 180
15
+ MIN_TILT_ANGLE = 15
16
+ MIN_PAN_ANGLE = 0
17
+ INCREMENT = 5
18
+
19
+ board = Dino::Board.new(Dino::TxRx::Serial.new)
20
+ tilt_servo = Dino::Components::Servo.new(pin: 9, board: board)
21
+ pan_servo = Dino::Components::Servo.new(pin: 11, board: board)
22
+
23
+ pan_angle = MIN_PAN_ANGLE
24
+ tilt_angle = MIN_TILT_ANGLE
25
+
26
+ def self.run
27
+ while key = STDIN.getch
28
+ case key
29
+ when ESCAPE
30
+ break
31
+ when LEFT_ARROW
32
+ if pan_angle > MIN_PAN_ANGLE
33
+ pan_angle = pan_angle - INCREMENT
34
+ pan_servo.position = pan_angle
35
+ end
36
+ when RIGHT_ARROW
37
+ if pan_angle < MAX_PAN_ANGLE
38
+ pan_angle = pan_angle + INCREMENT
39
+ pan_servo.position = pan_angle
40
+ end
41
+ when DOWN_ARROW
42
+ if tilt_angle > MIN_TILT_ANGLE
43
+ tilt_angle = tilt_angle - INCREMENT
44
+ tilt_servo.position = tilt_angle
45
+ end
46
+ when UP_ARROW
47
+ if tilt_angle < MAX_TILT_ANGLE
48
+ tilt_angle = tilt_angle + INCREMENT
49
+ tilt_servo.position = tilt_angle
50
+ end
51
+ end
52
+ puts "p: #{pan_angle}, t: #{tilt_angle}"
53
+ end
54
+ end
55
+ end
data/pan_tilt.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pan_tilt/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "pan_tilt"
8
+ spec.version = PanTilt::VERSION
9
+ spec.authors = ["Will Mernagh"]
10
+ spec.email = ["wmernagh@gmail.com"]
11
+ spec.description = %q{Pan and Tilt Arduino connected Servos}
12
+ spec.summary = %q{TBA}
13
+ spec.homepage = "https://github.com/wmernagh/pan_tilt"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split("\n")
17
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "dino"
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pan_tilt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Will Mernagh
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: dino
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.3'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Pan and Tilt Arduino connected Servos
63
+ email:
64
+ - wmernagh@gmail.com
65
+ executables:
66
+ - pan_tilt
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .ruby-version
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.md
75
+ - bin/pan_tilt
76
+ - lib/du/Dino.cpp
77
+ - lib/du/Dino.h
78
+ - lib/du/du.ino
79
+ - lib/pan_tilt.rb
80
+ - lib/pan_tilt/version.rb
81
+ - pan_tilt.gemspec
82
+ homepage: https://github.com/wmernagh/pan_tilt
83
+ licenses:
84
+ - MIT
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.23
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: TBA
107
+ test_files: []