A Serial.print make my function work differently, WHY?

hello,
in first place I am not an English native so sorry for my bad English.
I work on a robot with multiple functions. Here I work on the use of the 2 wheels. All my function work perfectly if I don't mind this bug.
The goal of this function is to make the robot go forward or backward, my speed (vitesse) is returned by a function who do a acceleration and deceleration ramp. when I print the speed I see that everything work perfectly and the motor turn at full speed, BUT when I remove it my motor turn really slowly. I want to test the value of the speed when it doesn't work but if I put the serial.print it work.... so I don't know how to resolve this bug without letting the serial.print

 while (!(flag1 && flag2)) {
    vitesse = calcule_vitesse(abs(tck1), abs(pas), v_max);
    error = abs(tck2) - abs(tck1);
    error_sum += error;
    correction1 = Kp * error + Ki * error_sum;
    correction2 = Kp * error + Ki * error_sum;
    vitesse_m1 = vitesse + correction1;
    vitesse_m2 = vitesse - correction2;
    vitesse_m1 = max(min_speed, min(max_speed, vitesse_m1));
    vitesse_m2 = max(min_speed, min(max_speed, vitesse_m2));
    Serial.println(vitesse);
    //Serial.println(abs(tck2) - abs(tck1));
    if (abs(tck1) < abs(pas)) {
      m_gauche(sens, vitesse_m1);
    } else {
      flag1 = true;
      m_gauche('s', 0);
    }

    if (abs(tck2) < abs(pas)) {
      m_droite(sens, vitesse_m2);
    } else {
      flag2 = true;
      m_droite('s', 0);
    }
  }

It could be timing, or it could be something in the code you didn't post.

It was the first thing I tried to add delay, But it don't work

what is the difference?
which value or condition changes when a print is added?

what are states of the variables?

how can i reproduce your error

There is any , only print can fix the bug , but maybe I have found , when the error get too high at the start Arduino fail the calcul and set a wrong speed on my motors. but I don't see why the serial fix it

...all of the code

My first thought is baud rate and bandwidth but that’s just a wild guess without the code.

I can give u full code but:
-it is in frech so I not sure u will understand
-there is 900 lines :joy:

but maybe only this one should be good:

// to make motor turn
void m_droite(char s, int vitesse) {
  switch (s) {
    case 'a':
      digitalWrite(in1, LOW);
      analogWrite(in2, vitesse);
      break;
    case 'r':
      digitalWrite(in2, LOW);
      analogWrite(in1, vitesse);
      break;
    case 's':
      digitalWrite(in2, LOW);
      analogWrite(in1, LOW);
      break;
    default:
      break;
  }
}

void m_gauche(char s, int vitesse) {
  switch (s) {
    case 'a':
      digitalWrite(in4, LOW);
      analogWrite(in3, vitesse);
      break;
    case 'r':
      digitalWrite(in3, LOW);
      analogWrite(in4, vitesse);
      break;
    case 's':
      digitalWrite(in3, LOW);
      analogWrite(in4, LOW);
      break;
    default:
      break;
  }
}



// ramp:
float calcule_vitesse(double pas, double pas_cible, int vitesse) {
  double deceleration = -500 * pas / pas_cible + 880;
  double acceleration = 500 * pas / pas_cible + 30;

  return (min(min(acceleration, vitesse), min(deceleration, vitesse)));
}


// and full go forward func

void avancer(double v_max, int l) {
  tck1 = 0;
  tck2 = 0;
  double vitesse_m1, vitesse_m2, vitesse;
  double flag1 = false, flag2 = false;


  l = l - 30;
  double pas = l / dist_tick;



  char sens;
  double min_speed = v_max * 0.15, max_speed = v_max;
  double correction=0, error, error_sum=0;
  float Ki = 0.001, Kp = 1;
  if (pas < 0) {
    sens = 'r';
  } else {
    sens = 'a';
  }

  while (!(flag1 && flag2)) {
    vitesse = calcule_vitesse(abs(tck1), abs(pas), v_max);
    
    error = abs(tck2) - abs(tck1);
    error_sum += error;
    correction = Kp * error + Ki * error_sum;
    //correction=max(-500,min(correction,500));
    
    vitesse_m1 = vitesse + correction;
    vitesse_m2 = vitesse - correction;
   
   Serial.println(tck1-tck2);
    vitesse_m1 = max(min_speed, min(max_speed, vitesse_m1));
    vitesse_m2 = max(min_speed, min(max_speed, vitesse_m2));
    
    //Serial.println(abs(tck2) - abs(tck1));
    if (abs(tck1) < abs(pas)) {
      m_gauche(sens, vitesse_m1);
    } else {
      flag1 = true;
      m_gauche('s', 0);
    }

    if (abs(tck2) < abs(pas)) {
      m_droite(sens, vitesse_m2);
    } else {
      flag2 = true;
      m_droite('s', 0);
    }
  }

// here is just some debug code
  delay(1000);

  l = l + 30;
  pas = l / dist_tick;
  Serial.println("\n\n\npas theo");
  Serial.println(pas);
  Serial.println("pas réel");
  Serial.println(tck1);
  Serial.println("erreur");
  Serial.println(abs(tck1) - abs(tck2));
  Serial.println("erreure de pos");
  Serial.println(((double)abs(tck1) - (double)abs(pas)) / (double)abs(pas));
}

//and here some odometrie shit

void deplacement(int x, int y, int vitesse) {

  double a = x - x_reel, b = y - y_reel, c = sqrt(a * a + b * b);
  double angle_cible = atan(b / a) * 180 / PI, angle_d = 0;
  x_reel = x;
  y_reel = y;
  if (a >= 0) {
    if (b >= 0) {
      angle_cible = angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    } else {
      angle_cible = 360 + angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    }
  } else {
    if (b >= 0) {
      angle_cible = 180 + angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    } else {
      angle_cible = 270 - angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    }
  }
  if (angle_d < -180) {
    angle_d = angle_d + 360;
  } else {
    if (angle_d > 180) {
      angle_d = angle_d - 360;
    }
  }
  if (angle_d > 1 || angle_d < -1) {
    tourner(150, angle_d);
  }
  delay(500);
  avancer(c, vitesse);
  delay(500);
}




No ! post the complete sketch.
There are possabilities that should be examined that can be done without knowing the meanings of all french variables.

As english is not your native language and variable-names are french
Have you considered to send a message to a moderator that the moderator shall MOVE your thread to the french-speaking subforum?

you should not start a second thread on the same question in the french subforum. Starting a second thread on the same question would be violating forum-rules (cross-posting) Even if it is another language
best regards Stefan

I was thinking that I will have a lot more answer here cause there is not a lot of french and I know how to speak English , anyway, I think I have the issue , I use a variable that I had to itself but I never initialize it. I am pretty sure it will work.

Edit: it don't work the issue wasn't the non initialized variable
And finnaly here is the cleaned code:

#include <Servo.h>

// defines pins numbers
const int in1 = 2;
const int in2 = 3;
const int in3 = 4;
const int in4 = 5;
#define cp_1 18
#define cm_1 16
#define cp_2 19
#define cm_2 17
#define PI 3.141592
#define nb_pas 1120
#define r_roue 30.36
#define fc_gauche 21
#define fc_start 15
#define sw_team 14
#define fc_droite 20
#define pin_servo_droit 7
#define pin_servo_gauche 6

bool flag1 = false, flag2 = false;
double p_robot = 214;
float compensation = 300;
double P_roue = PI * 2 * r_roue;                      //Définition & Calcul du périmètre dz la roue
double P_tour = PI * p_robot;                         //Définition & Calcul du périmètre du robot
float theta_tick = 360 * P_roue / (P_tour * nb_pas);  //Calcul la valeur du tick pour avoir parcourue 1rad
float dist_tick = P_roue / nb_pas;                    //Calcul la valeur du tick pour avoir parcourue 1mm*
double tck1, tck2, x_reel, y_reel, angle;

Servo s_gauche;
Servo s_droit;

void compteur1() {
  if (!digitalRead(cm_1)) {
    tck2--;
  } else {
    tck2++;
  }
}

void compteur2() {
  if (!digitalRead(cm_2)) {
    tck1--;
  } else {
    tck1++;
  }
}

void setup() {
  s_droit.attach(pin_servo_gauche);
  s_gauche.attach(pin_servo_droit);
  // Sets the two pins as Outputs
  Serial.begin(115200);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(cp_1, INPUT_PULLUP);
  pinMode(cp_2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(cp_1), compteur1, FALLING);
  attachInterrupt(digitalPinToInterrupt(cp_2), compteur2, RISING);

  x_reel = 1250;
  y_reel = 400;
  angle = 90;
  servo('p');
}
int state, lstate = digitalRead(fc_start);
bool flagstart = false;

void loop() {

  //a loop just for debugging
  while (true) {
    state = digitalRead(fc_start);
    if (state != lstate) {
      flagstart = true;
    }
    lstate = state;
    while (flagstart) {

      avancer(200, 1000);delay(3000);      avancer(200, -1000);delay(300);
    }
  }
   //end of this loop


  go_zone_bleu();
  //pousser de palet
  servo('o');
  digitalWrite(in1, LOW);
  analogWrite(in2, 90);

  analogWrite(in3, 90);
  digitalWrite(in4, LOW);
  delay(2500);
  // set du x
  avancer(-75, 200);
  servo('f');
  // reset pos

  servo('f');
  while (!(flag1 && flag2)) {
    if (!digitalRead(fc_gauche) && !flag1) {
      analogWrite(in4, 100);
      digitalWrite(in3, LOW);
    } else {
      analogWrite(in4, 0);
      digitalWrite(in3, LOW);
      flag1 = true;
    }

    if (!digitalRead(fc_droite) && !flag2) {
      digitalWrite(in2, LOW);
      analogWrite(in1, 100);
    } else {
      flag2 = true;
      digitalWrite(in2, LOW);
      analogWrite(in1, 0);
    }
  }
  delay(500);



  //set du y
  avancer(500, 200);

  flag1 = false;
  flag2 = false;
  while (!(flag1 && flag2)) {
    if (!digitalRead(fc_gauche) && !flag1) {
      analogWrite(in4, 100);
      digitalWrite(in3, LOW);
    } else {
      analogWrite(in4, 0);
      digitalWrite(in3, LOW);
      flag1 = true;
    }

    if (!digitalRead(fc_droite) && !flag2) {
      digitalWrite(in2, LOW);
      analogWrite(in1, 100);
    } else {
      flag2 = true;
      digitalWrite(in2, LOW);
      analogWrite(in1, 0);
    }
  }
  avancer(200, 200);

  avancer(480, 200);
  Serial.println("3\n");
  delay(3000);
  avancer(-105, 300);
  delay(3000);
  avancer(-105, 300);
  delay(3000);
  delay(1000000);
}
 //com with an other arduino
void grab(int x) {
  switch (x) {
    case 1:
      Serial.print("h0000\n");
      delay(3000);
      Serial.println("0\n");
      delay(500);
      Serial.print("h2000\n");
      delay(3000);
      break;
    case 2:
      Serial.print("h0400\n");
      delay(1300);
      Serial.println("0\n");
      delay(500);
      Serial.print("h1200\n");
      delay(2500);
      break;
    case 3:
      Serial.print("h0900\n");
      delay(3000);
      Serial.println("0\n");
      delay(800);
      Serial.print("h2000\n");
      delay(3000);
      break;
  }
}
 //com with an other arduino
void releas(int x) {
  switch (x) {
    case 1:
      Serial.print("h0000\n");
      delay(3000);
      Serial.println("1\n");
      delay(100);
      Serial.print("h1500\n");
      delay(2000);
      break;
    case 2:
      Serial.print("h0500\n");
      delay(1500);
      Serial.println("1\n");
      delay(500);
      Serial.print("h1999\n");
      delay(3000);
      break;
    case 3:
      Serial.print("h1000\n");
      delay(3000);
      Serial.println("1\n");
      delay(500);
      Serial.print("h1500\n");
      delay(3000);
      break;
  }
}

void go_zone_bleu() {
  servo('p');

  deplacement(1250, 790, 170);
  deplacement(1880, 790, 170);
  deplacement(2040, 290, 170);
  deplacement(2600, 290, 200);
  servo('o');
}


void servo(char x) {
  switch (x) {
    case 'f':
      s_gauche.write(360);
      s_droit.write(0);
      Serial.println("fermer");
      break;
    case 'o':
      s_gauche.write(0);
      s_droit.write(360);
      Serial.println("ouvert");
      break;
    case 'p':
      s_gauche.write(50);
      s_droit.write(150);
      Serial.println("pousser");
      break;
    default:
      break;
  }
}
void deplacement(int x, int y, int vitesse) {

  double a = x - x_reel, b = y - y_reel, c = sqrt(a * a + b * b);
  double angle_cible = atan(b / a) * 180 / PI, angle_d = 0;
  x_reel = x;
  y_reel = y;
  if (a >= 0) {
    if (b >= 0) {
      angle_cible = angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    } else {
      angle_cible = 360 + angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    }
  } else {
    if (b >= 0) {
      angle_cible = 180 + angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    } else {
      angle_cible = 270 - angle_cible;
      angle_d = angle_cible - angle;
      angle = angle_cible;
    }
  }
  if (angle_d < -180) {
    angle_d = angle_d + 360;
  } else {
    if (angle_d > 180) {
      angle_d = angle_d - 360;
    }
  }
  if (angle_d > 1 || angle_d < -1) {
    tourner(150, angle_d);
  }
  delay(500);
  avancer(c, vitesse);
  delay(500);
}

void debug() {
  Serial.println("reele:");
  Serial.println(tck1);
  Serial.println("erreur:");
  Serial.println(abs(tck1) - abs(tck2));
}

void m_droite(char s, int vitesse) {
  switch (s) {
    case 'a':
      digitalWrite(in1, LOW);
      analogWrite(in2, vitesse);
      break;
    case 'r':
      digitalWrite(in2, LOW);
      analogWrite(in1, vitesse);
      break;
    case 's':
      digitalWrite(in2, LOW);
      analogWrite(in1, LOW);
      break;
    default:
      break;
  }
}

void m_gauche(char s, int vitesse) {
  switch (s) {
    case 'a':
      digitalWrite(in4, LOW);
      analogWrite(in3, vitesse);
      break;
    case 'r':
      digitalWrite(in3, LOW);
      analogWrite(in4, vitesse);
      break;
    case 's':
      digitalWrite(in3, LOW);
      analogWrite(in4, LOW);
      break;
    default:
      break;
  }
}

/*

    Commencez avec une valeur de Kp relativement élevée et Ki à zéro. Ensuite, ajustez Kp jusqu'à ce que le système réponde de manière stable à une entrée de référence.
Ensuite, ajustez Ki jusqu'à ce que l'erreur à long terme (offset) soit minimisée. Cependant, trop augmenter Ki peut causer une oscillation indésirable, donc il faut trouver un bon équilibre.
Si le système montre des oscillations indésirables, diminuez Kp et augmentez Ki. Si la réponse est trop lente, augmentez Kp et diminuez Ki.
Il est important de noter que les valeurs de Ki et Kp peuvent changer si le système est modifié, donc il faut réajuster régulièrement pour s'assurer des bonnes performances.


    */
float calcule_vitesse(double pas, double pas_cible, int vitesse) {
  double deceleration = -500 * pas / pas_cible + 880;
  double acceleration = 500 * pas / pas_cible + 30;

  return (min(min(acceleration, vitesse), min(deceleration, vitesse)));
}

void avancer(double v_max, int l) {
  tck1 = 0;
  tck2 = 0;
  double vitesse_m1, vitesse_m2, vitesse;
  double flag1 = false, flag2 = false;


  l = l - 30;
  double pas = l / dist_tick;



  char sens;
  double min_speed = v_max * 0.15, max_speed = v_max;
  double correction=0, error, error_sum=0;
  float Ki = 0.001, Kp = 1;
  if (pas < 0) {
    sens = 'r';
  } else {
    sens = 'a';
  }

  while (!(flag1 && flag2)) {
    vitesse = calcule_vitesse(abs(tck1), abs(pas), v_max);
    
    error = abs(tck2) - abs(tck1);
    error_sum += error;
    correction = Kp * error + Ki * error_sum;
    //correction=max(-500,min(correction,500));
    
    vitesse_m1 = vitesse + correction;
    vitesse_m2 = vitesse - correction;
   
   Serial.println(tck1-tck2);
    vitesse_m1 = max(min_speed, min(max_speed, vitesse_m1));
    vitesse_m2 = max(min_speed, min(max_speed, vitesse_m2));
    
    //Serial.println(abs(tck2) - abs(tck1));
    if (abs(tck1) < abs(pas)) {
      m_gauche(sens, vitesse_m1);
    } else {
      flag1 = true;
      m_gauche('s', 0);
    }

    if (abs(tck2) < abs(pas)) {
      m_droite(sens, vitesse_m2);
    } else {
      flag2 = true;
      m_droite('s', 0);
    }
  }
  delay(1000);

  l = l + 30;
  pas = l / dist_tick;
  Serial.println("\n\n\npas theo");
  Serial.println(pas);
  Serial.println("pas réel");
  Serial.println(tck1);
  Serial.println("erreur");
  Serial.println(abs(tck1) - abs(tck2));
  Serial.println("erreure de pos");
  Serial.println(((double)abs(tck1) - (double)abs(pas)) / (double)abs(pas));
}

void tourner(int v_max, int angle) {
  tck1 = 0;
  tck2 = 0;
  double P_tour = PI * p_robot;  //Définition & Calcul du périmètre du robot
  float theta_tick = 360 * P_roue / (P_tour * nb_pas);
  double pas = angle / theta_tick;  //Calcul du nombre de tick pour tourné en fonction de l'angle voulu

  double vitesse_m1, vitesse_m2, vitesse;
  double flag1 = false, flag2 = false;

  char sens1, sens2;
  double min_speed = v_max * 0.15, max_speed = v_max;
  double correction1, correction2, error, error_sum;
  float Ki = 0.00, Kp = 5;
  if (pas < 0) {
    sens1 = 'a';
    sens2 = 'r';
  } else {
    sens1 = 'r';
    sens2 = 'a';
  }
  Serial.println("\n\n\npas theo");
  Serial.println(pas);
  while (!(flag1 && flag2)) {
    vitesse = calcule_vitesse(abs(tck1), abs(pas), v_max);
    error = abs(tck2) - abs(tck1);
    error_sum += error;
    correction1 = Kp * error + Ki * error_sum;
    correction2 = Kp * error + Ki * error_sum;
    vitesse_m1 = vitesse + correction1;
    vitesse_m2 = vitesse - correction2;
    vitesse_m1 = max(min_speed, min(max_speed, vitesse_m1));
    vitesse_m2 = max(min_speed, min(max_speed, vitesse_m2));

    //Serial.println(vitesse);
    //Serial.println(abs(tck2) - abs(tck1));
    if (abs(tck1) < abs(pas)) {
      m_gauche(sens1, vitesse_m1);
    } else {
      flag1 = true;
      m_gauche('s', 0);
    }

    if (abs(tck2) < abs(pas)) {
      m_droite(sens2, vitesse_m2);
    } else {
      flag2 = true;
      m_droite('s', 0);
    }
  }
}

The Non-English moderators don't like english and the language mixed, understandable it makes for harder reading.

I would advise to leave in the english section.

tck1 and tck2 are modified in an ISR. They should be marked 'volatile'. It also make no sense to use a 'double' as a counter. Use 'long int' instead:

volatile unsigned long tck1, tck2;
double x_reel, y_reel, angle;

I will change it thx

What processor are you using? When you compile the code how much RAM is left?

When problems move with seemingly unrelated code changes it is usually due to memory corruption. Bad pointers, bad array references, allocating memory when there isn't any left and not checking return codes, etc. Since simple micro controllers have no memory protection bad things happen with no warning. Processors like the esp will give an exception. (Which a lot of people will then come here complaining about without doing the exception analysis.)

From experience, adding or removing (print) statements making the code work or fail indicate memory issues; e.g. writing or reading outside the boundaries of arrays, incorrect use of the String (capital S) object.

I can't look at your code now.