Go Down

Topic: Qu'est ce qui ne va pas dans mon sketch ? (Read 1 time) previous topic - next topic

FRIDA24

Bonsoir les Arduinautes,
Y aurait-il quelqu'un qui puisse me dire pourquoi mon code ne fonctionne pas comme je voudrais,
malgré que je travaille dessus depuis 3 jours.

Ce que je cherche, c'est que si le détecteur a ultra-sons détecte un obstacle, une led s'allume pendant 3 secondes , puis s'éteint, en utilisant la fonction millis,car je voudrais que mon code ne soit pas bloquant.
Bien sur, j'ai regarder " le sketch,  blink an LED. " , mais il marche pour une durée de l'intervalle, et non une durée d'allumage de ma led..; J'ai essayé de le manipuler dans tous les sens , mais ça veut pas  >:(

Aussi je fais appel à vous.
Merci d'avance
Mon code:



Code: [Select]

#include <Wire.h>
#include <NewPing.h>

const int ledPin = 11;
int ledState = HIGH;  // ledState HIGH correspondant à  LED  ETEINTE

int trig1 = 4;
int echo1 = 5;
long lecture_echo;
long cm1;

// État d'activation de la tempo
int tempoActive = 0;

// Temps à l'activation de la tempo
unsigned long tempoDepart = 0;

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

  pinMode(trig1, OUTPUT);
  digitalWrite(trig1, LOW);
  pinMode(echo1, INPUT);
 pinMode(ledPin, OUTPUT);
}

void loop() {

  digitalWrite(trig1, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig1, LOW);
  lecture_echo = pulseIn(echo1, HIGH);
  cm1 = lecture_echo / 58;
  Serial.print("Distance : ");
  Serial.println(cm1);
  delay(20);

  if (cm1 < 11) {
    ledState = LOW;
  }

 // Alors on active la temporisation
     tempoActive = 1;
     tempoDepart = millis();

  // Si la temporisation est active,
      if ( tempoActive  ) {

  // Et si il s'est écoulé 3 secondes,
      if ( ( millis() - tempoDepart ) >= 3000 ) {

  // Et on désactive la temporisation pour ne pas afficher ce message une seconde fois
      tempoActive = 0;
  }
  }
  else  ledState = HIGH;
  }


Alain46

Code: [Select]

tempoActive = 1;


      if ( tempoActive  ) {
      }


La variable tempoActive est forcée à la valeur 1 à chaque tour de la boucle loop()

Donc le test if( tempoActive) est toujours vrai

Nota : utilise l'indentation automatique de l'Ide Arduino (Ctrl+T) pour rendre ton code plus lisible

Un programme qui se compile sans erreur n'est pas forcément un programme qui fonctionne.

J-M-L

#2
Oct 17, 2018, 07:29 am Last Edit: Oct 17, 2018, 07:32 am by J-M-L
C'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement, vous y verrez comment gérer le temps pour une extinction automatique)

Sinon vous n'êtes pas très loin, il faut que le drapeau tempoActive soit mis à vrai  uniquement quand vous allumez la LED (et ne pas la rallumer si elle l'est déjà à moins que vous ne souhaitiez que la LED reste allumée 3s après la dernière détection)
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

FRIDA24

Bonsoir,
Après quelques soirées à essayer de résoudre le problème, je vous soumet le code rectifié,suite aux bons conseils qui m'ont étés formulés.
Je vous rappelle que je désire que la Led s'allume simplement  pendant 3 secondes quand la distance à un obstacle devient inférieure à 11 cms.
J'ai utilisé l'indentation automatique de l'Ide Arduino (Ctrl+T)


Code: [Select]

#include <Wire.h>
#include <NewPing.h>

const int ledPin = 11;
int ledState = HIGH;  // ledState HIGH correspondant à  LED  ETEINTE

int trig1 = 4;
int echo1 = 5;
long lecture_echo;
long cm1;

// État d'activation de la tempo
int tempoActive = 0;

// Temps à l'activation de la tempo
unsigned long tempoDepart = 0;

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

  pinMode(trig1, OUTPUT);
  digitalWrite(trig1, LOW);
  pinMode(echo1, INPUT);
  pinMode(ledPin, OUTPUT); // à ce stade la led est automatiquement allumée (car ledPin output allume la led)
  digitalWrite(ledPin, HIGH);  // on éteint donc la led
}

void loop() {

  digitalWrite(trig1, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig1, LOW);
  lecture_echo = pulseIn(echo1, HIGH);
  cm1 = lecture_echo / 58;
  Serial.print("Distance : ");
  Serial.println(cm1);
  delay(20);

  if (cm1 < 11) {
    if ( ledState = HIGH) { // si led est eteinte
      // Alors on allume la led et on active la temporisation
      digitalWrite(ledPin, LOW)&& tempoActive = 1;
    }
    if ( ledState = LOW) {
      tempoActive = 0; // si la led est allumée , on ne fait rien
    }
    tempoDepart = millis();  // on note le temps de départ


    if ( tempoActive  ) {   // Si la temporisation est active,


      if ( ( millis() - tempoDepart ) >= 3000 ) {  // Et si il s'est écoulé 3 secondes,
        ledState = HIGH; // on éteint la led

        tempoActive = 0;// Et on désactive la temporisation pour ne pas recommencer  une seconde fois
      }
    }
  }

else  ledState = HIGH; //  si la distance est superieure à 11 cm , on laisse la led éteinte , qu'elle soit  allumée ou éteinte auparavant
}



Mais quand je compile il apparait le message suivant :

  " Exit status1
could not convert 'digitalwrite (11u, ou)' from 'void' to 'bool'  "
si je comprend , on ne peut pas convertir 2 choses différentes entre elles, comme des chaussettes et des éléphants ...ce que je conçois aisément , mais comment faire  :o 


Je voudrai comprendre comment m'en sortir, y aurait il une âme charitable qui puisse me montrer un exemple de code pour que je puisse comprendre comment faire?
Quand j'aurai compris quel code utilisé, je ferais avec la machine à états , car le tuto m'a paru Super ; :)
Un grand merci à tous .
Frida




J-M-L

#4
Oct 21, 2018, 10:55 pm Last Edit: Oct 21, 2018, 11:03 pm by J-M-L
Pour votre erreur... Prenez l'habitude de faire les choses correctement... pourquoi un && dans ce code?
Code: [Select]
digitalWrite(ledPin, LOW)&& tempoActive = 1;un point virgule entre les deux expressions suffirait à les séparer en 2 instructions et pas essayer de faire une opération booléenne (qui n'est pas possble car le digitalWrite ne retourne rien)

Code: [Select]
if ( ledState = HIGH) { // si led est eteinteOooopssss
Code: [Select]
if ( ledState = LOW) {...Re-Oooooopppppsss
(Attention = n'est pas la même chose que ==)

Sinon attention ledState = HIGH; // on éteint la led ne va pas éteindre la LED... faut faire un digitalWrite pour cela
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

FRIDA24

Bonsoir J-M-L,
D'abord merci beaucoup pour votre aide qui m'est précieuse.
J'ai donc corrigé selon vos remarques.
Voici mon code corrigé:

Code: [Select]



#include <Wire.h>
#include <NewPing.h>

const int ledPin = 11;
int ledState = HIGH;  // ledState HIGH correspondant à  LED  ETEINTE

int trig1 = 4;
int echo1 = 5;
long lecture_echo;
long cm1;

// État d'activation de la tempo
int tempoActive = 0;

// Temps à l'activation de la tempo
unsigned long tempoDepart = 0;

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

  pinMode(trig1, OUTPUT);
  digitalWrite(trig1, LOW);
  pinMode(echo1, INPUT);
  pinMode(ledPin, OUTPUT); // à ce stade la led est automatiquement allumée (car ledPin output allume la led)
  digitalWrite(ledPin, HIGH);  // on éteint donc la led
}

void loop() {

  digitalWrite(trig1, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig1, LOW);
  lecture_echo = pulseIn(echo1, HIGH);
  cm1 = lecture_echo / 58;
  Serial.print("Distance : ");
  Serial.println(cm1);
  delay(20);
  if ( ledState == HIGH) { // si led est eteinte

    if (cm1 < 11) {
      digitalWrite(ledPin, LOW ); tempoActive = 1; // Alors on allume la led et on active la temporisation
      tempoDepart = millis();
    }
    if ( ( millis() - tempoDepart ) >= 3000 ) {  // Et si il s'est écoulé 3 secondes,
      digitalWrite(ledPin, HIGH );   // on éteint la led
      // Et on désactive la temporisation
      tempoActive = 0;
    }
  }

  else  ledState == HIGH; //  si la distance est superieure à 11 cm , on laisse la led éteinte , qu'elle soit  allumée ou éteinte auparavant
}





Reste encore un soucis :
La led reste allumée tant que la distance est inférieure à 11 cms, puis quand la distance devient supérieure à 11 cms, elle attend 3 secondes et s'éteint.
Ce n'est pas ce que je désire, comme indiqué plus haut, il faudrait que la led s'allume dès que la distance lue est inférieure à 11 cms , et s'éteigne au bout de 3 secondes ( que la distance lue reste inférieure à 11 cms, ou qu'elle soit devenue supérieure )


Merci de m'expliquer ce qui se passe et quelle solution est à mettre en œuvre .


Bonne soirée


Frida

ps Tous les commentaires des membres de ce forum sont les bienvenus  :)





J-M-L

À quoi sert #include <NewPing.h> ? Vous avez abandonné ?

Pour votre question, cf le post #2

Sinon comme déjà dit l'affectation de la variable ledState sans digitalWrite associé ne change pas l'état de La LED...
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

bidouilleelec

Bonjour FRIDA24
Bonsoir J-M-L,
D'abord merci beaucoup pour votre aide qui m'est précieuse.
Vous n'avez pas vraiment l'air d'entendre J-M-L:

1/
Code: [Select]

else  ledState == HIGH;


n'a pas de sens dans votre contexte. Je suis même surpris qu'il n'y ait pas au moins un message d'alerte à la compilation. MAIS , avec le compilateur de l'IDE arduino !?!?!?!?

Vous confondez
=           opérateur d'affectation   :  x = y  --> on met la valeur de y dans x
et
==         opérateur de comparaison utile dans un if  : x == y  est VRAI si x = y sinon FAUX

2/C'est uniquement un digitalWrite qui peut changer l'état de la led.

3/ Plutôt que vous lancer dans l'écriture (je suppose directement au clavier) dans une suite de if then else if and not else  if not.... rapidement illisible:
Pourquoi ne pas utiliser une "machine à états" ?
J-M-L vous a donné le lien de son tutorial.

Ce n'est pas synonyme de "usine à gaz" , bien au contraire.

Cordialement,
bidouilleelec


J-M-L

#8
Oct 23, 2018, 06:20 am Last Edit: Oct 23, 2018, 06:21 am by J-M-L
Bonjour FRIDA24
Vous n'avez pas vraiment l'air d'entendre J-M-L:
C'est un peu mon sentiment de parler dans le vide sidréal...

Code: [Select]

else  ledState == HIGH;
n'a pas de sens dans votre contexte.
Tout à fait....

Je suis même surpris qu'il n'y ait pas au moins un message d'alerte à la compilation.
l'expression est syntaxiquement et sémantiquement correcte, elle n'a juste pas d'effet donc sera virée par l'optimiseur.

MAIS , avec le compilateur de l'IDE arduino !?!?!?!?
la chaîne de compilation de l'IDE est GCC, un des compilateur le plus utilisé et performant au monde. c'est simplement lié aux options de compilation et niveau de warning que l'on veut. (À noter que LLVM Clang C/C++ est en train de rattraper la perf de GCC et offre des avantages sur GCC en terme de debug)

Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

bidouilleelec

 Bonsoir J-M-L

C'est un peu mon sentiment de parler dans le vide sidréal...

Tant pis pour moi : sidéral ou cidréal. Oups.
Quand aux options d'optimisation,  heu!, heu?
Certaines curieuses optimisations ( weird loop.........)........

Cordialement,
bidouilleelec

J-M-L

#10
Oct 23, 2018, 10:49 pm Last Edit: Oct 23, 2018, 10:49 pm by J-M-L
ça s'adressait À l'OP pour le vide..
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

FRIDA24

Bonsoir,
N'arrivant pas à trouver la bonne solution, le code que je vous ai reposter, présentait des morceaux que je n'arrive pas à formuler correctement, que j'ai formuler comme j'ai pu,dans le but que vous m'aidiez à le rendre correct.....
Ce que vous m'avez répondu n'est pas sympa, je sais que l'enseignement et l'aide au débutants, qui rament, vous prennent beaucoup de votre temps , n'est pas facile, et demande de se répéter, et c'est en cela que je trouve (et encore maintenant ) votre aide précieuse.
Si vous le voulez bien, reprenons au début:

Vous m'avez écrit :
Sinon vous n'êtes pas très loin, il faut que le drapeau tempoActive soit mis à vrai  uniquement quand vous allumez la LED (et ne pas la rallumer si elle l'est déjà )

Comment faire pour que  le drapeau tempoActive soit mis à vrai  uniquement quand j' allume la LED , et ne pas la rallumer si elle l'est déjà ?
Je ne vois pas comment transcrire ça en code .(j'ai essayer avec un digitalWrite, ça ne veut pas...,)


Pour ce qui est de la machine à états, j'aurai aimé comprendre comment ce sketch fonctionne, avant de me lancer dans cette 2ème solution .
J'ai regarder , et l'ai étudié un peu, et où je bloque, c'est le fait que " Vous déclarez un objet bouton en précisant sur quelle pin il est connecté et s'il est actif à l'état High ou Low " et On déclare ensuite une fonction de call back

void simpleclick()
{
... // le code à exécuter quand on fait un click sur le bouton
}  "

Or dans mon cas , il ne me semble pas y avoir un état High ou Low , mais un capteur ultrason qui detecte la distance et fait agir en conséquence (meme si ça fait passer a l'etat haut ou bas), mais je ne vois pas comment m'y prendre.
Espérant encore pouvoir compter sur vous

Frida

J-M-L

Désole si je vous ai choqué - pas l'objectif - l'idée c'est de vous donner des indices et que vous essayez par vous même

Vous devez faire un && entre deux conditions ou deux if à la suite
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

FRIDA24

Bonjour,
Voici ce que j'ai fait, ( avant que vous me répondiez ) pour essayer d'améliorer.

Code: [Select]

#include <Wire.h>
#include <NewPing.h>

/* Partie "capteur ULTRASON"  */
int trig1 = 4;
int echo1 = 5;
long lecture_echo;
long cm1;

/* Partie "LED" */
const byte LEDPin = 11;
boolean ledEteinte;

/* Partie temporisation */
unsigned long previousMillis = 0;
int interval = 20000;

void setup() {
  Serial.begin(9600);
  pinMode(trig1, OUTPUT);
  pinMode(echo1, INPUT);
  pinMode(LEDPin, OUTPUT);
  pinMode(trig1, OUTPUT);
  digitalWrite(LEDPin, HIGH); // éteinte
  ledEteinte = true;
}

void loop() {
  digitalWrite(trig1, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig1, LOW);
  lecture_echo = pulseIn(echo1, HIGH);
  cm1 = lecture_echo / 58;
  Serial.print("Distance : ");
  Serial.println(cm1);
  delay(20);

  if (cm1 < 11) {               // distance<11cm
    digitalWrite(LEDPin, LOW);    // allumée
  }
  if (cm1 < 40000) {  // distance superieure au possibilités de détection
    unsigned long currentMillis = millis();
    if ((unsigned long)(currentMillis - previousMillis) >= interval)
    {
      digitalWrite(LEDPin, HIGH);
      // previousMillis = currentMillis;
    }
  }
}



L'INTERVALLE EST + COURT QUE CE QUE JE METS COMME DURÉE POUR " INTERVAL " 


Et en effet , la led s'allume bien 1 fois, même si le capteur s'éloigne de + de 11 cms, c'est ce que je veux.
Cependant, je suis étonnée que la durée pendant laquelle la led est allumée soit de 'environ' la moitié de la durée fixée par "interval" ...Je ne vois pas à quoi c'est dû ?

De plus ce code n'est certainement pas parfait...


Merci de me conseiller en me  donnant  des indices.
Cordialement   :)
Frida






















J-M-L

Commencez par nettoyer un peu le début du programme en utilisant les bons types et en virant NewPing puisque vous avez décidé de ne pas l'utiliser. J'en ai profité aussi pour renommer les constantes qui désignent des numéros de pin pour rajouter "pin" dans le nom. c'est plus lisible.


Code: [Select]
/* Partie "capteur ULTRASON"  */
const byte trigPin = 4;
const byte echoPin = 5;
long lecture_echo;
long cm1;

/* Partie "LED" */
const byte LEDPin = 11;
boolean ledEteinte;

/* Partie temporisation */
unsigned long previousMillis = 0;
unsigned long intervalle = 20000ul;


ensuite y'a des choses que je ne comprends pas:

pourquoi en mette la pin de la LED à LOW ça va l'allumer?
Code: [Select]
  if (cm1 < 11) {               // distance<11cm
    digitalWrite(LEDPin, LOW);    // allumée
  }
comment est-ce câblé?

sinon dans ce code:
Code: [Select]
  if (cm1 < 40000) {  // distance superieure au possibilités de détectionje ne suis pas sûr que < soit le bon symbole notamment en fonction du commentaire...


et là
Code: [Select]
      // previousMillis = currentMillis;pourquoi est-ce en commentaire? qui va mettre à jour previousMillis ?





je reprends ce que je disais plus haut la boucle doit:

1. lire la distance
2. regarder si la distance est inférieur à 11
3. si OUI, 2 possibilités. elle était déjà inférieure à 11 avant ou pas (donc il faut une variable pour mémoriser cela)

--> que devez vous faire si elle était déjà inférieure avant ?
--> que devez vous faire si c'est la première fois que la distance devient inférieure à 11?

Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

Go Up