Skip to content
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

Feature Request: Support AdaFruit Motorshield v2.3 w/ NEMA 17 Steppers #77

Open
Lutraphobia opened this issue Oct 1, 2020 · 3 comments

Comments

@Lutraphobia
Copy link

Lutraphobia commented Oct 1, 2020

I am collaborating with K6VUG on an Arduino (Uno/Mega) build with the Adafruit MotorShield (my ver 2.3) driving two Nema 17 HS4401S.

His Sketch works great. Since it's a bare bones solution I'd like to eventually add ability to use a display and LM303 Magnetometer, etc.

However, after coming across this project, he was ok with me reaching out to see if a port of his code was possible. It would be great to assist others with this setup since there are so many more features.

Here is Umesh's (K6VUG) working code for the steppers and shield with EasyComm commands. How would I incorporate this into K3NG? I've tried but it will probably take me months to integrate with my limited abilities.

All credits go to UMESH/K6VUG and a huge thanks to him for helping me get up and running with his code.

Thanks!
-Walt / WA7ZYW

// Includes for Adafruit Motor Shield V2 and stepper motors

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Constants for Adafruit Motor Shield V2 and stepper motors

#define SPEED_DEFAULT 1000.0
#define ACCEL_DEFAULT 1000.0

#define STEP_TYPE SINGLE // can be changed to DOUBLE or INTERLEAVE or MICROSTEP
#define STEPS_360 200 // as specified in stepper specifications

#define CCW_MOTOR_AZ false // set this to true if clockwise command moves rotor anti-clockwise
#define CCW_MOTOR_EL false // set this to true if clockwise command moves rotor anti-clockwise

// ---------------------------- AdaFruit Shield Initialisation ----------------------------

////Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers

// Connect two steppers with 200 steps per revolution (1.8 degree) to the top shield
Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(STEPS_360, 1);
Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(STEPS_360, 2);

// create wrappers for the motors!
void forwardstep1() {
myStepper1->onestep(FORWARD, STEP_TYPE);
}

void backwardstep1() {
myStepper1->onestep(BACKWARD, STEP_TYPE);
}

void forwardstep2() {
myStepper2->onestep(FORWARD, STEP_TYPE);
}

void backwardstep2() {
myStepper2->onestep(BACKWARD, STEP_TYPE);
}

// create AccelStepper objects
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);

// ----------------------------------------------------------------------------------------

void setupSteppers() {
// initialize motor shield
initMotorShield();
// initialize motors
initMotors();
// initialize current position based on stepper data
curAz = stepper1.currentPosition() * 360 / STEPS_360;
curEl = stepper2.currentPosition() * 360 / STEPS_360;
}

void loopSteppers() {
// move the motors one step towards target position
//if ((!stepper1.isRunning()) && (stepper1.distanceToGo() != 0)) {
if ((stepper1.distanceToGo() != 0)) {
stepper1.run();
//Serial.print(stepper1.distanceToGo());
//Serial.print(",");
curAz = stepper1.currentPosition() * 360 / STEPS_360;
}
//if ((!stepper2.isRunning()) && (stepper2.distanceToGo() != 0)) {
if ((stepper2.distanceToGo() != 0)) {
stepper2.run();
//Serial.print(stepper2.distanceToGo());
//Serial.print(",");
curEl = stepper2.currentPosition() * 360 / STEPS_360;
}
}

void initMotorShield() {
////AFMSbot.begin(); // Start the bottom shield
AFMStop.begin(); // Start the top shield
}

void initMotors() {
stepper1.setMaxSpeed(SPEED_DEFAULT);
stepper1.setAcceleration(ACCEL_DEFAULT);
stepper2.setMaxSpeed(SPEED_DEFAULT);
stepper2.setAcceleration(ACCEL_DEFAULT);
}

void setNewAz(int pos) {
long newAzStep = ((long)pos) * STEPS_360 / 360;
stepper1.moveTo(newAzStep); // set new target for stepper motor
}

void setNewEl(int pos) {
long newElStep = ((long)pos) * STEPS_360 / 360;
stepper2.moveTo(newElStep); // set new target for stepper motor
}

void stopMotorAz() {
////stepper1.stop();
delay(200);
// calculate current position from stepper data
curAz = stepper1.currentPosition() * 360 / STEPS_360;
}

void stopMotorEl() {
////stepper2.stop();
delay(200);
// calculate current position from stepper data
curAz = stepper2.currentPosition() * 360 / STEPS_360;
}

void setZeroPositions() {
stepper1.setCurrentPosition(0);
stepper2.setCurrentPosition(0);
curAz = 0; newAz = curAz;
curEl = 0; newEl = curEl;
initMotors();
}

// Sends the current parameters of the azimuth servo back to the PC
void printMotorParameters() {
Serial.print("Stepper Speed: ");
Serial.println(SPEED_DEFAULT);
Serial.print("Stepper Accel: ");
Serial.println(ACCEL_DEFAULT);
Serial.print("Current Azimuth: ");
Serial.println(curAz);
Serial.print("Current Elevation: ");
Serial.println(curEl);
}

//////////////////////////////////////////////////////////////////////////////////////

K6VUG SatTrackerIV.zip

@Lutraphobia Lutraphobia changed the title Feature Request: Support AdaFruit Motorshield v2.3 Feature Request: Support AdaFruit Motorshield v2.3 w/ NEMA 17 Steppers Oct 1, 2020
@Supermagnum
Copy link
Contributor

Supermagnum commented Oct 8, 2020

I am collaborating with K6VUG on an Arduino (Uno/Mega) build with the Adafruit MotorShield (my ver 2.3) driving two Nema 17 HS4401S.

His Sketch works great. Since it's a bare bones solution I'd like to eventually add ability to use a display and LM303 Magnetometer, etc.

However, after coming across this project, he was ok with me reaching out to see if a port of his code was possible. It would be great to assist others with this setup since there are so many more features.

Here is Umesh's (K6VUG) working code for the steppers and shield with EasyComm commands. How would I incorporate this into K3NG? I've tried but it will probably take me months to integrate with my limited abilities.

All credits go to UMESH/K6VUG and a huge thanks to him for helping me get up and running with his code.

Thanks!
-Walt / WA7ZYW

// Includes for Adafruit Motor Shield V2 and stepper motors

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Constants for Adafruit Motor Shield V2 and stepper motors

#define SPEED_DEFAULT 1000.0
#define ACCEL_DEFAULT 1000.0

#define STEP_TYPE SINGLE // can be changed to DOUBLE or INTERLEAVE or MICROSTEP
#define STEPS_360 200 // as specified in stepper specifications

#define CCW_MOTOR_AZ false // set this to true if clockwise command moves rotor anti-clockwise
#define CCW_MOTOR_EL false // set this to true if clockwise command moves rotor anti-clockwise

// ---------------------------- AdaFruit Shield Initialisation ----------------------------

////Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers

// Connect two steppers with 200 steps per revolution (1.8 degree) to the top shield
Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(STEPS_360, 1);
Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(STEPS_360, 2);

// create wrappers for the motors!
void forwardstep1() {
myStepper1->onestep(FORWARD, STEP_TYPE);
}

void backwardstep1() {
myStepper1->onestep(BACKWARD, STEP_TYPE);
}

void forwardstep2() {
myStepper2->onestep(FORWARD, STEP_TYPE);
}

void backwardstep2() {
myStepper2->onestep(BACKWARD, STEP_TYPE);
}

// create AccelStepper objects
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);

// ----------------------------------------------------------------------------------------

void setupSteppers() {
// initialize motor shield
initMotorShield();
// initialize motors
initMotors();
// initialize current position based on stepper data
curAz = stepper1.currentPosition() * 360 / STEPS_360;
curEl = stepper2.currentPosition() * 360 / STEPS_360;
}

void loopSteppers() {
// move the motors one step towards target position
//if ((!stepper1.isRunning()) && (stepper1.distanceToGo() != 0)) {
if ((stepper1.distanceToGo() != 0)) {
stepper1.run();
//Serial.print(stepper1.distanceToGo());
//Serial.print(",");
curAz = stepper1.currentPosition() * 360 / STEPS_360;
}
//if ((!stepper2.isRunning()) && (stepper2.distanceToGo() != 0)) {
if ((stepper2.distanceToGo() != 0)) {
stepper2.run();
//Serial.print(stepper2.distanceToGo());
//Serial.print(",");
curEl = stepper2.currentPosition() * 360 / STEPS_360;
}
}

void initMotorShield() {
////AFMSbot.begin(); // Start the bottom shield
AFMStop.begin(); // Start the top shield
}

void initMotors() {
stepper1.setMaxSpeed(SPEED_DEFAULT);
stepper1.setAcceleration(ACCEL_DEFAULT);
stepper2.setMaxSpeed(SPEED_DEFAULT);
stepper2.setAcceleration(ACCEL_DEFAULT);
}

void setNewAz(int pos) {
long newAzStep = ((long)pos) * STEPS_360 / 360;
stepper1.moveTo(newAzStep); // set new target for stepper motor
}

void setNewEl(int pos) {
long newElStep = ((long)pos) * STEPS_360 / 360;
stepper2.moveTo(newElStep); // set new target for stepper motor
}

void stopMotorAz() {
////stepper1.stop();
delay(200);
// calculate current position from stepper data
curAz = stepper1.currentPosition() * 360 / STEPS_360;
}

void stopMotorEl() {
////stepper2.stop();
delay(200);
// calculate current position from stepper data
curAz = stepper2.currentPosition() * 360 / STEPS_360;
}

void setZeroPositions() {
stepper1.setCurrentPosition(0);
stepper2.setCurrentPosition(0);
curAz = 0; newAz = curAz;
curEl = 0; newEl = curEl;
initMotors();
}

// Sends the current parameters of the azimuth servo back to the PC
void printMotorParameters() {
Serial.print("Stepper Speed: ");
Serial.println(SPEED_DEFAULT);
Serial.print("Stepper Accel: ");
Serial.println(ACCEL_DEFAULT);
Serial.print("Current Azimuth: ");
Serial.println(curAz);
Serial.print("Current Elevation: ");
Serial.println(curEl);
}

//////////////////////////////////////////////////////////////////////////////////////

K6VUG SatTrackerIV.zip

Very nice!
But I think that the code should account for worm gear box ratios like 1:60 as those does not need any form for braking.

Also, for those who need to be able to run BIG stepper motors:
PicoBorg Reverse - Dual 5A Motor Controller is the only controller that handles that kind of Amperes.
You will need one Picoborg reverse per motor, they communicate using I2C bus.

@Lutraphobia
Copy link
Author

Thanks for the feedback!

What I was really hoping for was someone with coding experience could pull this into a testing release and make the changes necessary to enable these features. AFAIK, the latest release doesn't support the motorshield or stepper motors?

Maybe it's more complicated then I thought based on your comments?

@Supermagnum
Copy link
Contributor

Supermagnum commented Oct 9, 2020

Thanks for the feedback!

What I was really hoping for was someone with coding experience could pull this into a testing release and make the changes necessary to enable these features. AFAIK, the latest release doesn't support the motorshield or stepper motors?

Maybe it's more complicated then I thought based on your comments?

My knowledge of programming is severely limited,- but I like the idea and I hope that you succeed as this is a great feature. I really can use it for 2X NEMA 23 steppers.

OH6ETB used steppers in his code, it can be found here:
https://github.com/Supermagnum/Pirotator/blob/main/pirotator.py

I think that automatic detection and setup of stepper controllers by scanning the I2C bus could eventually be implemented as some of us may want to use controllers like ThunderBorg or two Diablo boards by Piborg. The Diablo board can drive steppers that require up to 55A !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants