Combien de détecteurs ultrason peut-on connecter sur une MEGA?

Bonsoir,

Combien de détecteurs ultrason peut-on connecter sur une MEGA?

J'ai branché 7 HC-SR04 sur une MEGA 2560 des Pin A0 à A13, dénommé ECHO_A0, TRIG_A1, et ainsi de suite.
Tout ces modules fonctionnent à merveille sauf un. toujours le même.

J'ai beau intervertir les pins, le connecteur sur pin 12 et 13 par exemple, tester d'autres capteurs, rien y fait
J'ai tester avec un autre programme ce détecteur fonctionne. (Ainsi que tout les autres un à un)
J'ai modifié le nom des constantes, parce que peut-être trop proche des uns des autres,
AVGB, AVDB, AVCGB, AVCDB, etc ...

Rien ...

Avez-vous une idée de ce qui ce passe ?

Merci

Le HC-SR04 se commande avec des signaux numériques.
Je ne connais pas la carte Mega, surtout son microcontrôleur, et je me pose la question suivante :

Est-ce que toutes les E/S de A0 à A13 sont également reliées à un port numérique ?

Si ce n'est pas le cas essaye d'utiliser des E/S numériques, sur la Mega ce n'est pas ce qu'il manque.

Les entrées A0 -A15 ont toutes la double fonction entrée analogique ou logique.
Si le capteur fonctionne avec un autre programme et si le câblage est bon, il y a fort à parier que le problème est plus dans le code que dans la carte Arduino.

Laissez vous suffisamment de temps entre deux pings consécutifs ? Il faut que les rebonds du précédent aient fini de se propager sinon ils peuvent perturber la lecture.

Utilisez vous la bibliothèque newPing ?

Postez le code.

[code]

#include <HCSR04.h>
#include <SoftwareSerial.h>

//DEFINITION CAPTEUR BLUETOOTH
SoftwareSerial hc06(0, 1);
unsigned char Bluetooth_val;        //définition de la valeur val

#define Gpwm_pin 16                 //Pin ajustement vitesse Gauche
#define Dpwm_pin 17                 //Pin ajustement vitesse Droit

//DEFINITION CONNEXION MOTEUR
int pinARG = 18;                       // définition de la broche 18 arrière gauche
int pinAVG = 19;                       // définition du broche 19 avant gauche
int pinARD = 20;                       // définition de la broche 20 arrière droite
int pinAVD = 21;                       // définition de la broche 21 avant droit

int dist_securite = 55;                // dist_securite Avant

int lgrobot = 30;                      // Largeur Robot Avant
int vdG = 0;                           // Delai des delay Gauche
int vdD = 0;                           // Delai des delay Droit
int dist_securiteDG = 18;              // dist_securite Gauche Droite

int distance_AVGH = 0;            // distance AVant Gauche Haut
int distance_AVCH = 0;            // distance AVant Centre Haut
int distance_AVCH_mem = 0;        // distance AVant Centre Haut memrosise
int distance_AVDH = 0;            // distance AVant Droit Haut

int distance_AVGB = 0;            // distance AVant Gauche Bas
int distance_AVCGB = 0;           // distance AVant Centre Gauche Bas
int distance_AVCDB = 0;           // distance AVant Centre Droit Bas
int distance_AVDB = 0;            // distance AVant Droit Bas

int mesureAVGH = 0;                 // mesure AVant Gauche Haut
int mesureAVCH = 0;                 // mesure AVant Centre Haut
int mesureAVDH = 0;                 // mesure AVant Droit Haut

int mesureAVGB = 0;                 // mesure AVant Gauche Bas
int mesureAVCDB = 0;                // mesure AVant Centre Droit Bas
int mesureAVCGB = 0;                // mesure AVant Centre Gauche Bas
int mesureAVDB = 0;                 // mesure AVant Droit Bas

int lgpassageH = 0;                     // largeur de passage disponible soit largeur du robot+distance dispo à gauche=distance dispo à droite Haut
int lgpassageB = 0;                     // largeur de passage disponible soit largeur du robot+distance dispo à gauche=distance dispo à droite Bas
int lgpassagetmpH = 0;   // largeur de passage tmp disponible soit largeur du robot+distance dispo à gauche=distance dispo à droite Haut
int lgpassagetmpB = 0;   // largeur de passage tmp disponible soit largeur du robot+distance dispo à gauche=distance dispo à droite Bas

int val;
int ledpin = 1;
String messageRecu = "";  // stockage du message venant du bluetooth
String messageRecu1 = ""; // stockage du message venant du bluetooth

// CAPTEUR ULTRASONIQUE HC-SR04
const byte ECHO_A0 = A0;    // Broche ECHO    Avant Centre Gauche BAS AVCGB
const byte TRIG_A1 = A1;    // Broche TRIGGER Avant Centre Gauche BAS

const byte ECHO_A2 = A2;    // Broche ECHO    AVant Gauche BAS AVGB
const byte TRIG_A3 = A3;    // Broche TRIGGER AVant Gauche BAS

const byte ECHO_A4 = A4;    // Broche ECHO    Avant Centre Droit BAS AVCDB
const byte TRIG_A5 = A5;    // Broche TRIGGER Avant Centre Droit BAS

const byte ECHO_A6 = A6;    // Broche ECHO    Avant Droit Bas AVDB
const byte TRIG_A7 = A7;    // Broche TRIGGER Avant Droit Bas

const byte ECHO_A8 = A8;    // Broche ECHO    AVant Centre Haut AVCH
const byte TRIG_A9 = A9;    // Broche TRIGGER AVant Centre Haut

const byte ECHO_A10 = A10;  // Broche ECHO    Avant Gauche Haut AVGH
const byte TRIG_A11 = A11;  // Broche TRIGGER Avant Gauche Haut

const byte ECHO_A12 = A12;    // Broche ECHO    Avant Droit Haut AVDH
const byte TRIG_A13 = A13;    // Broche TRIGGER Avant Droit Haut
// Constantes pour le timeout //
const unsigned MESURE_TIMEOUT = 25000UL; // 25ms = ~8m à 340m/s

// Vitesse du son dans l'air en mm/us //
const float VIT_SON = 340.0 / 1000;


}
void mesure_distance_obstacle()          // Mesure des Distances
{
  // Mesure de distance par impulsion sur detecteur Avant Centre Gauche BAS - A0 A1 AVCGB
  digitalWrite(TRIG_A1, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_A1, HIGH);
  delayMicroseconds(4);
  digitalWrite(TRIG_A1, LOW);
  // Mesurer le temps entre l'envoi de l'impulsion ultrasonique et son écho
  mesureAVCGB = pulseIn(ECHO_A0, HIGH, MESURE_TIMEOUT);
  // Calculer la distance à partir du temps mesuré //
  distance_AVCGB = mesureAVCGB * 0.034 / 2;

  // Mesure de distance par impulsion sur detecteur AVant Gauche BAS - A2 A3 AVGB
  digitalWrite(TRIG_A3, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_A3, HIGH);
  delayMicroseconds(4);
  digitalWrite(TRIG_A3, LOW);
  mesureAVGB = pulseIn(ECHO_A2, HIGH, MESURE_TIMEOUT);
  // Calculer la distance à partir du temps mesuré //
  distance_AVGB = mesureAVGB * 0.034 / 2;
  vdG = distance_AVGB - dist_securiteDG;

  // Mesure de distance par impulsion sur detecteur AVant Centre Droit Bas - A4 A5
  digitalWrite(TRIG_A5, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_A5, HIGH);
  delayMicroseconds(4);
  digitalWrite(TRIG_A5, LOW);
  // Mesurer le temps entre l'envoi de l'impulsion ultrasonique et son écho
  mesureAVCDB = pulseIn(ECHO_A4, HIGH, MESURE_TIMEOUT);
  // Calculer la distance à partir du temps mesuré //
  distance_AVCDB = mesureAVCDB * 0.034 / 2;

  // Mesure de distance par impulsion sur detecteur AVant Droit Bas AVDB - A6 A7
  delayMicroseconds(2);
  digitalWrite(TRIG_A7, HIGH);
  delayMicroseconds(4);
  digitalWrite(TRIG_A7, LOW);
  // Mesurer le temps entre l'envoi de l'impulsion ultrasonique et son écho
  mesureAVDB = pulseIn(ECHO_A6, HIGH, MESURE_TIMEOUT);
  // Calculer la distance à partir du temps mesuré //
  distance_AVDB = mesureAVDB  * 0.034 / 2;
  vdD = distance_AVDB - dist_securiteDG;

  // Mesure de distance par impulsion sur detecteur AVant Centre Haut AVCH - A8 A9
  digitalWrite(TRIG_A9, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_A9, HIGH);
  delayMicroseconds(4);
  digitalWrite(TRIG_A9, LOW);
  // Mesurer le temps entre l'envoi de l'impulsion ultrasonique et son écho
  mesureAVCH = pulseIn(ECHO_A8, HIGH, MESURE_TIMEOUT);
  // Calculer la distance à partir du temps mesuré //
  distance_AVCH = mesureAVCH * 0.034 / 2;

  // Mesure de distance par impulsion sur detecteur Avant Gauche Haut AVGH - A10 A11
  digitalWrite(TRIG_A11, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_A11, HIGH);
  delayMicroseconds(4);
  digitalWrite(TRIG_A11, LOW);
  // Mesurer le temps entre l'envoi de l'impulsion ultrasonique et son écho
  mesureAVGH = pulseIn(ECHO_A10, HIGH, MESURE_TIMEOUT);
  // Calculer la distance à partir du temps mesuré //
  distance_AVGH = mesureAVGH * 0.034 / 2;

  // Mesure de distance par impulsion sur detecteur  Avant Droit Haut AVDH - 12 13
  digitalWrite(TRIG_A13, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_A13, HIGH);
  delayMicroseconds(4);
  digitalWrite(TRIG_A13, LOW);
  // Mesurer le temps entre l'envoi de l'impulsion ultrasonique et son écho
  mesureAVDH = pulseIn(ECHO_A12, HIGH, MESURE_TIMEOUT);
  // Calculer la distance à partir du temps mesuré //
  distance_AVDH = mesureAVDH * 0.034 / 2;


  lgpassagetmpH = (pow(distance_AVGH + lgrobot, 2) + pow(distance_AVDH + lgrobot, 2));
  lgpassageH = sqrt(lgpassagetmpH) / 2;


  lgpassagetmpB = (pow(distance_AVGB + lgrobot, 2) + pow(distance_AVDB + lgrobot, 2));
  lgpassageB = sqrt(lgpassagetmpB) / 2;
  /*
    Serial.print("lgpassageB : "); Serial.print(lgpassageB); Serial.print(" ----- distance_AVGB : "); Serial.print(distance_AVGB); Serial.print(" ---- distance_AVDB : "); Serial.println(distance_AVDB);
  */
  Serial.print(" distance_AVGB : "); Serial.print(distance_AVGB);
  Serial.print(" distance_AVCGB : "); Serial.print(distance_AVCGB);
  Serial.print(" distance_AVDB : "); Serial.print(distance_AVDB);
  Serial.print(" distance_AVCDB : "); Serial.println(distance_AVCDB);
  Serial.print(" distance_AVGH : ");  Serial.println(distance_AVGH);
  Serial.print(" distance_AVCH : "); Serial.println(distance_AVCH);
  Serial.print(" distance_AVDH : "); Serial.println(distance_AVDH);
  Serial.print(" distance de securite : "); Serial.println(dist_securite);
  delay(1000);
}


  }
}

[/code]

Ci-dessus le code que j’utilise. Pour des raisons évidentes de place, plus de 9000 caractères, j’ai supprimé les lignes pas en rapport. J’ai toujours un petit soucis coté droit qui je suppose est dû à la non lecture de AVCDB ( Avant Centre Droit Bas)

Merci de vos réponses, cordialement.

Sans le code complet difficile d'être précis mais je vois déjà deux soucis:

1/ pulseIn() retourne un entier de type unsigned long. Avec des int vous allez sans doute avoir des déconvenues.

2/ il y a une recommendation d'attente de 60ms entre deux pings consécutifs pour éviter les rebonds du ping précédent. là vous les enchaînez sans précaution

sinon je vous recommande de prendre la bibliothèque newPing et définir une distance max compatible avec ce que vous voulez faire.

La connexion de plusieurs HC-SR04 sur un seul Arduino est récurrente, on trouve plein d’exemples sur Internet.
Voici un lien vers un exemple qui en utilise 5 avec des interruptions. Sinon, Google avec “arduino multiple ultrasonic sensors” renvoie de nombreux liens. Ici une vidéo avec 5 capteurs aussi

OK, merci à tous pour vos réponses. Je vais tenter avec la bibliothèque newping. je vous recontacterais pour confirmer.

Bonjour,
J'ai donc essayé la bibliothèque NewPing. Dans un premier temps pas de progrès notoire. Le détecteur incriminé ne fonctionnait toujours pas, incompréhensible...
J'ai retesté toutes mes connections et retesté avec un autre programme tout les détecteurs fonctionnaient parfaitement bien.
Il n'y avait donc que la procédure qui pouvait être incriminé. J'ai lu et relu cette procédure, pas de problème. J'ai supprimé dans la procédure tout ce qui concernait ce détecteur et j'ai refait un copié collé à partir d'un autre détecteur en modifiant les paramètres. MIRACLE... Ca marche.

Caractère à la con et invisible qui trainait dans le code.

Surprenant... postez le code final, ça pourra servir à quelqu’un

Poster le code ?

683 lignes, plus de 9000 caractères avec les commentaires. Ca fait pas un peu beaucoup ?

en Pièce Jointe ça passe - mais c’est comme vous voulez

Même avec l'IDE Arduino il est possible de travailler en fichiers séparés (les règles du C s'appliquent).
Il me semble que c'est plus aisé que de gérer un fichier de plus de 600 lignes.

Ok pour le code.

Je l'ai fait d'après mes connaissance en Arduino. C'est pas la perfection mais le robot évite pas mal d'obstacles. Il aime pas les rideaux. Il est pilotable à la voix et au joystick ave logiciel Remote Controller MyValley dans playstore.

Toutes aides pour l'améliorer sera le bienvenue.

Cordialement

Controle_vocale_bluetooth_Fonctionnel_BOB.ino (22.5 KB)

Salut à tous,

Petit robot à bien grandi.

J'aimerais lui adjoindre une tête.
Je me suis procuré deux servos MG996R,( un pour OUI et un pour NON) les SG90 n'étant pas assez costaux pour soutenir le casque de réalité virtuel que j'avais en stock.

Seulement voilà, les servos MG996R ont une facheuse tendance à tourner en rond lors des tests.
J'ai beau essayer de les calibrer, ca fonctionne un certain temps puis ca part en sucette.
J'ai chercher sur le forum mais sans succès, de plus c'est en anglais.

Pouvez vous me donner un petit coup de main.

Cordialement

Seulement voilà, les servos MG996R ont une facheuse tendance à tourner en rond lors des tests.
J'ai beau essayer de les calibrer, ca fonctionne un certain temps puis ca part en sucette.
J'ai chercher sur le forum mais sans succès, de plus c'est en anglais.

avec quel code , quelle alimentation etc ?

Pour l’instant j’ai uniquement testé avec un code TEST connecté sur pin 7 PWM. J’ai essayé d’autre pin, ca fait pareil. Sur AT MEGA 2560. Alimentation 2 batteries IMR 18650 3.7V 2500mAh. J’ai modifié l’incrémentation et les delay, ca change pas grand chose.

[code]
/* 
 Programme de test pour servomoteur de positionnement angulaire 
 Traduction en français, ajout de variables
 Code original de BARRAGAN <http://barraganstudio.com>
 et Scott Fitzgerald http://www.arduino.cc/en/Tutorial/Sweep
 
 www.projetsdiy.fr - 19/02/2016
 public domain
*/
#include <Servo.h>

Servo myservo;  // création de l'objet myservo 

int pin_servo = 7;       // Pin 7 sur lequel est branché le servo sur l'Arduino si vous utilisez un ESP32 remplacez le 6 par 4 et si vous utilisez un ESP8266 remplacez le 6 par 2

int pos = 0;             // variable permettant de conserver la position du servo
int angle_initial = 20;   //angle initial
int angle_final = 160;   //angle final
int increment = 2;       //incrément entre chaque position
bool angle_actuel = false;//Envoi sur le port série la position courante du servomoteur

void setup() {
  Serial.begin(9600);                       
  while(!Serial){;} 
  myservo.attach(pin_servo);  // attache le servo au pin spécifié sur l'objet myservo
  
}

void loop() {
  for (pos = angle_initial; pos <= angle_final; pos += increment) { // Déplace le servo de 0 à 180 degréespar pas de 1 degrée 
    myservo.write(pos);              // Demande au servo de se déplacer à cette position angulaire
    delay(20);                       // Attend 30ms entre chaque changement de position
    if (angle_actuel) {
        Serial.println(myservo.read());
    }
  }
  for (pos = angle_final; pos >= angle_initial; pos -= increment) { // Fait le chemin inverse
    myservo.write(pos);              
    delay(20);   
    if (angle_actuel) {
        Serial.println(myservo.read());
    }
  }
}

[/code]

que voulez vous dire par “tourner en rond” ?

essayez ce code (la saisie de l’angle n’est pas un modèle du genre mais pour un test ça fait l’affaire). j’ai tapé ça ici, donc il se peut qu’il y ait un bug, je vous laisse compiler

#include <Servo.h>

Servo servoMoteur;  // création de l'objet servoMoteur
const byte pin_servo = 7;

void setup() {
  Serial.begin(115200);
  servoMoteur.attach(pin_servo);  // attache le servo au pin spécifié sur l'objet servoMoteur
  servoMoteur.write(20); // 20°
  Serial.println(F("\n----- SERVO TEST -----"));
}

void loop() {
  Serial.print(F("Entrez l'angle (entre 20° et 170°) : "));
  while (!Serial.available());
  int angle = Serial.parseInt();
  if (angle >= 20 && angle <= 170) {
    Serial.println(angle);
    servoMoteur.write(angle);
  } else Serial.println(F("invalide"));
  while (Serial.available()) Serial.read(); // vide le buffer
}

ouvrez la consoles série à 115200 bauds avec comme validation NL (new Line) ou les 2 (CRL/F)
au lancement le servo doit aller à l’angle 20°
vous tapez et validez un angle entre 20° et 170° et le servo devrait y aller

(les petits servo pas chers ne vont pas forcément de 0° à 180°)

==> est-ce que ça fonctionne ?

PS/ on est bien d’accord que vous ne passez pas au travers de l’Arduino pour alimenter les moteurs? (et que les GNDs sont connectés)

PS/ on est bien d’accord que vous ne passez pas au travers de l’Arduino pour alimenter les moteurs? (et que les GNDs sont connectés)

Justement si. C’est peut-être de là que vient le problème alors ? . Si je comprends bien ce n’est que le PWM (orange) qui doit être connecté sur l’arduino. Et le + et - sur une autre alimentation de 7V.