Hardware:
- Arduino Uno Rev3
- A4988 Driver
- Nema 8 Stepper
Setup: I've adjusted the VRef of the driver based on the formula VRef = Imot * 8 * Rsen. With the values of Imot = .5 (max = .6), Rsen = .068. A 12-Volt power supply is being used to supply power to the breadboard hat for the Arduino.
The Arduino code is being activated by a Python GUI, that is sending commands to the Arduino to make adjustments to the code in order to manipulate delay between steps, step size, and enable/disable. here is a simplified version of the Arduino code.
#include "src/Laser_Welder_8124.h"
void setup() {
//
Serial.begin(115200);
pinMode(STEPPER_DIR, OUTPUT);
pinMode(STEPPER_STEP, OUTPUT);
pinMode(STEPPER_ENABLE, OUTPUT);
pinMode(STEPPER_MS1, OUTPUT);
pinMode(STEPPER_MS2, OUTPUT);
pinMode(STEPPER_MS3, OUTPUT);
digitalWrite(STEPPER_MS1, HIGH);
digitalWrite(STEPPER_MS2, HIGH);
digitalWrite(STEPPER_MS3, HIGH);
digitalWrite(STEPPER_DIR, HIGH);
digitalWrite(STEPPER_ENABLE, HIGH);
}
void loop() {
curMillis = millis();
commsCheck();
singleStep();
}
void commsCheck(){
if(Serial.available() > 0){
int rlen = Serial.readBytes(incomingMsg, MSGSIZE);
byte cmd = incomingMsg[CMD_POS];
int val = incomingMsg[VAL_POS];
switch(cmd){
case 0xC0:{
enableStepperMotor(val);
break;
}
case 0xC1:{
toggleStepperDirection(cmdLookup[2].pin, val);
break;
}
case 0xC2:{
cmdLookup[0].state = val;
millisBetweenSteps = val;
break;
}
case 0xC7:{
setStepSize(val);
break;
}
}
}
}
void setStepSize(int val){
switch(val){
case 0xD0:{
stepSize(HIGH, HIGH, HIGH);
break;
}
case 0xD1:{
stepSize(HIGH, HIGH, LOW);
break;
}
case 0xD2:{
stepSize(LOW, HIGH, LOW);
break;
}
case 0xD3:{
stepSize(HIGH, LOW, LOW);
break;
}
case 0xD4:{
stepSize(LOW, LOW, LOW);
break;
}
}
}
void stepSize(int MS1, int MS2, int MS3){
digitalWrite(STEPPER_MS1, MS1);
digitalWrite(STEPPER_MS2, MS2);
digitalWrite(STEPPER_MS3, MS3);
}
void toggleStepperDirection(int pin, int val)
{
if (val == 0){
cmdLookup[1].state = CW;
digitalWrite(STEPPER_DIR, LOW);
}
else{
cmdLookup[1].state = CCW;
digitalWrite(STEPPER_DIR, HIGH);
}
}
void singleStep() {
if (curMillis - prevStepMillis >= millisBetweenSteps) {
prevStepMillis = curMillis;
digitalWrite(STEPPER_STEP, HIGH);
digitalWrite(STEPPER_STEP, LOW);
}
}
This works, for the most part.
I'm using the GUI to pass a value from 1-255 to represent a delay between steps in milliseconds.
If I set the time between steps to 1 ms, then it runs smoothly on all step sizes. However, when I start to play with the time delay, I get all sorts of jitter, at different time delays with different step sizes. How do I go about smoothing out the motor so I can use a range of delays across different step sizes?
I've attached a video link to show you what I'm seeing.