PCF8574 double interruption?

Bonjour,
je me pose une question sur l'utilisation du composant PCF8574 qui permet de rajouter des e/s au µp et c'est sur son comportement au travers d'un simulateur: TinkerCAD
je ne sais pas si c'est le logiciel, ou ma programmation, ou un fonctionnement normal, et je souhaiterais avoir votre avis...

Lorsque je commence des projets, il m'arrive de tester des fonctionnement sous Tinkercad surtout quand je ne suis pas souvent chez moi pour tester en réel...
c'est ce qu'il se passe dans ce cas ou j'ai besoin de rajouter 8 entrées (boutons poussoir) au µp pour ce faire je souhaite utiliser un PCF8574 qui possède en plus de ses 8 ports paramétrables une patte permettant de signaler une interruption...
voici le schéma:

le code:

#include <Wire.h>

const byte adrPCF8574 = 0x20;

volatile boolean FlInterrupt0; //!volatile pour l'interruption
volatile boolean FlInterrupt1;

void setup()
{
  Serial.begin(9600);
  
  Wire.begin(); //initialisation du bus I2C
  
  Wire.beginTransmission(adrPCF8574); //test si le PCF8574 répond
  if(Wire.endTransmission() != 0) {
    Serial.print( "PCF8574 @?");
    while(1); //arret du pgm
  }
  
  //Passage des toutes les E/S du PCF8574 en "entrée"
  Wire.beginTransmission(adrPCF8574);
  Wire.write(0b11111111); // Mise à 1 des pins P7 à P0 du PCF8574
  Wire.endTransmission();

  Serial.println(); Serial.println();
  
  byte pinAction = 2; //l'interruption n°0 = pin n°2 (interr n°1=pin n°3)
  pinMode(pinAction, INPUT); 
  attachInterrupt(digitalPinToInterrupt(pinAction), FunInterrupt0, FALLING); // (FALLING/RISING)) attache l'interruption externe
  Serial.print("Interruption #"); Serial.print(digitalPinToInterrupt(pinAction));
  Serial.print(" Sur la Pin #");  Serial.println(pinAction);
 
  pinAction = 3; //l'interruption n°0 = pin n°2 (interr n°1=pin n°3)
  pinMode(pinAction, INPUT); 
  attachInterrupt(digitalPinToInterrupt(pinAction), FunInterrupt1, FALLING); // (FALLING/RISING)) attache l'interruption externe
  Serial.print("Interruption #"); Serial.print(digitalPinToInterrupt(pinAction));
  Serial.print(" Sur la Pin #");  Serial.println(pinAction);
 
  FlInterrupt0 = false;
  FlInterrupt1 = false;
}

//*****************************************************
//
void loop()
{
  if (FlInterrupt0) {
    Serial.println(F("interruption #0!!"));
    funPCF8574Get();
    FlInterrupt0 = false;
  }  
  if (FlInterrupt1) {
    Serial.println(F("interruption #1!!"));
    FlInterrupt1 = false;
  }  
}

//*****************************************************
// fonction de l'interruption
void FunInterrupt0 () { 
  FlInterrupt0 = true; //flag permettant d'aller dans la fonction
}

//*****************************************************
// fonction de l'interruption
void FunInterrupt1 () { 
  FlInterrupt1 = true; //flag permettant d'aller dans la fonction
}

//*****************************************************
//
void funPCF8574Get () {
  
  Wire.requestFrom(adrPCF8574, 1); //interrogation le PCF8574, 
  //en lui demandant de retourner 1 octet (qui contiendra l'état des broches P0 à P7)

  if(Wire.available()) {
    byte reponseDuPCF8574 = Wire.read();
    Serial.print(F("PCF8574 = "));
    Serial.print(reponseDuPCF8574, BIN);

    //affiche quelle broche est à l'origine de l'interruption (remarque : ne prend pas en compte les appuis simultanés)
    if(reponseDuPCF8574 == 0b01111111)  Serial.print(F("  ==> Déclanchement de la pin P7"));
    if(reponseDuPCF8574 == 0b10111111)  Serial.print(F("  ==> Déclanchement de la pin P6"));
    if(reponseDuPCF8574 == 0b11011111)  Serial.print(F("  ==> Déclanchement de la pin P5"));
    if(reponseDuPCF8574 == 0b11101111)  Serial.print(F("  ==> Déclanchement de la pin P4"));
    if(reponseDuPCF8574 == 0b11110111)  Serial.print(F("  ==> Déclanchement de la pin P3"));
    if(reponseDuPCF8574 == 0b11111011)  Serial.print(F("  ==> Déclanchement de la pin P2"));
    if(reponseDuPCF8574 == 0b11111101)  Serial.print(F("  ==> Déclanchement de la pin P1"));
    if(reponseDuPCF8574 == 0b11111110)  Serial.print(F("  ==> Déclanchement de la pin P0"));
    if(reponseDuPCF8574 == 0b11111111)  Serial.print(F("  ==> Toutes les entrees sont 'relachees'"));

    Serial.println("");
  }  
}  

le lien directe pour la simulation: Arduino PCF8574 interruption

le fonctionnement que je n'arrive pas à comprendre c'est en ouvrant le moniteur série, je clic sur le bouton a gauche du PCF8574 et cela me renvoie:

interruption #1!!

ici tous ce passe comme prévu , il y à qu'un seul allé dans l'interruption

mais quand je clic sur sur un bouton à droite du PCF8574 cela me revoie:

interruption #0!!
PCF8574 = 11110111  ==> Declanchement de la pin P3
interruption #0!!
PCF8574 = 11111111  ==> Toutes les entrees sont 'relachees'

on peut remarquer qu'il y a 2 passage dans l'interruption...
et quand je clic plus doucement la 1ère interruption à lieu lors de l’appuie sur le bouton, et la 2nde interruption lorsque je relâche le bouton...
pourtant que ce soit pour l'interruption 0 ou 1, elle sont toutes les 2 paramétrées sur "FALLING" dans la commande "attachInterrupt"

donc j'aimerais savoir si c'est un fonctionnement normal avant d'acheter le composant et dans ces condition je trouverais bien un pansement pour gérer ce fonctionnement...
ou peut être c'est ma programmation qui est encore une foi "chelou" ou encore c'est le simulateur qui est en cause....

quel est votre avis?

Je vous remercie

hello :grinning:

voir en page 2

Hummm si je comprends bien je souffre encore une fois du syndrome de celui qui n'a pas correctement lu la doc technique!! encore une fois...

donc l'interruption se déclenche lorsque qu'une patte passe à un état high à low ET de low à à high donc le fonctionnement que j'ai considéré comme anormal est tout à fait normal...
Soit... bon maintenant, il faut que j'imagine un fonctionnement pour aménager le fonctionnement comme je le voudrais...

merci dfgh!!!

Du coup, à savoir! je vais modifier le code de mon programme(dons je donne le lien), et donc il ne fonctionnera plus comme je le donne dans mon post initiale.

Bonjour,
Peut-être quelques éléments ici

merci @icare pour le lien, c'est tjs trés instructif!!

la sur mon projet je voulais évité d'utiliser les bibliothèques autant que possible, et si je n'y avait pas été arrivé je les aurais certainement utilisé.

mais maintenant ça fonctionne avec les petits ajustement :+1:
je redonne le lien: mon projet Tinkercad et il fonctionne maintenant!!!

Je pense aussi que tu souffre du syndromme de l’utilisation de composants antediluviens .
Le PCf 8574 peut avantageusement etre remplacé par un MCP 23017 (16 bits) il existe aussi en version 8 bits.

Ce composant est un Vrai bidirectionnel comme un entrée sortie de microcontroleur sans utiliser d’interruption.

Je pense que c'est plutôt du côté de Tinkercad que le problème se situe

Ce n'était pas une attaque personnelle.
En 2022, c'est ultra-pénible de voir que des sites puissent encore conseiller ces antiquités qui sont totalement obsolètes.

Signification originelle d'obsolète :
Qui fonctionne toujours parfaitement selon le fonctionnement prévu à la conception, mais qui est complètement dépassé par rapport aux produits modernes.

Je n'ai pas dit cela.
Que le PCF8574 soit toujours en vente ne me pose aucun problème, il est d'ailleurs souvent intégré à des modules afficheurs ou boutons pour lesquels il remplit parfaitement son rôle, mais Tinkercad pourrait proposer d'autres circuits plus modernes.

héhé j'ai 50 ans... cela explique peut être mes références...
si vous avez des composants modernes pour gérer du 8bit avec une gestion de l'interruption sur chacun des bit... je suis preneur...
viva la coopération!

merci a vous et vos commentaires

Hola, j'ai 65 ans, et je n'ai jamais utilisé Tinkercad.
Réponse à ta question : MCP23008, mais absent de Tinkercad.

Question : est-ce un réel besoin où c'est par analogie avec le PCF ne sait pas s'en sortir autrement qu'avec des interruptions ?

Le MCP que l'on te propose se comporte comme une entre /sortie de microcontrôleur.
Il y a des ordres à lui envoyer pour placer une voie soit en entrée, soit en sortie.

Une bibliothèque est disponible.

Ce qui fait, qu'à part que cela se passe en I2C , on l'utilise comme un GPIO de micro.

Bande de gamins, j'en ai 76 ! :grinning:

Ce sujet est mieux à sa place dans la partie générale que dans le bar, déplacement effectué.

merci @68tjs pour le déplacement et mes excuse sincère pour ne pas avoir eut l'intelligence de le mettre dans cet endroit dés le début...

l'interruption n'est pas un réel besoin, c'est plutôt une opportunité car je me dit que scanner en permanence les pattes d'un composant c'est consommer du temps pour d'autres fonctions...
c'est juste un avis totalement personnel et qui ne s'appuie sur aucun test...

et puis aussi il n'y à que ce composant dans tinkercad...

clap clap pour tes 65! tu est un barbu comme on dit de par chez moi :wink:

bon j'ai commandé des MCP23008 et je ferais mes tests hors simu... ça m'obligera a retourner dans ma grotte...

La question est à se poser, en effet.
Quel intérêt de procéder par interruption ? Mis à part pour réveiller un processeur en deep-sleep, je ne vois pas. Mais dans ce cas pourquoi choisir une UNO, qui consomme un max d'énergie ?

En général quand on scanne des boutons-poussoirs on n'est pas à la µs près.
Avec un bus I2C à 400KHz par défaut (modifiable) le temps n'est pas un problème.
La question à se poser est plutôt : pendant l'exécution d'une fonction X, la durée de traitement de ladite fonction va t-elle empêcher la lecture des boutons ?

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