Aide pour vérif code et montage RTC & lcd I2C

Bonjour,
L'horloge de ma voiture a rendu l'âme, je tente d'en refaire une avec une Arduino Nano, un module RTC 1331 et un écran lcd I2C.
J'ai trouvé un modèle qui me convient ici: https://www.instructables.com/Arduino-DS3231-RTC-Clock/
Tout est monté sur breadboard, avec SDA sur A4 et SCL sur A5 (écran et RTC), le tout alimenté en 5V.
Les boutons sur A0, A1, A2 avec résistances pullup.

Au premier montage il y a quelques jours, tout fonctionnait bien. Après avoir finalisé le montage sur un support imprimé convenant au véhicule et la Nano montée sur un "Nano Terminal Adapter" (trouvé sur Amaz*n), le comportement est erratique...
La ligne supérieure n'affiche plus l'heure, les boutons n'ont plus d'action sur les heures, mais seulement sur les minutes.

Alors j'ai besoin de l'aide de quelqu'un qui pourrait faire le montage et voir si mon code merdouille, ou bien si j'ai abîmé un composant (le RTC?, j'ai testé avec 2 Nano et 2 lcd différents).
Je me casse les dent depuis 2 jours à tenter de comprendre ce qui ne va pas :unamused:

Je remercie quiquonque voudra bien se pencher sur mon cas. :slightly_smiling_face:

Voici le code utilisé:

// ------------------------------------------------------------------------------------
// Simple clock based on a DS3231 RTC and simple 16x2 LCD
// Setup includes 3 push buttons for up, down, and enter
// 15th July 2015, Andrew W. - arwhitus.weebly.com
// Visit arwhitus.weebly.com for more info or to contact author for any reason
// ------------------------------------------------------------------------------------

//#include LCD and Wire library
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>
#include <Wire.h>

//define button pins
#define enterButtPin A2
#define upButtPin A1
#define downButtPin A0
 
//define RTC address
#define DS3231_I2C_ADDRESS (0x68)

// Ci dessous code ajouté à l'original

LiquidCrystal_I2C lcd(0x27, 16 , 2 ); ////Instance d'écran



//define LCD pins and initialize LCD library !! Ligne commentée pour désactiver au passage de I2C
//LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

//variables for button states
int enterState = 0;
  int enterStateLast = 0;
int upState = 0;
  int upStateLast = 0;
int downState = 0;
  int downStateLast = 0;

//variables for ui
boolean blinkOn = true; //visibility of ':' between hour and minutes
boolean setVisible = false; //visibility of the set time ui

//variables for new time
int setM = 0; //users new minute value
int setH = 0; //users new hour value

//convert normal decimal numbers to binary coded decimals
byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}
//convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}

//code that runs once at setup
void setup() {
  //start wire and lcd
  Wire.begin();
  lcd.begin(16,2); //(col, rows)

  //intialize buttons as inputs
  pinMode(enterButtPin, INPUT);
  pinMode(upButtPin, INPUT);
  pinMode(downButtPin, INPUT);
  
  //Use below code to set time and date once from code
  //it will run at every reset and you will lose the time on the RTC
  //format is (sec, min, hr, day of week, day of month, month, year)
    //setRTCTime(0, 3, 23, 4, 15, 7, 15);
}

//code that runs on a constant loop
void loop() {
  checkButtons();
  //printTime();
}

//easy and dirty way to clear the LCD
void clearLCD ()
{
  lcd.setCursor(0,0);
  lcd.print("                ");
  lcd.setCursor(0,1);
  lcd.print("                ");
  lcd.setCursor(0,0);
}

//set the time and date to the RTC
void setRTCTime(byte second, byte minute, byte hour, byte dayOfWeek, byte
                dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}

//read the time and date from the RTC
void readRTCTime(byte *second, byte *minute, byte *hour, byte *dayOfWeek,
                 byte *dayOfMonth, byte *month, byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

//reads the RTC time and prints it to the top of the LCD
void printTime()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  
  //retrieve time
  readRTCTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  
  //print to lcd top
  lcd.setCursor(0,0);
  lcd.print(" Il est ");
  if (hour<10)
  {
    lcd.print("0");
  }
  lcd.print(hour, DEC);
  if (blinkOn == true)
  {
    lcd.print(" ");
    blinkOn = false;
  }
  else if (blinkOn == false)
  {
    lcd.print(":");
    blinkOn = false;
  }
  if (minute<10)
  {
    lcd.print("0");
  }
  lcd.print(minute, DEC);
  
  delay(100);
}


//checks if buttons are pressed and responds accordingly
void checkButtons()
{
  //check enter
  enterState = digitalRead(enterButtPin);
  if (enterState != enterStateLast)
  {
    if (enterState == HIGH)
    {
      if (setVisible == true)
      {
        byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
        readRTCTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
        
        setRTCTime(0, setM, setH, dayOfWeek, dayOfMonth, month, year);
        hideSet();
      }
      else if (setVisible == false)
      {
        showSet();
      }
    }
  }
  enterStateLast = enterState;
  
  //check up
  upState = digitalRead(upButtPin);
  if (upState != upStateLast)
  {
    if (upState == HIGH)
    {
      if (setVisible == true)
      {
        addMin();
        printSetTime();
      }
      else if (setVisible == false)
      {
        showSet();
      }
    }
  }
  upStateLast = upState;

  //check down
  downState = digitalRead(downButtPin);
  if (downState != downStateLast)
  {
    if (downState == HIGH)
    {
      if (setVisible == true)
      {
        subMin();
        printSetTime();
      }
      else if (setVisible == false)
      {
        showSet();
      }
    }
  }
  downStateLast = downState;
}

//displays the new time interface in the bottom of the LCD
void showSet ()
{
  //update new time variables to current RTC values
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  readRTCTime(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    setH = hour, DEC;
    setM = minute, DEC;

  //pints to the LCD
  lcd.setCursor(0,1);
  lcd.print("   New: ");
  printSetTime();
  setVisible = true;
}

//hides the new time interface
void hideSet ()
{
  clearLCD();
  setVisible = false;
}

//adds a minute to new time
void addMin()
{
  if (setM < 59)
  {
    setM++;
  }
  else if (setM == 59)
  {
    setM = 0;
    addHr();
  }
}

//subtracts a minute from new time
void subMin()
{
  if (setM > 0)
  {
    setM--;
  }
  else if (setM == 0)
  {
    setM = 59;
    subHr();
  }
}

//adds an hour to new time
void addHr ()
{
  if (setH < 23)
  {
    setH++;
  }
  else if (setH == 23)
  {
    setH = 0;
  }
}

//subtracts an hour from new time
void subHr ()
{
  if (setH > 0)
  {
    setH--;
  }
  else if (setH == 0)
  {
    setH = 23;
  }
}

//prints the new time values on the bottom of the LCD
void printSetTime()
{
 lcd.setCursor(8,1); 
 if (setH<10)
  {
    lcd.print("0");
  }
  lcd.print(setH);
  lcd.print(":");
  if (setM<10)
  {
    lcd.print("0");
  }
  lcd.print(setM); 
}

Tu peux encore brancher ton montage sur ton PC?
Le plus simple serait que tu écrives sur le port série, l'état de ton programme en différent point de celui-ci.

dans void printTime()

Dans le else je pense que tu devrais avoir
blinkOn = true;

Avec printTime() en commentaire, il ne doit pas se passer grand chose!

Autrement si ça fonctionnait et que d'un seul coup ça ne fonctionne plus rererevérifier le câblage et rererevérifier les soudures.

A noter dans une voiture, l'été, il fait très chaud. Pas sûr que le LCD apprécie.

Si le montage fonctionne sur breadboard, et ne fonctionne plus sur support imprimé, il y a des chances pour que l'on puisse soupçonner le câblage.
Qu'entends-tu par support imprimé ? un vrai PCB ?

Bonjour Sgt_McRae

Ce qui valide ton programme.

Ces symptômes ressemblent "furieusement" à des GND non ou mal connectés.
Contrôle que le GND du LCD, de la RTC, des boutons soient bien reliés au GND du Nano,
Contrôle, également, les connexions de l'alimentation +5V.

Cordialement
jpbbricole

L'heure s'affiche de nouveau après avoir décommenté. Génial.
Je ne peux qu'être coupable de cette erreur incompréhensible. Fatigue?

Le montage fonctionnait au stade prototype sur bread board. J'ai imprimé en 3d un support à intégrer au tableau de bord, sur lequel vient se monter l'affichage lcd.
Par dessus et à l'aide d'entretoises, j'a monté une platine (elle aussi imprimée en 3d) recevant le "terminal" Nano et le module RTC. Tout ça pour éviter les montages en l'air et que tout soit le mieux calé et le plus stable possible.

Les boutons fonctionnent sur le bread board (mais pas pour les heures) et les masses sont l'objet d'attention (vérif au métrix).

Par contre j'avoue que j'ai du mal avec les soudures sur mini poussoirs (6x6 mm) et fil AWG 26/28.
C'est du monobrin bien trop fin.... Mais je n'ai que ça, avec du multibrin AWG 18, bien trop gros lui.

Le monobrin se comporte mal en vibration. Pour un câblage définitif il vaut mieux soit :

  • utiliser du multibrin, solution à privilégier selon moi
  • accrocher les fils à la structure pour limiter les vibrations

Encore vérifier les soudures.
Faire un petit programme simple qui affiche l'état des boutons cela permet de mettre rapidement le doigt sur la liaison défectueuse.

Oui, je vais acheter du multibrin, le mono que j'ai casse comme un rien. Quel calibre serait adapté pour une utilisation générale? (plus fin que AWG 18, que je possède).

Autre chose: le "terminal qui vient de chez Amaz*n destiné à accueillir la Nano est un ramassis de faux contacts....
J'avais acheté ça pour remplacer les connecteurs à broche au pas de 2.54 que j'ai et dont le plastique fond beaucoup trop vite: impossible de faire des soudures.
Aurais tu une référence de bonne qualité?

Pour cette fois, je crois que je vais souder directement sur la Nano, mais je n'aime pas faire ça.

Les borniers à vis ce n'est pas trop adapté à du fil fin

Il faut faire attention en le dénudant de ne pas blesser le fil car cela crée une amorce de rupture. Si c'est dénudédans les règles le fil peut tenir longtemps.

Un AWG26 devrait faire l'affaire il n'y a pas de courant à faire passer et cela doit entrer dans les trous de la carte.

C'est pourtant le plus sûr. Il ne faut pas travailler avec une panne trop grosse pour éviter de faire des patés.

Voilà, c'est bon. J'ai viré les bp, juste gardé les résistances; je remplacerai les boutons par des modèles un peu plus gros et faciles pour moi à souder, mais il me faut refaire mes impressions 3d car les entraxes sont un poil juste rapprochés pour accueillir les bp 12x12 mm.... Pas possible de rattraper la chose :grimacing:
En attendant, j'ai l' heure dans la voiture!
Merci pour tout

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