Background :.....
I have an old surface grinder that I am attempting to "semi - automate", at present both x & y axes are manual. The x axis table weighs around 65 kg without the magnetic chuck, so cranking this back & forth by hand is quite a chore!!
Accel & decel would be a benefit from the controller - inertia etc.
Initially simply cycling this table between adjustable limit switches/sensors, with adjustable acceleration & max speed would be a huge improvement.
If successful I will look at converting the y axis & then possibly integration of the 2 & possibly even some cnc?
As a complete novice, I have taken code published by Brian Schmalz & modified it to include a pot for speed control & also accel & decel.
I now have 1 di to start the drive in cw & 1 to start in ccw.
Toggling the opposite di when running, causes the controller to decel to a stop & the accel in the oposite direction up to a speed defined by the analogue input.
All ok so far.
If the analogue input is turned to increase the speed, the motor accelerates as expected.
If however the pot signal is reduced, the motor speed reduces WITHOUT deceleration.
This I find a bit puzzling since the same fragment of code is used for both processes?
If the stop input is activated the motor stops without deceleration.
This may be linked to the point above since I believe deceleration should take place during a stop.
Apologies up front for lots of comments in code text below - very much work in progress.
Any pointers/suggestions would be much appreciated.
Example code below :........................
// so far WORKING but decel & stop a problem
// The code for this example is shown below:
// Example5 code for Brian Schmalz's Easy Driver Example page
#include <AccelStepper.h>
// Define the stepper and the pins it will use
AccelStepper stepper1(1, 9, 8);
int SetMotorSpeed = 4000;
// Define our three input button pins
#define LEFT_PIN 4
#define STOP_PIN 3
#define RIGHT_PIN 2
// Define our analog pot input pin
#define SPEED_PIN 0
// Define our maximum and minimum speed in steps per second (scale pot to these)
#define MAX_SPEED 2000
#define MIN_SPEED 0.2
void setup() {
// The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go
// stepper1.setMaxSpeed(4000.0);
stepper1.setAcceleration(100);
// Set up the three button inputs, with pullups
pinMode(LEFT_PIN, INPUT_PULLUP);
pinMode(STOP_PIN, INPUT_PULLUP);
pinMode(RIGHT_PIN, INPUT_PULLUP);
}
void loop() {
static float current_speed = 0.0; // Holds current motor speed in steps/second
static int analog_read_counter = 1000; // Counts down to 0 to fire analog read
static char sign = 0; // Holds -1, 1 or 0 to turn the motor on/off and control direction
static int analog_value = 0; // Holds raw analog value.
/*In order to add acceleration, you'll need to change the sketch in some fundamental ways.
You'll need to remove the runSpeed() calls (as you suggest) and replace them with run() calls.
You will also need to set target positions based on which switch is pressed.
If S3 is pressed, you need to set the target very far positive.
This will cause the motor to accelerate in a positive direction.
If the S1 is pressed, you'll want to set the target very far negative.
For S2 to stop the motion, you will need to compute a target position at exactly
the right distance from your current position such that the motor starts smoothly decelerating.
There are probably other ways to do it but this is how I'd start out.
*/
// snips from m macauley author of accelstepper
// stepperB.setCurrentPosition(0);
// stepper1.setCurrentPosition(0); this doesnt seem to be needed ??
// stepperB.setMaxSpeed(SetMotorSpeed);
//stepper1.setMaxSpeed(SetMotorSpeed);
stepper1.setMaxSpeed(2000); // this adjusts speed - maybe use analog to raise lower??
// stepperB.setAcceleration(100);
stepper1.setAcceleration(50); // Lowervalue longer accel
// stepper1.moveTo(1000000);
// stepper1.run();
// }
// If a switch is pushed down (low), set the sign value appropriately
if (digitalRead(LEFT_PIN) == 0) {
sign = 1;
stepper1.moveTo(1000000); // set target way positive for using dig start/stop
}
else if (digitalRead(RIGHT_PIN) == 0) {
sign = -1;
stepper1.moveTo(-1000000); // set target way negative for using dig start/stop
}
else if (digitalRead(STOP_PIN) == 0) {
stepper1.setMaxSpeed(0); // swap sign of speed ref
// stepper1.run();
// write new speed ref
// check if speed output is zero - if so send stop command
// sign = 0; //
stepper1.stop();
// stepper1.setCurrentPosition(0); // added by mm to zero position at stop
}
// We only want to read the pot every so often (because it takes a long time we don't
// want to do it every time through the main loop).
if (analog_read_counter > 0) {
analog_read_counter--;
}
else {
analog_read_counter = 500;
// Now read the pot (from 0 to 1023)
analog_value = analogRead(SPEED_PIN);
// Give the stepper a chance to step if it needs to
stepper1.run();
// And scale the pot's value from min to max speeds
current_speed = sign * ((analog_value/1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED;
// Update the stepper to run at this new speed
stepper1.setMaxSpeed(sign * current_speed);
Serial.println(current_speed);
// Serial.println(distanceToGo);
Serial.println(analog_read_counter);
Serial.println(stepper1.currentPosition());
}
// This will run the stepper at a constant speed
// stepper1.runSpeed();
stepper1.run();
}
/*
Some explanation on this example code: Because reading the analog value takes a (relatively) long period of time,
and during that time we can't be updating the stepper motor's position (that only happens in the runSpeed() call)
we only grab a new analog value every 3000 times through the main loop. We do this by using a counter called analog_read_counter,
and decrementing it each time through the loop until it gets to zero. Then we reload it with 3000, and perform the analog conversion.
We've also inserted a runSpeed() call between the analog conversion and the math necessary to scale the result to MAX_SPEED and MIN_SPEED.
This is because that math also takes a (relatively) long time, and so we want to give the stepper a chance to step (if it needs to) in between these to time intensive operations.
You can adjust the values of MIN_SPEED and MAX_SPEED to make the range of speeds whatever you want.
Note that there are only 1024 possible values that the analogRead() call can return, and so there are only that many discrete speeds the motor can take on.
For this example (because we wanted it to be just a fixed speed) we did not use the normal AccelStepper run() call, but rather the runSpeed() call.
*/