probleme fiabilité programme

bonjour à tous, j ai un programme tout bete une entrée et une sortie

on saisie une valeur de decalage et une valeur de durée via les bouton de l ecran

des le front montant de l entrée, on applique le temps de decalage, on active la sortie pendant le temps de la durée, puis on recommence

l operation marche 9 fois sur 10, et 1 fois sur 10 il bloque sur l etape g1=10 ou g1=20, au hasard

voici le programme

machine_a_feutre.ino (7.2 KB)

j oubliais, la sortie est un relais 5v

et l entrée est un inter, pour eviter d'avoir une patte en l air, j ai mis une resistance de 10k entre la masse et l entrée, et l'inter commute avec le 5v

l'alimentation de l arduino est par l usb en 5v

Postez directement le code (en utilisant les balises de code)- peut pas le lire sur mobile

ok voici:

include <LiquidCrystal.h>

// Variables pour utiliser l'ecran
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Definir les pins utilisees par le LCD
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

#define indiceDuree 0
#define indiceDecalage 1

// Variables du programme Adrien
// ENTREES
#define ENTREE 11

// SORTIES
#define SORTIE 12

int g1 = -10;

float duree = 4.0;
float decalage = 3.0;

/************************************************************************************************************/
// Fonction lire les boutons
/************************************************************************************************************/
int read_LCD_buttons()
{
  adc_key_in = analogRead(0); // Lire les valeurs du capteurs
  // Les valeurs renvoyees sont sensees etre: 0, 144, 329, 504, 741
  // Il y a une erreur possible de 50
if (adc_key_in > 1000) return btnNONE; // Nous découpons les valeurs possibles en zone pour chaque bouton
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 144) return btnUP;
if (adc_key_in < 329) return btnDOWN;
if (adc_key_in < 504) return btnLEFT;
if (adc_key_in < 741) return btnSELECT;
  return btnNONE; // On renvoie cela si l'on est au dessus de 850
}

/************************************************************************************************************/
// Fonction qui retourne l'identifiant du bouton appuye
// Retourne btnNONE si pas d'appui bouton
// Attention : ce test est bloquant pendant 100ms
/************************************************************************************************************/
int getButton()
{
  int button = btnNONE;
  int nbCheckButton = 2;

  // On teste 2x si on a un appui sur un bouton
  // les 2 tests sont espaces de 100ms (anti-rebonds)
  // Si on a 2x le meme bouton, on retourne l'identifiant du bouton
  for (int i = 0; i < nbCheckButton; i++)
  {
    lcd_key = read_LCD_buttons(); // Lire les boutons
    switch (lcd_key) // Selon le bouton appuyer
    {
      case btnRIGHT:
      case btnLEFT:
      case btnUP:
      case btnDOWN:
      case btnSELECT:
        {
          if (button == btnNONE)
          {
            button = lcd_key;
            delay(200) ; // temps de filtrage anti-rebonds
          }
          else if (lcd_key == button)
          {
            return button;
          }
          break;
        }
      default:
        {
          // Pas un bouton valide -> on quitte
          return btnNONE;
        }
    }
  }
  return btnNONE; // on quitte avant, mais par securite...
}

float unite = 1.0;
float valeur = decalage;
/************************************************************************************************************/
// Fonction 
/************************************************************************************************************/
bool setNombreDecimal(int indice)
{
  bool retour = false;
  char bufValue[50];

  lcd.setCursor(0, 0); // Placer le curseur au debut de la 1ere ligne
  if (indice == indiceDuree)
  {
    valeur = duree;
    if(unite == 1.0)
    {
      lcd.print("duree +/- 1.0   ");
    }
    else
    {
      lcd.print("duree +/- 0.1   ");
    }
  }
  else
  {
    valeur = decalage;
    if(unite == 1.0)
    {
      lcd.print("decalage +/- 1.0");
    }
    else
    {
      lcd.print("decalage +/- 0.1");
    }
  }
  lcd.setCursor(0, 1); // Placer le curseur au debut de la 2eme ligne
  dtostrf(valeur, 2, 1, bufValue);
  lcd.print(bufValue);

  int button = getButton();
  switch (button) // Selon le bouton appuye
  {
    case btnRIGHT: // Pour le bouton "Right"
      {
        lcd.setCursor(0, 0); // Placer le curseur au debut de la seconde ligne
        unite = 0.1;
        if(indice == indiceDuree)
        {
          lcd.print("duree +/- 0.1");
        }
        else
        {
          lcd.print("decalage +/- 0.1");
        }
        break;
      }
    case btnLEFT: // Pour le bouton "Left"
      {
        lcd.setCursor(0, 0); // Placer le curseur au debut de la seconde ligne
        unite = 1.0;
        if(indice == indiceDuree)
        {
          lcd.print("duree +/- 1.0");
        }
        else
        {
          lcd.print("decalage +/- 1.0");
        }
        break;
      }
    case btnDOWN: // Pour le bouton "Down"
      {
        valeur -= unite;
        if (valeur <= 0.1)
        {
          valeur = 0.1;
        }
        lcd.setCursor(0, 1); // Placer le curseur au debut de la 2eme ligne
        dtostrf(valeur, 2, 1, bufValue);
        lcd.print(bufValue);
        break;
      }
    case btnUP: // Pour le bouton "Up"
      {
        valeur += unite;
        if (valeur > 9.9)
        {
          valeur = 9.9;
        }
        lcd.setCursor(0, 1); // Placer le curseur au debut de la 2eme ligne
        dtostrf(valeur, 2, 1, bufValue);
        lcd.print(bufValue);
        break;
      }
    case btnSELECT: // Pour le bouton "Select"
    {
      retour = true;
      break;
    }
    default:
    {
      break;
    }
  }
  
  if (indice == indiceDuree)
  {
    duree = valeur;
  }
  else
  {
    decalage = valeur;
  }
  return retour;
}

int temps0 = millis();
int temps1 = millis();

/************************************************************************************************************/
// FONCTION D'INITIALISATION
/************************************************************************************************************/
void setup()
{
  lcd.begin(16, 2); // Demarrer la librairie ecran
  
  //pinmode
  pinMode(ENTREE, INPUT);
  pinMode(SORTIE, OUTPUT);
  digitalWrite(SORTIE, HIGH);
}

void loop()
{
  if(g1 >= 0)
  {
    char buf[255];
    lcd.setCursor(0, 0);
    sprintf(buf, "g1=%d", g1);
    lcd.print(buf);
  }
  
  if(g1 == -10)
  {
    // on définit le décalage
    if(setNombreDecimal(indiceDecalage))
    {
      g1 = -5;
    }
  }
  else if(g1 == -5)
  {
    // on définit la duree
    if(setNombreDecimal(indiceDuree))
    {
      g1 = 0;   
      /*²   
      lcd.setCursor(0, 0);
      lcd.print("attente signal  ");
      lcd.setCursor(0, 1);
      lcd.print("                ");
      */
    }
  }
  else if((g1 == 0) && (digitalRead(ENTREE) == HIGH))
  {
    // anti-rebond sur l'entrée : on lit 2x l'entrée à 10ms d'intervalle
    delay(100);
    if (digitalRead(ENTREE) == HIGH)
    {
      
      temps0 = millis();
      g1 = 10;
      /*
      lcd.setCursor(0, 0);
      lcd.print("signal detecte  ");
      lcd.setCursor(0, 1);
      lcd.print("attente depart  ");
      */
    }
  }
  else if((g1 == 10) && (millis() > temps0 + int(decalage*1000)))
  {
    digitalWrite(SORTIE, LOW);
    temps1 = millis();
    g1 = 20;
    /*
      lcd.setCursor(0, 0);
      lcd.print("sortie active  ");
      lcd.setCursor(0, 1);
      //lcd.print("duree en cours ");
      lcd.print((millis() - temps1 + int(duree*1000)));
      */
  }
  else if((g1 == 20) && (millis() > temps1 + int(duree*1000)))
  {
    digitalWrite(SORTIE, HIGH);
    if(digitalRead(ENTREE) == LOW)
    {
      // anti-rebond sur l'entrée : on lit 2x l'entrée à 10ms d'intervalle
      delay(100);
      if (digitalRead(ENTREE) == LOW)
      {
        g1 = 0;
      /*
      lcd.setCursor(0, 0);
      lcd.print("attente signal  ");
      lcd.setCursor(0, 1);
      lcd.print("                ");
      */
      }
    }
  }
} // fin loop()

le type de vos variables n’est pas bon

int temps0 = millis();
int temps1 = millis();

et ...millis() > temps0 + int(decalage*1000)) va faire n’importe quoi au bout de 36 secondes environ sur un UNO ou similaire (int sur 16 bits)... passez en unsigned long et on teste toujours par soustraction if (millis() - t0 > duree) {...} pour ne pas avoir de soucis quand millis() retourne à 0 (au bout de 49 jours, 17 heures et quelques)

N’oubliez pas que vous avez peu de SRAM.. 255 me semble exagéré dans ce code

if(g1 >= 0)
  {
    char buf[255];
    lcd.setCursor(0, 0);
    sprintf(buf, "g1=%d", g1);
    lcd.print(buf);
  }

et surtout le buffer ne sert à rien d’utile, vous devriez faire

if(g1 >= 0)
  {
    lcd.setCursor(0, 0);
    lcd.print("g1=“);
    lcd.print(g1);
   }

tout simplement

Votre gestion de l’anti-rebond est à revoir : 100 ou 200ms d’attente va tuer la réactivité de votre programme - 15 à 20ms suffit généralement pour la majorité des boutons. un front suffit pour savoir si le bouton a été appuyé (en supposant que vous ayez une résistance de pull down sur votre bouton) et au prochain front, s’il a lieu dans les 15 à 20ms suivantes alors vous l’ignorez. la fonction getButton() est à revoir

est ce que cette nouvelle version vous convient mieux:

include <LiquidCrystal.h>

// Variables pour utiliser l'ecran
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Definir les pins utilisees par le LCD
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

#define indiceDuree 0
#define indiceDecalage 1

// Variables du programme Adrien
// ENTREES
#define ENTREE 11

// SORTIES
#define SORTIE 12

int g1 = -10;

float duree = 4.0;
float decalage = 3.0;

/************************************************************************************************************/
// Fonction lire les boutons
/************************************************************************************************************/
int read_LCD_buttons()
{
  adc_key_in = analogRead(0); // Lire les valeurs du capteurs
  // Les valeurs renvoyees sont sensees etre: 0, 144, 329, 504, 741
  // Il y a une erreur possible de 50
if (adc_key_in > 1000) return btnNONE; // Nous découpons les valeurs possibles en zone pour chaque bouton
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 144) return btnUP;
if (adc_key_in < 329) return btnDOWN;
if (adc_key_in < 504) return btnLEFT;
if (adc_key_in < 741) return btnSELECT;
  return btnNONE; // On renvoie cela si l'on est au dessus de 850
}

/************************************************************************************************************/
// Fonction qui retourne l'identifiant du bouton appuye
// Retourne btnNONE si pas d'appui bouton
// Attention : ce test est bloquant pendant 100ms
/************************************************************************************************************/
int getButton()
{
  int button = btnNONE;
  int nbCheckButton = 2;

  // On teste 2x si on a un appui sur un bouton
  // les 2 tests sont espaces de 100ms (anti-rebonds)
  // Si on a 2x le meme bouton, on retourne l'identifiant du bouton
  for (int i = 0; i < nbCheckButton; i++)
  {
    lcd_key = read_LCD_buttons(); // Lire les boutons
    switch (lcd_key) // Selon le bouton appuyer
    {
      case btnRIGHT:
      case btnLEFT:
      case btnUP:
      case btnDOWN:
      case btnSELECT:
        {
          if (button == btnNONE)
          {
            button = lcd_key;
            delay(15) ; // temps de filtrage anti-rebonds
          }
          else if (lcd_key == button)
          {
            return button;
          }
          break;
        }
      default:
        {
          // Pas un bouton valide -> on quitte
          return btnNONE;
        }
    }
  }
  return btnNONE; // on quitte avant, mais par securite...
}

float unite = 1.0;
float valeur = decalage;
/************************************************************************************************************/
// Fonction 
/************************************************************************************************************/
bool setNombreDecimal(int indice)
{
  bool retour = false;
  char bufValue[50];

  lcd.setCursor(0, 0); // Placer le curseur au debut de la 1ere ligne
  if (indice == indiceDuree)
  {
    valeur = duree;
    if(unite == 1.0)
    {
      lcd.print("duree +/- 1.0   ");
    }
    else
    {
      lcd.print("duree +/- 0.1   ");
    }
  }
  else
  {
    valeur = decalage;
    if(unite == 1.0)
    {
      lcd.print("decalage +/- 1.0");
    }
    else
    {
      lcd.print("decalage +/- 0.1");
    }
  }
  lcd.setCursor(0, 1); // Placer le curseur au debut de la 2eme ligne
  dtostrf(valeur, 2, 1, bufValue);
  lcd.print(bufValue);

  int button = getButton();
  switch (button) // Selon le bouton appuye
  {
    case btnRIGHT: // Pour le bouton "Right"
      {
        lcd.setCursor(0, 0); // Placer le curseur au debut de la seconde ligne
        unite = 0.1;
        if(indice == indiceDuree)
        {
          lcd.print("duree +/- 0.1");
        }
        else
        {
          lcd.print("decalage +/- 0.1");
        }
        break;
      }
    case btnLEFT: // Pour le bouton "Left"
      {
        lcd.setCursor(0, 0); // Placer le curseur au debut de la seconde ligne
        unite = 1.0;
        if(indice == indiceDuree)
        {
          lcd.print("duree +/- 1.0");
        }
        else
        {
          lcd.print("decalage +/- 1.0");
        }
        break;
      }
    case btnDOWN: // Pour le bouton "Down"
      {
        valeur -= unite;
        if (valeur <= 0.1)
        {
          valeur = 0.1;
        }
        lcd.setCursor(0, 1); // Placer le curseur au debut de la 2eme ligne
        dtostrf(valeur, 2, 1, bufValue);
        lcd.print(bufValue);
        break;
      }
    case btnUP: // Pour le bouton "Up"
      {
        valeur += unite;
        if (valeur > 9.9)
        {
          valeur = 9.9;
        }
        lcd.setCursor(0, 1); // Placer le curseur au debut de la 2eme ligne
        dtostrf(valeur, 2, 1, bufValue);
        lcd.print(bufValue);
        break;
      }
    case btnSELECT: // Pour le bouton "Select"
    {
      retour = true;
      break;
    }
    default:
    {
      break;
    }
  }
  
  if (indice == indiceDuree)
  {
    duree = valeur;
  }
  else
  {
    decalage = valeur;
  }
  return retour;
}

unsigned long t0 = millis();
unsigned long t1 = millis();

/************************************************************************************************************/
// FONCTION D'INITIALISATION
/************************************************************************************************************/
void setup()
{
  lcd.begin(16, 2); // Demarrer la librairie ecran
  
  //pinmode
  pinMode(ENTREE, INPUT);
  pinMode(SORTIE, OUTPUT);
  digitalWrite(SORTIE, HIGH);
}

void loop()
{
if(g1 >= 0)
  {
    lcd.setCursor(0, 0);
    sprintf(buf, "g1=%d", g1);
    lcd.print("g1=");
    lcd.print(g1);
   }
  if(g1 == -10)
  {
    // on définit le décalage
    if(setNombreDecimal(indiceDecalage))
    {
      g1 = -5;
    }
  }
  else if(g1 == -5)
  {
    // on définit la duree
    if(setNombreDecimal(indiceDuree))
    {
      g1 = 0;   
      /*²   
      lcd.setCursor(0, 0);
      lcd.print("attente signal  ");
      lcd.setCursor(0, 1);
      lcd.print("                ");
      */
    }
  }
  else if((g1 == 0) && (digitalRead(ENTREE) == HIGH))
  {
    // anti-rebond sur l'entrée : on lit 2x l'entrée à 15ms d'intervalle
    delay(15);
    if (digitalRead(ENTREE) == HIGH)
    {
      
      t0 = millis();
      g1 = 10;
      /*
      lcd.setCursor(0, 0);
      lcd.print("signal detecte  ");
      lcd.setCursor(0, 1);
      lcd.print("attente depart  ");
      */
    }
  }
  else if((g1 == 10) && (millis()-t0 > int(decalage*1000)))
  {
    digitalWrite(SORTIE, LOW);
    t1 = millis();
    g1 = 20;
    /*
      lcd.setCursor(0, 0);
      lcd.print("sortie active  ");
      lcd.setCursor(0, 1);
      lcd.print("duree en cours ");
      */
  }
  else if((g1 == 20) && (millis()-t1 > int(duree*1000)))
  {
    digitalWrite(SORTIE, HIGH);
    if(digitalRead(ENTREE) == LOW)
    {
      // anti-rebond sur l'entrée : on lit 2x l'entrée à 15ms d'intervalle
      delay(15);
      if (digitalRead(ENTREE) == LOW)
      {
        g1 = 0;
      /*
      lcd.setCursor(0, 0);
      lcd.print("attente signal  ");
      lcd.setCursor(0, 1);
      lcd.print("                ");
      */
      }
    }
  }
} // fin loop()

la variable decalage et durée sont en int, car elle ne depasse pas 9.9

ça compile?

c'est quoi g1?

g1 est mon etat

je ne sais coder que comme ça, avec des etapes