Problème d'afficheur

Bonjour à tous,

Je programme un petit contrôleur pour aquarium avec un Arduino mega1280.
Mon problème est qu'après un moment (8-15h je ne sais pas exactement) l'affichage se met à afficher des caractères bizarres, après un redémarrage tout reviens à la normal...
Lorsque je change de menu je vois que les caractères bizarres changent, le lcd est donc encore bien commandé par le arduino. Le lcd est compatible HD44780 et est 16x2lignes.
A savoir que toutes les autres fonctions fonctionnent sans problème (contrôle des relais pour lumière, chauffage, capteur température, stockage des températures minimal/maximal...)

Voila une petite vidéo du problème:

Le code complet est joint à ce post et voilà quelques bout de mon code, j'ai retiré les parties ne concernant pas l'affichage:

void setup(){
  lcd.begin(16, 2);     // start the lcdlibrary
  lcd.setCursor(0,0);
  lcd.print("Aqua++");    // print a simple message
  delay(1000);            
  lcd.clear();
}

void loop(){
  lcd_key = read_LCD_buttons();  // read the buttons from the LCD board
  switch (lcd_key)               // depending on which button was pushed, we perform an action
  {

   case btnLEFT:
     {
     reset_min_max_temp();
     affichage_reset_minmax();
     break;
     }
   case btnSELECT:
     {
     affichage_minmax();
     break;
     }
   case btnNONE:
     {
     affichage_accueil();
     break;
     }
  }
}

void affichage_accueil()
{
  affichage_temperature();
  affichage_heure(); 
}

void affichage_heure()
{
/********************************************************************************
	Cette fonction permet d'afficher l'heure sur l'écrans LCD
********************************************************************************/
lcd.setCursor(0,1);
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  if(hour<10)
  lcd.print("0");
  lcd.print(hour);
  lcd.print(":");
  if(minute<10)
  lcd.print("0");
  lcd.print(minute);
  lcd.print(":");
  if(second<10)
  lcd.print("0");
  lcd.print(second);
}

void affichage_reset_minmax()
{
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Resetting min");
   lcd.setCursor(0,1);
   lcd.print("max value");
   delay(1000);
   lcd.print(".");
   delay(1000);
   lcd.print(".");
   delay(1000);
   lcd.print(".");
   delay(1000);
   lcd.clear();  
}

void affichage_minmax()
{
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("T1: ");
   lcd.print(tempmM.fTank1TempMin);    // Valeur en degré
   lcd.print("-");
   lcd.print(tempmM.fTank1TempMax);
   lcd.setCursor(0,1);
   lcd.print("T2: ");
   lcd.print(tempmM.fTank2TempMin);
   lcd.print("-");
   lcd.print(tempmM.fTank2TempMax);
   delay(2500);
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("T2: ");
   lcd.print(tempmM.fTank2TempMin);
   lcd.print("-");
   lcd.print(tempmM.fTank2TempMax);
   lcd.setCursor(0,1);
   lcd.print("Rm: ");
   lcd.print(tempmM.fRoomTempMin);
   lcd.print("-");
   lcd.print(tempmM.fRoomTempMax);
   delay(2500);
   lcd.clear();
}

void affichage_temperature()
{

/********************************************************************************
	Cette fonction permet d'interroger les deux capteurs de temperature
        OneWire et d'afficher la temperature sur le LCD
********************************************************************************/
  if(affichageStamp>=0&&affichageStamp<15)
  {
    temperature[0].valeur =getStuff(temperature[0].addr,temperature[0].pin); //getStuff implique un delay de 100
    temperature[1].valeur =getStuff(temperature[1].addr,temperature[1].pin); 
    lcd.setCursor(0,0);
    lcd.print("Tank1: ");
    lcd.print(temperature[0].valeur);
    lcd.print("c");
    Serial.println(" C ");
    if(tempmM.fTank1TempMax<temperature[0].valeur)
    {
      TemperatureChangeFlag=1;
      tempmM.fTank1TempMax=temperature[0].valeur;
    }
    if(tempmM.fTank1TempMin>temperature[0].valeur)
    {
      TemperatureChangeFlag=1;
      tempmM.fTank1TempMin=temperature[0].valeur;
    }
  }
  if(affichageStamp>=15&&affichageStamp<30)
  {
    temperature[0].valeur =getStuff(temperature[0].addr,temperature[0].pin);
    temperature[1].valeur =getStuff(temperature[1].addr,temperature[1].pin); //getStuff implique un delay de 100
    lcd.setCursor(0,0);
    lcd.print("Tank2: ");
    lcd.print(temperature[1].valeur);
    lcd.print("c");
    Serial.println(" C ");
    if(tempmM.fTank2TempMax<temperature[1].valeur)
    {
      TemperatureChangeFlag=1;
      tempmM.fTank2TempMax=temperature[1].valeur;
    } 
    if(tempmM.fTank2TempMin>temperature[1].valeur)
    {
      TemperatureChangeFlag=1;
      tempmM.fTank2TempMin=temperature[1].valeur;
    }
  }
  if(affichageStamp==30||affichageStamp==37)
  {
    temperature[0].valeur = getStuff(temperature[0].addr,temperature[0].pin);
    tempRoom = getLM35value(); 
    lcd.setCursor(0,0);
    lcd.print("Room:  ");
    lcd.print(tempRoom);//tempRoom);
    lcd.print("c");
    lcd.print("                "); //efface la fin de ligne  
    if(tempmM.fRoomTempMax<tempRoom)
    {
      TemperatureChangeFlag=1;
      tempmM.fRoomTempMax=tempRoom; 
    }
    if(tempmM.fRoomTempMin>tempRoom)
    {
      TemperatureChangeFlag=1;
      tempmM.fRoomTempMin=tempRoom;
    }    
  }
  if(affichageStamp>=30&&affichageStamp<45)
  {
    delay(100);                    //egalise le delai avec les capteur DS18B20
  }
  
    delay(20);
    affichageStamp++;
    if(affichageStamp==45)
      affichageStamp=0;

}

ProjetAqua.ino (16.5 KB)

Ce matin en me réveillant je vois que l'écran refonctionne normalement... Je vais essayer de voir si cela suit un rythme précis ou non. Si ça continu je programmerai un reset software toutes les nuits pour régler ce problème

Si quelqu'un a une idée qu'il n'hésite pas a m'en faire part :slight_smile:

Fuite mémoire et écrasement des chaines de caractères?

Est-ce possible juste avec l'usage de la fonction lcd.print() sachant que les 2 ligne utilisent des fonctions et données séparé?

De plus, quand j'appuie sur btnLEFT par exemple la fonction d'affichage exécute seulement le code suivant mais malgré cela l'affichage reste tout de même erroné

   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Resetting min");
   lcd.setCursor(0,1);
   lcd.print("max value");
   delay(1000);
   lcd.print(".");
   delay(1000);
   lcd.print(".");
   delay(1000);
   lcd.print(".");
   delay(1000);
   lcd.clear();

Merci en tout cas pour ce début de piste je vais aller voir dans la librairie LiquidCrystal ce qu'il se passe

Pour info les matrices de caractères sont stockées dans l'afficheur. Donc si écrasement mémoire c'est dans l'afficheur que cela se produit.

Mais de ce que je vois ce ne sont pas des caractères défectueux qui s'affichent mais d'autres caractères faisant partie de la police.

Pour moi c'est un des bits de données qui est défectueux (mauvais contact ?). Pour savoir quel est le bit en question il faudrait que je sache ce qui devrait être affiché. Voici le moyen :

  • Tu notes en hexa le code du caractère qui devrait s'afficher.
  • Tu recherches dans la table des caractères le code hexa du caractère qui s'affiche à la place.
  • Tu répètes cela sur plusieurs caractères.
  • Si à chaque fois c'est le même bit qui diffère c'est la que se trouve la défectuosité.

Bien sur tout ce que je viens de dire ne s'apllique pas si l'afficheur est en SPI ou en I2C.

JLB

Au niveau branchement c'est du classique avec branchement de DB4 à DB7, RS et E.

Pour le bit de données défectueux je ne pense pas être dans ce cas là. Mon afficheur affiche normalement une des trois température sur la première ligne, toutes les 3 secondes environ une nouvelle température est affiché.
Voila ce qui devrait s'afficher sur la première ligne:
"Tank1: 28.15c"
puis 3 secondes plus tard:
"Tank2: 24.12c"
puis 3 secondes plus tard:
"Room: 23.15c"
et ainsi de suite en reprenant a Tank1 après 3sec.

Quand l'afficheur se met a afficher des caractères aléatoire les changement de caractère sont beaucoup plus fréquent que 5 secondes, il y a un changement toutes les secondes voir demi-secondes, voir sur cette vidéos du défault:

La seconde ligne affichant l'heure actuel ne devrait pas non plus changer tellement, a part le 7 et 8ème caractère représentant les secondes.

Voila une vidéos du fonctionnement normal:

Est-ce qu'une mauvaise connexion d'un des bits de données pourrait aussi être à l'origine de ce problème?

Bonjour,

Je pencherai plus pour un bug dans la "charmap" de l'afficheur.
L'espace est au bon endroit, de même que certain chiffre, seul les lettres semble réellement affecté par le bug.

Ou alors c'est vraiment un gros soucis de câblage :

a:0x61:01100001
n:0x6E:01101110
k:0x6B:01101011

#:0x23:00100011
B:0x42:01000010
omega:0xE3:11100011/code]

Dans ce cas je penche pour un problème hardware sur les signaux de commande (enable, clock, ...) qui généreraient des commandes aléatoires.

JLB

Une connexion défectueuse (intermittente) entre l'afficheur et l'arduino?
Pas d'humidité sur l'afficheur?

jihelbi:
Dans ce cas je penche pour un problème hardware sur les signaux de commande (enable, clock, ...) qui généreraient des commandes aléatoires.

L'hypothèse d'un probléme hardware est la plus probable.

Câbler la broche R/W vers l'arduino (et non vers GND) et utiliser le prototype : LiquidCrystal(rs, rw, enable, d4, d5, d6, d7) permettrai d'écarter tout probléme de timings / software.
Si le bug continue d'apparaitre tu devrais alors regarder de beaucoup plus prés ton câblage, la qualité des connexions, des fils, etc ...

Merci a tous pour vos réponse, je vais essayer de câbler R/W mais va falloir que je vois comment faire... Mon LCD est sur un ensemble: 1602 lcd keypad shield, qui se connecte directement sur la board et qui comprend aussi un petit clavier (mon niveau en électronique n'étant pas énorme j'ai préféré éviter la partie électronique au possible, et niveau coût aussi c'est intéressant!)

C'est bizarre quand même que ce problème apparaisse après plusieurs heures, reste plusieurs heures pour redisparaitre ensuite! Le redémarrage de l'ensemble (en débranchant simplement le transfo) résous aussi le problème, alors que ma carte et son boitier ne bouge pas quand je le débranche. Si c'est un mauvais contact, le redémarrage ne devrait pas résoudre le problème, si?

fdufnews:
Une connexion défectueuse (intermittente) entre l'afficheur et l'arduino?
Pas d'humidité sur l'afficheur?

Comme dit plus haut le LCD connecté sur une board et celle-ci est directement connecté a l'Arduino mais je vérifierai quand même les connexions de l'ensemble.
Non l'Arduino est son électronique sont dans un compartiment en dessous des aquariums sans aucun passage d'eau (pas de filtre, pas de stockage de matériau ou outils humide... de plus celui-ci est "protégé" dans son coffret). La pièce doit certainement être un peu plus humide que la moyenne due à la présence des aqua mais bon pas au point de gêner une électronique, cette pièce est trop aéré pour cela.

Ha ok c'est sur une shield lcd ... c'est effectivement plus compliqué.
Bon si tu ne peut pas écarter l'hypothèse du bug software via R/W repartons avec de bonne base :wink:

Prend le sketch de démo de LiquidCrystal (le compteur avec un petit message) et upload le sur ton arduino.
Laisse migoter le tout un bonne nuit (enfin le temps normal avant bug) et regarde si tu te retrouve avec du méli-mélo de caractére.

Si oui : probléme hardware (soudure froide, soudure "en boule", soudure sans soudure (déja vu malheureusement sur bon nombre de truc chinois), ...)
Si non : bug software ? bug hardware liée au reste du montage (alim ?) ?

Ok je vais vérifié tout ça demain :slight_smile: Pour l'instant il est l'heure d'aller faire un petit billard!

L'alim est une alim de récup donc le problème vient peut-être de là, est-ce possible malgré qu'au moment du bug tout le reste fonctionne? (thermomètre, relais du chauffage, relais des lumière,...)

rominou1987:
Ok je vais vérifié tout ça demain :slight_smile: Pour l'instant il est l'heure d'aller faire un petit billard!

Si c'est l'heure du billard c'est sacrée :grin:

rominou1987:
L'alim est une alim de récup donc le problème vient peut-être de là, est-ce possible malgré qu'au moment du bug tout le reste fonctionne? (thermomètre, relais du chauffage, relais des lumière,...)

J'ai vu des trucs pas nette avec certaine alim / batterie, surtout celle qui ont déja bien vécu :grin:

Oui je ne peux pas manquer l'heure du billard!! :stuck_out_tongue:

Pour l'alim après avoir cherché une alimentation stabilisé de pointe j'ai choisi d'utiliser une alimentation 12v 1 ampère d'antenne TV... C'est pas le must c'est sûr mais bon j'avais que ça sous la main!

Donc au programme demain je vais vérifié les soudures de ma board LCD, si tout à l'air ok -> Changement d'alim;
Si le problème se reproduit à nouveau-> Test du sketch démo de LiquidCrystal;
Si le problème se reproduit encore(!!!) (sinon galère dans le prog...) -> coupure de piste et connexion de R/W à l'arduino

Merci en tout cas à tous pour toutes les pistes proposé!! J'ai programmé avec pas mal de board, environnement et framework (LM3s9b96, STM32, sc13, Keil, uVision, quantum framework...) et c'est la première fois que je vois une communauté aussi réactive que sur ce forum :slight_smile:

rominou1987:
Pour l'alim après avoir cherché une alimentation stabilisé de pointe j'ai choisi d'utiliser une alimentation 12v 1 ampère d'antenne TV... C'est pas le must c'est sûr mais bon j'avais que ça sous la main!

C'est le genre petit bloc secteur ou truc monstrueux avec un bloc et deux grands fils de chaque côté ?
Si c'etait un bloc secteur comme celui des "box TV internet" ça poserai surement aucun probléme (alim à découpage + filtrage en interne).
Si c'est un truc low-cost chinois il y a fort à parier que la tension de sortie soit peu (voir pas) filtré.

rominou1987:
Merci en tout cas à tous pour toutes les pistes proposé!! J'ai programmé avec pas mal de board, environnement et framework (LM3s9b96, STM32, sc13, Keil, uVision, quantum framework...) et c'est la première fois que je vois une communauté aussi réactive que sur ce forum :slight_smile:

C'est ça l'esprit arduino :grin:
(Tient même pas de LPCxpresso dans la liste ? Moi je suis un grand fan de STM32F10x et F4xx, et d'arduino ^_^)

Non c'est le genre de bloc encore plus monstrueux qui se branche directement au mur et avec juste une paire de fil d'un coté!

Je verrais ça un peu plus tard, je doit bien avoir une alim de modem/routeur qui sera certainement plus stable.
(Non pas de LPCxpresso, jamais testé! J'avais travaillé sur du STM32F107 avec la board STM3210C-EVAL , on utilisait Keil uVision ou IAR. Egalement testé la DK-LM3S9B96 de TI pour finalement utiliser le LM3S9D92 en prod)

Alimentation... une piste...

Attention 12 volts est la limite pour alimenter l'Arduino. Au dela son régulateur chauffe exagérément.

Les alims basiques 12 volts chinoises n'ont en sortie qu'un pont et une capa. Comme le tranfo est dimentionné au plus juste sa tension de sortie est largement supérieure à 12 volts à vide.

Il ne serait pas impossible que le 7805 ait de brèves coupures occasionné par sa protection interne à la surchauffe. Cela ne provoque pas forcément un reset de l'Arduino. Je m'explique :

Par défaut l'ATmega328P a le BOD désactivé (Brown-out detector c'est à dire maintien bas de la pin reset en dessous d'une certaine tension). Par contre si l'on regarde le fichier boards.txt de l'IDE Arduino (donc la valeur de l'extended fuse qui sera appliquée lors d'un burn bootloader) on s'aperçoit que le BOD est activé à 2,7 volts. Je suppose que les Arduino livrés avec l'OptiBoot sont programmés ainsi. Mes ATmega328P sont comme cela puisque j'ai enlevé et remis le bootloader de nombreuses fois. En tout cas on peut modifier cette valeur mais il serait préférable de résoudre préalablement le problème d'alim et déja de faire quelques mesures.

En tout cas des informations erronées peuvent ainsi arriver à l'afficheur sans que l'Arduino ne reset.

JLB

rominou1987:
Non c'est le genre de bloc encore plus monstrueux qui se branche directement au mur et avec juste une paire de fil d'un coté!

... ok :sweat_smile:

rominou1987:
(Non pas de LPCxpresso, jamais testé! J'avais travaillé sur du STM32F107 avec la board STM3210C-EVAL , on utilisait Keil uVision ou IAR. Egalement testé la DK-LM3S9B96 de TI pour finalement utiliser le LM3S9D92 en prod)

Pour les STM32 test CoIDE de coocox, c'est un ide gratuit, basé sur eclipse utilisant la toolchain arm-gcc :wink:
Pas de limitation en debug, en compilation / optimisation, ...

jihelbi:
Attention 12 volts est la limite pour alimenter l'Arduino. Au dela son régulateur chauffe exagérément.

Les alims basiques 12 volts chinoises n'ont en sortie qu'un pont et une capa. Comme le tranfo est dimensionné au plus juste sa tension de sortie est largement supérieure à 12 volts à vide.

+1, la tension "idéal" d'alimentation c'est 9v, c'est toujours bon à préciser.

jihelbi:
Il ne serait pas impossible que le 7805 ait de brèves coupures occasionné par sa protection interne à la surchauffe. Cela ne provoque pas forcément un reset de l'Arduino. Je m'explique :
(...)
En tout cas des informations erronées peuvent ainsi arriver à l'afficheur sans que l'Arduino ne reset.

C'est un hypothèse à ne pas négliger, mais pour quoi seul les lettres et certain nombre sont affecté ?
C'est quand même bizarre ce bug ...

J'ai souvent constaté cela. Il semble que souvent tous les bits d'un port n'aient pas le même comportement et que certains soient affectés plus facilement. Si des écritures sporadiques ont lieu il est difficile de savoir comment sont positionnées les bits à ce moment.

Je n'ai pas investigé plus avant mais il y a probablement une histoire de capacité parallèle sur les entrées provenant soit du montage soit de l'ATmega proprement dit.

JLB