rwaldron / johnny-five

JavaScript Robotics and IoT programming framework, developed at Bocoup.
http://johnny-five.io
Other
13.3k stars 1.77k forks source link

Proposed addition to stepper #1218

Open dtex opened 8 years ago

dtex commented 8 years ago

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

five.Stepper({
  type: five.Stepper.TYPE.FOUR_WIRE
  stepsPerRev: number,
  pins: {
    motor1: number,
    motor2: number,
    motor3: number,
    motor4: number,
    enable: number
  }
});

// or

five.Stepper({
  type: five.Stepper.TYPE.FOUR_WIRE
  stepsPerRev: number,
  pins: [ motor1, motor2, motor3, motor4, enable ]
});

or Two Wire

five.Stepper({
  type: five.Stepper.TYPE.TWO_WIRE
  stepsPerRev: number,
  pins: {
    motor1: number,
    motor2: number,
    enable: number
  }
 });

// or 

five.Stepper({
  type: five.Stepper.TYPE.TWO_WIRE
  stepsPerRev: number,
  pins: [ motor1, motor2, enable ]
}); 

Alternately enable could be a separate param:

five.Stepper({
  type: five.Stepper.TYPE.TWO_WIRE
  stepsPerRev: number,
  pins: {
    motor1: number,
    motor2: number
  },
  enable: number
 });
rwaldron commented 8 years ago

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?

dtex commented 8 years ago

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

rwaldron commented 8 years ago

Ok, go for it

dtex commented 8 years ago

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:

https://github.com/firmata/protocol/issues/42

dtex commented 8 years ago

edited 9/30:

edited 10/3:

edited 10/13

edited 7/24

Stepper API Proposal

Breaking changes

Parameters

options An object of property parameters

Property Type Value/Description Default Required
pins Object * See table. An object containing the names pin addresses for the 6 supported types yes1
pins Array * See Table. An array containing the pin addresses for the 6 supported types yes1
controller constant five.Stepper.CONTROLLER.DEFAULT,
five.Stepper.CONTROLLER.FIRMATASTEPPER
DEFAULT yes
device constant five.Stepper.TYPE.DRIVER,
five.Stepper.TYPE.TWO_WIRE,
five.Stepper.TYPE.THREE_WIRE,
five.Stepper.TYPE.FOUR_WIRE,
five.Stepper.TYPE.MICRO_FOUR_WIRE,
five.Stepper.TYPE.HALF_THREE_WIRE,
five.Stepper.TYPE.HALF_FOUR_WIRE
yes
type Number Alias for device no
controller constant Chooses where stepping is managed
five.Stepper.CONTROLLER.DEFAULT
five.Stepper.CONTROLLER.FIRMATASTEPPER
DEFAULT no
stepsPerRev Number Steps per revolution. This will differ by motor, refer to motor specs for value yes
units constant five.Stepper.UNITS.REVS
five.Stepper.UNITS.RADS
five.Stepper.UNITS.DRADS
five.Stepper.UNITS.DEGREES
five.Stepper.UNITS.STEPS
STEPS no
maxSpeed Number Maximum speed in units per second 30 steps per second no
speed Number Units per second 60 RPM no
acceleration Number Maximum steps per second 1.0 no
deceleration Number Maximum steps per second 1.0 no
position Number Starting position 0 no
direction constant five.Stepper.DIRECTION.CW,
five.Stepper.DIRECTION.CCW
no2
autoEnable Boolean Automatically toggle enable pin when movement begins or ends no

Pins

Config As Object As Array
DRIVER { step, dir [, enable] } [ step, dir [, enable] ]
TWO_WIRE { m1, m2 [, enable] } [ m1, m2 [, enable] ]
THREE_WIRE { m1, m2, m3 [, enable] } [ m1, m2, m3 [, enable] ]
FOUR_WIRE { m1, m2, m3, m4 [, enable] } [ m1, m2, m3, m4 [, enable] ]
HALF_THREE_WIRE { m1, m2, m3 [, enable] } [ m1, m2, m3 [, enable] ]
HALF_FOUR_WIRE { m1, m2, m3, m4 [, enable] } [ m1, m2, m3, m4 [, enable] ]
MICRO_FOUR_WIRE { m1, m2, m3, m4 [, enable] } [ m1, m2, m3, m4 [, enable] ]
  1. The pins property is required, but can be EITHER an object or an array.
  2. The direction property is not required, but if it is undefined then Stepper.step() will do nothing.

Shape

{
  id: A user definable id value. Defaults to a generated uid
  pins: Object containing the pin addresses for the Stepper
  units: Units to be used by class
  maxSpeed: Maximum speed in units/second
  direction:
  speed: Current set speed in units/second
  position: Current step position
  accel: Units per second^2
  decel: Units per second^2
}

API

step(unitsOrOpts, callback) Move a stepper motor.

// unitsOrOpts
{
  units: Distance to move in this.units
  steps: explicit number of steps to move
  speed: speed in units/second
  direction: 1, 0 (CCW, CW)
  duration: ms to complete movement
  accel: Units per second^2
  decel: Units per second^2
}

//
//   - 10 full revolutions
//   - Clockwise
//   -
//   -
//

stepper.step({ step: 2000, direction: 1, accel: 1600, decel: 1600 }, function() {
  console.log("Done stepping!");
});

to(positionOrOpts, callback) Move a stepper motor to a specific position.

// positionOrOpts
{
  position: Position in chosen units (this.units)
  speed: speed in units/second
  duration: ms to complete movement
  accel: Steps per second^2
  decel: Steps per second^2
}

//
//   - Move to step 228 in 1 second
//   - Accel over the first 1600 steps
//   - Decel over the last 1600 steps
//

stepper.step({ position: 228, duration: 1000, accel: 1600, decel: 1600 }, function() {
  console.log("Done stepping!");
});

stop(callback) Stop a stepper motor. Optional callback receives the current position.

stepper.stop(function(pos) {
  console.log("Stepper position: " + pos);
});

disable() Disable a stepper by setting all pins low. If there is an enable pin it will also be set low.

stepper.disable();

enable() Enable a stepper by restoring pin state. If there is an enable pin it will also be set high.

stepper.enable();

rpm() Get the rpm.

rpm(value) Set the rpm.

stepper.rpm(180).step(2000, function() {
  console.log("Done stepping!");
});

speed() Get the speed.

speed(value) Set the speed in units/second.

// 50 steps per second
stepper.speed(50).step(200, function() {
  console.log("Done stepping in four seconds!");
});

direction() Get the direction.

direction(value) Set the direction.

stepper.direction(1).step(2000, function() {
  console.log("Done stepping!");
});

stepper.direction(0).step(2000, function() {
  console.log("Done stepping!");
});

Or...

stepper.direction(five.Stepper.DIRECTION.CW).step(2000, function() {
  console.log("Done stepping!");
});

stepper.direction(five.Stepper.DIRECTION.CCW).step(2000, function() {
  console.log("Done stepping!");
});

accel() Get the acceleration in steps per second2.

accel(value) Set the acceleration in steps per second2.

stepper.accel(1600).step(2000, function() {
  console.log("Done stepping!");
});

decel() Get the deceleration in steps per second2.

decel(value) Set the deceleration in steps per second2.

stepper.decel(1600).step(2000, function() {
  console.log("Done stepping!");
});

maxSpeed() Get the maximum speed in steps per second.

maxSpeed(value) Set the maximum speed in steps per second.

stepper.maxSpeed(100).step(2000, function() {
  console.log("Welcome to 20 seconds later!");
});

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.

stepper.position(100);

cw() Set the Stepper to move Clockwise.

stepper.cw().step(2000);

ccw() Set the Stepper to move Counter-Clockwise.

stepper.ccw().step(2000);

MultiStepper API

Parameters

options An object of property parameters

Property Type Value/Description Default Required
Steppers Steppers collection A Steppers collection whose movements should be coordinated by firmata running on a single stepper yes

API

to(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.

multiStepper.to([140, 210], function() {
  console.log("Done stepping!");
});

stop(callback) Stop a multiStepper group. Optional callback receives an array of the current positions.

multiStepper.stop(function(positions) {
  positions.each(function(pos, index) {
    console.log("Stepper " + index + " position: " + pos);
  });
});

Constants

Units

Unit Value Constant
STEPS 0 Stepper.UNITS.STEPS
REVS 1 Stepper.UNITS.REVS
RADS 2 Stepper.UNITS.RADS
DRADS 3 Stepper.UNITS.DRADS
CRADS 4 Stepper.UNITS.CRADS
MRADS 4 Stepper.UNITS.MRADS
DEGREES 5 Stepper.UNITS.DEGREES

Run States

State Value Constant
STOP 0 Stepper.RUNSTATE.STOP
DRIVE 1 Stepper.RUNSTATE.ACCEL
DRIVE 2 Stepper.RUNSTATE.DECEL
DRIVE 3 Stepper.RUNSTATE.RUN

Directions

Direction Value Constant
CCW 0 Stepper.DIRECTION.CCW
CW 1 Stepper.DIRECTION.CW
rwaldron commented 8 years ago

Wow.

This will take me a bit to get through, please be patient <3

dtex commented 8 years ago

Submitted a PR to https://github.com/firmata/protocol/pull/66

dtex commented 8 years ago

That PR to protocol has landed. Next steps, updating configurableFirmata, firmata.js, and then finally Johnny-Five

dtex commented 7 years ago

The new protocol (AKA Stepper 2) had some minor revisions to how we pass certain values. Those changes are here https://github.com/firmata/protocol/pull/81

Also note that we are now using a new command value so client libraries can continue to use the old stepper interface.

MiaoDX commented 7 years ago

@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:

Example files: Version 2.0 of the stepper protocol has not yet been implemented.

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!

dtex commented 7 years ago

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.

joepuzzo commented 6 years ago

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 to(position) function. What would happen if i said go to(228) and then one second later say to(228) would it go further than expected. Similar to now if i say step(1000) and then after 500 steps say step(1000) again the stepper will go 1500 steps.

dtex commented 6 years ago

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.

What would happen if i said go to(228) and then one second later say to(228) would it go further than expected.

firmataStepper - n/a. There is no "to" firmataAccelStepper - It will go to 228. Calling a second "to" would immediately halt the first, but firmataAccelStepper keeps track of the position so we only trigger the number of steps remaining. Keep in mind that we know how many steps we have requested at any point in time, but some physical obstruction may have stopped the motor from completing a step so our real world position would be off.

if i say step(1000) and then after 500 steps say step(1000) again the stepper will go 1500 steps

firmataStepper - I don't remember. I'd have to dig into firmataStepper, or run some tests. firmataAccelStepper - Yes, the stepper will go 1500 steps. The second call will stop the first.

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.

joepuzzo commented 6 years ago

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? ).

dtex commented 6 years ago

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.

joepuzzo commented 6 years ago

Wow dude this is so cool i had no clue you could do this! But wait you never required firmata.js in your example above? is that returired to have those methods on io?

dtex commented 6 years ago

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.

joepuzzo commented 6 years ago

Thanks a lot! I got it all working and its awesome! Cant wait to see this become part of J5.

a1xon commented 6 years ago

Any idea when this becomes part of J5? Is there another workaround to stop a stepper?

dtex commented 6 years ago

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 });

});
dtex commented 6 years ago

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 });

});
a1xon commented 6 years ago

@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?

dtex commented 6 years ago

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.

rwaldron commented 6 years ago

Sorry about the delay... that patch is landed and temporal@0.7.0 is published.

joepuzzo commented 5 years ago

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.

dtex commented 5 years ago

@joepuzzo I ran into a problem with multiple steppers running on more than one board and took some time away from it. I'll get back on it this week.

joepuzzo commented 5 years ago

Awesome thanks! 🙏

panchalmanish2208 commented 4 years ago

Is it possible to use johnny five for controlling multiple stepper motors (3 or 4) using h bridge drivers like L293D ic or motor driver shield?

dtex commented 4 years ago

Yes and But...

Yes, It's totally possible thanks to the new accelStepper features in firmata.js

But Johnny-Five doesn't have support yet. I got stuck on how to handle multiple steppers with more than one board and I haven't solved it bu you can still use this firmata feature.

Before I go into details I want to make sure that you're are using an Arduino or Arduino compatible board running firmata.

panchalmanish2208 commented 4 years ago

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.

panchalmanish2208 commented 4 years ago

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.

dtex commented 4 years ago

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}`);
    });

  });

});
panchalmanish2208 commented 4 years ago

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. Thanks a lot.

panchalmanish2208 commented 4 years ago

@dtex while running above code i got this error, can you please tell how to fix it? Capture

dtex commented 4 years ago

Ah, I see. the STEPPERobject is on board.io, not board.

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 stepSize lines

panchalmanish2208 commented 4 years ago

@dtex now i get this error Capture_1

dtex commented 4 years ago

What version of node are you using?

panchalmanish2208 commented 4 years ago

What version of node are you using?

Capture_2

dtex commented 4 years ago

The exponentiation operator was added in version 7. Johnny-Five requires version 8 or newer.

panchalmanish2208 commented 4 years ago

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. Capture _3 @dtex can u please tell what is happening here?

dtex commented 4 years ago

@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.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

TheLogan commented 3 years ago

Was this ever added :)

dtex commented 3 years ago

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. 🤞

TheLogan commented 3 years ago

I'll be waiting with bated breath, but until then I'll try your suggestion from above ^_^

joepuzzo commented 2 years ago

@dtex

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. Thanks a lot.

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 ?

dtex commented 2 years ago

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.

joepuzzo commented 2 years ago

The latter causes both to move but the former does not

dtex commented 2 years ago

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?

joepuzzo commented 2 years ago

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);
    }
  });

});