Barrière Arduino

Bonjour

En ce moment je crée un projet de barrière pour continuer à progresser sur Arduino.

Le problème: lorsque qu'un objet s'approche du capteur ultrason donc quand la distance est inférieure à ma variable seuil alors il se déroule une série d'action comme le buzzer d'où vient le problème. Je voudrais que le buzzer sonne qu'une fois que quand l'objet s'approche et pas tous le temps même si la distance est inferieur au seuil.
voici mon programme:

#include <Servo.h>              
 
 const int Seuil=30;
 long duree, distance;           
 Servo moteur;                 
 
 #define trigg 3
 #define echo 4
 #define ledrouge 5
 #define ledjaune 6
 #define ledverte 7
#define buzzer 11
 
 

void setup() {
 pinMode(trigg, OUTPUT);            
 pinMode(echo, INPUT); 
 pinMode(ledrouge, OUTPUT);
 pinMode(ledjaune, OUTPUT);
 pinMode(ledverte, OUTPUT);
 pinMode(buzzer, OUTPUT);
 digitalWrite(ledrouge,HIGH);
 digitalWrite(ledjaune,LOW);
 digitalWrite(ledverte,LOW);
  moteur.write(0);
 
 moteur.attach(9);            
 
}

void loop() {
 digitalWrite(trigg,LOW);           
 delayMicroseconds(2);          
 digitalWrite(trigg, HIGH);         
 delayMicroseconds(10);         
 digitalWrite(trigg, LOW);            

 
 duree = pulseIn(echo, HIGH);             
 distance = duree * 340 / (2 * 10000); 

 if (distance<=Seuil){          
   delay(300);
   tone(buzzer,900,100);
   digitalWrite(ledrouge,LOW);
   delay(1000);
   digitalWrite(ledjaune,HIGH);
   delay(100);
   moteur.write(90);
   delay(1000);
   digitalWrite(ledjaune,LOW);
   delay(1000);
   digitalWrite(ledverte,HIGH);
   tone(buzzer,900,100);
 } 
 else
 {
 digitalWrite(ledjaune,LOW);
 digitalWrite(ledverte,LOW); 
   delay(100);
 digitalWrite(ledrouge,HIGH);
 moteur.write(0);
 
 } 
  
   delay(1000);
                 
}

Bonjour;

Si j'ai bien compris ton probléme, tant que la condition suivante est vraie

La boucle exécute à chaque passage ce qui suit:

A mon avis, si c'est possible, il faudrait que tu puisse détecter au moins 2 seuils

1er seuil, quand tu approche et que tu est à une distance inférieur à D1, tu enclenche ta procédure et l'alarme.

2éme seuil tu es à l'intérieur de la zone de déclenchement à la distance < D2, et tu veux arréter l'alarme.

Avec D2<D1.

Il faut voir aussi le probléme dans le sens sortie (éloignement), je présume que dans ce cas il ne faut pas déclencher d'alarme.

PS:
Tu a écris 2 fois

Dans ton "if".

Avec

oui pardon j ai oublier de suprimer le deuxieme buzzer

oui dans le sens sortie il ne faut pas déclencher l'alarme

Donc il faut arriver à déterminer le sens "je m'approche" ou "je m'éloigne".

Les 2 seuils peuvent aussi servir à cela, suivant dans quel ordre ils seront déclenchés, tu peux savoir si le sujet s'approche ou s'éloigne je pense.

c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)

la machine à état peut ressembler à cela :

Il suffit d'avoir deux variables, une pour avoir la variation de la distance(le signe donnant le sens), l'autre pour indiqué que l'alarme a été actionné.

Bonjour hugoo17

Il te faut une variable globale booléenne qui te dit si le beep a déjà été émis:
boolean beepFait = false; // Si beep déjà émis

dans la condition d'émission du beep tu ajoute le contrôle de cette variable:

	if (distance<=Seuil){
		if (!beepFait){

Si la distance est plus petite que le seuil et beepFait n'est pas vrai (!)
A la fin de cette condition, mettre beepFait à vrai:
beepFait = true;

Dans le else:
beepFait = false;

Et ton programme ressemble à ça:

#include <Servo.h>
boolean beepFait = false; // Si beep déjà émis


const int Seuil=30;
long duree, distance;
Servo moteur;

#define trigg 3
#define echo 4
#define ledrouge 5
#define ledjaune 6
#define ledverte 7
#define buzzer 11



void setup() {
	pinMode(trigg, OUTPUT);
	pinMode(echo, INPUT);
	pinMode(ledrouge, OUTPUT);
	pinMode(ledjaune, OUTPUT);
	pinMode(ledverte, OUTPUT);
	pinMode(buzzer, OUTPUT);
	digitalWrite(ledrouge,HIGH);
	digitalWrite(ledjaune,LOW);
	digitalWrite(ledverte,LOW);
	
	moteur.attach(9);
	moteur.write(0);
}

void loop() {
	digitalWrite(trigg,LOW);
	delayMicroseconds(2);
	digitalWrite(trigg, HIGH);
	delayMicroseconds(10);
	digitalWrite(trigg, LOW);

	
	duree = pulseIn(echo, HIGH);
	distance = duree * 340 / (2 * 10000);

	if (distance<=Seuil){
		if (!beepFait){
			delay(300);
			tone(buzzer,900,100);
			digitalWrite(ledrouge,LOW);
			delay(1000);
			digitalWrite(ledjaune,HIGH);
			delay(100);
			moteur.write(90);
			delay(1000);
			digitalWrite(ledjaune,LOW);
			delay(1000);
			digitalWrite(ledverte,HIGH);
			tone(buzzer,900,100);

			beepFait = true;
		}
	}
	else
	{
		digitalWrite(ledjaune,LOW);
		digitalWrite(ledverte,LOW);
		delay(100);
		digitalWrite(ledrouge,HIGH);
		moteur.write(0);

		beepFait = false;
	}
	
	delay(1000);	
}

Attention à l'ordre des instructions sur le servo:

moteur.write(0);
moteur.attach(9);

avant l'attach, le servo "n'existe pas", c'est mieux ainsi:
moteur.attach(9);
moteur.write(0);

A+
Cordialement
jpbbricole

un exemple de la machine à états avec une LED en plus pour montrer quand on est à l'état ACTIF même si le son ne se fait plus

click to see the code
const byte brocheEcho = 10;
const byte brocheTrig = 11;
const byte brocheBuzz = 5;
const byte brocheLed = 4;

const unsigned int distanceSeuil = 50;  // cm
const unsigned int deltaSeuil = 5;      // cm

const unsigned long dureeBuzz = 1000;   // ms
unsigned long chronoDebutBuzz;


enum {REPOS, ACTIVATION, ACTIF} etat = REPOS;

unsigned long distance() {
  static unsigned long d;
  const unsigned long periodeMesure = 100; // en ms => 10Hz (min 29ms entre 2 pings)
  unsigned long chronoDerniereMesure = -periodeMesure;
  if (millis() - chronoDerniereMesure >= periodeMesure) {
    digitalWrite(brocheTrig, HIGH);
    delayMicroseconds(10);
    digitalWrite(brocheTrig, LOW);
    d = pulseIn(brocheEcho, HIGH) / 58;
    chronoDerniereMesure = millis();
  }
  return d;
}

void setup() {
  pinMode(brocheBuzz, OUTPUT);
  pinMode(brocheLed, OUTPUT);
  pinMode(brocheTrig, OUTPUT);
  pinMode(brocheEcho, INPUT);
}

void loop() {
  switch (etat) {
    case REPOS:
      if (distance() < distanceSeuil) {
        chronoDebutBuzz = millis();
        tone(brocheBuzz, 500);
        digitalWrite(brocheLed, HIGH);
        etat = ACTIVATION;
      }
      break;

    case ACTIVATION:
      if (millis() - chronoDebutBuzz >= dureeBuzz) {
        noTone(brocheBuzz);
        etat = ACTIF;
      } else {
        if (distance() >= distanceSeuil + deltaSeuil) {
          noTone(brocheBuzz);
          digitalWrite(brocheLed, LOW);
          etat = REPOS;
        }
      }
      break;

    case ACTIF:
      if (distance() >= distanceSeuil + deltaSeuil) {
        digitalWrite(brocheLed, LOW);
        etat = REPOS;
      }
      break;
  }
}

merci pour la solution

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.