[RESOLU] anti-collision débutant

Bonjour,

débutant sur arduino, je me permets de mettre ici un petit programme permettant de mettre en route un petit robot éviteur d'obstacle composé d'une UNO R3, d'un contrôle moteur à 2 x L293D, d'un capteur à ultrason HC-SR04 et d'un chassis à 4 moteurs couplés par paires.

La UNO est alimentée par une pile batterie de 9V et les moteurs par un coupleur 6x LR06 via le shield.

//inclure bibliotheques moteurs
#include <AFMotor.h>
#include <Servo.h>

//inclure bibliotheque ultrasons
#include <NewPing.h>

//definition des connections module ultrasons
#define  TRIGGER_PIN  13 
#define  ECHO_PIN     9

// definition de la distance de detection maximum
//400 cm limite le risque d'avoir un retour zéro
#define MAX_DISTANCE 400 

//declaration des moteurs
AF_DCMotor moteur1(1); // create motor #1
AF_DCMotor moteur2(2); // create motor #2

//declaration du sonar
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

//declaration de la variable de distance
int Distance;

///*******************************************************///
void setup() {

  //Serial.begin(9600);
  //Serial.println("mesure de distances:");
  //vitesse maxi = 255 / mini = 0
  moteur1.setSpeed(255);     
  moteur2.setSpeed(255);
}
///*******************************************************///

void loop()
{
  //delai de 125ms entre 2 pings soit 8 pings par seconde
  delay(125);
  //mesure de la distance en centimetres
  Distance = sonar.ping_cm();

  //Serial.println("Ping: ");
  //Serial.print(Distance);
  //Serial.println(" cm");

  //marche avant s'il n'y a pas d'obstacle a moins de 30 cm
  if (Distance > 30) {
    moteur1.run(FORWARD);
    moteur2.run(FORWARD);
  }  

  //tourne a droite pendant 1/2 seconde quand un obstacle se situe entre 25 et 30 cm
  //moteur1 en avant et moteur2 en arriere pour tourner plus court
  if (Distance <= 30 && Distance >= 25) {
    moteur1.run(FORWARD);  
    moteur2.run(BACKWARD);
    delay(500);
  }

  //tourne a gauche pendant 1/2 seconde quand un obstacle se situe entre 19 et 24 cm
  //moteur1 en arriere et moteur2 en avant
  if (Distance <= 24 && Distance >= 19) {
    moteur1.run(BACKWARD);  
    moteur2.run(FORWARD);
    delay(500);
  }

  //marche arriere pendant une seconde si un obstacle est à moins de 19 cm
  if (Distance < 19 && Distance > 0) {
    moteur1.run(BACKWARD);     
    moteur2.run(BACKWARD);
    delay(1000);
  }
} //fin de la fonction loop

Le code, inspiré de ce que j'ai trouvé dans différents tutos, est très commenté.

Maintenant, même si ça fonctionne parfaitement, quelqu'un serait-il en mesure de me guider pour améliorer, alléger... ce programme qui sera la brique de base d'un robot plus perfectionné doté d'une MEGA 2560 R3 ?

bonjour,
sympa pour un premier projet
pour l'alléger, tu pourrais utilise un switch case avec une seule fonction

vite fait comme ca, mais pas testé mais l'idée est là

void loop() {
int distance = analogRead(A0);
switch (distance){
  
  case 30 :
  actionmoteur(forward,forward);
  break;
  
  case 25 :
  actionmoteur(forward,backward);
  break;
}
}

void actionmoteur(string moteur1, string moteur2)
{
  moteur1.run(moteur1);
  moteur2.run(moteur2);
}

j'avais vu l'instruction switch mais je ne savais pas trop comment l'utiliser.

Cà me plait bien :slight_smile:

merci

Par contre, les timer, je les place à quel endroit ? Ils servent à garantir que le robot (le mobile plus exactement pour l'instant) recule suffisamment, par rapport à sa longueur et à sa vitesse de déplacement, pour se décoincer.

attention au switch : si la distance passe de 26 à 24, le 25 ne sera pas vu, donc pas terrible. if / else if c'est mieux.

void loop() {
int distance = analogRead(A0);
if (distance > 30){
  actionmoteur(forward,forward);
} else if (distance < 25){
  actionmoteur(forward,backward);
}
}

void actionmoteur(string moteur1, string moteur2)
{
  moteur1.run(moteur1);
  moteur2.run(moteur2);
}

Super_Cinci:
attention au switch : si la distance passe de 26 à 24, le 25 ne sera pas vu, donc pas terrible. if / else if c'est mieux.

c'était une idée pour éclaircir un peu le code :wink:
tu peux aussi mélanger les 2, ca permet de rajouter d'autres conditions

void loop() {
int distance = analogRead(A0);
int voix = analogRead(A1);//[b]micro electret branché pas regardé son fonctionnement[/b]
if (distance>30) distance1=1;
if (distance <= 30 && distance >= 25) distance1=2;
if (distance<25) distance1=3;
if (voix==1 && distance<25) distance1=25;

switch (distance1){
  
  case 1 :
  actionmoteur(forward,forward);
  break;
  
  case 2 :
  actionmoteur(forward,backward);
  break;

  case 3 :
  actionmoteur(backward,backward);
  break;

 case 25:
  actionPOUET(1,0);
  break;
}
}

void actionmoteur(string moteur1, string moteur2)
{
  moteur1.run(moteur1);
  moteur2.run(moteur2);
}

void actionPOUET(byte ton, byte ton1)
{
digitalWrite(led,ton);
digitalWrite(led1,ton1);
}

J'ai effectivement constaté les "trous" avec l'instruction "switch / case".

Le mélange de swicht / case et de if / then est assez séduisant et me permet de reprendre les conditions de distance très simplement sans avoir à tout retaper.

En plus, la fonction "actionPOUET" m'a donné une idée pour faire bouger mes chats qui ont tendance à venir jouer avec minibot ^^

merci