From 4761d5c6877617c5dbc82c713555815017613d47 Mon Sep 17 00:00:00 2001 From: kolban Date: Sun, 13 Mar 2016 22:21:59 -0500 Subject: [PATCH] sync update --- README.md | 17 +++--- src/stepper-wiringpi.js | 114 ++++++++++++++++++++++++++++------------ tests/test5.js | 51 ++++++++++++++++++ 3 files changed, 141 insertions(+), 41 deletions(-) create mode 100644 tests/test5.js diff --git a/README.md b/README.md index 3db59cb..41be066 100644 --- a/README.md +++ b/README.md @@ -81,14 +81,15 @@ is specified by the number of pins supplied in the `setup` call. In summary, the methods are: -| Method | Description | -|---------------------------|---------------------------| -| `setSpeed(rpm)` | Set the speed of rotation | -| `forward()` | Start rotating forwards | -| `backward()` | Start rotating backwards | -| `stop()` | Stop rotating | -| `step(steps, [callback])` | Step the motor | - +| Method | Description | +|--------------------------------------------------------------|----------------------------| +| `setup(stepsInRevolution, pin1, pin2, [pin3, pin4, [pin5]])` | Setup the motor | +| `setSpeed(rpm)` | Set the speed of rotation | +| `forward()` | Start rotating forwards | +| `backward()` | Start rotating backwards | +| `stop()` | Stop rotating | +| `step(steps, [callback])` | Step the motor | +| `halt()` | Halt the motor (free turn) | ## Dependencies This package depends upon: diff --git a/src/stepper-wiringpi.js b/src/stepper-wiringpi.js index 3f89c6c..57df8e0 100644 --- a/src/stepper-wiringpi.js +++ b/src/stepper-wiringpi.js @@ -1,7 +1,7 @@ /** * stepper-wiringpi * A module that moves a stepper motor for the Raspberry Pi based on the Wiring-Pi - * module for GPIO access. + * module for GPIO access. See the README.md file for usage details. * * Based on the design and implementation of the Arduino Stepper class found here: * @@ -12,14 +12,24 @@ */ -const wpi = require('wiring-pi'); +var wpi = require('wiring-pi'); wpi.setup('gpio'); + + +// Create definitions for the constants. var FORWARD = 1; var BACKWARD = -1; + +// Publish the constants. exports.FORWARD = FORWARD; exports.BACKWARD = BACKWARD; +// A global used to identify motors for debugging purposes. The first motor created +// will have index 1, the next will have index 2 and so on. +var motorIndex=1; + + function setup2Wire(motorPin1, motorPin2) { // Pi pins for the motor control connection: @@ -93,14 +103,19 @@ exports.setup = function(stepsPerRevolution, motorPin1, motorPin2, motorPin3, mo forward: forward, // Function backward: backward, // Function stop: stop, // Function + halt: halt, // Function + _motorIndex: motorIndex, // The index of the motor used for debugging purposes. _stepDelay: 60*1000/stepsPerRevolution, // Set the default step delay to 1 rpm. _stepNumber: 0, // Which step the motor is on. - _direction: 0, // Motor direction. - _timerId: null, - _moveTimeoutId: null, + _direction: FORWARD, // Motor direction. + _timerId: null, // Interval object for stepping fixed number of steps. + _moveTimeoutId: null, // Timeout object for continuous rotation _stepsPerRevolution: stepsPerRevolution // Total number of steps for this motor. } + + motorIndex++; // Increment the global motorIndex count (used for debugging). + // Determine whether we are being called with 2,4 or 5 pins and setup accordingly. if (motorPin3 == undefined) { setup2Wire.call(context, motorPin1, motorPin2); @@ -114,7 +129,8 @@ exports.setup = function(stepsPerRevolution, motorPin1, motorPin2, motorPin3, mo /** - * Sets the speed in revs per minute + * PUBLIC: + * Sets the speed in revolutions per minute (RPM) */ function setSpeed(desiredRPM) { @@ -141,6 +157,7 @@ function setSpeed(desiredRPM) this._stepDelay = maxRPM / desiredRPM; } // End of setSpeed + //PUBLIC: Set the motor to rotate forwards at the current set speed. function forward() { stop.call(this); @@ -158,11 +175,11 @@ function move(direction) { //console.log("move: direction: %d", direction); //console.log("move: %j", this); if (direction == FORWARD) { - this._stepNumber++; + incrementStepNumber.call(this); } else { - this._stepNumber--; + decrementStepNumber.call(this); } - //console.log("Step number: %d", this._stepNumber); + console.log("Step number: %d", this._stepNumber); stepMotor.call(this, this._stepNumber); this._moveTimeoutId = setTimeout(move.bind(this), this._stepDelay, direction); } @@ -176,7 +193,8 @@ function stop() { } /** - * Moves the motor stepsToMove steps. If the number is negative, + * PRIVATE: + * Moves the motor a fixed number of steps defined by `stepsToMove`. If the number is negative, * the motor moves in the reverse direction. The optional callback * function will be invoked when the number of steps being asked to * be moved have been moved. @@ -193,14 +211,16 @@ function step(stepsToMove, callback) var stepsLeft = Math.abs(stepsToMove); // how many steps to take // determine direction based on whether stepsToMove is + or -: - if (stepsToMove > 0) { this._direction = 1; } - if (stepsToMove < 0) { this._direction = 0; } + if (stepsToMove > 0) { this._direction = FORWARD; } + if (stepsToMove < 0) { this._direction = BACKWARD; } // If we should already be in the middle of a movement, cancel it. if (this._timerId != null) { clearInterval(this._timerId); } + stop(); // If we are in a continuous rotation ... stop that too. + // Note: A question comes up on scheduling the first move immediately // as opposed to a stepDelay later. We should always pause at least // one stepDelay even for the first step. Consider what would happen @@ -214,46 +234,74 @@ function step(stepsToMove, callback) // we started. this._timerId = setInterval(function() { + // If we have moved the correct number of steps then cancel the timer and return + // after invoking a callback (if one has been supplied). + if (stepsLeft <= 0) { + clearInterval(this._timerId); + this._timerId = null; + if (callback != null) { + callback(); + } + return; + } // End of stepsLeft <= 0 + // increment or decrement the step number, depending on direction: - if (this._direction == 1) + if (this._direction == FORWARD) { - this._stepNumber++; - if (this._stepNumber == this._stepsPerRevolution) { - this._stepNumber = 0; - } + incrementStepNumber.call(this); } else { - if (this._stepNumber == 0) { - this._stepNumber = this._stepsPerRevolution; - } - this._stepNumber--; + decrementStepNumber.call(this); } // step the motor to step number 0, 1, ..., {3 or 10} stepMotor.call(this, this._stepNumber); - // Decrement the steps left to move. If we have moved the correct number - // of steps, cancel the timer as there is no need to move anymore. - stepsLeft--; - if (stepsLeft <= 0) { - clearInterval(this._timerId); - this._timerId = null; - if (callback != null) { - callback(); - } - } // End of stepsLeft == 0 + stepsLeft--; // Decrement the steps left to move. + }.bind(this), this._stepDelay); // End of setInterval } // End of step +// PUBLIC: +// Halt the motors by setting all the voltages to low. There will now be no +// force restricting the movement of the motors. +function halt() { + wpi.digitalWrite(this._motorPin1, wpi.LOW); + wpi.digitalWrite(this._motorPin2, wpi.LOW); + if (this._pinCount == 2 || this._pintCount == 4) { + wpi.digitalWrite(this._motorPin3, wpi.LOW); + wpi.digitalWrite(this._motorPin4, wpi.LOW); + } + if (this._pinCount == 5) { + wpi.digitalWrite(this._motorPin5, wpi.LOW); + } +} // End of halt + + +function incrementStepNumber() { + this._stepNumber++; + if (this._stepNumber >= this._stepsPerRevolution) { + this._stepNumber = 0; + } +} + +function decrementStepNumber() { + this._stepNumber--; + if (this._stepNumber < 0) { + this._stepNumber = this._stepsPerRevolution - 1; + } +} + /* + * PRIVATE: * Moves the motor forward or backwards. */ function stepMotor(thisStep) { thisStep = Math.abs(thisStep); - //console.log("Step: %d, mod4=%d, pinCount=%d", thisStep, thisStep%4, this._pinCount); + console.log("Step: %d, \tmod4=%d", thisStep, thisStep%4); if (this._pinCount == 2) { switch (thisStep % 4) { @@ -378,4 +426,4 @@ function stepMotor(thisStep) } } } // End of stepMotor -// End of file \ No newline at end of file +// End of file diff --git a/tests/test5.js b/tests/test5.js new file mode 100644 index 0000000..eeb0bf1 --- /dev/null +++ b/tests/test5.js @@ -0,0 +1,51 @@ +/** + * Sample for the stepper-wiringpi.js. + * + * Here we are testing a Stepper motor that has 200 steps per revolution + * which equates to 360/200 = 1.8 degrees per step. + */ + +var wpi = require("wiring-pi"); +wpi.setup("gpio"); +wpi.pcf8574Setup(100, 0x20); + +// In this test we are going to use a PCF8574 for control and control +// two motors +console.log("Starting stepper-wiringpi - test5"); + +var stepperWiringPi = require("../src/stepper-wiringpi"); +var m1pinIN1 = 100; // Stepper Red +var m1pinIN2 = 101; // Stepper Blue +var m1pinIN3 = 102; // Stepper Green +var m1pinIN4 = 103; // Stepper Black + +var m2pinIN1 = 104; // Stepper Red +var m2pinIN2 = 105; // Stepper Blue +var m2pinIN3 = 106; // Stepper Green +var m2pinIN4 = 107; // Stepper Black + +var motor1 = stepperWiringPi.setup(200, m1pinIN1, m1pinIN2, m1pinIN3, m1pinIN4); +var motor2 = stepperWiringPi.setup(200, m2pinIN1, m2pinIN2, m2pinIN3, m2pinIN4); +var direction = 1; +console.log("Globals: FORWARD=%d, BACKWARD=%d", stepperWiringPi.FORWARD, stepperWiringPi.BACKWARD); + +function changeDirection() { + console.log("Changing direction from %d", direction); + if (direction == stepperWiringPi.FORWARD) { + direction = stepperWiringPi.BACKWARD; + motor1.backward(); + motor2.backward(); + } else { + direction = stepperWiringPi.FORWARD; + motor1.forward(); + motor2.forward(); + } + setTimeout(changeDirection.bind(this), 2000); +} + +motor1.setSpeed(20); +motor2.setSpeed(60); + +changeDirection(); + +console.log("Step requested submitted.");