Go Down

Topic: probleme fiabilité programme (Read 397 times) previous topic - next topic

vtec35

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

vtec35

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

J-M-L

Postez directement le code (en utilisant les balises de code)- peut pas le lire sur mobile
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

vtec35

#3
Mar 13, 2018, 10:34 pm Last Edit: Mar 13, 2018, 10:41 pm by vtec35
ok voici:


Code: [Select]

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()




J-M-L

#4
Mar 14, 2018, 04:53 am Last Edit: Mar 14, 2018, 03:10 pm by J-M-L
le type de vos variables n'est pas bon
Code: [Select]
int temps0 = millis();
int temps1 = millis();
et
Code: [Select]
...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
Code: [Select]
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
Code: [Select]
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
Code: [Select]
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

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

vtec35

est ce que cette nouvelle version vous convient mieux:

Code: [Select]

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

J-M-L

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

vtec35

g1 est mon etat

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

Go Up