New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposed addition to stepper #1218
Comments
Seems like a good addition to me, but I'd like to see Stepper re-written to match the design of Motor and Servo before any new additions are made. WDYT? |
I'd say wait a bit on the rewrite. @soundanalgous is looking to replace FirmataStepper with AccelStepper which could give us lots of new features. I'm auditing AccelStepper features to see what makes sense in a new protocol for stepper commands in firmata. AccelStepper includes support for enable pins so the feature will remain... and it would only take a couple of hours... and I need it by Saturday :-P |
Ok, go for it |
Okay, #1225 had this feature added (as long as you instantiated your stepper with an opts object and not an array), but I've closed because that branch was good enough for my purposes and stepper really needs that refactor. First step is to update Firmata. I've proposed a new firmata protocol for stepper here: |
edited 9/30:
edited 10/3:
edited 10/13
edited 7/24
Stepper API Proposal
Breaking changes
Parametersoptions An object of property parameters
Pins
Shape
APIstep(unitsOrOpts, callback) Move a stepper motor.
to(positionOrOpts, callback) Move a stepper motor to a specific position.
stop(callback) Stop a stepper motor. Optional callback receives the current position.
disable() Disable a stepper by setting all pins low. If there is an enable pin it will also be set low.
enable() Enable a stepper by restoring pin state. If there is an enable pin it will also be set high.
rpm() Get the rpm. rpm(value) Set the rpm.
speed() Get the speed. speed(value) Set the speed in units/second.
direction() Get the direction. direction(value) Set the direction.
Or...
accel() Get the acceleration in steps per second2. accel(value) Set the acceleration in steps per second2.
decel() Get the deceleration in steps per second2. decel(value) Set the deceleration in steps per second2.
maxSpeed() Get the maximum speed in steps per second. maxSpeed(value) Set the maximum speed in steps per second.
position() Get the current position. This is only updated when a movement has completed position(value) Set the current position. This cannot be called while a stepper is moving.
cw() Set the Stepper to move Clockwise.
ccw() Set the Stepper to move Counter-Clockwise.
MultiStepper APIParametersoptions An object of property parameters
APIto(positionsArray, callback) Move a multiStepper group of motors to an array of desired positions. The positions will be passed in a single firmata message and firmata will handle linear tweening so that all steppers arrive at the desired position simultaneously.
stop(callback) Stop a multiStepper group. Optional callback receives an array of the current positions.
ConstantsUnits
Run States
Directions
|
Wow. This will take me a bit to get through, please be patient <3 |
Submitted a PR to firmata/protocol#66 |
That PR to protocol has landed. Next steps, updating configurableFirmata, firmata.js, and then finally Johnny-Five |
The new protocol (AKA Stepper 2) had some minor revisions to how we pass certain values. Those changes are here firmata/protocol#81 Also note that we are now using a new command value so client libraries can continue to use the old stepper interface. |
@dtex Come from Add enable pin for stepper #1225, and see updates to stepper 2.0 proposal based on comments, it seems that you(and many other people) have spend so much time on the improvements of Stepper, THANKS A LOT! And the community is pretty nice! However, it says:
in stepper-2.0.md, and I really wonder when shall we have the luck to use the Stepper-2? It will be great help for us(me especially) to make code cleaner and concentrate more on the really logical stuff, though it may seems a little push for you guys, I am really looking forward to it! |
It's good to hear other people are looking forward to it and it certainly hasn't fallen off my radar. Hopefully I'll have a first commit in the next couple of weeks. |
Hey guys, any updates on this? This new proposed interface looks great. Is there code written for this that I could look at? Also I have a question about the |
Hi @joepuzzo Progress has been made, but this has been taking a back seat to another J5 change I'm working on. Here's where we stand:
The upcoming changes in J5 will allow users to take advantage of all the new firmata stuff, or control steppers with standardFirmata, and control steppers on other platforms besides Arduino (like Raspi-io). For now the only way to control a stepper on a Raspberry Pi with Johnny-Five is to connect an Arduino to it. There are two ways to control steppers connected to an Arduino when running Johnny-Five. If you build configurableFirmata with firmataStepper you can use Johnny-Five's stepper class. If you build configurableFirmata with firmataAccelStepper you can use firmata.js's stepper methods. You can still use Johnny-Five for other devices on the same Uno along side the firmata.js stepper instance. firmataAccelStepper gives much more functionality than firmataStepper so I recommend that path. The firmata.js API for stepper is much more "J5-like" than other firmata methods so it shouldn't feel to weird.
firmataStepper - n/a. There is no "to"
firmataStepper - I don't remember. I'd have to dig into firmataStepper, or run some tests. Sorry this is taking so long to land. The other changes I'm working on for J5 span several repos and I'm slow even in the best of circumstances. |
Thanks thats fine! I am already using J5 with a teensy LC connected to ras pi to control a stepper motor and its working great! To do this I flashed the teensy with AdvancedFirmata as specified in the J5 docs. It sounds like if i wanted the more advanced features now i would have to push firmataAccelStepper and use firmata.js instead of johnny five. ( I could not use them both at the same time correct? ). |
You wil need a custom build of configurable firmata from http://firmatabuilder.com/ I usually include the first five options and accelStepperFirmata. The docs for firmata's new stepper API are here You can absolutiely use Johnny-Five and firmata's stepper API at the same time. Something like this: var Five = require("johnny-five");
var board = new Five.Board();
board.on("ready", function() {
// Here's a J5 class isntance
let led = new Five.Led(9);
led.blink();
// The firmata.js instance for this board is at this.io
this.io.accelStepperConfig({
deviceNum: 0,
type: this.io.STEPPER.TYPE.FOUR_WIRE,
motorPin1: 4,
motorPin2: 5,
motorPin3: 6,
motorPin4: 7,
stepSize: this.io.STEPPER.STEP_SIZE.WHOLE
});
this.io.accelStepperSpeed(0, 300);
this.io.accelStepperAcceleration(0, 100);
this.io.accelStepperStep(0, 2000, function(position) {
console.log("Current position: " + position);
});
});
}); The Johnny-Five class will of course make everything a little easier (like working with an instance of stepper instead of having to pass the deviceNum with every call) and will add some helpers, but you can do most everything you will need to do with just firmata. |
Wow dude this is so cool i had no clue you could do this! But wait you never required |
If you don't pass a different IO plugin when you initialize your board, Johnny-Five will assume you want to use firmata, will initialize it for you then make it available on board.io. In other words, J5 handles the require. |
Thanks a lot! I got it all working and its awesome! Cant wait to see this become part of J5. |
Any idea when this becomes part of J5? Is there another workaround to stop a stepper? |
Hopefully soon. This PR is blocking. In the meantime you can use the firmata io object in the Johnny-Five board instance (assuming you are using an Arduino). It requires the latest firmata.js and a custom build of firmata which includes accelStepper. You can get the custom build over at firmatabuilder.com. The firmata stepper API is documented here For example: // Note I just typed in this code and didn't test so
// there may be (er, probably is) a typo or two
let Five = require("johnny-five");
let board = new Five.Board();
board.on("ready", function() {
board.accelStepperConfig({
deviceNum: 0,
type: board.STEPPER.TYPE.FOUR_WIRE,
motorPin1: 32,
motorPin2: 34,
motorPin3: 36,
motorPin4: 38,
enablePin: 30,
stepType: board.STEPPER.STEPTYPE.HALF
});
this.io.accelStepperSpeed(0, 200);
this.io.accelStepperAcceleration(0, 100);
this.io.step(10000);
// Stop after 2 seconds
setTimeout(() = {
this.io.stop(0);
}, 2000 });
}); |
Yep, typos and brain farts. Here's the corrected code let Five = require("johnny-five");
let board = new Five.Board();
board.on("ready", function() {
this.io.accelStepperConfig({
deviceNum: 0,
type: this.io.STEPPER.TYPE.FOUR_WIRE,
motorPin1: 32,
motorPin2: 34,
motorPin3: 36,
motorPin4: 38,
enablePin: 30,
stepType: this.io.STEPPER.STEPTYPE.HALF
});
this.io.accelStepperSpeed(0, 200);
this.io.accelStepperAcceleration(0, 100);
this.io.accelStepperStep(10000);
// Stop after 2 seconds
setTimeout(() = {
this.io.accelStepperStop(0);
}, 2000 });
}); |
@dtex thanks very much! I'll try that. Do you know the reason why this wasn't in the initial commit for the stepper module? I mean are most users hardcode their bot-movements? Doesn't nearly every stepper need some kind of homeposition or haltpoints? |
Johnny-Five depends on firmata.js which is the host side interface to firmata (the client) which runs on the Arduino. The old Firmata stepper code was very basic and just didn’t have these features. Once this lands we will still have a ton of work to get the other platforms up to speed. |
Sorry about the delay... that patch is landed and temporal@0.7.0 is published. |
Any updates on this? The workaround i have been using for the past year has been great! No problems there. But it would be nice to see this as part of the core. |
Yes I am using Arduino board for driving multiple stepper motor(3 or 4) and arduino board gets instruction from Raspberry Pi. Pls provide some example or code for the same. |
And on the arduino board ,I had uploaded Configurable Firmata. |
You can find documentation for using accelStepper directly with firmata.js here and here is an example of it playing nice with Johnny-Five. All other devices (LED's, Sensor's, etc) can be used with the Johnny-Five API. let Five = require("johnny-five");
let board = new Five.Board();
board.on("ready", () => {
board.io.accelStepperConfig({
deviceNum: 0,
type: board.STEPPER.TYPE.FOUR_WIRE,
motorPin1: 5,
motorPin2: 6,
motorPin3: 7,
motorPin4: 8,
stepSize: board.STEPPER.STEP_SIZE.WHOLE
});
board.io.accelStepperConfig({
deviceNum: 1,
type: board.STEPPER.TYPE.FOUR_WIRE,
motorPin1: 9,
motorPin2: 10,
motorPin3: 11,
motorPin4: 12,
stepSize: board.STEPPER.STEP_SIZE.HALF
});
board.io.accelStepperSpeed(0, 400);
board.io.accelStepperSpeed(1, 400);
board.io.multiStepperConfig({
groupNum: 0,
devices: [0, 1]
});
board.io.multiStepperTo(0, [2000, 3000], () => {
board.io.accelStepperReportPosition(0, value => {
console.log(`Stepper 0 position: ${value}`);
});
board.io.accelStepperReportPosition(1, value => {
console.log(`Stepper 1 position: ${value}`);
});
});
}); |
Can u pls tell in detail how to use johnny five and firmata.js simultaneously ? firmata.js for stepper motor and johnny-five for others sensor,led ,etc. |
@dtex while running above code i got this error, can you please tell how to fix it? |
Ah, I see. the The two lines that say type: board.STEPPER.TYPE.FOUR_WIRE, should be type: board.io.STEPPER.TYPE.FOUR_WIRE, You'll also need to fix the |
@dtex now i get this error |
What version of node are you using? |
The exponentiation operator was added in version 7. Johnny-Five requires version 8 or newer. |
Previously code was running but now it was showing only Connected, Available and Repl initialized (as in pic ) and there is no more execution further. |
@manish2208 We've strayed pretty far from the original topic. Can you open a new issue? If you're using the code from above, I suspect you do not have the proper version of firmata installed on the Uno. If there is anything different about your code, please post it in a new issue. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
Was this ever added :) |
Sadly no. I got stuck on how to handle stepper collections and kinda forgot about it. I should revisit and see if it's any easier with the new codebase, or maybe I've gotten smarter in the past few years and it'll be easier to figure out. 🤞 |
I'll be waiting with bated breath, but until then I'll try your suggestion from above ^_^ |
So Im trying this and its not working. When I tell a single motor to go to a position it works fine. but with same code here no movement. Any thoughts ? |
Hmmm, not sure. First I would see if replacing board.io.multiStepperTo(0, [2000, 3000], () => {
board.io.accelStepperReportPosition(0, value => {
console.log(`Stepper 0 position: ${value}`);
});
board.io.accelStepperReportPosition(1, value => {
console.log(`Stepper 1 position: ${value}`);
});
}); with board.io.accelStepperTo(0, 2000);
board.io.accelStepperTo(1, 3000); causes both motors to move. It might be a problem with the multiStepper class. |
The latter causes both to move but the former does not |
Well, that helps. This could be a problem in firmata.js or the accelStepper addon to configurable firmata. Are you able to make your project work with individual stepper control? |
Yes I can do it with individual stepper control. I just wrote my own var five = require("johnny-five");
var board = new five.Board();
//var Board = require("firmata");
//var board = new Board();
const ENABLED = true;
const DISABLED = !ENABLED;
board.on("ready", function () {
board.io.accelStepperConfig({
deviceNum: 0,
type: this.io.STEPPER.TYPE.DRIVER,
stepPin: 0,
directionPin: 1,
enablePin: 33,
invertPins: [33]
});
board.io.accelStepperConfig({
deviceNum: 1,
type: this.io.STEPPER.TYPE.DRIVER,
stepPin: 6,
directionPin: 7,
enablePin: 36,
});
board.io.accelStepperSpeed(0, 1000);
board.io.accelStepperSpeed(1, 1000);
board.io.multiStepperConfig({
groupNum: 0,
devices: [0, 1]
});
board.io.accelStepperEnable(1, ENABLED)
board.io.accelStepperEnable(0, ENABLED)
const steppers = [0,0];
this.repl.inject({
to: (id, loc, speed = 1000) =>{
this.io.accelStepperSpeed(id, speed);
this.io.accelStepperTo(id,loc);
},
multi: (speed = 1000) =>{
this.io.accelStepperSpeed(0, speed);
this.io.accelStepperSpeed(1, speed);
board.io.multiStepperTo(0, [2000, 3000], () => {
console.log("Moved Multi")
this.io.accelStepperReportPosition(0, value => {
console.log(`Stepper 0 position: ${value}`);
});
this.io.accelStepperReportPosition(1, value => {
console.log(`Stepper 1 position: ${value}`);
});
});
},
mine: (positions) =>{
// First find the stepper that will take the longest time
let longestTime = 0;
for(let i = 0; i < 2; i++ ){
const thisDistance = positions[i] - steppers[i];
const thisTime = Math.abs(thisDistance) / 1000;
if(thisTime > longestTime){
longestTime = thisTime;
}
}
console.log('Longest Time:', longestTime);
// Set speed for each based on time
for(let i = 0; i < 2; i++ ){
const thisDistance = positions[i] - steppers[i];
const thisSpeed = thisDistance / longestTime;
this.io.accelStepperSpeed(i, thisSpeed);
}
// Now go!
for(let i = 0; i < 2; i++ ){
this.io.accelStepperTo(i, positions[i], (pos) =>{
// update pos for this stepper
console.log('Update:', pos);
steppers[i] = pos;
});
}
},
loc: (id) => {
console.log( this.io.accelStepperReportPosition(id) );
},
enable: (id) => {
this.io.accelStepperEnable(id, ENABLED)
},
disable: (id) => {
this.io.accelStepperEnable(id, DISABLED)
},
zero: (id) => {
this.io.accelStepperZero(id);
}
});
}); |
|
in other words calling |
Also while I have your attention @dtex do you know who I can contact to get this merged ? firmata/firmata.js#261 . I cant seem to get in touch with anyone that works on firmata js |
I think @rwaldron is the only one able to merge PRs on that repo. |
Ok thanks will try to get in touch with him. Also for anyone that attempts to use the methods described above with accelStepper and Johnny five with the latest stepper drivers make sure you check the pulse width settings inside of |
Also I would like to add for anyone using a teensy4.1 board you need to add the following code to the // Teensy 4.0 & 4.1
#elif defined(__IMXRT1062__)
#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
#define TOTAL_PINS NUM_DIGITAL_PINS
#define VERSION_BLINK_PIN 13
#define PIN_SERIAL1_RX 0
#define PIN_SERIAL1_TX 1
#define PIN_SERIAL2_RX 7
#define PIN_SERIAL2_TX 8
#define PIN_SERIAL3_RX 15
#define PIN_SERIAL3_TX 14
#define PIN_SERIAL4_RX 16
#define PIN_SERIAL4_TX 17
#define PIN_SERIAL5_RX 21
#define PIN_SERIAL5_TX 20
#define PIN_SERIAL6_RX 25
#define PIN_SERIAL6_TX 24
#define PIN_SERIAL7_RX 28
#define PIN_SERIAL7_TX 29
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < NUM_DIGITAL_PINS)
#ifdef ARDUINO_TEENSY40
#define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 27)
#define PIN_TO_ANALOG(p) ((p) - 14)
#endif
#ifdef ARDUINO_TEENSY41
#define IS_PIN_ANALOG(p) (((p) >= 14 && (p) <= 27) || ((p) >= 38 && (p) <= 41))
#define PIN_TO_ANALOG(p) (((p) <= 27) ? (p) - 14 : (p) - 24)
#endif
#define IS_PIN_PWM(p) digitalPinHasPWM(p)
#define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
#define IS_PIN_I2C(p) ((p) == PIN_WIRE_SDA || (p) == PIN_WIRE_SCL)
#define IS_PIN_SERIAL(p) (((p) >= 0 && (p) <= 1) || ((p) >= 7 && (p) <= 8) || ((p) >= 14 && (p) <= 17) || ((p) >= 20 && (p) <= 21) || ((p) >= 24 && (p) <= 25) || ((p) >= 28 && (p) <= 29))
#define PIN_TO_DIGITAL(p) (p)
#define PIN_TO_PWM(p) (p)
#define PIN_TO_SERVO(p) (p)
|
I'm working on a project that requires getting down into stepper and I have a proposed addition. I want to be able to control the enable pin of a motor controller to shut off a stepper so it's not consuming power when it is not needed (and getting super hot).
I could do this independently of the stepper class by controlling an independent digital pin, or I could integrate it as a parameter on stepper. For example:
Four-Wire
or Two Wire
Alternately enable could be a separate param:
The text was updated successfully, but these errors were encountered: