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);
}
}
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);
}
}
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.
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.
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.
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.
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.
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!
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).
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