digitalWrite en 0 ou LOW ne répond pas

Bonjour à tous, je contrôle 2 moteurs cc via un arduino, j'utilise le code ci-dessous(trouvé sur internet et modifié pour mon besoin) :

lorsque je lance la commande "avancerdrone" le drone avance normalement, lorsque je lance la commande "reculerdrone", le drone recule correctement et cela même si il était en trin d'avancer. Je peux faire vis versa, je le fais reculer puis avancer ca fonctionne.

Le soucis intervient dans le "stoperdrone", il ne coupe pas les moteurs et repart systématiquement en marche avant, lorsqu'il est à l'arret je peux spamer la commande "stoperdrone" rien ne se passe comme prévue, c'est uniquement lorsqu'il est en marche avant ou arrière, lors de la reception de la commande "stoperdrone" il part en marche avant :o

Auriez-vous une idée de mon erreur ?

const int A1A = 10;//define pin 2 for A1A
const int A1B = 11;//define pin 3 for A1B

const int B1A = 8;//define pin 8 for B1A
const int B1B = 9;//define pin 9 for B1B
String readString;

void setup(){
  Serial.begin(9600);
  pinMode(B1A,OUTPUT);// define pin as output
  pinMode(B1B,OUTPUT);
  
  pinMode(A1A,OUTPUT);
  pinMode(A1B,OUTPUT);
}
void loop(){
  while (Serial.available()) {
    delay(3);  
    char c = Serial.read();
    readString += c; 
  }
  readString.trim();
    if (readString.length() >0) {
		if (readString == "avancerdrone"){
				AvancerDrone();
		}
		 if (readString == "reculerdrone"){
				ReculerDrone();
		}
		if (readString == "stoperdrone"){
				StoperDrone();
		}
	}
}

void AvancerDrone(){
   Serial.println("Avancer");
   motorA('R');// Turn motor A to RIGHT
   motorB('R'); // Turn motor A to RIGHT 
}
void ReculerDrone(){
   Serial.println("Reculer");
   motorA('L');// Turn motor A to RIGHT
   motorB('L'); // Turn motor A to RIGHT 
}
void StoperDrone(){
   Serial.println("Stoper");
    motorA('0');// Turn motor A OFF
    motorB('0');// Turn motor B OFF
}

void motorA(char d){
  if(d =='R'){
    digitalWrite(A1A,0);
    digitalWrite(A1B,127); 
  }else if (d =='L'){
    digitalWrite(A1A,127);
    digitalWrite(A1B,0);    
  }else{
    //Robojax.com L9110 Motor Tutorial
    // Turn motor OFF
    digitalWrite(A1A,0);
    digitalWrite(A1B,0);    
  }
}

void motorB(char d){

    if(d =='R'){
      digitalWrite(B1A,0);
      digitalWrite(B1B,127); 
    }else if(d =='L'){
      digitalWrite(B1A,127);
      digitalWrite(B1B,0);    
    }else{
    //Robojax.com L9110 Motor Tutorial
    // Turn motor OFF      
      digitalWrite(B1A,0);
      digitalWrite(B1B,0);     
    }

}

Essaye if... else if... else if

    readString += c;

Ou t'as initialisé readString?

Tes foncions doivent être à l’extérieur du loop. Ce code ne peux pas fonctionner.

Bonjour ArduinoTesteur09,

Votre code n'est pas compilable.

Voir : readString += c;

Cordialement,
bidouilleelec

J'avais oublié la déclaration en début de code dans mon copier/coller et mal replacé ma parenthèse, c'est modifié

cdlt

ArduinoTesteur09:
J'avais oublié la déclaration en début de code dans mon copier/coller c'est modifié

cdlt

Le code n'est pas compilable : vérifiez les {et} .

Qu'est censé faire : readString += c;

Je viens de faire le test, ca compile et ca dessend sur mon arduino

ArduinoTesteur09:
Je viens de faire le test, ca compile et ca dessend sur mon arduino

Ach! Vous avez traîtreusement modifié le code du post original

oui tout à fait, je viens de faire la modification avec des else if même réaction, ca repart en marche avant à chaque fois, pourtant rien dans le moniteur serie n'indique une demande de marche avant

j'avais oublié de réinitialiser "readstring" en fin de boucle, cependant le problème persiste

code mise a jour :

const int A1A = 10;//define pin 2 for A1A
const int A1B = 11;//define pin 3 for A1B

const int B1A = 8;//define pin 8 for B1A
const int B1B = 9;//define pin 9 for B1B
String readString;

void setup(){
 Serial.begin(9600);
 pinMode(B1A,OUTPUT);// define pin as output
 pinMode(B1B,OUTPUT);
 
 pinMode(A1A,OUTPUT);
 pinMode(A1B,OUTPUT);
}
void loop(){
 while (Serial.available()) {
   delay(3);  
   char c = Serial.read();
   readString += c; 
 }
 readString.trim();
   if (readString.length() >0) {
   if (readString == "avancerdrone"){
       AvancerDrone();
   }
    if (readString == "reculerdrone"){
       ReculerDrone();
   }
   if (readString == "stoperdrone"){
       StoperDrone();
   }
 }
 readString = "";
}

void AvancerDrone(){
  Serial.println("Avancer");
  motorA('R');// Turn motor A to RIGHT
  motorB('R'); // Turn motor A to RIGHT 
}
void ReculerDrone(){
  Serial.println("Reculer");
  motorA('L');// Turn motor A to RIGHT
  motorB('L'); // Turn motor A to RIGHT 
}
void StoperDrone(){
  Serial.println("Stoper");
   motorA('0');// Turn motor A OFF
   motorB('0');// Turn motor B OFF
}

void motorA(char d){
 if(d =='R'){
   digitalWrite(A1A,0);
   digitalWrite(A1B,127); 
 }else if (d =='L'){
   digitalWrite(A1A,127);
   digitalWrite(A1B,0);    
 }else{
   //Robojax.com L9110 Motor Tutorial
   // Turn motor OFF
   digitalWrite(A1A,0);
   digitalWrite(A1B,0);    
 }
}

void motorB(char d){

   if(d =='R'){
     digitalWrite(B1A,0);
     digitalWrite(B1B,127); 
   }else if(d =='L'){
     digitalWrite(B1A,127);
     digitalWrite(B1B,0);    
   }else{
   //Robojax.com L9110 Motor Tutorial
   // Turn motor OFF      
     digitalWrite(B1A,0);
     digitalWrite(B1B,0);     
   }

}

Comme un parfait newbin moi je ferais ça:

void loop() {
  while (Serial.available()) {
    delay(3);
    char c = Serial.read();
    readString += c;
  }
  readString.trim();
  if (readString.length() > 0) {
    if (readString == "avancerdrone") {
      AvancerDrone();
    }
    if (readString == "reculerdrone") {
      ReculerDrone();
    }
    if (readString == "stoperdrone") {
      StoperDrone();
    }
  }
  Serial.println(readString);
  readString = "";
}

J'ai un doute sur string += char;
Je l'ai utilisé une fois mais j'avais l'impression qui ne faisait pas ce que je voulais;
J’étais passé par le classique string = string + char
C'est vrais que je n'avais pas cherché plus loin.

Bonjour,

L'instruction digitalWrite prend plutôt les valeurs 'LOW' ou 'HIGH'.
Pour une utilisation en mode analogique (PWM), il faudra utiliser analogWrite.
Voir les broches compatibles en fonction de votre carte.

D'accord avec Zlika. Pour les else je pensais aux if de la loop

Le dernier code ne fonctionnera pas je pense.

readString = "";

sera exécuté à chaque fois que le buffer de réception sera vide.
Ce sera sûrement la cas si on compare la vitesse de réception des données et la vitesse d'exécution de la boucle.
Peu de chance que la chaine de commande soit complètement reçu en une seule loop.

Il faudrait la placer après chaques commandes validées.

sera exécuté à chaque fois que le buffer de réception sera vide.

C'est peut être pour ça qu'il a mit un delay(3).

L’histoire de LOW à la place de 0 m'avait échappée.
Par contre dans le titre il dit que avec un 0 ou un LOW ça ne marche pas.

Pour Arduino, les définitions LOW et HIGH sont respectivement à 0 et 1.

On ne peut donc pas prévoir le comportement d'un programme pour toutes autres valeurs.

Si, dans une fonction, la comparaison se limite à 0 et not(0), pas de problèmes car on englobe toutes les valeurs possibles.

Par contre, dans le cas d'une comparaison avec la constante HIGH qui vaut 1, une valeur autre que 1 et 0 ne donnera pas forcément une égalité à HIGH. Même si on sait qu'elle n'est pas égale à 0 donc logiquement !LOW soit HIGH.

Il est donc expressément recommandé d'utiliser LOW et HIGH pour garantir le bon fonctionnement d'un programme. De plus, toute évolution de leurs valeurs réelles n'aura aucune influence sur le programme.

Bonjour Zlika,

Zlika:
........Si, dans une fonction, la comparaison se limite à 0 et not(0), pas de problèmes car on englobe toutes les valeurs possibles..................

Il se trouve que c'est exactement le test effectué par digitalWrite() pour l'Arduino.
Mais je suis tout à fait en accord avec l'ensemble de votre post.

Cordialement,
bidouilleelec

Bonjour Zlika

Zlika:
Le dernier code ne fonctionnera pas je pense.

readString = "";

sera exécuté à chaque fois que le buffer de réception sera vide.
Ce sera sûrement la cas si on compare la vitesse de réception des données et la vitesse d'exécution de la boucle.
Peu de chance que la chaine de commande soit complètement reçu en une seule loop.
Il faudrait la placer après chaques commandes validées.

Toute la chaine de caractères est reçue dans le

while (Serial.available()) {

delay(3) n'est pas utile.

readString = "";

"Il faudrait la placer après chaques commandes validées." :
C'est plus joli mais pas nécessaire et ça n'use pas beaucoup plus l'Arduino.
Au moins on est certain que la String (horreur!) est réinitialisée!

Cordialement,
bidouilleelec

savoriano:
Comme un parfait newbin moi je ferais ça:

void loop() {

while (Serial.available()) {
    delay(3);
    char c = Serial.read();
    readString += c;
  }
....
}

Ne jamais se croire plus intelligent qu’un protocole asynchrone et faire un delay() pour attendre que les caractères arrivent... si available dit qu’il y a quelque chose, alors il faut le lire et attendre le prochain en regardant si available est non nul (ou si read ne retourne pas -1).

dans le cas d'une comparaison avec la constante HIGH qui vaut 1, une valeur autre que 1 et 0 ne donnera pas forcément une égalité à HIGH.

C'est dans les posts comme celui-ici qu'on apprends le plus.

et faire un delay() pour attendre que les caractères arrivent

J'avais juste ajouté au code un serial.println(readString) pour voir justement si la transmission était juste.

String (horreur!)

Ça, ça mérite un post! je vais chercher d’abord s'il n'y eu un dans le passé.

Si vous voulez comprendre comment bien écouter le port série (ou gérer un flux asynchrone genre keypad) vous pouvez jeter un oeil à mon petit tuto sur le sujet