From f61b573f1ce8fcaf25c66175ed6455408d5ef711 Mon Sep 17 00:00:00 2001 From: Sijawusz Pur Rahnama Date: Fri, 14 Sep 2012 04:44:21 +0300 Subject: [PATCH 1/3] Update README.md Added list of changes. --- README.md | 60 ++++++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index f3d84d2..69eb43d 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ A framework for working with Arduinos in node.js # usage ````javascript -var arduino = require('duino'), - board = new arduino.Board(); +var Arduino = require('duino'), + board = new Arduino.Board(); -var led = new arduino.Led({ +var led = new Arduino.Led({ board: board, pin: 13 }); @@ -27,7 +27,7 @@ led.blink(); The way this works is simple (in theory, not in practice). The Arduino listens for low-level signals over a serial port, while we abstract all of the logic on the Node side. 1. Plug in your Arduino -2. Upload the C code at `./src/du.ino` to it +2. Upload Standard Firmata firmware (found in `Examples -> Firmata`) 3. Write a simple **duino** script 4. ????? 5. Profit! @@ -36,11 +36,12 @@ The way this works is simple (in theory, not in practice). The Arduino listens f ##board -Right now, the board library will attempt to autodiscover the Arduino. I'm going to make it configurable, don't worry. +Board library will attempt to autodiscover the Arduino unless you specify `serialPort` option. ````javascript var board = new arduino.Board({ - debug: true + debug: true, + baudrate: 9600 }); ```` @@ -91,7 +92,7 @@ Write a value between 0-255 to a pin ##led ````javascript -var led = new arduino.Led({ +var led = new Arduino.Led({ board: board, pin: 13 }); @@ -122,7 +123,7 @@ Current brightness of the LED ##piezo ````javascript -var led = new arduino.Piezo({ +var led = new Arduino.Piezo({ board: board, pin: 13 }); @@ -144,7 +145,7 @@ Write a square wave to the piezo element. ##button ````javascript -var button = new arduino.Button({ +var button = new Arduino.Button({ board: board, pin: 13 }); @@ -167,7 +168,7 @@ setInterval(function(){ ##servo ````javascript -var servo = new arduino.Servo({ +var servo = new Arduino.Servo({ board: board }); @@ -188,42 +189,11 @@ Instruct the servo to immediately go to a position from 0 to 180. ##potentiometer -# protocol +# changes in this fork -Each message sent to the Arduino board by the **board** class has 8 bytes. - -A full message looks like this: - - !0113001. - -`!` Start -`01` Command (digitalWrite) -`13` Pin number -`001` Value (high) -`.` Stop - -I was drunk. It works. - -##command - -What is implemented right now: - -* `00` pinMode -* `01` digitalWrite -* `02` digitalRead -* `03` analogWrite -* `04` analogRead -* `99` debug - -##pin - -Pins can be sent as an integer or a string(`1`, `2`, `"3"`, `"A0"`) - -##value - -* `board.LOW`(`0`) -* `board.HIGH`(`255`) -* integer/string from `0`-`255` for PWM pins +* Switched to Firmata protocol instead of using custom C code +* Added `I2C` related methods, namely: `sendI2CConfig`, `sendI2CWriteRequest` and `sendI2CReadRequest` +* Made baudrate and serial port path customizable # license From 6a146584b4ca9153aeee56cf53a444aa0ee92899 Mon Sep 17 00:00:00 2001 From: Sijawusz Pur Rahnama Date: Fri, 14 Sep 2012 04:45:01 +0300 Subject: [PATCH 2/3] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 69eb43d..0e45393 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ The way this works is simple (in theory, not in practice). The Arduino listens f Board library will attempt to autodiscover the Arduino unless you specify `serialPort` option. ````javascript -var board = new arduino.Board({ +var board = new Arduino.Board({ debug: true, baudrate: 9600 }); From fddf36cc1bd4c7c39ae7bb725ea4aea5192522fc Mon Sep 17 00:00:00 2001 From: Sijawusz Pur Rahnama Date: Sat, 15 Sep 2012 00:23:26 +0200 Subject: [PATCH 3/3] Switched to Firmata firmware - Added `serialPort` option to `Board` constructor allowing to specify serial port path instead of relying on duino's auto detection feature - Bumped version --- README.md | 5 +- lib/board.js | 174 +++++++++++++--------------------- lib/button.js | 40 ++++---- lib/led.js | 19 ++-- lib/piezo.js | 5 +- lib/pir.js | 30 +++++- lib/sensor.js | 36 +++----- package.json | 5 +- src/du.ino | 252 -------------------------------------------------- 9 files changed, 142 insertions(+), 424 deletions(-) delete mode 100644 src/du.ino diff --git a/README.md b/README.md index 0e45393..792ef41 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,7 @@ Board library will attempt to autodiscover the Arduino unless you specify `seria ````javascript var board = new Arduino.Board({ - debug: true, - baudrate: 9600 + debug: true }); ```` @@ -193,7 +192,7 @@ Instruct the servo to immediately go to a position from 0 to 180. * Switched to Firmata protocol instead of using custom C code * Added `I2C` related methods, namely: `sendI2CConfig`, `sendI2CWriteRequest` and `sendI2CReadRequest` -* Made baudrate and serial port path customizable +* Made serial port path customizable # license diff --git a/lib/board.js b/lib/board.js index 770d4c8..71ed591 100644 --- a/lib/board.js +++ b/lib/board.js @@ -1,9 +1,10 @@ -var events = require('events'), - child = require('child_process'), - util = require('util'), - colors = require('colors'), - serial = require('serialport'); +var events = require('events'), + child = require('child_process'), + util = require('util'), + colors = require('colors'), + serial = require('serialport'), + firmata = require('firmata'); /* * The main Arduino constructor @@ -12,48 +13,38 @@ var events = require('events'), var Board = function (options) { this.log('info', 'initializing'); this.debug = options && options.debug || false; - this.writeBuffer = []; + this.options = options; var self = this; - this.detect(function (err, serial) { + this.detect(function (err, port) { if (err) { - if(self.listeners('error').length) + if (self.listeners('error').length) self.emit('error', err); else throw new Error(err); - }else{ - self.serial = serial; - self.emit('connected'); - - self.log('info', 'binding serial events'); - self.serial.on('data', function(data){ - self.log('receive', data.toString().red); - self.emit('data', data); - }); - - setTimeout(function(){ + } else { + self.firmata = new firmata.Board(port, function(err) { + if (err) { + if (self.listeners('error').length) + return self.emit('error', err); + else + throw new Error(err); + } self.log('info', 'board ready'); - self.sendClearingBytes(); + self.log('info', 'firmware: ' + self.firmata.firmware.name + '-' + + self.firmata.firmware.version.major + '.' + self.firmata.firmware.version.minor + ); if (self.debug) { - self.log('info', 'sending debug mode toggle on to board'); - self.write('99' + self.normalizePin(0) + self.normalizeVal(1)); process.on('SIGINT', function(){ - self.log('info', 'sending debug mode toggle off to board'); - self.write('99' + self.normalizePin(0) + self.normalizeVal(0)); - delete self.serial; + delete self.firmata; setTimeout(function(){ process.exit(); }, 100); }); } - - if (self.writeBuffer.length > 0) { - self.processWriteBuffer(); - } - - self.emit('ready'); - }, 500); + self.emit('ready'); + }); } }); } @@ -69,71 +60,34 @@ util.inherits(Board, events.EventEmitter); * This should really message the device and wait for a correct response */ Board.prototype.detect = function (callback) { + var serialPort = this.options['serialPort']; + if (serialPort) { + this.log('info', 'attempting to connect to port ' + serialPort); + return callback(null, serialPort); + } this.log('info', 'attempting to find Arduino board'); var self = this; - child.exec('ls /dev | grep usb', function(err, stdout, stderr){ + child.exec('ls /dev | grep usb | grep ^tty', function(err, stdout, stderr) { var usb = stdout.slice(0, -1).split('\n'), found = false, err = null, possible, temp; while ( usb.length ) { - possible = usb.pop(); - - if (possible.slice(0, 2) !== 'cu') { - try { - temp = new serial.SerialPort('/dev/' + possible, { - baudrate: 115200, - parser: serial.parsers.readline('\n') - }); - } catch (e) { - err = e; - } - if (!err) { - found = temp; - self.log('info', 'found board at ' + temp.port); - break; - } else { - err = new Error('Could not find Arduino'); - } + possible = '/dev/' + usb.shift(); + + if (!err) { + found = possible; + self.log('info', 'found board at ' + found); + break; + } else { + err = new Error('Could not find Arduino'); } } - callback(err, found); }); } -/* - * The board will eat the first 4 bytes of the session - * So we give it crap to eat - */ -Board.prototype.sendClearingBytes = function () { - this.serial.write('00000000'); -} - -/* - * Process the writeBuffer (messages attempted before serial was ready) - */ -Board.prototype.processWriteBuffer = function () { - this.log('info', 'processing buffered messages'); - while (this.writeBuffer.length > 0) { - this.log('info', 'writing buffered message'); - this.write(this.writeBuffer.shift()); - } -} - -/* - * Low-level serial write - */ -Board.prototype.write = function (m) { - if (this.serial) { - this.log('write', m); - this.serial.write('!' + m + '.'); - } else { - this.log('info', 'serial not ready, buffering message: ' + m.red); - this.writeBuffer.push(m); - } -} /* * Add a 0 to the front of a single-digit pin number @@ -142,10 +96,6 @@ Board.prototype.normalizePin = function (pin) { return this.lpad( 2, '0', pin ); } -Board.prototype.normalizeVal = function(val) { - return this.lpad( 3, '0', val ); -} - // Board.prototype.lpad = function(len, chr, str) { return (Array(len + 1).join(chr || ' ') + str).substr(-len); @@ -154,23 +104,29 @@ Board.prototype.lpad = function(len, chr, str) { /* * Define constants */ -Board.prototype.HIGH = '255'; -Board.prototype.LOW = '000'; +Board.prototype.MODES = { + INPUT: 0x00, + OUTPUT: 0x01, + ANALOG: 0x02, + PWM: 0x03, + SERVO: 0x04 +}; +Board.prototype.I2C_MODES = { + WRITE: 0x00, + READ: 1, + CONTINUOUS_READ: 2, + STOP_READING: 3 +}; +Board.prototype.HIGH = 1; +Board.prototype.LOW = 0; /* * Set a pin's mode - * val == out = 001 - * val == in = 000 */ Board.prototype.pinMode = function (pin, val) { pin = this.normalizePin(pin); this.log('info', 'set pin ' + pin + ' mode to ' + val); - val = ( - val == 'out' ? - this.normalizeVal(1) : - this.normalizeVal(0) - ); - this.write('00' + pin + val); + this.firmata.pinMode(pin, val); } /* @@ -178,30 +134,28 @@ Board.prototype.pinMode = function (pin, val) { */ Board.prototype.digitalWrite = function (pin, val) { pin = this.normalizePin(pin); - val = this.normalizeVal(val); - this.log('info', 'digitalWrite to pin ' + pin + ': ' + val.green); - this.write('01' + pin + val); + this.log('info', 'digitalWrite to pin ' + pin + ': ' + (val ? 'HIGH'.green : 'LOW'.red)); + this.firmata.digitalWrite(pin, val); } /* * Tell the board to extract data from a pin */ -Board.prototype.digitalRead = function (pin) { +Board.prototype.digitalRead = function (pin, callback) { pin = this.normalizePin(pin); this.log('info', 'digitalRead from pin ' + pin); - this.write('02' + pin + this.normalizeVal(0)); + this.firmata.digitalRead(pin, callback); } Board.prototype.analogWrite = function (pin, val) { - pin = this.normalizePin(pin); - val = this.normalizeVal(val); - this.log('info', 'analogWrite to pin ' + pin + ': ' + val.green); - this.write('03' + pin + val); + pin = this.normalizePin(pin); + this.log('info', 'analogWrite to pin ' + pin + ': ' + val.toString().green); + this.firmata.analogWrite(pin, val); } -Board.prototype.analogRead = function (pin) { - pin = this.normalizePin(pin); - this.log('info', 'analogRead from pin ' + pin); - this.write('04' + pin + this.normalizeVal(0)); +Board.prototype.analogRead = function (pin, callback) { + pin = this.normalizePin(pin); + this.log('info', 'analogRead from pin ' + pin); + this.firmata.analogRead(pin, callback); } /* diff --git a/lib/button.js b/lib/button.js index 636a132..490a093 100644 --- a/lib/button.js +++ b/lib/button.js @@ -7,32 +7,28 @@ var events = require('events'), * Tell the board to set it up */ var Button = function (options) { + var self = this; if (!options || !options.board) throw new Error('Must supply required options to Button'); this.board = options.board; this.pin = options.pin || 13; this.down = false; - this.board.pinMode(this.pin, 'in'); - var self = this; - setInterval(function () { - self.board.digitalRead(self.pin); - }, 50); - this.board.on('data', function (m) { - m = m.slice(0, -1).split('::'); - - var err = null; - - if (m.length > 1 && m[0] == self.pin) { - // 0 is up - // 1 is down - if (m[1] == 0 && self.down) { - self.down = false; - self.emit('up', err); - } - if (m[1] == 1 && !self.down) { - self.down = true; - self.emit('down', err); - } - } + this.board.on('ready', function() { + self.board.pinMode(self.pin, self.board.MODES.INPUT); + + setInterval(function () { + self.board.digitalRead(self.pin, function(err, data) { + if (err) { + return self.emit('error', err); + } + if (data && self.down) { + self.down = false; + self.emit('up'); + } + if (!data && !self.down) { + self.down = true; + self.emit('down'); + }); + }, 50); }); } diff --git a/lib/led.js b/lib/led.js index 6017587..0eef5a6 100644 --- a/lib/led.js +++ b/lib/led.js @@ -5,12 +5,15 @@ * Tell the board to set it up */ var Led = function (options) { + var self = this; if (!options || !options.board) throw new Error('Must supply required options to LED'); this.board = options.board; this.pin = options.pin || 13; this.bright = 0; - this.board.pinMode(this.pin, 'out'); - this.direction = -1; + this.board.on('ready', function() { + self.board.pinMode(self.pin, self.board.MODES.OUTPUT); + }); + this.direction = 1; } /* @@ -34,14 +37,14 @@ Led.prototype.brightLevel = function(val) { } Led.prototype.fade = function(interval) { - to = (interval||5000)/(255*2); + interval = (interval || 5000) / (255 * 2); var self = this; setInterval(function() { - if(!self.board.serial) return; //Interval too fast for debug messages on ^c - if(self.bright==0) direction = 1; - if(self.bright==255) direction = -1; - self.brightLevel(self.bright+direction); - },to); + if (!self.board.firmata) return; // Interval too fast for debug messages on ^c + if (self.bright == 0) self.direction = 1; + if (self.bright == 255) self.direction = -1; + self.brightLevel(self.bright + self.direction); + }, interval); } diff --git a/lib/piezo.js b/lib/piezo.js index a3a0dbb..5fbe824 100644 --- a/lib/piezo.js +++ b/lib/piezo.js @@ -5,11 +5,14 @@ * Tell the board to set pin mode */ var Piezo = function (options) { + var self = this; if (!options || !options.board) throw new Error('Must supply required options to Piezo'); this.board = options.board; this.pin = options.pin || 13; this.bright = false; - this.board.pinMode(this.pin, 'out'); + this.board.on('ready', function() { + self.board.pinMode(self.pin, self.board.MODES.OUTPUT); + }); } /* diff --git a/lib/pir.js b/lib/pir.js index cef77dc..74afdf2 100644 --- a/lib/pir.js +++ b/lib/pir.js @@ -15,8 +15,36 @@ var PIR = function (options) { this.state = null; this.calibrated = false; + var self = this; setInterval(function () { - this.board.digitalRead(this.pin); + this.board.digitalRead(this.pin, function(err, data) { + // If this is not a calibration event + if (self.state != null && self.state != +data) { + + // Update current state of PIR instance + self.state = +data; + + // 'motionstart' event fired when motion occurs + // within the observable range of the PIR sensor + if (data === '01') { + self.emit('motionstart', err, timestamp); + } + + // 'motionend' event fired when motion has ceased + // within the observable range of the PIR sensor + if (data === '00') { + self.emit('motionend', err, timestamp); + } + } + + // 'calibrated' event fired when PIR sensor is + // ready to detect movement/motion in observable range + if (!self.calibrated) { + self.calibrated = true; + self.state = +data; + self.emit('calibrated', err, timestamp); + } + }); }.bind(this), 50); this.board.on('data', function (message) { diff --git a/lib/sensor.js b/lib/sensor.js index a1883fc..548fde5 100644 --- a/lib/sensor.js +++ b/lib/sensor.js @@ -7,34 +7,20 @@ var events = require('events'), * Tell the board to set it up */ var Sensor = function (options) { + var self = this; if (!options || !options.board) throw new Error('Must supply required options to Sensor'); this.board = options.board; this.pin = options.pin || 'A0'; - this.board.pinMode(this.pin, 'in'); - - // Poll for sensor readings - setInterval(function () { - this.board.analogRead(this.pin); - }.bind(this), options.throttle || 50); - - // When data is received, parse inbound message - // match pin to instance pin value - this.board.on('data', function (message) { - var m = message.slice(0, -1).split('::'), - err = null, - pin, data; - - if (!m.length) { - return; - } - - pin = m[0] - data = m.length === 2 ? m[1] : null; - - if (pin === this.pin) { - this.emit('read', err, data); - } - }.bind(this)); + this.board.on('ready', function() { + self.board.pinMode(self.pin, self.board.MODES.INPUT); + + // Poll for sensor readings + setInterval(function () { + self.board.analogRead(self.pin, function(err, data) { + self.emit('read', err, data); + }); + }, options.throttle || 50); + }); }; /* diff --git a/package.json b/package.json index 7c7b79b..93a9ba8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ ], "name": "duino", "description": "Arduino framework for mad scientists", - "version": "0.0.7", + "version": "0.0.8", "keywords": [ "arduino", "serial", @@ -15,13 +15,14 @@ ], "repository": { "type": "git", - "url": "git://github.com/ecto/duino.git" + "url": "git://github.com/Sija/duino.git" }, "main": "index.js", "engines": { "node": "*" }, "dependencies": { + "firmata": "*", "serialport": "*", "colors": "*" }, diff --git a/src/du.ino b/src/du.ino deleted file mode 100644 index 2427435..0000000 --- a/src/du.ino +++ /dev/null @@ -1,252 +0,0 @@ -#include - - -bool debug = false; - -int index = 0; - -char messageBuffer[12]; -char cmd[3]; -char pin[3]; -char val[4]; -char aux[4]; - -Servo servo; - -void setup() { - Serial.begin(115200); -} - -void loop() { - while(Serial.available() > 0) { - char x = Serial.read(); - if (x == '!') index = 0; // start - else if (x == '.') process(); // end - else messageBuffer[index++] = x; - } -} - -/* - * Deal with a full message and determine function to call - */ -void process() { - index = 0; - - strncpy(cmd, messageBuffer, 2); - cmd[2] = '\0'; - strncpy(pin, messageBuffer + 2, 2); - pin[2] = '\0'; - - if (atoi(cmd) > 90) { - strncpy(val, messageBuffer + 4, 2); - val[2] = '\0'; - strncpy(aux, messageBuffer + 6, 3); - aux[3] = '\0'; - } else { - strncpy(val, messageBuffer + 4, 3); - val[4] = '\0'; - strncpy(aux, messageBuffer + 7, 3); - aux[4] = '\0'; - } - - if (debug) { - Serial.println(messageBuffer); - } - int cmdid = atoi(cmd); - - // Serial.println(cmd); - // Serial.println(pin); - // Serial.println(val); - // Serial.println(aux); - - switch(cmdid) { - case 0: sm(pin,val); break; - case 1: dw(pin,val); break; - case 2: dr(pin,val); break; - case 3: aw(pin,val); break; - case 4: ar(pin,val); break; - case 97: handlePing(pin,val,aux); break; - case 98: handleServo(pin,val,aux); break; - case 99: toggleDebug(val); break; - default: break; - } -} - -/* - * Toggle debug mode - */ -void toggleDebug(char *val) { - if (atoi(val) == 0) { - debug = false; - Serial.println("goodbye"); - } else { - debug = true; - Serial.println("hello"); - } -} - -/* - * Set pin mode - */ -void sm(char *pin, char *val) { - if (debug) Serial.println("sm"); - int p = getPin(pin); - if(p == -1) { if(debug) Serial.println("badpin"); return; } - if (atoi(val) == 0) { - pinMode(p, OUTPUT); - } else { - pinMode(p, INPUT); - } -} - -/* - * Digital write - */ -void dw(char *pin, char *val) { - if (debug) Serial.println("dw"); - int p = getPin(pin); - if(p == -1) { if(debug) Serial.println("badpin"); return; } - pinMode(p, OUTPUT); - if (atoi(val) == 0) { - digitalWrite(p, LOW); - } else { - digitalWrite(p, HIGH); - } -} - -/* - * Digital read - */ -void dr(char *pin, char *val) { - if (debug) Serial.println("dr"); - int p = getPin(pin); - if(p == -1) { if(debug) Serial.println("badpin"); return; } - pinMode(p, INPUT); - int oraw = digitalRead(p); - char m[7]; - sprintf(m, "%02d::%02d", p,oraw); - Serial.println(m); -} - -/* - * Analog read - */ -void ar(char *pin, char *val) { - if(debug) Serial.println("ar"); - int p = getPin(pin); - if(p == -1) { if(debug) Serial.println("badpin"); return; } - pinMode(p, INPUT); // don't want to sw - int rval = analogRead(p); - char m[8]; - sprintf(m, "%s::%03d", pin, rval); - Serial.println(m); -} - -void aw(char *pin, char *val) { - if(debug) Serial.println("aw"); - int p = getPin(pin); - pinMode(p, OUTPUT); - if(p == -1) { if(debug) Serial.println("badpin"); return; } - analogWrite(p,atoi(val)); -} - -int getPin(char *pin) { //Converts to A0-A5, and returns -1 on error - int ret = -1; - if(pin[0] == 'A' || pin[0] == 'a') { - switch(pin[1]) { - case '0': ret = A0; break; - case '1': ret = A1; break; - case '2': ret = A2; break; - case '3': ret = A3; break; - case '4': ret = A4; break; - case '5': ret = A5; break; - default: break; - } - } else { - ret = atoi(pin); - if(ret == 0 && (pin[0] != '0' || pin[1] != '0')) { - ret = -1; - } - } - return ret; -} - -/* - * Handle Ping commands - * fire, read - */ -void handlePing(char *pin, char *val, char *aux) { - if (debug) Serial.println("ss"); - int p = getPin(pin); - - if(p == -1) { if(debug) Serial.println("badpin"); return; } - Serial.println("got signal"); - - // 01(1) Fire and Read - if (atoi(val) == 1) { - char m[16]; - - pinMode(p, OUTPUT); - digitalWrite(p, LOW); - delayMicroseconds(2); - digitalWrite(p, HIGH); - delayMicroseconds(5); - digitalWrite(p, LOW); - - Serial.println("ping fired"); - - pinMode(p, INPUT); - sprintf(m, "%s::read::%08d", pin, pulseIn(p, HIGH)); - Serial.println(m); - - delay(50); - } -} - -/* - * Handle Servo commands - * attach, detach, write, read, writeMicroseconds, attached - */ -void handleServo(char *pin, char *val, char *aux) { - if (debug) Serial.println("ss"); - int p = getPin(pin); - if(p == -1) { if(debug) Serial.println("badpin"); return; } - Serial.println("signal: servo"); - - // 00(0) Detach - if (atoi(val) == 0) { - servo.detach(); - char m[12]; - sprintf(m, "%s::detached", pin); - Serial.println(m); - - // 01(1) Attach - } else if (atoi(val) == 1) { - // servo.attach(p, 750, 2250); - servo.attach(p); - char m[12]; - sprintf(m, "%s::attached", pin); - Serial.println(m); - - // 02(2) Write - } else if (atoi(val) == 2) { - Serial.println("writing to servo"); - Serial.println(atoi(aux)); - // Write to servo - servo.write(atoi(aux)); - delay(15); - - // TODO: Experiment with microsecond pulses - // digitalWrite(pin, HIGH); // start the pulse - // delayMicroseconds(pulseWidth); // pulse width - // digitalWrite(pin, LOW); // stop the pulse - - // 03(3) Read - } else if (atoi(val) == 3) { - Serial.println("reading servo"); - int sval = servo.read(); - char m[13]; - sprintf(m, "%s::read::%03d", pin, sval); - Serial.println(m); - } -}