Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions arduino/src/sketch/MultiStepper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// MultiStepper.cpp
//
// Copyright (C) 2015 Mike McCauley
// $Id: MultiStepper.cpp,v 1.2 2015/10/04 05:16:38 mikem Exp $

#include "MultiStepper.h"
#include "AccelStepper.h"

MultiStepper::MultiStepper()
: _num_steppers(0)
{
}

boolean MultiStepper::addStepper(AccelStepper& stepper)
{
if (_num_steppers >= MULTISTEPPER_MAX_STEPPERS)
return false; // No room for more
_steppers[_num_steppers++] = &stepper;
}

void MultiStepper::moveTo(long absolute[])
{
// First find the stepper that will take the longest time to move
float longestTime = 0.0;

uint8_t i;
for (i = 0; i < _num_steppers; i++)
{
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
float thisTime = abs(thisDistance) / _steppers[i]->maxSpeed();

if (thisTime > longestTime)
longestTime = thisTime;
}

if (longestTime > 0.0)
{
// Now work out a new max speed for each stepper so they will all
// arrived at the same time of longestTime
for (i = 0; i < _num_steppers; i++)
{
long thisDistance = absolute[i] - _steppers[i]->currentPosition();
float thisSpeed = thisDistance / longestTime;
_steppers[i]->moveTo(absolute[i]); // New target position (resets speed)
_steppers[i]->setSpeed(thisSpeed); // New speed
}
}
}

// Returns true if any motor is still running to the target position.
boolean MultiStepper::run()
{
uint8_t i;
boolean ret = false;
for (i = 0; i < _num_steppers; i++)
{
if ( _steppers[i]->distanceToGo() != 0)
{
_steppers[i]->runSpeed();
ret = true;
}
}
return ret;
}

// Blocks until all steppers reach their target position and are stopped
void MultiStepper::runSpeedToPosition()
{
while (run())
;
}

78 changes: 78 additions & 0 deletions arduino/src/sketch/MultiStepper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// MultiStepper.h

#ifndef MultiStepper_h
#define MultiStepper_h

#include <stdlib.h>
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#include <wiring.h>
#endif

#define MULTISTEPPER_MAX_STEPPERS 10

class AccelStepper;

/////////////////////////////////////////////////////////////////////
/// \class MultiStepper MultiStepper.h <MultiStepper.h>
/// \brief Operate multiple AccelSteppers in a co-ordinated fashion
///
/// This class can manage multiple AccelSteppers (up to MULTISTEPPER_MAX_STEPPERS = 10),
/// and cause them all to move
/// to selected positions at such a (constant) speed that they all arrive at their
/// target position at the same time. This can be used to support devices with multiple steppers
/// on say multiple axes to cause linear diagonal motion. Suitable for use with X-Y plotters, flatbeds,
/// 3D printers etc
/// to get linear straight line movement between arbitrary 2d (or 3d or ...) positions.
///
/// Caution: only constant speed stepper motion is supported: acceleration and deceleration is not supported
/// All the steppers managed by MultiStepper will step at a constant speed to their
/// target (albeit perhaps different speeds for each stepper).
class MultiStepper
{
public:
/// Constructor
MultiStepper();

/// Add a stepper to the set of managed steppers
/// There is an upper limit of MULTISTEPPER_MAX_STEPPERS = 10 to the number of steppers that can be managed
/// \param[in] stepper Reference to a stepper to add to the managed list
/// \return true if successful. false if the number of managed steppers would exceed MULTISTEPPER_MAX_STEPPERS
boolean addStepper(AccelStepper& stepper);

/// Set the target positions of all managed steppers
/// according to a coordinate array.
/// New speeds will be computed for each stepper so they will all arrive at their
/// respective targets at very close to the same time.
/// \param[in] absolute An array of desired absolute stepper positions. absolute[0] will be used to set
/// the absolute position of the first stepper added by addStepper() etc. The array must be at least as long as
/// the number of steppers that have been added by addStepper, else results are undefined.
void moveTo(long absolute[]);

/// Calls runSpeed() on all the managed steppers
/// that have not acheived their target position.
/// \return true if any stepper is still in the process of running to its target position.
boolean run();

/// Runs all managed steppers until they acheived their target position.
/// Blocks until all that position is acheived. If you dont
/// want blocking consider using run() instead.
void runSpeedToPosition();

private:
/// Array of pointers to the steppers we are controlling.
/// Fills from 0 onwards
AccelStepper* _steppers[MULTISTEPPER_MAX_STEPPERS];

/// Number of steppers we are controlling and the number
/// of steppers in _steppers[]
uint8_t _num_steppers;
};

/// @example MultiStepper.pde
/// Use MultiStepper class to manage multiple steppers and make them all move to
/// the same position at the same time for linear 2d (or 3d) motion.

#endif
67 changes: 49 additions & 18 deletions arduino/src/sketch/sketch.ino
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
#include "AccelStepper.h"
#include "axisDirectionStruct.h" //importing AxisAndDirection
#include "MultiStepper.h"

String incomingByte; // for incoming serial data
int speed = 20;
// The X Stepper pins
#define STEPPER_DIR_PIN 10
#define STEPPER_STEP_PIN 2
#define STEPPER1_DIR_PIN 2
#define STEPPER1_STEP_PIN 3

#define STEPPER2_DIR_PIN 8
#define STEPPER2_STEP_PIN 9

//#define STEPPER3_DIR_PIN 10
//#define STEPPER3_STEP_PIN 2
#define led_pin 13

// Define some stepper and the pins the will use
//AccelStepper::DRIVER means that we are using Driver, or we can write simply "1"
AccelStepper stepper(AccelStepper::DRIVER, STEPPER_STEP_PIN, STEPPER_DIR_PIN);
/** Define some stepper and the pins the will use
AccelStepper::DRIVER means that we are using Driver, or we can write simply "1"
stepper1 : x-axis movement
stepper2, stepper3 : y and z axis movement
when both motor move in same direction with same speed : y axis, and when both motor moves in different direction with same speed : z axis
*/
AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_DIR_PIN, STEPPER1_STEP_PIN);
AccelStepper stepper2(AccelStepper::DRIVER, STEPPER2_DIR_PIN, STEPPER2_STEP_PIN);

//To add multiple steppers to MultiStepper
MultiStepper steppers;
void setup()
{

Serial.begin(9600);
pinMode(led_pin, OUTPUT);
stepper.setMaxSpeed(40);
//Set Max speed of steppers
stepper1.setMaxSpeed(10);
stepper2.setMaxSpeed(10);
stepper1.moveTo(0);
stepper2.moveTo(0);
// Then give them to MultiStepper to manage
steppers.addStepper(stepper1);
steppers.addStepper(stepper2);
}

void blockingRunSpeedToPosition(long position)
Expand All @@ -27,18 +49,27 @@ void blockingRunSpeedToPosition(long position)
But we want blocking so we have to implement own loop using while
*/

stepper.setCurrentPosition(0);

///stepper.moveTo function : Set the target position absolute to the current position
// stepper.moveTo(position);

///stepper.move funtion : Set the target position relative to the current position
/// if position is negative then anticlockwise from the current position, else clockwise from current position
stepper.move(position);
stepper.setSpeed(speed);
stepper1.setCurrentPosition(0);
stepper2.setCurrentPosition(0);
stepper1.setAcceleration(100);
stepper2.setAcceleration(100);
/**stepper.moveTo function : Set the target position absolute to the current position
stepper.moveTo(position);
stepper.move funtion : Set the target position relative to the current position
if position is negative then anticlockwise from the current position, else clockwise from current position
*/
// stepper1.move(position);
// stepper1.setSpeed(speed);
// stepper.setAcceleration(100.0);
while (stepper.distanceToGo() != 0)
stepper.runSpeedToPosition();
// while (stepper1.distanceToGo() != 0)
// stepper1.runSpeedToPosition();

long positions[2];
positions[0] = position;
positions[1] = position;
// steppers.setCurrentPosition(0);
steppers.moveTo(positions);
steppers.runSpeedToPosition();
}


Expand All @@ -50,7 +81,7 @@ void loop()
Serial.println(incomingByte);
AxisAndDirection axisAndDirection = getAxisAndDirection(incomingByte);
int stepsPerKeyStrock = 200;
if(axisAndDirection.axis == 'x') {
if(axisAndDirection.axis == 'y') {
digitalWrite(led_pin,HIGH);
if(axisAndDirection.direction == -1) {
stepsPerKeyStrock = -stepsPerKeyStrock;
Expand Down