[conseil] projet de détéction d'obstacle, question de compréhension

Bonjour tout le monde :slight_smile:

Peut etre ça vous dira quelque chose mais lors d'un topic que j'ai recement posté, j'ai parlé d'un projet que je voulais faire.
Tout d'abord je vais essayer de décrire le projet en question puis parler du soucis que je rencontre.

Projet : J'aimerai creer un programme permettant une detection d'obstacle.
Pour cela, j'ai une carte arduino duemilanove avec le support que l'on met au dessus où j'y est branché un buzzer (sur la voie 12). et j'ai également un sonar (MB 1200) qui envoie un valeur en fonction de la distance de l'obstacle (ex :100 = 1m).
J'aimerai que cette detection se déroule ainsi:
Au dela de 2m, tout va bien, rien ne se passe. Arrivé a 2m le sonar detecte et fait biper le buzzer. Plus le l'objet s'approche du radar et plus le buzzer sonne vite (donc temps entre chaque bip diminue) et arrivé à 1m et - le buzzer sonne en continue.

Voici mon soucis, je ne voie pas comment réaliser la fonction entre 2 m et 1m (celle où plus la valeur envoyé par le sonar diminue, plus le buzzer sonne à intervalle reduit) ou plus précisement, je ne sais pas quelle fonction utiliser pour réaliser ceci.

Je débute depuis quelques jours l'arduino et pour m'entrainer j'ai creer des programmes divers et varier, allant du simple bip en continue pour un obstacle repéré à moins de 1 m, à un programme faisant sonné le buzzer a intervalle régulier entre 1m50 et 1m et à moins d'1m un bip en continue (je vous cache pas que pour celui si j'ai galerer en essayant de mettre des if dans un if (avec succes) ou en utilsant un switch case (en vain)).

Bref, je ne cherche pas a ce qu'on me fasse le programme, mais qu'on m'explique comment je peut réalisé ceci et avec quels moyens.

j'espere avoir ete asser clair si ce n'est pas le cas n'hésitez pas à me questionner :slight_smile:

Cordialement
Benoit

Benoit1121:
...
Bref, je ne cherche pas a ce qu'on me fasse le programme, mais qu'on m'explique comment je peut réalisé ceci et avec quels moyens.

j'espere avoir ete asser clair si ce n'est pas le cas n'hésitez pas à me questionner :slight_smile:

Cordialement
Benoit

bonjour
le probleme est bien exposé, mais sa résolution implique de bien connaitre les paramètres :grin:
donc !
lien vers :

  • le programme qui fonctionne bien chez toi déjà sur le bip ou pas bip , fonction de la distance . 8)
  • liens vers les shields
    -- comment est connecté le buzzer, et c'est quoi comme buzzer ?
    -- liens techniques exploitables vers la capteur US (le sonar)

Bonjour Artouste

Merci d'avoir répondu :slight_smile:

Malheureusement j'ai sauvegardé mes programmes deja existent sur un pc dont j'aurai acces que vendredi ... (Oui j'ai pas géré sur le coup, je n'ai pas fait de sauvegarde sur clé usb)

Tant qu' à faire, comment faire pour ecrire mon programme qui est plus ou moins long dans une réponse? je voie que certains le fond via une fentre qui se deroule ^^

Ensuite, pour parler du sonar c'est un sonar MB1200 : http://www.maxbotix.com/documents/MB1200-MB1300_Datasheet.pdf

J'ai décidé de connecter le sonar sur sa PIN 3 qui en fait m'envoie une tensions analogique, je le branche sur l'entree analogique 3 de la carte Arduino duemilanove. Le sonar envoie comme information une valeur comprise entre 0 et 1023.
par exemple : un obstacle repérer à 1m correspondra à une valeur de 100 envoyé par le sonar.

Voici le lien de la carte arduino : http://arduino.cc/fr/Main/MaterielDuemilanove

PS: promis vendredi matin j'envoie les programmes que j'ai créer si ca peut vous aider.

Merci :slight_smile:

Benoit

J'ai une idée mais je sais pas si cela est possible...

Voila en fait ce que je veux c'est que (en gros) j'ai une valeur X qui est comprise entre 0 et 200 (je peux peut etre la declarer en tant que variable car X serais la valeur envoyé par mon sonar)
Et qu'on initialise X à 200 donc, plus X diminue, plus le "delay" (temps qui est entre chaque bip) diminue.

Fiouu, ca parait peut etre brouillon, mais si vous avez une idée mieux que ca je suis preneur !

Cordialement
Benoit

Bonjour, javais fait une petit sketch pour faire "beeper" un mini hp (comme un radar de recule) en fonction de la distance d'un objet mesurée par un capteur Sharp GP2Y0A021YK
et de la lib "Tone", inspire toi :smiley:

long previousMillis = 0;       
int interval = 200;           
boolean beep_state;
int val_A0;

void setup() 
{
 Serial.begin(9600);     
}

void loop()
{
  lecture_A0();
  beep();
}


void lecture_A0()
{
val_A0 = analogRead(A0);
interval = 600 - val_A0;
Serial.println (interval);
}


void beep()
{
   unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval)
  {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   


    if (beep_state == 0)
      {
      beep_state = 1;
      tone(8, 1319);
      }
    else
     {
      beep_state = 0;
      noTone(8);
      }
   }
}

Bonjour,
Moi j'aurais tendance à utiliser un timer soft pour piloter le buzzer mais si tu découvres la programmation tu peux utiliser un truc simple du genre:
tu mesures la distance, si < 2m et >1m tu fais un on-off du buzzer et tu fais un delay() inversement proportionnel à la distance mesurée
si distance <1m tu laisses le buzzer on.

Bonjour,

@cutprod: Merci de me donner ton prog en exemple, le hic, c'est que j'ai un peu de mal a tout comprendre. Du coup je sais pas si ca correspond à mon cahier des charges. c'est à dire plus un obstacle s'approche, plus le buzzer sonne rapidement (entre 2m et 1 m).
Je sais pas comment écrire ça: (en gros) on concidere X la valeur donné par le sonar (1m = 100 et 2m=200) Donc, si X=200 le buzzer bip avec un delay de 1s et plus X diminue en direction de 100 et plus la valeur de delay diminue..
déja je dois utiliser un if (ca tombe bien je commence a maitriser) mais pour ce qui est du reste, je sais pas.
Ps: comment tu fais pour introduire ton code dans cette fenetre ?

@patg_: Tu sous entends quoi par "inversement proportionnel", je pense que ton idée pourrait marcher car si j'ai bien compris (ou pas ^^) la valeur de delay fluctura en fonction de la valeur comprise entre 2m et 1m.

Merci à vous deux pour vos réponses :slight_smile:

Benoit

exemple, tu as la distance * 100 dans la variable x:
à la fin de la boucle du sketch (qui mesure la distance et émet 1 beep si la distance est < 2m) tu mets:

delay (x/200 * 1000);

pour une distance de 2m tu auras 1 beep toutes les secondes
pour une distance de 1m tu auras 1 beep toutes les 500ms

La période entre 2 beeps est donc inversement proportionnelle à la distance mesurée.
En diminuant le facteur 1000 tu augmente la fréquence des beeps (enfin des coups de buzzer).

Ce mécanisme simple fonctionne à condition que tu ne doives rien faire d'autre pendant le temps d'attente (l'AVR est bloqué).
On peut faire autrement si nécessaire (par un timer soft ou par un delay() un peu plus évolué).

Ok merci,ça me parait clair maintenant. Je vais essayer, je vous tiens au courant si je rencontre d'autre difficulté.

Merci Patq_ :slight_smile:

Benoit

Comme promis, je mets mon exemple de captage d'objet entre 1m50 0m. Avec un buzzer et une LED.
Il est peut être basic mais il marche :wink:

int analogPin = 3;     // Sonar branché sur la PIN analogique 3

int val = 0; // variable de type int pour stocker la valeur de la mesure

void setup() {
  
pinMode(12, OUTPUT); //Buzzer
pinMode(11, OUTPUT); // LED
Serial.begin(9600);  
}

void loop() {
  
   val = analogRead(analogPin);
   Serial.println(val);  
   

     if ( val < 100)
  {
     digitalWrite(12, HIGH);  // set the buzzer on
     digitalWrite(11, HIGH);  // set the LED on
    
   }
   else 
   {
     if (val < 150)
     {
      digitalWrite(12, HIGH);   // set the buzzer on 
    digitalWrite(11, HIGH);   // set the LED on 
    delay (1000);
    digitalWrite(12, LOW);   // set the buzzer off
    digitalWrite(11, LOW);   // set the LED off 
    delay (1000);
     }
     else 
     {
     }
     
   }  
}

Cordialement

Benoit

Alors voila j'ai enfin réussis a trouver un programme permettant de réaliser ce que je veux.
Il est super simple, basic mais vue mon niveau je suis assez content du resultat..

int analogPin = 3;     // Sonar branché sur l'entrée analogique 3 

int val = 0; // variable de type int pour stocker la valeur de la mesure

void setup() 
{
  
pinMode(12, OUTPUT); // Le signal est envoyé sur le buzzer qui est branché sur la sortie 12
pinMode(11, OUTPUT); // Le signal est envoyé sur la LED qui est branché sur la sortie 13
Serial.begin(9600); // initialise le serial monitor a 9600 bauds  
}

void loop() 
{
   
   val = analogRead(analogPin); // la valeur lue sera appelé "val"
   Serial.println(val);  // le serial monitor affiche la valeur "val"
   

     if ( val < 100)
  {
     digitalWrite(12, HIGH);  // active le buzzer (ON)
     digitalWrite(11, HIGH);  // active la LED (ON)
    
   }
   else 
   {
     if (val < 200)
     {
      digitalWrite(12, HIGH);   // active le buzzer (ON)
    digitalWrite(11, HIGH);   // active la LED (ON)
    delay (val * 5);   // Temps de l'activation qui sera d'une valeur = val x 5
    digitalWrite(12, LOW);   // désactive le buzzer (OFF)
    digitalWrite(11, LOW);   // désactive la LED (off)
    delay (val * 5 );  // Temps de la désactivation qui sera d'une veleur = val x 5
     } 
     else 
     {
     }
     
   }  
}

J'espere avoir des impressions (positive ou négative) et si vous avez des améliorations à me proposer, je suis prenneur !

Merci

Benoit

bravo.

Suggestion : Je pense que la durée du bip doit être constant et seule la période doit varier en fonction de la distance.

Prochain niveau : ton code utilise delay() qui est une fonction blocante et qui empêche le programme de faire autre chose pendant ce temps.
Regarde le code exemple BlinkNoDelay et essaye de faire évoluer ton programme pour ne plus utiliser delay() mais uniquement des comparaisons et des différences de temps.

Pareil.
Tu devrais allumer le buzzer et la led, attendre un temps bref et fixe, puis les éteindre.
Ensuite seulement tu fais ton attente variable fonction de la distance.

C'est pas mal pour un début.

Je suis moi aussi dans mes "arduineries" :grin:

@barbudor, @Patq_ : merci pour vos remarques :slight_smile:
Je vais bien entendu essayer d'améliorer le programme en fonction de vos remarques.
Dés lundi je m'attaque a l'amélioration de ce programme puis je viendrais le poster afin de vous montrer et bien entendu j’espère de vous avoir des remarques :slight_smile:

Il est vrai que j'avais remarqué que pendant que le buzzer et la LED s'allumaient rien ne ce passait pendant ce temps et ça peut poser problème ^^
Merci @barbudor pour l’exemple, je vais m'en inspirer :slight_smile:

Cordialement

Benoit

Bonjour
Barbudor, j'ai du mal à comprendre l'exemple "blinkwithoutdelay", j'ai compris qu'il y a des differences de temps mais je ne voie pas du tout comment avoir une influence sur le temps de clignotement.
c'est à dire, je ne voie pas comment faire clignoter la LED en fonction de la distance de l'obstacle...

cordialement

Benoit

Voilà, je me suis inspiré d'une part de l'exemple "blinkwithoutdelay" et de programme de cutprod . Voilà ce que ca donne :
dans cette exemple, je me suis servi que de la LED pour faire simple ^^

long previousMillis = 0;       
int interval = 200;           
boolean beep_state;
int analogPin = 3; 
int val = 0;

void setup() 
{
 Serial.begin(9600);     
 pinMode(11, OUTPUT); // Le signal est envoyé sur la LED qui est branché sur la sortie 13
}

void loop()
{
  lecture_val();
  beep();
}


void lecture_val()
{
val = analogRead(analogPin);
interval = 500 - val;
Serial.println (interval);
}


void beep()
{
   unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval)
  {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   


    if (beep_state == 0)
      {
      beep_state = 1;
digitalWrite(11, HIGH);  // active la LED (ON)
 tone(8, 1319);
      }
    else
     {
      beep_state = 0;
digitalWrite(11, LOW );  // active la LED (Off)
  noTone(8);
      }
   }
}

Le hic c'est que ca fait l'inverse de ce que j'attend, c'est a dire plus la distance (appelé ici "interval") est grande, plus la led Bip rapidement
j'ai beau changer des parametres, de changer les 1 et 0, ca m'inverse pas..

Deuxieme hic, je ne vois pas comment integrer un ligne me permettant de faire un bip continue lorsque je suis a moins de 1 m

Je suis à fond dessus pour essayer de trouver un moyen, il se peut que je la trouve cette solution ! si c'est le cas, je mettrais le code ^^

PS : je comprends pas pourquoi cutprod utilise "if beep state == 0" c'est quoi ce beep state? l'etat du beep qui est dans la suite c'est à dire O ou 1 ??
Merci

Cordialement

Benoit

Le principe est de ne gérer que les transitions sans bloquer
Donc il faut savoir dans quel état tu es pour que à l'expiration de la tempo tu sache ce que tu dois faire.

Ton code me parait parfait et tu dis qu'il marche sauf que la période n'évolue pas dans le bon sens.

Cela ne me surprend pas puisque dans ton code initial, le delay() est proportionel à val

delay (val * 5);   // Temps de l'activation qui sera d'une valeur = val x 5

Alors que dans ce nouveau code c'est le contraire :

interval = 500 - val;

Pourquoi n'as tu pas utilisé interval = 5 * val comme dans le 1er code ?

Deuxieme hic, je ne vois pas comment integrer un ligne me permettant de faire un bip continue lorsque je suis a moins de 1 m

Dans beep, il faut gérer ce cas. Il faut gérer les 3 cas d'ailleurs comme dans ton code initial.

unsigned long currentMillis = millis();

if ( val < 100)
{
    beep_state = 1;
    digitalWrite(11, HIGH);  // active la LED (ON)
    tone(8, 1319);
    previousMillis = currentMillis;
}
else if (val < 150)
{
    if ( currentMillis - previousMillis > interval )
    {
        // save the last time you blinked the LED 
        previousMillis = currentMillis;   
        if (beep_state == 0)
        {
            beep_state = 1;
            digitalWrite(11, HIGH);  // active la LED (ON)
            tone(8, 1319);
        }
        else
       {
            beep_state = 0;
            digitalWrite(11, LOW );  // active la LED (Off)
            noTone(8);
        }
    }
}
else 
{
    beep_state = 0;
    digitalWrite(11, LOW );  // active la LED (Off)
    noTone(8);
    previousMillis = currentMillis;
}

Tu remarqueras que je met à jour previousMillis chaque fois qu'il y a un changement d'état de façon a ce que le compteur de temps soit à jour si brutalement la distance change.

Merci beaucoup barbudor !

je vais essayer de faire comme dans le premier c'est a dire faire un 5 * val ou autrement

Voilà je pense que je touche au but ! :slight_smile:

long previousMillis = 0;       
int interval = 200;           
boolean beep_state;
int analogPin = 3; 
int val = 0;

void setup() 
{
 Serial.begin(9600);     
 pinMode(12, OUTPUT); // Le signal est envoyé sur le buzzer qui est branché sur la sortie 12
 pinMode(11, OUTPUT); // Le signal est envoyé sur la LED qui est branché sur la sortie 13
}

void loop()
{
  lecture_val();
  beep();
}


void lecture_val()
{
val = analogRead(analogPin);
interval = val;
Serial.println (interval);
}


void beep()
{
unsigned long currentMillis = millis();

if ( val < 100)
{
    beep_state = 1;
    digitalWrite(11, HIGH);  // active la LED (ON)
    tone(8, 1319);
    previousMillis = currentMillis;
}
else if (val < 250)
{
    if ( currentMillis - previousMillis > interval )
    {
        // save the last time you blinked the LED 
        previousMillis = currentMillis;   
        if (beep_state == 0)
        {
            beep_state = 1;
            digitalWrite(11, HIGH);  // active la LED (ON)
            
            tone(8, 1319);
        }
        else
       {
            beep_state = 0;
            digitalWrite(11, LOW );  // active la LED (Off)
             
            noTone(8);
        }
    }
}
else 
{
    beep_state = 0;
    digitalWrite(11, LOW );  // active la LED (Off)
    
    noTone(8);
    previousMillis = currentMillis;
}
}

mais il me reste encore deux questions que j'ai du mal a résoudre ...

  1. Je ne trouve aucune explication sur la librairie "tone" et "noTone" et à quoi corresponde les valeurs entre parenthese ? (Ca répondra peut être a ma deuxième question)
  2. comment puis je faire pour pour modifier le temps entre chaque bip car je trouve que même à 2 m ça bip assez rapidement..

(Edit : Je suis tombé sur un page wiki qui explique ce qu'est la librairie tones, (elle permet juste de faire des sons différent, grâce aux fréquence des notes). Donc ce ne répond pas à ma 2 eme questions ^^)

Merci

Benoit

comment puis je faire pour pour modifier le temps entre chaque bip car je trouve que même à 2 m ça bip assez rapidement

C'est une remarque purement subjective qui ne dépend que de toi.
A toi de déterminer la fonction intervale = f1(analogRead) sachant que analogRead est déjà f2(distance)

Regarde la spec de ton capteur pour avoir la fonction f2 et détermine f1 en fonction de cela.
Peut être faudra t'il définir un fonction par segment ?
(analogRead entre x1 et x2 -> interval = ?
(analogRead entre x2 et x3 -> interval = ?