Skip to content
Browse files

Merge branch 'servo-functions' into development

* servo-functions:
  Widen servo pulse range
  No formal param list for logging function
  Consistent quotes
  Abstract numeric normalization/padding into reusable method
  Servo event examples
  Adds functionality to Servo module to handle attached, detached, read events
  Updates all servo functionality for maximum flexibility in use cases. New events: attached, detached, read (returns current servo position reading)
  Simplify handleServo responsibilities
  Bolster servo controls
  • Loading branch information...
2 parents e8c08be + b1cf76f commit efc8fa2207c0ee02c23d0e686ba89ab654472374 @rwaldron rwaldron committed
Showing with 216 additions and 44 deletions.
  1. +44 −5 examples/servo.js
  2. +11 −12 lib/board.js
  3. +133 −23 lib/servo.js
  4. +28 −4 src/du.ino
View
49 examples/servo.js
@@ -1,11 +1,50 @@
-var arduino = require('../');
+var arduino = require('../'),
+ board, led, servo;
-var board = new arduino.Board({
+// Construct instances
+board = new arduino.Board({
debug: true
});
-var servo = new arduino.Servo({
- board: board
+led = new arduino.Led({
+ board: board,
+ pin: 13
});
-servo.sweep();
+servo = new arduino.Servo({
+ board: board,
+ pin: 9
+});
+
+// Once servo is attached:
+// - "read"
+// - log position
+// - "aftersweep"
+// - blink the led
+// - read the position
+// - detach the servo
+// - "detached"
+// - log detach message
+//
+// - execute full sweep
+
+servo.on('attached', function() {
+ console.log('attached');
+
+ this.on('read', function(pos) {
+ console.log(pos);
+ });
+
+ this.on('detached', function() {
+ console.log('detached');
+ });
+
+ this.on('aftersweep', function() {
+ led.blink();
+
+ this.read();
+ this.detach();
+ });
+
+ this.sweep();
+});
View
23 lib/board.js
@@ -73,7 +73,7 @@ Board.prototype.detect = function (cb) {
try {
tempSerial = new serial.SerialPort('/dev/' + possible[i], {
baudrate: 115200,
- parser: serial.parsers.readline("\n")
+ parser: serial.parsers.readline('\n')
});
} catch (e) {
err = e;
@@ -125,20 +125,18 @@ Board.prototype.write = function (m) {
* Add a 0 to the front of a single-digit pin number
*/
Board.prototype.normalizePin = function (pin) {
- return ("00" + pin).substr(-2);
- /*pin = String(pin).split('');
- if (pin.length > 1) {
- return pin.join('');
- } else {
- pin.unshift('0');
- return pin.join('');
- }*/
+ return this.lpad( 2, '0', pin );
}
Board.prototype.normalizeVal = function(val) {
- return ("000" + val).substr(-3);
+ return this.lpad( 3, '0', val );
}
+//
+Board.prototype.lpad = function(len, chr, str) {
+ return (Array(len + 1).join(chr || ' ') + str).substr(-len);
+};
+
/*
* Define constants
*/
@@ -203,9 +201,10 @@ Board.prototype.delay = function (ms) {
/*
* Logger utility function
*/
-Board.prototype.log = function (level, message) {
+Board.prototype.log = function (/*level, message*/) {
+ var args = [].slice.call(arguments);
if (this.debug) {
- console.log(String(+new Date()).grey + ' duino '.blue + level.magenta + ' ' + message);
+ console.log(String(+new Date()).grey + ' duino '.blue + args.shift().magenta + ' ' + args.join(', '));
}
}
View
156 lib/servo.js
@@ -1,3 +1,6 @@
+var events = require('events'),
+ util = require('util');
+
/*
* Main Servo constructor
* Process options
@@ -7,32 +10,139 @@ var Servo = function (options) {
if (!options || !options.board) throw new Error('Must supply required options to Sutton');
this.board = options.board;
this.pin = this.board.normalizePin(options.pin || 9);
- var self = this;
+
+ var types = {
+ attached: true,
+ detached: true,
+ read: true,
+ moved: true
+ };
+
this.board.on('ready', function () {
- self.attach();
- });
-}
+ this.attach();
+ }.bind(this));
-Servo.prototype.write = function (pos) {
- this.board.write('98' + this.pin + '02' + pos);
-}
+ this.board.on('data', function (message) {
+ var m = message.slice(0, -1).split('::'),
+ pin, type, data;
+
+ if (!m.length) {
+ return;
+ }
+
+ pin = m[0]
+ type = m[1];
+ data = m.length === 3 ? m[2] : null;
+
+ if (pin === this.pin && types[type]) {
+ this.emit(type, data);
+ }
+ }.bind(this));
+};
+
+util.inherits(Servo, events.EventEmitter);
+
+Servo.prototype.command = function () {
+ var msg = '98' + this.pin + ([].slice.call(arguments).join(''));
+
+ // this.board.log( 'info', 'command', msg );
+ this.board.write(msg);
+};
+
+Servo.prototype.detach = function () {
+ this.command('00');
+};
Servo.prototype.attach = function () {
- this.board.write('98' + this.pin + '01');
-}
-
-Servo.prototype.read = function () {}
-Servo.prototype.detach = function () {}
-Servo.prototype.writeMilliseconds = function () {}
-Servo.prototype.attached = function () {}
-
-Servo.prototype.sweep = function () {
- var self = this;
- var pos = 0;
- setInterval(function() {
- self.write(pos++);
- if (pos == 180) clearInterval(this);
- }, 25);
-}
+ this.command('01');
+};
+
+Servo.prototype.write = function (pos) {
+ pos = this.board.lpad(3, '0', pos);
+ this.board.log('info', 'moving to: ' + pos);
+ this.command('02' + pos);
+};
+
+Servo.prototype.read = function (callback) {
+ this.command('03');
+};
+
+// Servo.prototype.writeMilliseconds = function () {};
+// Servo.prototype.attached = function (callback) {
+// this.callbacks.attached.push(callback);
+// };
+
+Servo.prototype.sweep = function (options) {
+ // Ensure no missing options object
+ options = options || {};
+
+ var timeout = {
+ inner: null,
+ outer: null
+ },
+ moves = 0,
+ // sweep settings
+ lapse = options.lapse || 500,
+ to = options.to || 180,
+ from = options.from || 1;
+ // sweep handlers
+ doSweep = function doSweep(pos) {
+ // this.board.log('info', 'current position: ', pos);
+ var moveTo,
+ posint = +pos;
+
+ // this.board.log('info', 'current pos int: ', posint);
+
+ if (posint === 93) {
+ moveTo = 1;
+ } else {
+
+ // this.board.log('info', 'posint not 93.....');
+
+ if (posint < to) {
+ moveTo = to;
+ } else if (posint == to) {
+ moveTo = 90;
+ } else {
+ moveTo = from;
+ }
+ }
+
+ this.write(moveTo);
+
+ moves++;
+
+ // this.board.log( 'info', 'moves: ', moves );
+ };
+
+ this.on('read', doSweep);
+
+ // this.write(1);
+
+ // Initialize sweep; wait for for stack unwind.
+ timeout.outer = setTimeout(function loop() {
+ // Read the current position, will trigger
+ // 'read' event with position data;
+
+
+ if (moves < 2) {
+ this.read();
+
+ timeout.inner = setTimeout(loop.bind(this), lapse);
+ } else {
+ // this.board.log('info', 'info', 'clearing');
+
+ clearTimeout(timeout.inner);
+ clearTimeout(timeout.outer);
+
+ loop = null;
+
+ this.removeListener('read', doSweep);
+ this.emit.call(this, 'aftersweep');
+
+ // this.board.log('info', this);
+ }
+ }.bind(this), 0);
+};
module.exports = Servo;
View
32 src/du.ino
@@ -1,12 +1,18 @@
#include <Servo.h>
-char messageBuffer[12];
+
+bool debug = false;
+
int index = 0;
+
+char messageBuffer[12];
char cmd[3];
char pin[3];
char val[4];
char aux[4];
-bool debug = false;
+
+
+
Servo servo;
void setup() {
@@ -166,14 +172,32 @@ void handleServo(char *pin, char *val, char *aux) {
int p = getPin(pin);
if(p == -1) { if(debug) Serial.println("badpin"); return; }
Serial.println("got signal");
+
if (atoi(val) == 0) {
servo.detach();
+ char m[12];
+ sprintf(m, "%s::detached", pin);
+ Serial.println(m);
} else if (atoi(val) == 1) {
- servo.attach(p);
- Serial.println("attached");
+ servo.attach(p, 100, 2200);
+ char m[12];
+ sprintf(m, "%s::attached", pin);
+ Serial.println(m);
} else if (atoi(val) == 2) {
Serial.println("writing to servo");
Serial.println(atoi(aux));
+ // Write to servo
servo.write(atoi(aux));
+
+ // TODO: Experiment with microsecond pulses
+ // digitalWrite(pin, HIGH); // start the pulse
+ // delayMicroseconds(pulseWidth); // pulse width
+ // digitalWrite(pin, LOW); // stop the pulse
+ } else if (atoi(val) == 3) {
+ Serial.println("reading servo");
+ int sval = servo.read();
+ char m[8];
+ sprintf(m, "%s::read::%03d", pin, sval);
+ Serial.println(m);
}
}

0 comments on commit efc8fa2

Please sign in to comment.
Something went wrong with that request. Please try again.