Pensez-vous que mon programme va marcher?

Bonjour,j'ai vraiment besoin de votre aide!J'ai un projet à faire pour l'école et si je ne le réussi pas,je n'aurai pas mon diplome...

Donc mon projet est de faire une voiture qui peut suivre un autre véhicule et qui s'arrete quand il le détecte à mon de 30 cm.Si le véhicule tourne, ma voiture aussi.

En ce moment,la voiture est prete. Tle moteur a été testé avec Arduino,lethe servomoteur et les capteurs aussi. Il reste juste le code. Cependant, on est Jeudi et je ne pourrai pas tester mon voiture avant Lundi... Et il ne me reste pas beaucoup de temps!

alors,pouvez-vous regarder mon code et voir s'il va faire ce qu'il doit faire?

J'ai utilisé 2 capteurs,Ping et Maxsonar ez2 et un servomoteur.

Voici mon code. Arduino n'a pas trouvé d'erreur.

Merci!

const int pingPin = 7;
int moteur= 3;
#include <Servo.h> 
int rouge = 6;
int vert = 5;
int bleu= 4;
Servo myservo;
int pos = 0;
const int maxsonar = 1; 
long anVolt, inches, cm2;
int sum=0;
int avgrange=60;
long duration,cm;




void setup() {
  

pinMode(moteur, OUTPUT);
pinMode(rouge, OUTPUT);
pinMode(vert,OUTPUT);
pinMode(bleu,OUTPUT);
myservo.attach(9);
pinMode(maxsonar,INPUT);

}




void loop()
{
  
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

 

  cm = microsecondsToCentimeters(duration);
  


  
  delay(100);
}

long microsecondsToInches(long microseconds)
{
  
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;



  for(int i = 0; i < avgrange ; i++)
  {

    anVolt = analogRead(maxsonar)/2;
    sum += anVolt;
    delay(10);

  }  

  inches = sum/avgrange;
  cm2 = inches * 2.54;


  sum = 0;

  delay(500);
if (cm2>30 and cm>30 ) 
{
digitalWrite(rouge,HIGH);
delay(500);
digitalWrite(rouge,LOW);
delay(500);  
digitalWrite(vert,HIGH);
delay(500);
digitalWrite(vert,LOW);
delay(500); 
digitalWrite(bleu,HIGH);
delay(500);
digitalWrite(bleu,LOW);
delay(500);
  
analogWrite(moteur,170);
delay(500);


}

if (cm < 30 and cm2 <30 )
{
    analogWrite(moteur,0);
  delay(500);
  digitalWrite(rouge,HIGH);
  delay(500); 
 }
   
  if(cm2>30 and cm<30)
  
    { 
     analogWrite(moteur, 90);
  delay(500);
  
        for(pos = 0; pos < 180; pos += 1)  
  {                                   
    myservo.write(pos);            

    
   } 
 digitalWrite(vert,HIGH);
 delay(500);
 digitalWrite(vert,LOW);
delay(500); }
  
  if(cm2<30 and cm>30)
{  
  analogWrite(moteur, 90);
  delay(500);
  
   for(pos = 180; pos>=1; pos-=1)      
  {                                
   myservo.write(pos);               
                      
  } 
  digitalWrite(bleu,HIGH);
  delay(500);
  digitalWrite(bleu,LOW);
  delay(500); 
   } 

}

Là tu mélanges float et long. Autant dire que les chiffres après la virgule ne sont pas pris en compte

  cm2 = inches * 2.54;

Tous le code après le return ne sera pas exécuté

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;

  for(int i = 0; i < avgrange ; i++)
  {

    anVolt = analogRead(maxsonar)/2;
    sum += anVolt;
    delay(10);

  }  
  ......

Après pour le reste le code est tellement bien commenté qu'on ne sait pas trop ou tu veux en venir.
il y a quand même un truc bizarre avec cm et cm2.
Pas trop compris le logique de la fonction microsecondsToCentimeters qui en fait plus que ce que son nom indique.

cm et cm2... Bah j'ai besoin des valeurs de centimètre des deux capteurs et si je laissais cm2 avec le nom cm, bah ca ferait deux variables avec le même nom.

Et si tu ne comprend pas,bah je me suis beaucoup inspiré de l'exemple dans Sensors--Ping :

 /* Ping))) Sensor
  
   This sketch reads a PING))) ultrasonic rangefinder and returns the
   distance to the closest object in range. To do this, it sends a pulse
   to the sensor to initiate a reading, then listens for a pulse 
   to return.  The length of the returning pulse is proportional to 
   the distance of the object from the sensor.
     
   The circuit:
	* +V connection of the PING))) attached to +5V
	* GND connection of the PING))) attached to ground
	* SIG connection of the PING))) attached to digital pin 7

   http://www.arduino.cc/en/Tutorial/Ping
   
   created 3 Nov 2008
   by David A. Mellis
   modified 30 Aug 2011
   by Tom Igoe
 
   This example code is in the public domain.

 */

// this constant won't change.  It's the pin number
// of the sensor's output:
const int pingPin = 7;

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
}

void loop()
{
  // establish variables for duration of the ping, 
  // and the distance result in inches and centimeters:
  long duration, inches, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  
  delay(100);
}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

De plus,pour mon maxsonar, je me suis inspiré de ce code: Arduino Playground - MaxSonar

 const int anPin = 1;

//variables needed to store values
long anVolt, inches, cm;
int sum=0;//Create sum variable so it can be averaged
int avgrange=60;//Quantity of values to average (sample size)

void setup() {

  //This opens up a serial connection to shoot the results back to the PC console
  Serial.begin(9600);
}

void loop() {

  //MaxSonar Analog reads are known to be very sensitive. See the Arduino forum for more information.
  //A simple fix is to average out a sample of n readings to get a more consistant reading.\\ 
  //Even with averaging I still find it to be less accurate than the pw method.\\ 
  //This loop gets 60 reads and averages them

  for(int i = 0; i < avgrange ; i++)
  {
    //Used to read in the analog voltage output that is being sent by the MaxSonar device.
    //Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
    //Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches
    anVolt = analogRead(anPin)/2;
    sum += anVolt;
    delay(10);
  }  
  inches = sum/avgrange;
  cm = inches * 2.54;
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  //reset sample total
  sum = 0;
  delay(500);
}

J'ai testé les deux individuellement et ca a marché...

Mais comme vous pouvez le voir,j'ai du modifier des trucs.

j'ai été obligé de sortir long duration, inches, cm; du void loop de l'exemple de ping car arduino me disait sans arret :'' cm was not declared in this scope''. Dès que je l'ai sorti,il ne m'a plus dit d'erreur. Ca va l'empecher de marcher?

Et en gros,mon code ne marcherait pas du tout? :frowning:

pro3000:
cm et cm2... Bah j'ai besoin des valeurs de centimètre des deux capteurs et si je laissais cm2 avec le nom cm, bah ca ferait deux variables avec le même nom.

C'est sur mais c'est pas une raison pour faire un code bordélique qui mélange les actions

Tu appelles une fonction microsecondsToCentimeters et dedans tu fais une acquisition sur un deuxième senseur. Cela rend le code incompréhensible et en plus au passage tu te gourres.

pro3000:
Et en gros,mon code ne marcherait pas du tout? :frowning:

C'est quelque chose qui arrive souvent lorsqu'on copie du code sans bien comprendre ce qu'il fait

Si tu découpais ton code proprement il fonctionnerait certainement et tu trouverais plus vite tes problèmes
Il faut écrire:

  • des fonctions qui assurent l'acquisition de chacun des senseurs.
  • des fonctions qui assurent des conversions de format.
  • des fonctions qui prennent les décisions
  • des fonctions qui envoient des consignes aux actionneurs.
    Toutes ses fonctions tu les appelles les unes après les autres dans loop.

Et puis aussi il faut lire un peu pour savoir comment fonctionne le C. Par exemple http://arduino.cc/en/Reference/Return
où tu vois que return fait quitter la fonction et donc tout le code situé après n'est jamais exécuté comme par exemple la lecture du second capteur.

fdufnews:

pro3000:
cm et cm2... Bah j'ai besoin des valeurs de centimètre des deux capteurs et si je laissais cm2 avec le nom cm, bah ca ferait deux variables avec le même nom.

C'est sur mais c'est pas une raison pour faire un code bordélique qui mélange les actions

Tu appelles une fonction microsecondsToCentimeters et dedans tu fais une acquisition sur un deuxième senseur. Cela rend le code incompréhensible et en plus au passage tu te gourres.

pro3000:
Et en gros,mon code ne marcherait pas du tout? :frowning:

C'est quelque chose qui arrive souvent lorsqu'on copie du code sans bien comprendre ce qu'il fait

Si tu découpais ton code proprement il fonctionnerait certainement et tu trouverais plus vite tes problèmes
Il faut écrire:

  • des fonctions qui assurent l'acquisition de chacun des senseurs.
  • des fonctions qui assurent des conversions de format.
  • des fonctions qui prennent les décisions
  • des fonctions qui envoient des consignes aux actionneurs.
    Toutes ses fonctions tu les appelles les unes après les autres dans loop.

Et puis aussi il faut lire un peu pour savoir comment fonctionne le C. Par exemple http://arduino.cc/en/Reference/Return
où tu vois que return fait quitter la fonction et donc tout le code situé après n'est jamais exécuté comme par exemple la lecture du second capteur.

Oui, je suis vraiment désolé de ma petite connaissance, mais nous avons eu que deux semaines de cours d'Arduino il y a 3 mois,soit les bases, et celles-ci sont vraiment très très loin de me permettre de faire un tel projet. De plus, nous sommes un membre de plus dans l'équipe, alors le prof veut que notre projet soit plus complexe... :confused: Presque tout ce qui est dans ce code,je ne l'ai jamais vu en cours!

Donc ce que tu me dis, c'est que la fonction microsecondsToCentimeters ( qui converti les microsecondes calculées en centimètres? ) Ne marchera pas car je fais une acquisition sur un 2e capteur?

De plus,si je garde les deux fonctions return, tout ce qui suivra ne sera jamais exécuté? Je devrais donc les enlever?

Et ce que tu veux dire aussi, c'est que je devrais mélanger les commandes des deux capteurs? Ce qui voudrait dire que par exemple les fonctions qui effectuent l'acquisition de données des deux capteurs, je les mets ensembles,ceux qui assurent des conversions de format ensembles,etc?

Alors cela donnerait plutôt :

cm = microsecondsToCentimeters(duration);

  for(int i = 0; i < avgrange ; i++)
  {

    anVolt = analogRead(maxsonar)/2;
    sum += anVolt;
    delay(10);

  }
long microsecondsToInches(long microseconds)
 inches = sum/avgrange;
  cm2 = inches * 2.54;


  sum = 0;

  delay(500);

et ensuite les if?

Aussi j'ai un peu changé le code avec les servos.

Pour tourner à gauche:   myservo.write(170);

à droite myservo.write(0);

et tout droit: myservo.write(90);

vraiment désolé de mon manque de connaissance... J'essaye de lire ce que je trouve sur internet aussi à côté

Et ce que tu veux dire aussi, c'est que je devrais mélanger les commandes des deux capteurs? Ce qui voudrait dire que par exemple les fonctions qui effectuent l'acquisition de données des deux capteurs, je les mets ensembles,ceux qui assurent des conversions de format ensembles,etc?

J'ai dit exactement le contraire.
Une fonction par capteur. S'il y a 2 capteurs 2 fonctions. Chacune retourne le résultat sa conversion.

long int acquisitionPing(void){
    long int duration;

    pinMode(pingPin, OUTPUT);
    digitalWrite(pingPin, LOW);
    delayMicroseconds(2);
    digitalWrite(pingPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(pingPin, LOW);
    pinMode(pingPin, INPUT);
    duration = pulseIn(pingPin, HIGH);
    return duration / 29 / 2;
}
long int acquisitionMaxSonar(void){
   //variables needed to store values
    long int anVolt, cm;
    int sum=0;//Create sum variable so it can be averaged
    int avgrange=60;//Quantity of values to average (sample size)

  for(int i = 0; i < avgrange ; i++)
  {
    //Used to read in the analog voltage output that is being sent by the MaxSonar device.
    //Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
    //Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches
    anVolt = analogRead(anPin)/2;
    sum += anVolt;
    delay(10);
  }  
  cm = 254* sum/avgrange/100; // 254/100 = 2.54

Ok, je vois! Et ces fonctions, je les écrit a l'extérieur du void loop()? Ainsi,si je veux appeler la fonction dans le void loop(), je creerais une variable int acquisitionPing(void) et quand jen ai besoin besoin dans le void loop(), je l'appelle? Comme ici en faithttp://arduino.cc/en/Reference/FunctionDeclaration

De plus, j'ai remarqué que tu as enlevé la fonction microsecondstocentimeters, que tu as fais return 29/2 a duration. Cela voudrait dire que quand j'ai besoin de la distance calculée sur le ping, j'appelle la variable duration?

Merci de ta patience! :smiley:

pro3000:
De plus, j'ai remarqué que tu as enlevé la fonction microsecondstocentimeters, que tu as fais return 29/2 a duration. Cela voudrait dire que quand j'ai besoin de la distance calculée sur le ping, j'appelle la variable duration?

Non dans loop tu crées une variable locale qui va récupérer le résultat en centimètres retourné par la fonction.

void loop(void){
   long int valeurPing;
   long int valeurSonar;
   .......
    // on fait l'acquisition des senseurs
   valeurPing = acquisitionPing();
   valeurSonar = acquisitionMaxSonar();

  // on traite les informations recueillies
  // par exemple
  if (valeurPing<30) || (valeurSonar<40){
       // Code exécuté si les conditions ci-dessus sont réunies
      ......
  }
   .......
}

D'accord, je comprend!

Dans ce cas, mon nouveau code devient ceci?

const int pingPin = 7;
int moteur= 3;
#include <Servo.h> 
int rouge = 6;
int vert = 5;
int bleu= 4;
Servo myservo;
int pos = 0;
const int MaxSonar = 1; 
long anVolt, inches, cm2;
int sum=0;
int avgrange=60;





void setup() {
  

pinMode(moteur, OUTPUT);
pinMode(rouge, OUTPUT);
pinMode(vert,OUTPUT);
pinMode(bleu,OUTPUT);
myservo.attach(9);
pinMode(MaxSonar,INPUT);

}

long int acquisitionPing(void){
    long int duration;

    pinMode(pingPin, OUTPUT);
    digitalWrite(pingPin, LOW);
    delayMicroseconds(2);
    digitalWrite(pingPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(pingPin, LOW);
    pinMode(pingPin, INPUT);
    duration = pulseIn(pingPin, HIGH);
    return duration / 29 / 2;
}

long int acquisitionMaxSonar(void){
   //variables needed to store values
    long int anVolt, cm;
    int sum=0;//Create sum variable so it can be averaged
    int avgrange=60;//Quantity of values to average (sample size)

  for(int i = 0; i < avgrange ; i++)
  {
    //Used to read in the analog voltage output that is being sent by the MaxSonar device.
    //Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
    //Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches
    anVolt = analogRead(anPin)/2;
    sum += anVolt;
    delay(10);
  }  
  cm = 254* sum/avgrange/100; // 254/100 = 2.54
  }  



void loop()
{
  
   long int valeurPing;
   long int valeurSonar;
   .......
    // on fait l'acquisition des senseurs
   valeurPing = acquisitionPing();
   valeurSonar = acquisitionMaxSonar();

  // on traite les informations recueillies
  // par exemple
  if (valeurSonar>30 and valeurPing>30 ) 
{
digitalWrite(rouge,HIGH);
delay(500);
digitalWrite(rouge,LOW);
delay(500);  
digitalWrite(vert,HIGH);
delay(500);
digitalWrite(vert,LOW);
delay(500); 
digitalWrite(bleu,HIGH);
delay(500);
digitalWrite(bleu,LOW);
delay(500);
  
analogWrite(moteur,170);
delay(500);


}

if (valeurPing < 30 and valeurSonar <30 )
{
    analogWrite(moteur,0);
  delay(500);
  digitalWrite(rouge,HIGH);
  delay(500); 
 }
   
  if(valeurSonar>30 and valeurPing<30)
  
    { 
     analogWrite(moteur, 90);
  delay(500);
  
        for(pos = 0; pos < 180; pos += 1)  
  {                                   
    myservo.write(pos);            

    
   } 
 digitalWrite(vert,HIGH);
 delay(500);
 digitalWrite(vert,LOW);
delay(500); }
  
  if(valeurSonar<30 and valeurPing>30)
{  
  analogWrite(moteur, 90);
  delay(500);
  
   for(pos = 180; pos>=1; pos-=1)      
  {                                
   myservo.write(pos);               
                      
  } 
  digitalWrite(bleu,HIGH);
  delay(500);
  digitalWrite(bleu,LOW);
  delay(500); 
   } 

}

Maintenant, il serait fonctionnel?

pro3000:
Maintenant, il serait fonctionnel?

Fonctionnel je ne peux pas juger comme ça. Il faudrait avoir la plateforme sur laquelle il va tourner.
En tout cas il est plus clair et ce sera plus simple de trouver les problèmes s'il y en a.

Ouais c'est tellement plus clair que même moi je le comprend :smiley:

Donc lundi,je ferai des tests avec ma voiture et ce sera beaucoup plus facile de régler les problemes s'il y en a. Au pire des cas, mon prof est la pour m'aider.

Et bien sur je reviendrai ici pour te dire comme ca été :slight_smile:

Tu ne peux pas savoir a quel point je t'en suis reconnaissant, tu viens peut-être de permettre a 3 étudiants d'aller a l'université! :smiley:

Gros merci a toi!!!