All,
I’ve made a position controller for two stepper motors (for x & y angular positioning of a device). It’s based on a single Arduino Nano. Each motor position (rotation angle) is controlled by a separate rotary encoder that can be turned incrementally by hand.
Each step of the encoder knob corresponds to a number of definable steps on the appropriate motor. Pressing the encoder changes the rate (number of steps the motor turns) by a scaling factor set in the code.
These aspects of the controller work fine, and I can easily independently tune each motor to drive two different positioning mechanisms identical x & y angles per encoder step (despite one being via a friction drive, the other via a leadscrew).
The probelm is that I assumed that I would also be able to easily control the speed and acceleration of each motor as it moves from one position to another, by changing the vales for, for example:
motor1.setMaxSpeed
motor1.setAccelerationMax
However changing these values has no effect on speeding up the motors. To an extent it works for lower values, but is inconsistent (I need significantly higher speeds for motor 1), and sometimes acceleration of a motor seems to have a distinct step in it rather than being completely smooth. If I double the speed and acceleration for Motor 1 and upload the revised code, it just stays at the default value form the previous code.
I have generated code using AI, since this was the quickest way to get a workable result. however I’m now stuck.
Could anyone give advice how to solve this issue? A knowlegable friend fo mine has helped me with sorting another separate issue out on this, and reckons it could be something to do with the stepper library.
In all honesty what I need is a help with getting revised code I could copy and paste, since at my current skill level I’m unable to write the code from descriptions of general advice.
Appreciate any help because it’s been a long project, and this is the final hurdle to overcome.
Thanks.
#include <Wire.h>
#include <Adafruit_seesaw.h>
#include <AccelStepper.h>
// Create seesaw objects for two encoders
Adafruit_seesaw encoder1;
Adafruit_seesaw encoder2;
// Define TMC2209 pins for Motor 1
#define DIR_PIN1 2
#define STEP_PIN1 3
// Define TMC2209 pins for Motor 2
#define DIR_PIN2 6
#define STEP_PIN2 7
// Define scaling factors for encoder to motor steps
int stepsPerEncoderStep1;
int stepsPerEncoderStep2;
// High and low step scaling factors
const int HIGH_STEP_COUNT = 20;
const int LOW_STEP_COUNT = 1;
//binary state of adjustment pitch, true for coarse, false for fine
bool motorOneCoarse = true;
bool motorTwoCoarse = true;
//scale the indidivdual motors here
const int MOTOR_ONE_SCALE = 80; //Altitude factor
const int MOTOR_TWO_SCALE = 4; //Azimuth factor
int16_t lastEncoderPosition1 = 0;
int16_t lastEncoderPosition2 = 0;
// Create AccelStepper objects for two motors
AccelStepper motor1(AccelStepper::DRIVER, STEP_PIN1, DIR_PIN1);
AccelStepper motor2(AccelStepper::DRIVER, STEP_PIN2, DIR_PIN2);
void setup() {
// Initialize serial for debugging
Serial.begin(115200);
// Initialize I2C for encoder 1
if (!encoder1.begin(0x36)) {
Serial.println("Encoder 1 not found!");
while (1);
}
encoder1.pinMode(24, INPUT_PULLUP); // Set push-button pin for encoder 1
// Initialize I2C for encoder 2
if (!encoder2.begin(0x37)) { // Assuming encoder 2 is on address 0x37
Serial.println("Encoder 2 not found!");
while (1);
}
encoder2.pinMode(24, INPUT_PULLUP); // Set push-button pin for encoder 2
// Configure AccelStepper objects
motor1.setMaxSpeed(1000); // Maximum speed (steps per second)
motor1.setAcceleration(500); // Acceleration (steps per second^2)
motor2.setMaxSpeed(1000);
motor2.setAcceleration(500);
// Start at position 0 for both encoders
lastEncoderPosition1 = encoder1.getEncoderPosition();
lastEncoderPosition2 = encoder2.getEncoderPosition();
}
void loop() {
// Read button states to toggle scaling factors
if (motorOneCoarse)
{
//if in coarse adjustment, calculate total scaling factor by multiplying the initial scale by the high multiplier
stepsPerEncoderStep1 = (MOTOR_ONE_SCALE * HIGH_STEP_COUNT);
}
else
{
//if in fine adjustment, calculate total scaling factor by multiplying the initial scale by the low multiplier
stepsPerEncoderStep1 = (MOTOR_ONE_SCALE * LOW_STEP_COUNT);
}
if (motorTwoCoarse)
{
//if in coarse adjustment, calculate total scaling factor by multiplying the initial scale by the high multiplier
stepsPerEncoderStep2 = (MOTOR_TWO_SCALE * HIGH_STEP_COUNT);
}
else
{
//if in fine adjustment, calculate total scaling factor by multiplying the initial scale by the low multiplier
stepsPerEncoderStep2 = (MOTOR_TWO_SCALE * LOW_STEP_COUNT);
}
if (encoder1.digitalRead(24) == LOW) { // Button pressed on encoder 1
motorOneCoarse = !motorOneCoarse;
delay(300); // Debounce
}
if (encoder2.digitalRead(24) == LOW) { // Button pressed on encoder 2
motorTwoCoarse = !motorTwoCoarse;
delay(300); // Debounce
}
// Read positions from encoders
int16_t encoderPosition1 = encoder1.getEncoderPosition();
int16_t encoderPosition2 = encoder2.getEncoderPosition();
// Calculate steps to move for Motor 1
int stepsToMove1 = (encoderPosition1 - lastEncoderPosition1) * stepsPerEncoderStep1;
if (stepsToMove1 != 0) {
motor1.move(stepsToMove1); // Set target position
lastEncoderPosition1 = encoderPosition1;
}
// Calculate steps to move for Motor 2
int stepsToMove2 = (encoderPosition2 - lastEncoderPosition2) * stepsPerEncoderStep2;
if (stepsToMove2 != 0) {
motor2.move(stepsToMove2); // Set target position
lastEncoderPosition2 = encoderPosition2;
}
// Run motors to their target positions
motor1.run();
motor2.run();
// Debugging information
Serial.print("Encoder 1 Position: ");
Serial.println(encoderPosition1);
Serial.print("Steps for Motor 1: ");
Serial.println(stepsToMove1);
Serial.print("Encoder 2 Position: ");
Serial.println(encoderPosition2);
Serial.print("Steps for Motor 2: ");
Serial.println(stepsToMove2);
}




