/* AccelStepper6AxisArrayStruct.ino
See https://forum.arduino.cc/t/6-accelsteppers-as-an-array-of-struct-array-of-class-array-of-object/1311789/ and
https://wokwi.com/projects/411859783629453313 for some some parent sketches
This simulation demonstrates bouncing 6 stepper motors between different
limits while simultaneously reading potentiomters to adust speed
acceleration, and target positions during moves.
It also demonstrates use of an array of structs in order to
manage the steppers and their associated data together as a set.
https://wokwi.com/projects/428224295789685761
built from :
https://wokwi.com/projects/411859783629453313
and https://wokwi.com/projects/390741120778917889
*/
// For RAMPS 1.4, Copied from https://wokwi.com/projects/390741120778917889
// RAMPS pins from https://reprap.org/wiki/RAMPS_1.4#Pins & https://forum.arduino.cc/t/arduino-mega-use-analog-pins-as-digital/13844/6?u=davex
// with auxiliary pins for axis C controls and A,B,C min pins
#define X_DIR_PIN 55
#define X_STEP_PIN 54
#define X_ENABLE_PIN 38
#define X_MIN_PIN 3
#define Y_DIR_PIN 61
#define Y_STEP_PIN 60
#define Y_ENABLE_PIN 56
#define Y_MIN_PIN 14
#define Z_DIR_PIN 48
#define Z_STEP_PIN 46
#define Z_ENABLE_PIN 62
#define Z_MIN_PIN 18
#define A_DIR_PIN 28
#define A_STEP_PIN 26
#define A_ENABLE_PIN 24
#define A_MIN_PIN 27
#define B_DIR_PIN 34
#define B_STEP_PIN 36
#define B_ENABLE_PIN 30
#define B_MIN_PIN 29
//
#define C_DIR_PIN 32
#define C_STEP_PIN 47
#define C_ENABLE_PIN 45
#define C_MIN_PIN 25
#import <AccelStepper.h> // https://www.airspayce.com/mikem/arduino/AccelStepper/
// and https://github.com/waspinator/AccelStepper
// Assemble an array of structures
struct MyStruct {
const char *name;
const AccelStepper stepper;
int enablePin;
int button;
} stepperAssemblies[] = {
{"X", {AccelStepper::DRIVER, X_STEP_PIN, X_DIR_PIN}, X_ENABLE_PIN,X_MIN_PIN},
{"Y", {AccelStepper::DRIVER, Y_STEP_PIN, Y_DIR_PIN}, Y_ENABLE_PIN,Y_MIN_PIN},
{"Z", {AccelStepper::DRIVER, Z_STEP_PIN, Z_DIR_PIN}, Z_ENABLE_PIN,Z_MIN_PIN},
{"A", {AccelStepper::DRIVER, A_STEP_PIN, A_DIR_PIN}, A_ENABLE_PIN,A_MIN_PIN},
{"B", {AccelStepper::DRIVER, B_STEP_PIN, B_DIR_PIN}, B_ENABLE_PIN,B_MIN_PIN},
{"C", {AccelStepper::DRIVER, C_STEP_PIN, C_DIR_PIN}, C_ENABLE_PIN,C_MIN_PIN},
};
const int NUM_STEPPERS = sizeof(stepperAssemblies) / sizeof(stepperAssemblies[0]);
void usage() {
Serial.print(__FILE__ " on " __DATE__);
Serial.println(F(R"(AccelStepper6AxisRAMPSMega.ino V4_array_structs.ino
https://wokwi.com/projects/411859783629453313
Speed, acceleration change with potentiometers.
Bounce position changes with button press. )"));
}
const int PositionPin = A13, SpeedPin = A14, AccelPin = A15;
uint16_t position, speed, acceleration, lastPosition, lastSpeed, lastAccel; // pot-read
void readAllInputs() {
uint32_t now = millis();
const auto interval = 200;
static auto last = - interval;
if (now - last >= interval) {
now += interval;
speed = map(analogRead(SpeedPin), 0, 1023, 0, 2000);
acceleration = map(analogRead(AccelPin), 0, 1023, 0, 2000);
position = map(analogRead(PositionPin), 0, 1023, 0, 2000);
for (auto &obj : stepperAssemblies) {
if (digitalRead(obj.button) == LOW && obj.stepper.targetPosition() != position) {
Serial.print("Retargeting stepper ");
Serial.print(obj.name);
Serial.print(" to ");
Serial.println(position);
obj.stepper.moveTo(position);
}
}
}
}
void process() {
if (acceleration != lastAccel || speed != lastSpeed) {
for ( auto & assy : stepperAssemblies) {
assy.stepper.setAcceleration(acceleration);
assy.stepper.setMaxSpeed(speed);
lastSpeed = speed;
lastAccel = acceleration;
}
Serial.print("Speed:");
Serial.print(speed);
Serial.print(" Acceleration:");
Serial.println(acceleration);
}
}
void enableAllSteppersParallel() {
for (auto &assy : stepperAssemblies) {
assy.stepper.setEnablePin(assy.enablePin);
assy.stepper.setPinsInverted(false, false, true);
assy.stepper.enableOutputs();
assy.stepper.setMaxSpeed(1000);
assy.stepper.setAcceleration(100);
assy.stepper.moveTo(random(2000));
pinMode(assy.button, INPUT_PULLUP);
}
}
void enableAllSteppers() {
for (auto &obj : stepperAssemblies) {
obj.stepper.setEnablePin(obj.enablePin);
obj.stepper.setPinsInverted(false, false, true);
obj.stepper.enableOutputs();
obj.stepper.setMaxSpeed(1000);
obj.stepper.setAcceleration(100);
obj.stepper.moveTo(random(2000));
pinMode(obj.button, INPUT_PULLUP);
Serial.print("Initialized ");
Serial.print(obj.name);
Serial.print(" Stepper, enable Button Pin:");
Serial.println(obj.button);
}
}
void runAllSteppers() {
for (auto &obj : stepperAssemblies) {
if (obj.stepper.distanceToGo() == 0) {
obj.stepper.moveTo(-obj.stepper.currentPosition());
Serial.print(obj.name);
Serial.print("@");
Serial.print(obj.stepper.currentPosition());
Serial.print(" ");
}
obj.stepper.run();
}
}
// Arduino required #####################################
void setup() {
srandom( 20241015 + analogRead(SpeedPin) + analogRead(AccelPin));
Serial.begin(115200);
enableAllSteppers();
usage();
}
void loop() {
readAllInputs();
process();
runAllSteppers();
}
Acceleration 0-2000 steps/sec/sec
Speed 0:2000 steps/s
Position +0:2000 steps