Arduino Micro timming issue based on power supply

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:

  1. 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.
  2. 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.
  3. 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

A quick examination of your timing numbers shows:

12580
================
4196
224
192
196            <- This lot all add up to 12576
204
7564
================
9756
1740
220
188            <- This lot all add up to 12592
200
180
308
================
12600
================
6352
220
184            <- This lot all add up to 12564
216
196
5396
================
12584

Your monitoring Arduino seems to be detecting spurious pulses/noise in the step signal. I'm no expert, but more power supply filtering may help. Now, over to a power supply guru ...

Thanks for the reply. I did see research regarding reducing notice from the powersuply and tried adding in a 100uf capacitor on the 5v line but that didn't seem to help at all.

Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advice on) your project :wink: See About the Installation & Troubleshooting category.

Just bumping this to see if any one can assist with the timing issue. Is there anything I can do to clean the signal from the power supply?

You need to run your stepper motor timing function independent of any Serial print statements.

This is usually done using in combination with a Timer/Counter and an Interrupt. Take a look at the example "Timer Interrupts" mid-way down the page in this link..

Timer Interrupts

Depending on your required motor step rate, you might be able to configure the Timer/Counter to output PWM signal of the correct rate and not need an Interrupt. Otherwise, the Interrupt would facilitate incrementing a variable until it reached a specific value to be reset and toggle the processor pin from high to low or low to high.

In the pulse generator (arduino micro) you have

however at a cursory glance I see no serial. outputs.

my first thought from your description is that your stepper motor pulses might be causing interference. You SHOULD have a BIG capacitor at the power supply pins of the stepper driver; and also the grounds should be connected at a star point.

I see you are using hardware debouncing on the push button - which is fine - although you havent shown the capacitor value; but your diagram doesnt show a pull up.

a really excellent first post, and an interesting and useful project.
schematic, clear description, nicely commented code