Lenteur de réaction - mesure de distance

[EDIT: J-M-L: ce post était mis dans le tuto de la programmation par machine à états, ce n'était pas sa place et il est mieux en tant que question à part entière

Bonjour @J-M-L et merci @fdufnews de m'avoir transmis ce super tuto.
c'est très clair pour un débutant comme moi.

Concrètement est-ce que la machine à état va me permettre à un systeme de réagir plus vite ?

==>Je fais l'acquisition de la mesure de distance sur un arduino.
Je souhaite activer des sorties en fonctions de la présence d'un objet sur plusieurs intervalles données.

Aujourd'hui j'utilise une cascade de If pour activer des leds selon la distance sauf que le temps de réponse me semble hyper lent sur de simples "digitalwrite". Comprenez : je place l'objet dans un intervalle de distance donné et la sortie idoine s'active seulement 2 voire 4 secondes plus tard. Sur une autre plage j'utilise une boucle for pour créer un chenillard, là carrement une fois dans la boucle le systeme ne consulte même plus la mesure même si l'obstacle a bougé et le systeme se reveille un dizaine de seconde plus tard

SI je devais utiliser enum sur une variable int distance associée à plusieurs plages de distance {proche , moins proche, loin} couplé avec des switch/case , je comprends que je devrais tout de même à un moment donné utilisé une cascade de if pour associer plage de mesure à chaque valeur : proche, moins proche etc...

puis executer une serie de case etc...

est-ce que cela me permettrait d'avoir un rafraichissement et une exécution plus rapide ? je sais que je n'ai pas une cart d'acquisition haute fréquence mais on doit pouvoir obtenir une réponse sous la seconde non ?

merci pour votre soutine psychologique et votre temps :slight_smile:

j'ai déplacé le post pour qu'il ait sa propre vie indépendante du tuto.


sans votre code difficile de dire ce qui ne va pas.

lisez les recommandations listées dans "Les bonnes pratiques du Forum Francophone” et postez votre code et le schéma de votre montage et donnez des infos précises sur vos composants (liens clickables = super)

bonjour, je ne pensais pas avoir une réponse aussi rapide.

Ci-dessous mon code de débutant que j'essaie même pour moi de commenter un max.
merci pour votre temps.

  =======================================================================================================================*/

#include <SoftwareSerial.h>
#include "TFMini.h"
TFMini tfmini;

//===================================================================
//=================SECTIONS DECLARATION DE VARIABLES=================

//ENTREES ARDUINO & AFFECTATION DES PINS
SoftwareSerial SerialTFMini(10, 11);
int I_BPStart = 2;
int I_PosPot_Detect = 23;
int I_PosPot_Expo = 22;
int I_PosPot_Ouie = 26;
int I_PosPot_Odorat = 28;
int I_PosPot_LL = 30;
int I_PosPot_Vue = 34;
int I_PosPot_Lorenz = 32;
int I_PosPot_Gout = 36;


//SORTIES ARDUINO & AFFECTATION DES PINS
int O_InitOK = 25; //Allumage LED confirmation bonne alimentation.
int O_Ready = 27; //Allumage LED confirmation reception BP Start.
int O_Ouie = 31;
int O_Odorat = 33;
int O_Vue = 35;
int O_Lorenzini = 37;
int O_Gout = 39;
int Verrou_74HC = 6; // (12) ST_CP [RCK] on 74HC595
int Horl_74HC = 5; // (11) SH_CP [SCK] on 74HC595
int Data_74HC = 4; // (14) DS [S1] on 74HC595


//DECLARATION VARIABLES INTERNES & AFFECTATION DE VALEURS
int Ouie = 500; //On indique la distance en dessous de laquelle nous souhaitons voir la led s'allumer
int Odorat = 300;
int LL = 100;
int Vue = 50;
int Lorenzini = 30;
int Gout = 10;
int Tare = 5;
int DelaiSens = 300;
int Delai_MExpo = 500;
int DelaiInit = 100;
byte leds_74HC = 0;

//========================================================
//=================SECTION INITIALISATION=================
void setup() // Initialisation des Variables & Fonctions du PROG.
{
  Serial.begin(115200);       //Initialisation du port serie avec Baud Rate de connexion
  while (!Serial);            // Attente de réponse du terminal série
  Serial.println ("Initializing...");
  SerialTFMini.begin(TFMINI_BAUDRATE);    //Initialisation du baud rate software
  tfmini.begin(&SerialTFMini);            //Initialisation du Capteur TFMini-S
  //réglages des types d'entrées.
  pinMode(I_BPStart, INPUT_PULLUP);
  pinMode(I_PosPot_Detect, INPUT_PULLUP);
  pinMode(I_PosPot_Expo, INPUT_PULLUP);
  pinMode(I_PosPot_Ouie, INPUT_PULLUP);
  pinMode(I_PosPot_Odorat, INPUT_PULLUP);
  pinMode(I_PosPot_LL, INPUT_PULLUP);
  pinMode(I_PosPot_Vue, INPUT_PULLUP);
  pinMode(I_PosPot_Lorenz, INPUT_PULLUP);
  pinMode(I_PosPot_Gout, INPUT_PULLUP);
  //réglages des types de sorties et mise à zéro.
  digitalWrite(O_InitOK, LOW);
  pinMode(O_InitOK, OUTPUT);
  digitalWrite(O_Ready, LOW);
  pinMode(O_Ready, OUTPUT);
  digitalWrite(O_Gout, HIGH);
  pinMode(O_Gout, OUTPUT);
  digitalWrite(O_Lorenzini, HIGH);
  pinMode(O_Lorenzini, OUTPUT);
  digitalWrite(O_Vue, HIGH);
  pinMode(O_Vue, OUTPUT);
  digitalWrite(O_Odorat, HIGH);
  pinMode(O_Odorat, OUTPUT);
  digitalWrite(O_Ouie, HIGH);
  pinMode(O_Ouie, OUTPUT);
  pinMode(Verrou_74HC, OUTPUT);
  pinMode(Horl_74HC, OUTPUT);
  pinMode (Data_74HC, OUTPUT);
}

//=======================================================================================================
//=============== SECTIONS DES SOUS-FONCTIONS APPELEES DANS LA BOUCLE PRINCIPALE "LOOP"==================

//------Fonction de récupération des valeurs du capteur TFMini-S-------//
void getTFminiData(int* distance, int* strength)
{
  static char i = 0;
  char j = 0;
  int checksum = 0;
  static int rx[9];
  if (SerialTFMini.available())
  {
    rx[i] = SerialTFMini.read();
    if (rx[0] != 0x59)
    {
      i = 0;
    }
    else if (i == 1 && rx[1] != 0x59)
    {
      i = 0;
    }
    else if (i == 8)
    {
      for (j = 0; j < 8; j++)
      {
        checksum += rx[j];
      }
      if (rx[8] == (checksum % 256))
      {
        *distance = rx[2] + rx[3] * 256;
        *strength = rx[4] + rx[5] * 256;
      }
      i = 0;
    }
    else
    {
      i++;
    }
  }
}

//------Fonction Mise à jour 74HC595-------//
void Maj_Registre_Decal()
{
  digitalWrite(Verrou_74HC, LOW);
  shiftOut(Data_74HC, Horl_74HC, LSBFIRST, leds_74HC);
  digitalWrite(Verrou_74HC, HIGH);
}


//------Fonction d'activation Sens Ligne Latérale-------//
void Activation_LigneLat()
{
  leds_74HC = 0;
  Maj_Registre_Decal();

  for (int i = 0; i < 8; i++)
  {
    bitSet(leds_74HC, i);
    Maj_Registre_Decal();
    delay(200);
  }
  leds_74HC = 0;
  Maj_Registre_Decal();
  for (int i = 7; i >= 0; i--)
  {
    bitSet(leds_74HC, i);
    Maj_Registre_Decal();
    delay(200);
  }
  leds_74HC = 0;
  Maj_Registre_Decal();
  delay(200);
}


//------Fonction d'activation du Mode de Pilotage via Detecteur de Distance (TFMini-S)-------//
void Mode_Auto()
{
  delay(DelaiInit);
  int distance = 0;
  int strength = 0;

  getTFminiData(&distance, &strength);
  while (!distance)
  {

    getTFminiData(&distance, &strength);
    if (distance)
    {
      Serial.print(distance);
      Serial.print("cm\t");
      Serial.print("strength: ");
      Serial.println(strength);

      if (distance < Gout)
      {
        LL_Activ = false;
        digitalWrite(O_Ouie, HIGH);
        digitalWrite(O_Odorat, HIGH);
        digitalWrite(O_Vue, HIGH);
        digitalWrite(O_Lorenzini, HIGH);
        digitalWrite(O_Gout, LOW);
      }
      else if  (distance > Gout  & distance < Lorenzini)
      {
        LL_Activ = false;
        digitalWrite(O_Ouie, HIGH);
        digitalWrite(O_Odorat, HIGH);
        digitalWrite(O_Vue, HIGH);
        digitalWrite(O_Lorenzini, LOW);
        digitalWrite(O_Gout, HIGH);
      }
      else if  (distance > Lorenzini && distance < Vue)
      {
        LL_Activ = false;
        digitalWrite(O_Ouie, HIGH);
        digitalWrite(O_Odorat, HIGH);
        digitalWrite(O_Vue, LOW);
        digitalWrite(O_Lorenzini, HIGH);
        digitalWrite(O_Gout, HIGH);
      }
      else if  (distance > Vue && distance < LL) //<<<<<<<<<<< c'est ici que ça chi... que ça devient complexe.
      {
        digitalWrite(O_Ouie, HIGH);
        digitalWrite(O_Odorat, HIGH);
        digitalWrite(O_Vue, HIGH);
        digitalWrite(O_Lorenzini, HIGH);
        digitalWrite(O_Gout, HIGH);
        Activation_LigneLat();
      }
      else if  (distance > LL && distance < Odorat)
      {
        LL_Activ = false;       
        digitalWrite(O_Ouie, HIGH);
        digitalWrite(O_Odorat, LOW);
        digitalWrite(O_Vue, HIGH);
        digitalWrite(O_Lorenzini, HIGH);
        digitalWrite(O_Gout, HIGH);
      }
      else if  (distance > Odorat )//&& distance < Ouie)
      {
        LL_Activ = false; 
        digitalWrite(O_Ouie, LOW);
        digitalWrite(O_Odorat, HIGH);
        digitalWrite(O_Vue, HIGH);
        digitalWrite(O_Lorenzini, HIGH);
        digitalWrite(O_Gout, HIGH);
      }

      //Pour le moniteur série
      if ( distance <= 0) {
        Serial.println("Hors de portee");

      }
    }
  }
}

  void Mode_Expo()
  {
    leds_74HC = 0;
    Maj_Registre_Decal();

    digitalWrite(O_Ouie, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Ouie, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Ouie, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Ouie, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Odorat, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Odorat, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Odorat, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Odorat, HIGH);
    delay(Delai_MExpo);
    Activation_LigneLat();
    Activation_LigneLat();
    delay(Delai_MExpo);
    digitalWrite(O_Vue, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Vue, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Vue, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Vue, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Lorenzini, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Lorenzini, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Lorenzini, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Lorenzini, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Gout, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Gout, HIGH);
    delay(Delai_MExpo);
    digitalWrite(O_Gout, LOW);
    delay(Delai_MExpo);
    digitalWrite(O_Gout, HIGH);
  }

  //===================================================================================
  //=============== SECTION DE LA BOUCLE PRINCIPALE DE TRAVAIL "LOOP"==================

  void loop()
{
  delay(DelaiInit);
  leds_74HC = 0;
  Maj_Registre_Decal();
  digitalWrite(O_InitOK, HIGH);

  if (digitalRead(I_BPStart) == HIGH)
  {
    digitalWrite(O_Ready, HIGH);

    if (digitalRead(I_PosPot_Expo) == LOW)
    {
      Mode_Expo();
    }
    else if (digitalRead(I_PosPot_Detect) == LOW)
    {
      Mode_Auto();
    }
    else if (digitalRead(I_PosPot_Ouie) == LOW)
    {
      Activation_Ouie();
    }
    else if (digitalRead(I_PosPot_Odorat) == LOW)
    {
      Activation_Odorat();
    }
    else if (digitalRead(I_PosPot_LL) == LOW)
    {
      Activation_LigneLat();
    }
    else if (digitalRead(I_PosPot_Vue) == LOW)
    {
      Activation_Vue();
    }
    else if (digitalRead(I_PosPot_Lorenz) == LOW)
    {
      Activation_Lorenzini();
    }
    else if (digitalRead(I_PosPot_Gout) == LOW)
    {
      Activation_Gout();
    }
  }
  else
  {
    digitalWrite(O_Ready, LOW);
    digitalWrite(O_Gout, HIGH);
    digitalWrite(O_Lorenzini, HIGH);
    digitalWrite(O_Vue, HIGH);
    digitalWrite(O_Odorat, HIGH);
    digitalWrite(O_Ouie, HIGH);
  }
  delay(300);
}

combien de temps met la fonction void getTFminiData(int* distance, int* strength) pour faire une mesure ?

D’après ce que je vois sur le moniteur série je dirais 1/2 secondes (2 points par seconde).

Mais ça ralenti durant les phases de transitions et quand je passe dans le cas de déclenchement « Ligne Lat » la fonction for semble stopper les acquisitions. Et la boucle for se répète même plusieurs fois alors que j’ai changé l’obstacle de place …:man_shrugging:

@aureliendu13530 visiblement tu n'as pas tout lu parce qu'on ne connait pas le matériel que tu utilises.
Et quand les propositions de réponse sont dépendantes du matériel, difficile de répondre.

C'est ce que j'appelle une mesure en "virons". :grinning:
Le viron est certes une unité très répandue, toutefois elle n'est vraiment pas scientifique.
Dire qu'il faut optimiser, oui, mais il est important de savoir d'où on part.

Un moyen de connaître le temps pris par les instructions est de configurer un timer, le lancer et lire la valeur de son compteur avant et après le déroulement d'un groupe d'instruction.

C'est très simple à faire si tu utilises un micro avr (cartes Uno, nano, pro-mini, mega).
La datasheet du micro est très simple à comprendre, l'arbre des horloges est très simple : il n'y a que le tronc donc horloge 16 MHz partout.
Lecture du registre TCNTX -> éviter de modifier le timer0 qui sert aux fonctions delay() et millis()

Pour des micros évolués comme les arm ou les Espressif où tous les sous-ensembles du micro ne tournent pas à la même fréquence, c'est "moins" simple.
Sauf peut-être à utiliser les Systclick ou tic. N'ayant pas rencontré le besoin, je n'ai pas fait beaucoup d'effort pour apprendre à m'en servir, mais il me semble que cela doit coller à ton besoin.

1 Like

Pour éclaircir les choses ce fil de discussion est la suite de celui-ci

Pour info le LIDAR (TF-Mini S) est donné pour

  • Refresh Frequency: 100Hz

Donc on doit sans doute pouvoir faire mieux que 2 points par seconde.
En fait, c'est configurable.

Oui @J-M-L , merci @fdufnews oui j’utilise un LiDAR TF Mini S avec un Arduino Mega (Clone Elegoo).

hello, le problème ce produit lorsque que tu appelles la fonction Activation_LigneLat();, laquelle en appelle d'autres...

void Activation_LigneLat()
{
  leds_74HC = 0;
  Maj_Registre_Decal();

  for (int i = 0; i < 8; i++)
  {
    bitSet(leds_74HC, i);
    Maj_Registre_Decal();
    delay(200);
  }
  leds_74HC = 0;
  Maj_Registre_Decal();
  for (int i = 7; i >= 0; i--)
  {
    bitSet(leds_74HC, i);
    Maj_Registre_Decal();
    delay(200);
  }
  leds_74HC = 0;
  Maj_Registre_Decal();
  delay(200);
}
...

//------Fonction Mise à jour 74HC595-------//
void Maj_Registre_Decal()
{
digitalWrite(Verrou_74HC, LOW);
shiftOut(Data_74HC, Horl_74HC, LSBFIRST, leds_74HC);
digitalWrite(Verrou_74HC, HIGH);
}


et il y a ça aussi qui me semble étrange
 getTFminiData(&distance, &strength);
  while (!distance)
  {

    getTFminiData(&distance, &strength);

Bonjour, j'ai jeté un œil rapide au code et le premier truc que je vois c'est le nombre astronomique de ''delay''
Ca ne serait pas déjà une cause du problème de lenteur?

Je suis débutant en programmation mais tout ces "delay" c'est pas top, non ?

1 Like

Oui jsuis en train de tout lever et de créer une machine à état :sweat_smile:

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