Lcd I2C bloquant ?

Bonjour à tous.

Je pêche sur un problème qui je pense est assez simple mais je ne vois pas quel est mon erreur.

Il y a de cela 2 ans j'ai programmé une Arduino Mega avec un shield lcd+keypad.
Le tout fonctionne très bien à ce jour.
Je dois installer une carte identique et ayant le même programme.
Du coup je me lance dans quelques tests pour vérifier.

Le programme est donc similaire, la variante est que le lcd est en I2C à présent et j'ai utilisé une Leonardo car la Mega est une mini que souderait sur une PCB sur mesure.
Ma carte de test est simple (et c'est la même que le 1er montage) des connecteur phoenix contacts 5.08 avec une résistance de 10k en pull down pour chaque contact.

Le soucis est que le programme se "bloque" a HORLOGE OFF CDE INTRATONE
Si je reset la carte et que je ponte l'entrée horloge alors je bloque sur HORLOGE ON CDE INTRATONE
Une fois bloqué, quel que soit mes actions, l'écran et les relais en 10 et 11 ne changent pas d'état. D'ailleurs les relais ne colle à aucun moment.
J'ai aussi intervertit l'entrée Intratone avec lecteur ext par exemple mais c'est toujours CDE INTRATONE qui reste affiché.

Pour moi la grosse différence et l'utilisation de l'I2C, je n'ai malheureusement pas de LCD classique pour tester sans I2C

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);

/*-----ENTREES-ET-SORTIES----*/
int contact_cle = 0;
int bouton_portail = 8;
int bouton_barriere = 7;
int lecteur_int = 2;
int boucle_magnetique = 5;
int lecteur_ext = 4;
int horloge = 1;
int intrabox_relais_2 = 3;
int ouverture_barriere = 10;
int ouverture_portail = 11;

/*-----LISTING-ETATS-----*/
enum etat : byte {
  PROGRAMME_DEBUT,
  PROGRAMME_EN_ATTENTE,
  PROGRAMME_HORLOGE_INACTIVE,
  PROGRAMME_HORLOGE_ACTIVE,
  PROGRAMME_MAINTENANCE,
  SORTIE_COMMANDE
};
etat etat_programme = PROGRAMME_DEBUT;


void setup() {                    
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Gestionnaire     ");
  delay (800);
  lcd.setCursor(0, 1);
  lcd.print("Multi-Commandes ");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("GMC             ");
  delay (800);
  lcd.setCursor(0, 1);
  lcd.print("v0.93           ");
  delay(1000);

  pinMode(contact_cle, INPUT);
  pinMode(bouton_portail, INPUT);
  pinMode(bouton_barriere, INPUT);
  pinMode(lecteur_int, INPUT);
  pinMode(boucle_magnetique, INPUT);
  pinMode(lecteur_ext, INPUT);
  pinMode(horloge, INPUT);
  pinMode(intrabox_relais_2, INPUT);
  pinMode(ouverture_barriere, OUTPUT);
  pinMode(ouverture_portail, OUTPUT);
  lcd.clear();
}


void loop() {
  programme_normal();
}

void programme_normal() {

  switch (etat_programme) {


    case PROGRAMME_DEBUT:
      /*analogWrite(retroeclairage, 100);*/
      lcd.clear();
      digitalWrite(ouverture_barriere, LOW);
      digitalWrite(ouverture_portail, LOW);
      etat_programme = PROGRAMME_EN_ATTENTE;
      break;


    case PROGRAMME_EN_ATTENTE:
      if ((digitalRead(contact_cle) == HIGH) && (digitalRead(horloge) == LOW)) {
        digitalWrite(ouverture_barriere, HIGH);
        digitalWrite(ouverture_portail, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE OFF     ");
        etat_programme = PROGRAMME_HORLOGE_INACTIVE;
      }
      if ((digitalRead(contact_cle) == HIGH) && (digitalRead(horloge) == HIGH)) {
        digitalWrite(ouverture_barriere, LOW);
        digitalWrite(ouverture_portail, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE ON      ");
        etat_programme = PROGRAMME_HORLOGE_ACTIVE;
      }
      if (digitalRead(contact_cle) == LOW) {
        digitalWrite(ouverture_barriere, LOW);
        digitalWrite(ouverture_portail, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        etat_programme = PROGRAMME_MAINTENANCE;
      }
      break;


    case PROGRAMME_HORLOGE_INACTIVE:
      if (digitalRead(horloge) == HIGH) {
        etat_programme = PROGRAMME_DEBUT;
      }
      if ((digitalRead(horloge) == LOW) && (digitalRead(boucle_magnetique) == HIGH)) {
        digitalWrite(ouverture_portail, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE OFF     ");
        lcd.setCursor(0, 1);
        lcd.print("DETECTION BOUCLE");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if ((digitalRead(horloge) == LOW) && (digitalRead(lecteur_int) == HIGH)) {
        digitalWrite(ouverture_portail, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE OFF     ");
        lcd.setCursor(0, 1);
        lcd.print("LECTEUR INT     ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if ((digitalRead(horloge) == LOW) && (digitalRead(lecteur_ext) == HIGH)) {
        digitalWrite(ouverture_portail, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE OFF     ");
        lcd.setCursor(0, 1);
        lcd.print("LECTEUR EXT     ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if ((digitalRead(horloge) == LOW) && (digitalRead(intrabox_relais_2) == HIGH)) {
        digitalWrite(ouverture_portail, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE OFF     ");
        lcd.setCursor(0, 1);
        lcd.print("CDE INTRATONE   ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if (digitalRead(contact_cle) == LOW) {
        digitalWrite(ouverture_barriere, LOW);
        digitalWrite(ouverture_portail, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        etat_programme = PROGRAMME_MAINTENANCE;
      }
      break;


    case PROGRAMME_HORLOGE_ACTIVE:
      if (digitalRead(horloge) == LOW) {
        etat_programme = PROGRAMME_DEBUT;
      }
      if ((digitalRead(horloge) == HIGH) && (digitalRead(boucle_magnetique) == HIGH)) {
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE ON      ");
        lcd.setCursor(0, 1);
        lcd.print("DETECTION BOUCLE");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if ((digitalRead(horloge) == HIGH) && (digitalRead(lecteur_int) == HIGH)) {
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE ON      ");
        lcd.setCursor(0, 1);
        lcd.print("LECTEUR INT     ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if ((digitalRead(horloge) == HIGH) && (digitalRead(lecteur_ext) == HIGH)) {
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE ON      ");
        lcd.setCursor(0, 1);
        lcd.print("LECTEUR EXT     ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if ((digitalRead(horloge) == HIGH) && (digitalRead(intrabox_relais_2) == HIGH)) {
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("HORLOGE ON      ");
        lcd.setCursor(0, 1);
        lcd.print("CDE INTRATONE   ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if (digitalRead(contact_cle) == LOW) {
        digitalWrite(ouverture_barriere, LOW);
        digitalWrite(ouverture_portail, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        etat_programme = PROGRAMME_MAINTENANCE;
      }
      break;


    case PROGRAMME_MAINTENANCE:
      if (digitalRead(contact_cle) == HIGH) {
        etat_programme = PROGRAMME_DEBUT;
      }
      if (digitalRead(boucle_magnetique) == HIGH) {
        digitalWrite(ouverture_portail, HIGH);
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        lcd.setCursor(0, 1);
        lcd.print("DETECTION BOUCLE");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if (digitalRead(lecteur_int) == HIGH) {
        digitalWrite(ouverture_portail, HIGH);
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        lcd.setCursor(0, 1);
        lcd.print("LECTEUR INT     ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if (digitalRead(lecteur_ext) == HIGH) {
        digitalWrite(ouverture_portail, HIGH);
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        lcd.setCursor(0, 1);
        lcd.print("LECTEUR EXT     ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if (digitalRead(intrabox_relais_2) == HIGH) {
        digitalWrite(ouverture_portail, HIGH);
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        lcd.setCursor(0, 1);
        lcd.print("CDE INTRATONE   ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if (digitalRead(bouton_portail) == HIGH) {
        digitalWrite(ouverture_portail, HIGH);
        digitalWrite(ouverture_barriere, LOW);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        lcd.setCursor(0, 1);
        lcd.print("BOUTON PORTAIL  ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      if (digitalRead(bouton_barriere) == HIGH) {
        digitalWrite(ouverture_portail, LOW);
        digitalWrite(ouverture_barriere, HIGH);
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("MODE MAINTENANCE");
        lcd.setCursor(0, 1);
        lcd.print("BOUTON BARRIERE ");
        delay (200);
        etat_programme = SORTIE_COMMANDE;
      }
      break;


    /*-----Programme permettant de sortir après une commande-------*/
    case SORTIE_COMMANDE:
      if ((digitalRead(boucle_magnetique) == LOW) && (digitalRead(lecteur_int) == LOW) && (digitalRead(lecteur_ext) == LOW) && (digitalRead(intrabox_relais_2) == LOW) && (digitalRead(bouton_portail) == LOW) && (digitalRead(bouton_barriere) == LOW)) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("PROUT");
        lcd.setCursor(0, 1);
        lcd.print("PROUT");
        etat_programme = PROGRAMME_DEBUT;
      }
      break;
  }
}

Bonjour,

Je suppose qu'il y a 2 problèmes possibles.

1/ De ce que j'ai compris du bus I2C, il fonctionne avec SDA et SCL bidirectionnels en PULLUP, le PULLUP est je présume realisé sur la carte I2C de l'afficheur.

Et toi tu écris

Sur les lignes SDA et SCL, PULLUP + PULLDOWN, c'est contradictoires, il faudrait enlever les PULLDOWN selon moi.

2/ Sur la carte Leonardo, si tu utilise l'I2C, il ne faut pas utiliser en même temps les broches 2 et 3 qui sont respectivement reliées aux broches SDA et SCL

I2C Leonardo

Essaye d'attribuer d'autres broches dispo à

int lecteur_int = 2;
int intrabox_relais_2 = 3;

Voilà mes suggestions.

Bonne continuation.

Bien vu. Cela ne peut pas fonctionner.

Un étage de sortie I2C c'est cà :


Le circuit n'est pas fini volontairement pour pouvoir ajouter la résistance à l'extérieur du CI.

Si tu met un pull-down, c'est à dire en français une résistance entre la sortie SDA (ou la sortie SCL) et la masse il ne passera aucun courant dans le transistor.
La sortie SDA (ou SCL) sera bloquée à 0 V

Mais comme la bibliothèque Wire active d'office la pull-up interne de la sortie du micro, tu fais un pont diviseur entre environ 30k (pull-up micro) et la résistance que tu as ajouté.
D'où la remarque de @jef59 .

Pardon, j'ai mal détaillé. Seuls mes entrées ont des résistances Pull Down.
Je n'ai ajouté aucune résistance sur les sorties SDA, SCL, 10 et 11.

Bien vu pour la remarque sur les pins 2 et 3

En effet cela a résolu le problème

Merci

Bonne nouvelle.