Afficheur ne fonctionne que quelques heures...

Bonjour à tous,

Je viens vers vous car j'ai un problème avec mon afficheur 16x2.

Je détail mon projet, je souhaite fabriquer un petit contrôleur (qui tourne h24) pour mon aquarium. Ce contrôleur est constitué d'un Arduino UNO, une sonde de température, une horloge, 1 relais pour piloter l'éclairage, 2 boutons poussoir, et le fameux afficheur...

J'ai réussi à tous câbler, programmer, le tout fonctionne correctement pendant quelques heures.... Après l'afficheur ne m'affiche plus que des carrés sur la première ligne. Je suis donc obliger d'ouvrir le boitier et faire un Reset sur l'Arduino pour que l’affichage redémarre pour quelques heures.

Je n'ai constater aucun problème de chaleur, ni sur l'Arduino, ni sur l'afficheur. J'ai câblé et programmé ce dernier en 4 bits. Pensant à des faux contact j'ai bloqué tous les fils avec des serres-câbles, et un peu de colle à chaud. Mais cela ne résoud pas le problème. Mon afficheur est le suivant LCD 16x2 + EXTRA. Blanc sur Bleu.

J'ai eu le même soucis avec un autre afficheur (branché en 4 bits également) aussi de type HD44780. Lorsque l'afficheur ne fonctionne plus correctement, le programme lui continu de tourné correctement (il allume et éteint l'éclairage comme voulu...), et les boutons font les actions voulues.

Je ne vois vraiment pas d'ou viens le problème, cela me donne l'impression que les afficheurs de ce type se réinitialise tout seul après un certains temps... Si quelqu'un connait ce problème, ou a une idée d'ou cela peut venir je lui en serait très reconnaissant.

Je tiens à signaler que je n'utilise pas de tableaux de valeurs ou autre élément consommateur en ressource qui pourrait a terme saturer la mémoire. Le programme ne comporte que l'heure, la température, et une variable pour vérifier le changement d'état pour un des 2 boutons.

Si vous avez besoin de mon programme pour essayer de comprendre d'où cela vient, il suffit de le demander. Par contre je n'ai pas fait de schéma de câblage...

Par avance merci pour votre aide.

Bonjour,
J'ai eu un jour un pb similaire avec un écran graphique LCD et cela provenait d'un problème de chauffe.
Hors du boîtier tout fonctionnait 24/24 et dans le boîtier que quelques heures - Solution : des trous de ventilation.

Comment se comporte ton écran sans le boitier ?

Salut,

ça viens surement d'un parasite qui se produit lorsque tu coupes une de tes pompes

Merci pour vos réponses rapides,

Sans le boitier, étant donné que c'était que pour le débogage du programme, j'ai pas rencontrer de problèmes (mais il était allumé au maximum une heure d'affilé). Pour la chauffe c'est un problème probable, un ventilateur pourrais peut-être résoudre le problème (surement plus efficace que des trou de ventilation ?). Qu'en pensez vous, le programmer avec une sonde de température ?

Quant au parasite, la coupure de l'afficheur n'a pas lieu en même temps que le relais, donc je vois pas ce qui pourrais provoqué ce parasite.

ça peut venir de n'importe quel pompe proche de ton aquarium, pas forcement ce que tu pilotes par ton relais.

J'ai remarqué aussi que plus la pompe est petite, plus j'ai des problèmes sur mon installation.

Avant mes modifs, si je branchais une pompe moyenne dans la même pièce que l'aquarium, voir même la pièce d'à coté, mon LCD buggait comme tu le décris. Avec une toute petite pompe, ça faisait comme si j'appuyais sur mon bouton poussoir.

raphael76:
...
Quant au parasite, la coupure de l'afficheur n'a pas lieu en même temps que le relais, donc je vois pas ce qui pourrais provoqué ce parasite.

bonsoir
les LCD sont sensibles aux "parasites" et peuvent se retrouver sans un etat d'affichage bizarre
une solution mais qui ne pallie pas à l'origine du probleme est de lancer regulierement un lcd.begin

Salut,

Je connais ça aussi. Surtout en 4 fils, il suffit qu'une donnée ne soit pas prise en compte pour tout décaler de 4 bits, l'afficheur ne répond alors plus de rien. Il me semble que comme pour certains afficheurs graphiques, il y a un byte d'état contenant un flag "occupé", et s'il est à 1, aucune commande n'est prise en compte...

Encore merci pour vos réponses.

Je viens déjà de percer le boitier afin de mieux le refroidir, et je l'ai éloigné de l'éclairage qui produit un peu de chaleur. A voir si cela améliore les un peu les choses.

Pour les parasites je vois pas trop ce que je peux faire pour éliminer, ou réduire les parasites (la seule pompe que j'ai, c'est mon filtre). Peut-être il existe d'autres afficheur moins sensibles aux parasites, ou des boîtiers qui permettrait de l'isoler mieux des parasites.

Et il serait aussi judicieux de voir si tu n'as pas de dépassement de variables et s'il te reste assez de RAM.
Car parfois ça bug aussi à cause de ça.

Sinon ton LCD il est branché sur quoi au niveau de l'alimentation?

Si tu as tout branché sur la UNO il se peut que la chute de tension engendrée par la commutation de ton relais fasse bugger le LCD.

J'ai des afficheurs LCD branchés 24/24 et 7/7 qui ne plantent jamais (station thermomètre et gestion relais), donc je pense pas que ce soit lié à un problème particulier de ta part, ce n'est pas normal et il faut trouver d'où vient le problème.

Peux tu nous mettre ton code? on sait jamais...

Voici mon code :*

#include <LiquidCrystal.h>
#include <Wire.h>
#include <OneWire.h>
#include <EEPROM.h>
#include <RTClib.h>

RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int Lumiere = 7; //Relais éclairage broche 7
const int Ecran = 10; //Rétroéclairage écran broche 10
const int LevierMode = 9; // Levier Mode auto/manu
const int Retroeclairage = 8; //Bouton rétroéclairage
int TempsPerso;
int buttonState = 0;         //Variable pour l'état actuel du bouton poussoir
int lastButtonState = 0;     // Variable pour l'état précédent du bouton poussoir


//////////////////////////////////////////////////
//////////    SONDE DE TEMPERATURE     ///////////
//////////////////////////////////////////////////


#define DS18B20 0x28     // Adresse 1-Wire du DS18B20
#define BROCHE_ONEWIRE 6 // Broche utilisée pour le bus 1-Wire

OneWire ds(BROCHE_ONEWIRE); // Création de l'objet OneWire ds

// Fonction récupèrant la température depuis le DS18B20
// Retourne true si tout va bien, ou false en cas d'erreur
boolean getTemperature(float *temp){
  byte data[9], addr[8];
  // data : Données lues depuis le scratchpad
  // addr : adresse du module 1-Wire détecté

  if (!ds.search(addr)) { // Recherche un module 1-Wire
    ds.reset_search();    // Réinitialise la recherche de module
    return false;         // Retourne une erreur
  }

  if (OneWire::crc8(addr, 7) != addr[7]) // Vérifie que l'adresse a été correctement reçue
    return false;                        // Si le message est corrompu on retourne une erreur

  if (addr[0] != DS18B20) // Vérifie qu'il s'agit bien d'un DS18B20
      return false;         // Si ce n'est pas le cas on retourne une erreur

  ds.reset();             // On reset le bus 1-Wire
  ds.select(addr);        // On sélectionne le DS18B20

  ds.write(0x44, 1);      // On lance une prise de mesure de température
  delay(800);             // Et on attend la fin de la mesure

  ds.reset();             // On reset le bus 1-Wire
  ds.select(addr);        // On sélectionne le DS18B20
  ds.write(0xBE);         // On envoie une demande de lecture du scratchpad

  for (byte i = 0; i < 9; i++) // On lit le scratchpad
    data[i] = ds.read();       // Et on stock les octets reçus

  // Calcul de la température en degré Celsius
  *temp = ((data[1] << 8) | data[0]) * 0.0625; 

  // Pas d'erreur
  return true;
}


void setup() {
  Serial.begin(9600); //Initialiser le port serie
  Wire.begin();
  RTC.begin();
  lcd.begin(16, 2);
  pinMode(Lumiere, OUTPUT);
  pinMode(Ecran, OUTPUT);
  pinMode(LevierMode, INPUT);
  pinMode(Retroeclairage, INPUT);
  pinMode(17, OUTPUT);
  pinMode(16, OUTPUT);
}





void loop() {
  digitalWrite(17, HIGH);    // ALIMENTATION RTC
  digitalWrite(16, LOW);     // ALIMENTATION RTC
  
  DateTime now = RTC.now();
  
        //////////////////////////////////////////////////
	/////////     AFFICHAGE TEMPERATURE      /////////
	//////////////////////////////////////////////////    
           
          float temp;

          // Lit la température ambiante à  ~1Hz
          if(getTemperature(&temp)) 
          { 
            // Affiche la température
            lcd.setCursor(1, 1);
            lcd.print("Temp. : ");
            lcd.print(temp);
            lcd.write('C');
          }
  
  buttonState = digitalRead(LevierMode);
    {
   if (buttonState != lastButtonState) {
     lcd.clear();}
    }

   
  //////////////////////////////////////////////////
  //////////    CALCUL TEMPS PERSO      ////////////
  //////////////////////////////////////////////////
   
    // ++++++++++ Gestion de l'heure d'été pour la France ++++++++++
    // En France le changement d'heure fonctionne selon la règle suivante :
    // Le dernier dimanche de mars à  3 heure on ajoute une heure,
    // Le dernier dimanche d'octobre à  3 heure on retranche une heure

    if (now.dayOfWeek() == 7 && now.month() == 3 && now.hour() >1 && now.hour() <4 && now.day() >= 25 && now.day() <=31)  // On vérifie si on est le dernier dimanche de mars et qu'il est entre 2 ou 3 heure du matin
    {
      TempsPerso=(((now.hour()*100)+now.minute())+100);
    }
    else 
    {
      TempsPerso=((now.hour()*100)+now.minute());
    } 
  
  

  //////////////////////////////////////////////////
  //////////////    CHOIX MODE         /////////////
  //////////////////////////////////////////////////
  
    int Mode = digitalRead(LevierMode);
    if(Mode==LOW){
      
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      //////////////////////////////////////////////      MODE AUTOMATIQUE         ////////////////////////////////////////////////////////////
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      //////////////////////////////////////////////////
      /////////      GESTION ECLAIRAGE         /////////
      //////////////////////////////////////////////////
            
          if (((TempsPerso >= 900) && (TempsPerso < 1400)) || ((TempsPerso >= 1500) && (TempsPerso < 2100))) 
          {
            digitalWrite(Lumiere, HIGH);
          }
          else {
            digitalWrite(Lumiere,LOW);
          }  
        

        //////////////////////////////////////////////////
        ////////////     AFFICHAGE HEURE       ///////////
        //////////////////////////////////////////////////    

        
          lcd.setCursor(4, 0);
          lcd.print(now.hour());
          lcd.print(":");
          if (now.minute() < 10) 
          {
            lcd.print("0");
          }
          lcd.print(now.minute());
          lcd.print(":");
          if (now.second() < 10) 
          {
            lcd.print("0");
          }
          lcd.print(now.second());


        //////////////////////////////////////////////////
        ////////////     RETROECLAIRAGE       ////////////
        //////////////////////////////////////////////////  

        
          int GestionRetroeclairage = digitalRead(Retroeclairage);
          if(GestionRetroeclairage==HIGH){
            digitalWrite(Ecran, HIGH);
          }
          else {
            digitalWrite(Ecran, LOW);
          }
        
    }
else {
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      ///////////////////////////////////////////////////      MODE MAUNUEL        //////////////////////////////////////////////////////////////
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      digitalWrite(Ecran, HIGH);    // RETROECLAIRAGE ON
      digitalWrite(Lumiere,HIGH);   // LUMIERE ON
      


      
      //////////////////////////////////////////////////
      /////////     AFFICHAGE MODE MANU       //////////
      //////////////////////////////////////////////////    

      
        lcd.setCursor(0, 0);
        lcd.print("   MODE MANU.   ");
        } 
       //mémorise l'état courant du bouton poussoir pour les prochains passages dans la boucle loop
        lastButtonState = buttonState;     
  
}

Le code pourrait surement être optimisé, mais en tous cas il fonctionne (et c'est bien ça qui m'intéressait pour commencer) !

Quand a l'alimentation de l'écran, tout est brancher sur l'Arduino, mais j'ai rien de consommateur (liste sur mon premier poste). Comme dit plus haut, la commutation de mon relais n'a jamais eu lieu en même temps.

Ajoutes y un petit affichage régulier de la RAM dispo avec:

#include <avr/pgmspace.h>
freeRAM (); // for debug
static void freeRAM (){
  extern int __heap_start, *__brkval;
  int v;
  int free = (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
  lcd.setCursor(0,0);
  lcd.print(F("   Free RAM :   "));
  lcd.setCursor(3,1);
  lcd.print(free);
  delay(1000);
}

raphael76:
Comme dit plus haut, la commutation de mon relais n'a jamais eu lieu en même temps.

En même temps que quoi? D'après ce que j'ai compris tout est alimenté et de temps en temps tu commutes le relais pour alimenter tes pompes?

Ton relais il demande quelle tension? Il est câblé comment?

Par ailleurs, ton calcul du DST ne prend pas en compte tous les cas de figure.

Et une fois que tu as décalé ton heure tu risque de tourner en boucle car tu vas dire à ton horloge de se décaler puis tu vas refaire le test derrière ce qui fais que ta fonction va tourner en rond.
Tu pourrais l'améliorer en mettant un drapeau de type boolean DST_changé? mais je te propose:

int adjustDstEurope(DateTime t)
{
 /*You can use the following equations to calculate when DST starts and ends.
 The divisions are integer divisions, in which remainders are discarded.
 "mod" means the remainder when doing integer division, e.g., 20 mod 7 = 6.
 That is, 20 divided by 7 is 2 and 6/7th (where six is the remainder).
 With: y = year.
        For the United States:
            Begin DST: Sunday April (2+6*y-y/4) mod 7+1
            End DST: Sunday October (31-(y*5/4+1) mod 7)
           Valid for years 1900 to 2006, though DST wasn't adopted until the 1950s-1960s. 2007 and after:
            Begin DST: Sunday March 14 - (1 + y*5/4) mod 7
            End DST: Sunday November 7 - (1 + y*5/4) mod 7;
        European Economic Community:
            Begin DST: Sunday March (31 - (5*y/4 + 4) mod 7) at 1h U.T.
            End DST: Sunday October (31 - (5*y/4 + 1) mod 7) at 1h U.T.
            Since 1996, valid through 2099
(Equations by Wei-Hwa Huang (US), and Robert H. van Gent (EC))
 
 Adjustig Time with DST Europe/France/Paris: UTC+1h in winter, UTC+2h in summer
 
 */
 
  // last sunday of march
  int beginDSTDate=  (31 - (5* t.year() /4 + 4) % 7);
  //Serial.println(beginDSTDate);
  int beginDSTMonth=3;
  //last sunday of october
  int endDSTDate= (31 - (5 * t.year() /4 + 1) % 7);
  //Serial.println(endDSTDate);
  int endDSTMonth=10;
  // DST is valid as:
  if (((t.month() > beginDSTMonth) && (t.month() < endDSTMonth))
      || ((t.month() == beginDSTMonth) && (t.day() >= beginDSTDate)) 
      || ((t.month() == endDSTMonth) && (t.day() <= endDSTDate)))
  return 7200;      // DST europe = utc +2 hour (summer time)
  else return 3600; // nonDST europe = utc +1 hour (winter time)
}

Gardes ton heure UTC en now.Xxxxx et crée un nowDST.Xxxx pour avoir ton heure corrigée. :wink:

Tu peux mettre les déclarations:

digitalWrite(17, HIGH);    // ALIMENTATION RTC
  digitalWrite(16, LOW);     // ALIMENTATION RTC

dans le setup pour ne les effectuer qu'une seule fois. Inutile de les executer en permanence.

Comme dit plus haut, la commutation de mon relais n'a jamais eu lieu en même temps.

Ce n'est pas pour ça que tu n'est pas sujet à un parasite, ça peut venir de n'importe quel appareil qui contient un bobinage et qui n'est pas coupé lors du passage à 0 volt de la tension secteur.

Bonjour,

raphael76:
J'ai réussi à tous câbler, programmer, le tout fonctionne correctement pendant quelques heures.... Après l'afficheur ne m'affiche plus que des carrés sur la première ligne.

Pour un LCD de ce type l'état « petits carrés sur la première ligne» est celui d'un écran qui est alimenté mais pas encore initialisé. Si ton écran se retrouve dans cet état c'est donc qu'il a à un moment ou un autre perdu l'alimentation, même pour une durée minuscule.

Comme l'a dit Artouste plus tôt, une méthode crade-mais-qui-fonctionne serait d'appeler Serial.begin() régulièrement. Mais bon il serait quand même préférable de régler le problème à la source. Un condensateur supplémentaire entre le Vcc et le Gnd de l'écran pourrait sans doute aider.

haifger:
Bonjour,

raphael76:
J'ai réussi à tous câbler, programmer, le tout fonctionne correctement pendant quelques heures.... Après l'afficheur ne m'affiche plus que des carrés sur la première ligne.

Pour un LCD de ce type l'état « petits carrés sur la première ligne» est celui d'un écran qui est alimenté mais pas encore initialisé. Si ton écran se retrouve dans cet état c'est donc qu'il a à un moment ou un autre perdu l'alimentation, même pour une durée minuscule.

Comme l'a dit Artouste plus tôt, une méthode crade-mais-qui-fonctionne serait d'appeler Serial.begin() régulièrement. Mais bon il serait quand même préférable de régler le problème à la source. Un condensateur supplémentaire entre le Vcc et le Gnd de l'écran pourrait sans doute aider.

bonjour
Parfaitement c'est crade :grin: et pas satisfaisant intellectuellement 8) , mais avec les lcd en 4 bits , le deverminage peut etre une mission quasi impossible.
Il y a aussi la solution si il reste de l'entrée dispo , de prevoir un bouton "init lcd seul" c'est juste un peu moins crade :grin:

Moi j'aurais quand même bien aimé avoir un schéma du cablage et une idée de comment c'est relié parce que si le relais est en 12V et que son alim est prise sur le 5V de l'arduino c'est pas étonnant que ça saute.
Et en plus dans la doc de l'arduino en général ils conseille de mettre une alimentation séparée pour tout ce qui est bobines ou appareils pouvant être perturbateurs.

:wink:

Bonjour à tous,

Merci pour vos réponses, je vais essayais de répondre à tous le monde :

Pour ce qui est de mon relais : c'est bien un 5v, que j'alimente et pilote avec mon arduino (Masse, Vcc + Pilotage). Je l'ai acheté sur Ebay, objet n° 190823079261. Pour ce qui est du pilotage, je pilote juste mon éclairage pour commencer. Quand je parle de "en même temps", j'entend par là que la coupure de mon afficheur n'a pas lieu en même temps de je pilote le relais.

Pour ce qui est de la mémoire libre, je regarde ça et je vous tiens au courant.

Ensuite, pour le fait que l'écran pourrait perdre l'alimentation, pas de problème pour mettre un condensateur, dites moi ce qu'il faut comme capacité.

Pour ce qui est des parasites, si quelqu'un connait un moyen de limiter les dégâts au niveau de l'afficheur (boitier métallique, cage de faraday ,...) sachant que je ne peux pas les éliminer (ils proviennent certainement de mon éclairage à "néon").

Pour finir le fait de tout alimenter avec l'Arduino, c'est juste pour commencer, c'est prévu que j'alimente tous les équipements directement avec un transformateur 5v (dès qu'une prise se libère sous l'aquarium -> dans 1 mois maxi). En gros j'aurai Alim. Arduino et sur un autre transfo. Alim. Composants. Sur l'arduino, je pense que je laisserai juste l'alim de l'afficheur.

Je pense pas que ça provient de ton néon sinon tu aurais le soucis dès que tu l'éteint.

Dans mon cas, j'ai eu ce soucis avec les pompes et le bulleur que j'ai solutionné en utilisant des relais statiques car j'ai la chance de pouvoir piloter ce qui provoquait ces parasites mais c'est pas entièrement solutionné car si quelqu'un me débranche le bulleur sans l'éteindre avant via le relais, mon LCD est dans les choux.

Au début je pensais que ça venait de l'alimentation, on m'a conseillé d'utiliser deux alimentations, d'éloigner mon alimentation 5v des autres câbles 220v, si tu utilises une alimentation à découpage avec un câble de plus d'un mètre, on m'a dis d'ajouter un condensateur chimique de 47µF suivis d'un 100nF, un boitier en métal relié à la terre mais tout ça n'a pas solutionné mon problème.

Dès que j'ai du temps, je vais tester le double filtre secteur passe bas mais j'ai encore aucune idée de si ça va m'aider ^^
http://www.sonelec-musique.com/electronique_realisations_filtre_secteur_003.html

raphael76:
...

Ensuite, pour le fait que l'écran pourrait perdre l'alimentation, pas de problème pour mettre un condensateur, dites moi ce qu'il faut comme capacité.

Pour ce qui est des parasites, si quelqu'un connait un moyen de limiter les dégâts au niveau de l'afficheur (boitier métallique, cage de faraday ,...) sachant que je ne peux pas les éliminer (ils proviennent certainement de mon éclairage à "néon").

tu peux tester avec un 2200 µF 25V en un 100 nF en // , mais je ne pense pas que ça reglera le probleme, le probleme vient de la sensibilité aux erreurs des LCD cablés en mode 4bits, c'est tres pratique mais le revers de la medaille est aussi que ça diminue l'immunité.