Sending chars but not receiving the right thing

Hello, I'm currenctly programming a robot for a school project. I have 3 ultrasonic sensors (HC-SR04) . I'm using 2 arduinos, 1 as a slave, which just drives the motors and the other as a master. On the master one, I'm sending characters 'A' (Go forward) 'G' (Go left) 'D' (Go right) 'M' (End of the run). I'm using the uart on D0-D1 as a serial communication. I don't get why but when I send data I get AGDM on the serial of the first card, then only A0 on the second card. Why is that ?
Here is both important codes (Slave first) :

char etat;
void loop()
{

  if(Serial.available())
  {
    etat = Serial.read();
    Serial.println(etat);
    //Serial.println(angle_rotation);
  }
  switch (etat) {
    case 'A':
      //VERIFICATION DE LA ROTATION
      if (angle_rotation != 0) {
        //SI PAS ENCORE AVANCE POUR QUITTER L'ANGLE
        if (AVANCER) {
          avance(1000, VMAX);
          AVANCER = false;
        }
        //TOURNE A DROITE
        if (angle_rotation < 0) {
          tourne_droite();
        }
        //TOURNE A GAUCHE
        if (angle_rotation > 0) {
          tourne_gauche();
        }
      }
      else {
        //avance(250, VMAX);
        AVANCER = true;
      }
    case 'G':
      //TOURNE A GAUCHE
      pause();
      tourne_gauche();
    case 'D':
      //TOURNE A DROITE
      pause();
      tourne_droite();
    case 'M':
      break;
  }

Master one :

void setup()
{
  Serial.begin(9600); // Starts the serial communication
  pinMode(ST,INPUT);
  pinMode(SC,INPUT);  
  pinMode(POWER,INPUT);
  //  pinMode(ENA, OUTPUT); // sets the pin as output
  //  pinMode(ENB, OUTPUT); // sets the pin as output
  //  pinMode(G1, OUTPUT); // sets the pin as output
}

void loop() {
  delay(50);                      
  distance_gauche = capteur_gauche.ping() / US_ROUNDTRIP_CM; 
  distance_droite = capteur_droite.ping() / US_ROUNDTRIP_CM; 
  distance_centre = capteur_centre.ping() / US_ROUNDTRIP_CM;
  
/*  Envoi en uart de données sur le second arduino: 
 *  G = Gauche, D = Droite, C = Centre (mur), A = Avance  */
  // DISTANCE GAUCHE ONLY
  if((distance_gauche > 0 && distance_gauche < DISTANCE_RIEN)&&(distance_droite == 0 || distance_droite > DISTANCE_RIEN)){
    Serial.write('G');
    delay (100);    
  }
  // DISTANCE DROITE ONLY
  if((distance_droite > 0 && distance_droite < DISTANCE_RIEN)&&(distance_gauche == 0 || distance_gauche > DISTANCE_RIEN)){
    Serial.write('D');
    delay (100); 
  }
  // DISTANCE MUR
  if((distance_droite > 0 && distance_droite <= DISTANCE_RIEN)&&(distance_gauche > 0 && distance_gauche <= DISTANCE_RIEN)){
    Serial.write('M');
    delay (100);
  }
  // DETECTE RIEN
  if((distance_droite == 0 || distance_droite > DISTANCE_RIEN)&&(distance_gauche == 0 || distance_gauche > DISTANCE_RIEN)){
    Serial.write('A');
    delay (100);  
  } 
}

There's the whole code if I've missed something.

Here's my code for the master :

#include <NewPing.h>

/* EC-X = Echo capteur X    TC-X = Trigger capteur X
 * G = gauche   C = centre    D = droite           */
#define ECG 2
#define ECC 3
#define ECD 4
#define TCG 6
#define TCC 7
#define TCD 8
#define DISTANCE_RIEN 25
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

#define ST 10 //Servo tourelle
#define SC 11 //Servo capteur

#define POWER 12  //Switch on/off du programme
#define G2 7 // commande transistor 2 sur broche 7

unsigned int distance_gauche, distance_droite, distance_centre;

NewPing capteur_gauche(TCG, ECG, 50);
NewPing capteur_droite(TCD, ECD, 50);
NewPing capteur_centre(TCC, ECC, 50);

void setup()
{
  Serial.begin(9600); // Starts the serial communication
  pinMode(ST,INPUT);
  pinMode(SC,INPUT);  
  pinMode(POWER,INPUT);
  //  pinMode(ENA, OUTPUT); // sets the pin as output
  //  pinMode(ENB, OUTPUT); // sets the pin as output
  //  pinMode(G1, OUTPUT); // sets the pin as output
}

void loop() {
  delay(50);                      
  distance_gauche = capteur_gauche.ping() / US_ROUNDTRIP_CM; 
  distance_droite = capteur_droite.ping() / US_ROUNDTRIP_CM; 
  distance_centre = capteur_centre.ping() / US_ROUNDTRIP_CM;
  
/*  Envoi en uart de données sur le second arduino: 
 *  G = Gauche, D = Droite, C = Centre (mur), A = Avance  */
  // DISTANCE GAUCHE ONLY
  if((distance_gauche > 0 && distance_gauche < DISTANCE_RIEN)&&(distance_droite == 0 || distance_droite > DISTANCE_RIEN)){
    Serial.write('G');
    delay (100);    
  }
  // DISTANCE DROITE ONLY
  if((distance_droite > 0 && distance_droite < DISTANCE_RIEN)&&(distance_gauche == 0 || distance_gauche > DISTANCE_RIEN)){
    Serial.write('D');
    delay (100); 
  }
  // DISTANCE MUR
  if((distance_droite > 0 && distance_droite <= DISTANCE_RIEN)&&(distance_gauche > 0 && distance_gauche <= DISTANCE_RIEN)){
    Serial.write('M');
    delay (100);
  }
  // DETECTE RIEN
  if((distance_droite == 0 || distance_droite > DISTANCE_RIEN)&&(distance_gauche == 0 || distance_gauche > DISTANCE_RIEN)){
    Serial.write('A');
    delay (100);  
  } 
}

and my code for the slave (I think it's the slave)


#define ENA 3 // validation pont A sur broche 3
#define ENB 5 // validation pont B sur broche 5

/*  Le moteur de droite est le A, gauche le B
    si (IN1,H / IN2,L) si (IN3,H / IN4,l) alors
    le robot va tout droit                    */
#define IN1 9 // commande demi-pont 1 (A) sur broche 9
#define IN2 10 // commande demi-pont 2 (A) sur broche 10
#define IN3 12 // commande demi-pont 3 (B) sur broche 12
#define IN4 13 // commande demi-pont 4 (B) sur broche 13
#define G1 6 // commande transistor 1 sur broche 6
#define G2 7 // commande transistor 2 sur broche 7

#define VMAX 240
#define V50 120
#define VMIN 60

bool AVANCER = true;
int angle_rotation;
char etat;

void setup()
{
  Serial.begin(9600); // Starts the serial communication
  pinMode(ENA, OUTPUT); // sets the pin as output
  pinMode(ENB, OUTPUT); // sets the pin as output
  pinMode(G1, OUTPUT); // sets the pin as output
  pinMode(G2, OUTPUT); // sets the pin as output
  pinMode(IN1, OUTPUT); // sets the pin as output
  pinMode(IN2, OUTPUT); // sets the pin as output
  pinMode(IN3, OUTPUT); // sets the pin as output
  pinMode(IN4, OUTPUT); // sets the pin as output
  digitalWrite(G2, LOW); // relais 2 OFF
  digitalWrite(G1, LOW); // relais 1 OFF
  analogWrite(ENA, 0); // arrĂȘt du moteur A
  analogWrite(ENB, 0); // arrĂȘt du moteur B
}
void loop()
{

  /* Lecture de l'état affilié à la course en fonction des capteurs
      A = avance tout droit (si pas de capteurs detectent)
      G = tourne Ă  gauche (seulement si capteur droite detecte)
      D = tourne Ă  droite (seulement si capteur gauche detecte)
      M = mur final (si les deux capteurs detectent)

  */
  if(Serial.available())
  {
    etat = Serial.read();
    Serial.println(etat);
    //Serial.println(angle_rotation);
  }


 /*
   if(etat == 'A'){
    Serial.println("Avancer");
  }
    if(etat == 'D'){
    Serial.println("Droite");
  }
    if(etat == 'G'){
    Serial.println("Gauche");
  }
    if(etat == 'M'){
    Serial.println("Milieu");
  }

 */

  switch (etat) {
    case 'A':
      //VERIFICATION DE LA ROTATION
      if (angle_rotation != 0) {
        //SI PAS ENCORE AVANCE POUR QUITTER L'ANGLE
        if (AVANCER) {
          avance(1000, VMAX);
          AVANCER = false;
        }
        //TOURNE A DROITE
        if (angle_rotation < 0) {
          tourne_droite();
        }
        //TOURNE A GAUCHE
        if (angle_rotation > 0) {
          tourne_gauche();
        }
      }
      else {
        //avance(250, VMAX);
        AVANCER = true;
      }
    case 'G':
      //TOURNE A GAUCHE
      pause();
      tourne_gauche();
    case 'D':
      //TOURNE A DROITE
      pause();
      tourne_droite();
    case 'M':
      break;
  }

}

int pause() {
  digitalWrite(IN1, LOW); // moteur A tourne dans sens -
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW); // moteur A tourne dans sens -
  digitalWrite(IN4, LOW);
  delay(300);
}

int tourne_gauche() {
  digitalWrite(IN1, HIGH); // moteur A tourne dans sens -
  digitalWrite(IN2, LOW);
  analogWrite(ENA, V50); // moteur A vitesse 1/2
  digitalWrite(IN3, HIGH); // moteur A tourne dans sens -
  digitalWrite(IN4, LOW);
  analogWrite(ENB, V50); // moteur A vitesse 1/2
  angle_rotation -= 1;
  delay(250);
}

int tourne_droite() {
  digitalWrite(IN1, LOW); // moteur A tourne dans sens -
  digitalWrite(IN2, HIGH);
  analogWrite(ENA, V50); // moteur A vitesse 1/2
  digitalWrite(IN3, LOW); // moteur A tourne dans sens -
  digitalWrite(IN4, HIGH);
  analogWrite(ENB, V50); // moteur A vitesse 1/2
  angle_rotation += 1;
  delay(250);
}

int avance(int delai, int vitesse) {
  digitalWrite(IN1, HIGH); // moteur A tourne dans sens -
  digitalWrite(IN2, LOW);
  analogWrite(ENA, vitesse); // moteur A vitesse 1/2
  digitalWrite(IN3, LOW); // moteur A tourne dans sens -
  digitalWrite(IN4, HIGH);
  analogWrite(ENB, vitesse); // moteur A vitesse 1/2
  delay(delai);
}

Use software serial for serial comms with a Uno. Pins 0 and 1 are used for programing and serial monitor.

1 Like

Since you don't seem to use any debug command it's OK to use Hardware Serial if you upload the code with the cables unplugged between the master and slave to ensure the upload works fine

I noticed that your switch() statement in the slave code is missing many break; and if you send 'A' you'll got to 'A' then 'G' then 'D' then 'M' where you have the break; ➜ is that what you call AGDM ?

try with

  switch (etat) {
    case 'A':
      //VERIFICATION DE LA ROTATION
      if (angle_rotation != 0) {
        //SI PAS ENCORE AVANCE POUR QUITTER L'ANGLE
        if (AVANCER) {
          avance(1000, VMAX);
          AVANCER = false;
        }

        //TOURNE A DROITE
        if (angle_rotation < 0) {
          tourne_droite();
        }
        //TOURNE A GAUCHE
        if (angle_rotation > 0) {
          tourne_gauche();
        }
      }
      else {
        //avance(250, VMAX);
        AVANCER = true;
      }
      break;   // <========= MISSING

    case 'G':
      //TOURNE A GAUCHE
      pause();
      tourne_gauche();
      break;   // <========= MISSING

    case 'D':
      //TOURNE A DROITE
      pause();
      tourne_droite();
      break;  // <========= MISSING

    case 'M':
      break;
  }

(I've not checked that what you do makes sense)

1 Like

you are totally right, it was indeed the problem. Thanks for your comment !

It's also wise to have a default case in every switch statement. If I can, I try to use the default case to do something to alert me to an unexpected result - could be flashing the onboard LED, could be a special print statement, depends on what I'm doing, but doing it has saved me lots of head scratching; for example Serial.println('WHY DID WE GET HERE!!!").

1 Like

good to hear. Have fun !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.