Hi all,
First electronics project and first post. I have an Arduino micro controlling a stepper motor on an equatorial platform for my telescope and have been having some issues where it sometimes slows down and speeds up minutely but when looking at an object at 400x zoom it looks exaggerated. Having said that the overall performance is quite good, I'm just striving for every last bit of accuracy.
The issue could be a number of things but was advised to first ensure the Arduino is sending the step signal correctly and on-time. So I've connected a second Arduino to the step pin of the micro to calculate the delay between steps, however I'm getting some interesting results.
Firstly my set up for stepper motor:
- 12v 3amp power supply split so 12v goes directly to stepper drive and 12v goes into a buck converter which Converts to 5 v and powers Arduino via 5v pin.
- Arduino micro
- s109 driver
- NEMA 17 stepper 1.6 amp
Sketch:
int button = 13; // the number of the input pin
int Buzzer = 11; // the number of the output pin
int ms1 = 2;
int ms2 = 3;
int ms3 = 4;
int state = LOW; // the current state of the output pin
int reading; // the current reading from the input pin
int previous = LOW; // the previous reading from the input pin
#define dirPin 8
#define stepPin 7
#define stepsPerRevolution 5400
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0; // the last time the output pin was toggled
long debounce = 2000; // the debounce time, increase if the output flickers
unsigned long endTime;
boolean itAlreadyHappened = true;
unsigned long delay_Micros = 12620;
unsigned long next_Micros = 0;
void setup()
{
Serial.begin(9600);
pinMode(button, INPUT);
pinMode(Buzzer, OUTPUT);
// Declare pins as output:
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(ms1, OUTPUT);
pinMode(ms2, OUTPUT);
pinMode(ms3, OUTPUT);
digitalWrite(ms1, HIGH);
digitalWrite(ms2, HIGH);
digitalWrite(ms3, LOW);
// Next (first) step should occur delay_Micros from now
next_Micros = micros() + delay_Micros;
// Set the spinning direction clockwise (tracking direction)
digitalWrite(dirPin, HIGH);
}
void loop()
{
reading = digitalRead(button);
// If the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
}
if (state==LOW) {
if (itAlreadyHappened == false)
{
digitalWrite(dirPin, HIGH); // Enables motor to speed up in normal tracking direction to clear push button eliminating multiple reads.
for(int x = 0; x < 18000; x++) {
digitalWrite(stepPin, HIGH);
delayMicroseconds(200);
digitalWrite(stepPin, LOW);
delayMicroseconds(200);
}
// Reset our target time for the next "tracking" step
next_Micros = micros() + delay_Micros;
itAlreadyHappened = true;}
// Handle normal tracking steps
// These lines result in 1 step:
if (micros() >= next_Micros) {
next_Micros += delay_Micros;
digitalWrite(stepPin, HIGH);
delayMicroseconds(10);
digitalWrite(stepPin, LOW);
}
}
else {
// Set the spinning direction in reverse to reset platform and return to start position.
// this actualy runs first when arduino powered on.
digitalWrite(dirPin, LOW);
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(16);
digitalWrite(stepPin, LOW);
delayMicroseconds(16);
itAlreadyHappened = false;
}
}
Arduino monitoring step signal
- Arduino Uno
Sketch:
// Log the delay between successive low to high transitions
int testPin = 2;
void setup() {
Serial.begin(115200);
pinMode(testPin, INPUT_PULLUP);
Serial.println("Test:");
}
long timeStart = micros(); // Start time of previous transition.
long timeInterval = 0; // Duration.
boolean previousState = HIGH; // Pin state at last transition.
void loop() {
if (previousState == LOW && digitalRead(testPin) == HIGH) {
// Low to High transition has occurred
previousState = HIGH; // State is now High
timeInterval = micros() - timeStart; // Calculate interval
timeStart = micros(); // Reset timer
Serial.println(timeInterval); // Log it
}
else if (previousState == HIGH && digitalRead(testPin) == LOW) {
// High to Low transition has occurred.
previousState = LOW; // State is now Low
}
}
The issue is that when monitoring the step signal in my normal set up as per above I'm not getting consistent numbers, it's quite erratic please see sample below. However, If i was to also connect the USB from the computer to the Arduino micro the step signal immediately becomes more consistent/what was expected, example below. After some testing with different power supplies I have observed the following behaviour.
- 12v 3a power supply - timing issue present.
- 12v 5a power supply - timing issues present.
- 12v 2amp power supply -majority of problem removed but still some issues.
- 12v 3a as per set up above with USB from computer connected to Arduino micro - no issue, timing looks fine.
- 12v 3a only powering stepper driver, USB powering Arduino, most consistent method.
- how ever powering the Arduino micro via USB using a USB charger does not solve the issue.
Sample of timing steps:
12580
4196
224
192
196
204
7564
9756
1740
220
188
200
180
308
12600
6352
220
184
216
196
5396
12584
Sample of timing steps whith computer usb power:
12604
12604
12608
12604
12612
12608
12604
12600
12604
12608
12604
12608
12604
12604
12608
12608
12600
12604
My questions are:
- What is causing this problem, I have I wired something wrong? Although powering by USB is not the biggest deal I don't allways have a laptop near by when doing visual observing.
- Is this a glitch that would only be effecting the serial monitor time between steps or does it look like it will actually be effecting the stepper.
- I've noticed when the buck converter is disconnected the Arduino still works as it must be getting 5v front the stepper drive. Is that right?
Please let me know if you need any further info.
Thanks in advance.
Greg

