interaction actionneur - capteur

Bonjour,

toujours dans mon apprentissage des bases, je bute sur un problème qui doit être, je pense, basique. Mais je n'y trouvé aucun exemple susceptible de m'aider.

Je dispose d'une base à chenilles équipée de deux moteurs indépendants, d'un servo et d'un capteur à ultrasons HC-SR04.

Mon but est de mesurer la distance libre devant la base et, en cas d'obstacle à une distance déterminée, stopper les moteurs, faire tourner le servo sur lequel est fixé le capteur à ultrasons afin de rechercher un passage libre (donc prendre des mesures à intervale ou angle régulier) puis orienter la base dans la direction libre et la faire avancer.

Quelqu'un aurait-il un synoptique à me montrer ? Pas de programme tout fait, ça ne m'aiderait pas à apprendre, juste le cheminement à suivre.

Merci

albaflo:
...
Mon but est de mesurer la distance libre devant la base et, en cas d'obstacle à une distance déterminée, stopper les moteurs, faire tourner le servo sur lequel est fixé le capteur à ultrasons afin de rechercher un passage libre (donc prendre des mesures à intervale ou angle régulier) puis orienter la base dans la direction libre et la faire avancer.

Quelqu'un aurait-il un synoptique à me montrer ? Pas de programme tout fait, ça ne m'aiderait pas à apprendre, juste le cheminement à suivre.

Merci

bonjour

distingue 2 cas d'utilisation du capteur US (mode detection en marche et mode recherche )

debut de  boucle de decision 
-  determination de la zone angulaire la plus libre en distance  (à l'echelle des possibilité de detection du capteur) 
- caler le robot par action sur servo sur cette direction, recaler le capteur US en position mediane  
- avancer et proceder à intervalles X à une mesure de distance dans l'axe de progression
- Si detetection d'obstacle proche (selon tes criteres) 
-- stopper le robot
aller debut de boucle

Je vais tenter de suivre çà ce soir, ça me laissera l'après midi (au boulot) pour réfléchir au code, qui reste un peu obscure :cold_sweat:

merci

bon, ben je sêche.

J’ai fait ceci:

//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 servomoteur
Servo servo1;

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

//declaration de la variable de distance
int Distance;

//declaration de la position initiale du servo
int pos = 90;

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

  Serial.begin(9600);
  Serial.println("mesure de distances:");
  //vitesse maxi = 255 / mini = 0
  moteur1.setSpeed(255);     
  moteur2.setSpeed(255);
  //declaration de la broche du servo
  servo1.attach(10);
  servo1.write(pos);
}
///*******************************************************///
///*******************************************************///

void detect() {

Distance = sonar.ping_cm();
Serial.println(Distance);
delay(250); //4 mesures par seconde
}
///*******************************************************///
///*******************************************************///

void actionServo() 
{
  Serial.println("distance < 30 cm");
  /*leHC-SR04 a un angle de 15°
  prevoir une rotation de -30° et +30° du servo pour couvrir un angle de 60°
  faire un ping à gauche puis un ping à droite
  comparer les deux résultats (prévoir tableau ???)
  orienter robot vers le plus grand
  puis retourner dans void loop*/
}  
///*******************************************************///
///*******************************************************///

void loop(){

  //appel de la fonction detect
  detect();
  Serial.print(Distance);
  Serial.println(" cm dans loop");

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

  //marche arriere pendant une seconde si un obstacle est à moins de 10 cm
  if (Distance < 10 || Distance > 0) {
    moteur1.run(BACKWARD);     
    moteur2.run(BACKWARD);
    Serial.println("en arriere");
    delay(1000);
  }

  //**************TEST*************//
  //si distance inférieure ou égale à 30cm servo1 est activé
  if (Distance < 30 || Distance > 10){
    Serial.println("gloups");
    actionServo();
  }
} //fin de la fonction loop

mon idée est d’activer la fonction “actionServo” quand la distance mesurée est inférieur à 30 cm ou supérieur à 10 cm.

J’ai créé une fonction “detect” pour le sonar et la fonction “actionServo” pour le servo.

Les mesures sont bonnes, la distance est bien envoyée dans la fonction “loop” mais c’est après que ça se gâte:

les trois hypothèses sont actives en même temps (marche avant, marche arrière et celle de “actionServo”).

Je sêche completement, je ne vois pas où se trouve mon erreur.

Quelqu’un pourrait-il m’aider ?

Merci

les trois hypothèses sont actives en même temps

C’est que tes tests (if) ne sont pas bons. Formule les autrement et mets un print dedans pour voir si le prog y passe

à force de m'écarquiller les yeux sur ce code, je n'avais pas vu que j'avais oublié de remodifier le || (ou) en && (et) dans les tests...

encore une gaffe que je ne ferai plus.

Merci Carolyne

Je poursuis la mise au point de mon robot.

Pour le moment, tout roule, grace à vous, mais j'attaque le gros morceau. Je vais essayer d'être clair et précis.

Le sonar mesure la distance libre devant le robot tous les 1/4 de seconde, ce qui est nettement suffisant vu la vitesse de déplacement de la bête.
J'utilise un "delay(250)" pour paramétrer les intervalles, mais ça ne convient pas.

void detect() {

Distance = sonar.ping_cm();
delay(250); //4 mesures par seconde
}

Par exemple, lorsque les moteurs s'inversent, le sonar ne mesure plus car la marche arrière est également paramétrer par un "delay". Ca me pose problème.

En parcourant le forum, j'ai trouvé un sujet évoquant l'exemple "BlinkWithoutDelay". Je pense qu'il me faut m'en inspirer mais je ne sais pas comment. Il faudrait passer la broche du TRIGGER_PIN à LOW ?

En plus du problème lié aux moteurs, il y a également l'utilisation du servo et le repérage de la direction libre.

En cas d'obstacle, le robot s'arrête, le servo sur lequel est fixé le HC-SR04 tourne d'un côté, mesure la distance libre, une seule mesure, tourne de l'autre côté et mesure une seconde distance, une seule mesure aussi.

Les deux valeurs sont rangées dans un tableau puis comparée afin que le robot puisse s'orienter vers la direction libre. (Ca je devrais savoir le faire.)

//declaration du tableau de comparaison
int tab[2];
void actionServo() 
{

  pos = 110;
  servo1.write(pos); //rotation +30°
  tab[0] = Distance;
  delay(1000);
 
  pos = 50;
  servo1.write(pos);//rotation -30°
  tab[1] = Distance;
  delay(1000);

  pos = 80;
  servo1.write(pos);//retour au centre

Mais pour çà, il faut que je puisse faire une mesure à l'issue de chacune des deux rotation du capteur.
Et dans mon code, ça ne va pas du tout, les deux valeurs sont systématiquement identiques

Ensuite, une fois le chassis orienté, il reprend sa marche en envoyant un ping tous les 1/4 de seconde, jusqu'à l'obstacle suivant.

Quelqu'un pourrait-il me guider sur la marche à suivre pour les problèmes liés aux "delay" et pour réussir à faire une seule mesure à un instant T ?

Merci

albaflo:
Je poursuis la mise au point de mon robot.

...
Quelqu'un pourrait-il me guider sur la marche à suivre pour les problèmes liés aux "delay" et pour réussir à faire une seule mesure à un instant T ?

Merci

ne passe pas par des delay (fonction bloquante) mais par des condition de difference sur millis() ou micros()

C'est ce que j'essaie mais je n'ai aucune idée sur la façon de procéder.

L'exemple BlinkWithoutDelay semble ne pas convenir.

Voici ce que j'ai fait, devine quoi... ça ne fonctionne pas du tout.

Je devrais avoir un ping par seconde, là c'est beaucoup plus rapide et la fonction se bloque comme si elle était toujours gérée par un delay.

//declaration de l'intervalle de mesure
long interval = 1000;
//configuration de l'etat de echo
int echoState = LOW;
//declaration de la duree d'interruption
long previousMillis = 0;
void detect() {

  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    //delay(250); //4 mesures par seconde
    if (echoState == LOW)
      echoState = HIGH;
    else
      echoState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ECHO_PIN, echoState);
  }
  Distance = sonar.ping_cm();
  Serial.println(Distance);
}

précision: J'ai utilisé le code d'exemple sans le modifier, hormis le nom des variables pour m'y retrouver.