Serial.print() messing with my code??

Hey!

I uploaded some example code to my ArduioUno to test if the StepperMotor and DriverBoard I connected are working.
Everything worked as intended but I noticed that the motor was jittery in a specific range of the potentiometer I use to control the speed of the servo.
I thought that the incoming values might be fluctuating and added code to print the values to the Serial port.
After adding the Serial.print() command the motor stopped corresponding to changes of the potentiometer although the values sent via serial did change.
I thought that the pins I used may interfere with the Serial but that doesn’t seem to be the problem.

Here is the code i was using:

/*     Simple Stepper Motor Control Exaple Code
 *      
 *  by Dejan Nedelkovski, www.HowToMechatronics.com
 *  
 */
 
// Defines pins numbers
const int stepPin = 3;
const int dirPin = 4; 
int customDelay,customDelayMapped; // Defines variables
 
void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
 
  digitalWrite(dirPin,HIGH); //Enables the motor to move in a particular direction

  Serial.begin(9600);
}
void loop() {
  
  customDelayMapped = speedUp(); // Gets custom delay values from the custom speedUp function
  // Makes pules with custom delay, depending on the Potentiometer, from which the speed of the motor depends
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(customDelayMapped);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(customDelayMapped);
  
  Serial.print("Speed: ");
  Serial.println(customDelayMapped);
}
// Function for reading the Potentiometer
int speedUp() {
  int customDelay = analogRead(A0); // Reads the potentiometer
  int newCustom = map(customDelay, 0, 1023, 300,4000); // Convrests the read values of the potentiometer from 0 to 1023 into desireded delay values (300 to 4000) 
  return newCustom;
}

I am new to electronics and using the Arduino in general so there might be a really obvious solution but i can’t find it…

Dont print after every step. That will be slow.

It is best to use the blink-without-delay technique to only print once or twice per second.

Also, try adding the constrain() function after the map() function.

Okay, you are using 0-1023 so the constrain function would not be needed.

I changed my code as you suggested MorganS.

// Defines pin numbers
const int stepPin = 3;
const int dirPin = 4; 
// Defines variables
int customDelay,customDelayMapped;
int motorState = LOW;
unsigned long previousMicros= 0;
unsigned long currentMicros = 0;

void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);

  digitalWrite(dirPin,HIGH); //Enables the motor to move in a particular direction

  Serial.begin(9600);
}
void loop() {

  currentMicros = micros();
  customDelayMapped = speedUp(); // Gets custom delay values from the custom speedUp function
  // Makes pules with custom delay, depending on the Potentiometer, from which the speed of the motor depends
  
  if(currentMicros-previousMicros >= customDelayMapped){
    previousMicros = currentMicros;
    if(motorState==LOW){
      digitalWrite(stepPin, HIGH);
      motorState = HIGH;
    }else{
      digitalWrite(stepPin, LOW);
      motorState = LOW;
    }
    //Serial.print("Speed: ");
    //Serial.println(customDelayMapped);
  }
}
// Function for reading the Potentiometer
int speedUp() {
  int customDelay = analogRead(A0); // Reads the potentiometer
  int newCustom = map(customDelay, 0, 1023, 300,4000); // Convrests the read values of the potentiometer from 0 to 1023 into desireded delay values (300 to 4000)
  return newCustom;
}

The problem still remains. I think the Serial.print() messes with the timing somehow. For the project I am working on it should not matter too much because I wanted to use the Serial output for debugging purposes only but I would really like to understand what is going on.

Serial.begin(9600);How is the code affected when you increase this to 115200?

That's even worse! You print the data even when the motor isn't due to take a step.

Put another timer section around the Serial.print section. Something like...

const unsigned long printInterval = 1000; //milliseconds

void loop() {
  //stepper code goes here

  static unsigned long lastPrint = 0;
  if(millis()-lastPrint > printInterval) {
    Serial.print("Speed: ");
    Serial.println(customDelayMapped);
    lastPrint = millis();
  }
}

edited: added the line that updates lastPrint

MorganS: That's even worse! You print the data even when the motor isn't due to take a step.

Put another timer section around the Serial.print section. Something like...

I only executed the code with every update of the motor. I tried your idea and the motor reacts to the potentiometer again now but every second you can clearly hear that there's a small bump. So the problem is still there but occurs only every second now.

GrooveFlotilla: How is the code affected when you increase this to 115200?

This seemed to help but after further testing out all the other rates I now found out that the higher the baudrate, the faster the motor runs, and vice versa ( I call the print evry single time the motor updates). But the motor speed is a lot higher when I totally remove the print command. I also tried combining both suggestions but you can still clearly hear the bump every second.

Then I found this https://www.robotshop.com/letsmakerobots/arduino-fix-serialprint-used-diagnose-can-adversely-affect-timing and that explains the problem prefectly.

The print function takes several milliseconds to execute! So every print disabled several motor updates from happening.

Is there a place where you can look up the execution time of commands? I want t keep my motor timings as tight as I can.

I think I am going to use timer interrupts to ensure that the motor timing is as close to perfect as possible and I am only gonna use the print function for debuggin as needed.

Case closed ;)

Well, you've proven that the pot works. So remove the prints and run at full speed.

Show us the code which has a bump every second. If you combined my code with the code in reply #3 then it should not have that problem.

Also note that you only need a short pulse of 1 microsecond for most steppers drivers. So you do not need equal delays for high and low. This is one situation where delayMicroseconds() is a good thing to use.