[resolu] Fonction millis avec heltec esp lora32 ne fonctionne pas!

Bonsoir,
je viens vers vous pour un problème que je n'arrive pas a résoudre. j'ai pourtant déjà utilisé la fonction millis dans d'autres programmes sans soucis mais là, pas moyen de la faire fonctionner.
Mon programme est pourtant tout simple
une fois le paquet lu par le récepteur lora une led s'allume et je souhaite éteindre la led après X temps.
j'ai essayé de plusieurs façon avec long ,unsigned long uint32_t, mais rien a faire soit la led reste allumé soir elle s'allume une mico seconde voire pas du tout .
le programme utilisé est l'exemple fourni par heltec légèrement modifié pour mon besoin.
A savoir que c'est ma première utilisation d'un esp32 donc je ne connais pas encore les subtilités malgré les différents tuto trouvé ici et là .

je met le code avec mon dernier test qui ne fonctionne pas non plus

#include "heltec.h"
#include "string.h"
#include "stdio.h"
#define LED 25
#define BAND    868E6  //you can set band here directly,e.g. 868E6,915E6

char Readback[50];
boolean AlarmeBox1 = false;
boolean AlarmeBox2 = false;

unsigned long temps; 
unsigned long chrono;
boolean LedOn = false;

void setup() {
  //WIFI Kit series V1 not support Vext control
  Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
  pinMode(LED, OUTPUT); 
  digitalWrite(LED, LOW);
 
}

void DisplayAlarme() {
  Heltec.display->clear();
  Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
  Heltec.display->setFont(ArialMT_Plain_16);

  if (AlarmeBox1 == true ) {
    //Heltec.display->clear();
    Heltec.display->drawString(0 , 0 , "ALARME  BOX  1");

  }
  if (AlarmeBox2 == true ) {
    // Heltec.display->clear();
    Heltec.display->drawString(0 , 34 , "ALARME  BOX  2");

  }

  Heltec.display->display();
}

void Alarme() {    // en cas d'alarme allume une led et un buzzer qui s’éteint au bout d'un temps définit 

  digitalWrite(LED, HIGH);
  boolean LedOn = true;
  //delay(3000);
  chrono = temps;
Serial.println("led on");           // Affiche bien led on sur le moniteur 

   if (temps - chrono >= 3000L && LedOn == true)    //        <---------------     ne fonctionne pas  ??? 
  {
    Serial.println("Fin de chrono");
    digitalWrite(LED, LOW);
     LedOn = false ;
    //temps = millis();
  
}
}


void loop() {
  

  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");
    // read packet
    while (LoRa.available()) {
      sprintf(Readback + strlen(Readback), "%c", (char)LoRa.read());
    }
    Serial.print(Readback);

    if (strncmp(Readback, "Box1", strlen(Readback)) == 0) {
      AlarmeBox1 = true;
      DisplayAlarme();
      Alarme();

    }

    else if (strncmp(Readback, "Box2", strlen(Readback)) == 0) {
      AlarmeBox2 = true;
      DisplayAlarme();
      Alarme();

    }
    memset(Readback, 0, 50);
    // print RSSI of packet
    Serial.print(" with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

Merci de votre aide .

Dans cette portion de code:

  1. temps ne change jamais
  2. tu fais temps = chrono donc la condition temps - chrono >= 3000L ne peut jamais être remplie
  3. tu ne repasses jamais plus dans cette fonction puisque le seul appel à Alarme() ne se produit que lorsque tu reçois le message "Box1" ou "Box2", donc tu n'as aucune chance d'éteindre la LED.
  4. A aucun endroit AlarmeBox1 et AlarmeBox2 ne sont remis à false

Il faudrait avoir :

  • une fonction qui serait appelée lorsqu'une alarme arrive qui active la LED
  • une fonction qui serait appelée à chaque itération de loop() lorsqu'une alarme est active et qui se chargerait de vérifier si la temporisation s'est écoulée.

tu ne repasses jamais plus dans cette fonction puisque le seul appel à Alarme() ne se produit que lorsque tu reçois le message "Box1", donc tu n'as aucune chance d'éteindre la LED
alors oui je ne passe qu'une fois dans la fonction c'est un peut le but mais pourquoi je n'aurais aucune chance d’éteindre la led ?

Parce que c'est dans Alarme que tu fais le test pour éteindre la LED.

Et ça doit être dans le loop .
faut que je revois la façon de faire le code alors !
edit:
Bon j'ai enfin réussi
j'ai simplement ajouter un if alarme box 1 dans le loop qui renvois sur mon void alarme dans lequel j'ai refais toute ma tempo.

je passe donc a la suite de mon programme .

Merci fdufnews.

ça semble un peu spaghetti tout cela...

un peu de remise en forme, ça donnerait cela

#include <heltec.h>
const byte ledPin = 25;
#define BAND    868E6  //you can set band here directly,e.g. 868E6,915E6

const size_t tailleMaxMessage = 50;
char message[tailleMaxMessage + 1];

unsigned long chrono;
boolean ledIsOn = false;

void DisplayAlarme(int alarmNb) {
  Serial.print("Alarme #"); Serial.println(alarmNb);
  Heltec.display->clear();
  if (alarmNb == 1) Heltec.display->drawString(0 , 0 , "ALARME  BOX  1");
  else if (alarmNb == 2) Heltec.display->drawString(0 , 34 , "ALARME  BOX  2");
  Heltec.display->display();
  digitalWrite(ledPin, HIGH);
  ledIsOn = true;
  chrono = millis();
}

void gestionAlarme() {
  if (LoRa.parsePacket() != 0) {
    size_t i = 0;
    while (LoRa.available() && i < tailleMaxMessage) message[i++] = (char)LoRa.read();
    message[i] = '\0';
    Serial.println(message);

    if (strncmp(message, "Box1", 4) == 0) DisplayAlarme(1);
    else if (strncmp(message, "Box2", 4) == 0) DisplayAlarme(2);
    else Serial.println("message non reconnu");
  }

  // si la LED avait été allumée, on force l'extinction au bout de 3s
  if (ledIsOn && millis() - chrono >= 3000ul) {
    digitalWrite(ledPin, LOW);
    ledIsOn = false;
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
  Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
  Heltec.display->setFont(ArialMT_Plain_16);
}

void loop() {
  gestionAlarme();
}

(tapé ici, non vérifié)

ça semble un peu spaghetti tout cela...

Je fait ce que je peux je suis pas un pro de la programmation :sweat_smile:
j'ai juste repris l'exemple de heltec "led_control_lora_r" ou j'ai modifier quelque lignes .
C'est sur que ton programme a l'air bien mieux ordonné et fait plus pro, ce qui est loin d’être mon cas .
Je vais regarder ça de près et voir si je peux m'en inspirer .
Merci.

C’est l’objectif - vous donner une piste de travail.

L’idée pour la timing c’est que vous devez gérer cela en permanence, donc dans la loop(), indépendamment du fait que vous ayez reçu un message ou pas.

➜ d’où le test sur la led et millis qui est effectué à chaque fois dans la fonction de gestion.

Oui c'est mon erreur, je pensais que le timing se faisait à la suite dans le void sans avoir besoin d'être dans le loop. Le pire c'est que Je m'était déjà fait bouillir le cerveau sur un problème similaire.
Il me reste donc toute la gestion de l'affichage à faire et mettre un bp pour la réinitialisation.
A l'avenir je verrais peut être pour faire une communication en duplex avec les deux modules.. Mais ça c'est pour plus tard.
Encore merci pour l'aide apporté.

un void ça n'existe pas. on dit une fonction :slight_smile:
void c'est un type ou un mot clé pour dire "rien du tout"

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