PCF8574: Lire les pins

Bonjour

Je débute avec le Arduino. 1' post sur le forum Français, mais quelques un sur le forum Anglais.

J'ai un problème de lire les pins sur un pcf8574. Je peux écrire, mais les lectures me donne toujours une valeur "LOW" sur les pins. J'ai besoin d'avoir un niveau "HIGH" afin de lire lorsque mon bouton a été utilisé 9donne une valeur LOW).

J'utilise la libraire #include "PCF8574.h"

J'ai essayé avec INPUT_PULLUP.

Si je set une des pins comme output, je peux lui donner une valeur "HIGH". Aussitôt que je configure la même pin comme input, celle-ci est maintenue LOW.

Une idée comment résoudre le problème?

Martin
Montréal, Canada

Bonjour,

Il n'y a pas de pullup interne dans le pcf8574.
Il faut un pullup externe (ou pulldown externe).
Voilà ce qu'on peut lire dans pcf8574.h

  • @remarks INPUT_PULLUP does physicaly the same thing as INPUT (no software pull-up resistors available) but is REQUIRED if you use external pull-up resistor

Cela ne va pas t'aider pour l'immédiat mais le PCF8574 est une antiquité qui comme le DS1307 traîne dans le monde arduino pour des raisons que je ne comprends pas.
La prochaine fois approvisionne plutôt un MCP23017 (au même prix) qui bien plus récent et qui est bien plus simple à utiliser. Le MCP23017 est réellement bidirectionel alors que le PCF8574 n'est que "quasi" bidirectionnel.

Pour utiliser la possibilité de "quasi" bidirectionnel il faut surveiller une interruption du PCF8574 et toutes les bibliothèques ne la gère pas.
Si tu fait des fouilles "archéologiques" sur ce forum francophone tu trouvera une bibliothèque mise au point par un certain nombre de bénévoles.

Je pense avoir trouvé : GitHub - skywodd/pcf8574_arduino_library: PCF8574 / PCF8575 Arduino library (version 2.0)

Bonjour,

Avec le 8574, il faut obligatoirement des résistances de tirage (pull-up) vers le VCC.
Pour une entrée, 10k à 47k conviennent bien. Moins pour une sortie (1k), pour pouvoir fournir un peu de courant quand la sortie est à "1".
Le plus important est que pour qu'une patte fonctionne en entrée, il faut écrire un "1" dessus. Sinon, le drain ouvert court-circuite la patte vers le GND et on lit toujours un "0". Ce qui vous arrive.

Si votre bibliothèque ne gère pas cela, virez la, et utilisez directement Wire.

Le bon côté de la rusticité du 8574 est qu'il est vraiment simple à utiliser : on lit et on écrit directement sur les pattes de sortie, pas de registres à configurer.

Bonne bidouille,

Fred de MicroQuettas

PS : les interruptions, c'est si on veut être prévenu d'un changement de niveau. En général, il n'y en pas besoin.

68tjs:
La prochaine fois approvisionne plutôt un MCP23017

Ou un MCP23008 ou MCP23S08 (spi), 8 bits comme le PCF8574.

Je n'avais que la référence du 16 bits en tête mais quand on a l'une l'autre n'est pas bien loin.
Franchement je préfère programmer avec la version I2C qu'avec la SPI qui m'a paru un peu spéciale ou alors je n'ai pas tout compris.

@MicroQuettas :
Le circuit MCP est un vrai bidirectionnel : comme pour un microcontrôleur pour chaque chemin tu fixe par programmation la direction entrée ou sortie.
Le PCF n'a réellement qu'une seule direction (sortie), tu peux forcer le signal sur une sortie sans la détruire. Le PCF s'en aperçoit et il génère signal, qui doit être capté par une interruption, pour dire "on m'a forcé une sortie mais je ne sais pas dire laquelle". Il faut alors "lire" les sorties une par une pour voir celle qui a été forcée. C'est bien pour cela que son concepteur a pris la précaution de le qualifier de "pseudo" bidirectionnel.
Un peu lourd non ?

Et les MCP23008 et MCP23017 possèdent des pull-ups et pull-down.

@ 68tjs,

Le 8574 est une antiquité, un faux bidirectionnel, je suis d'accord.
Mais quand on en a un sous la main, on peut l'utiliser sans problème et ce n'est ni lourd ni compliqué.

Il n'est pas besoin de l'interruption pour savoir quelle "sortie" a été forcée à 0. Il suffit tout simplement de lire l'unique registre et la "sortie" en question se lit bien à "0" si elle a été écrite à "1".
On lit les 8 "sorties" d'un coup, pas une par une...
J'utilise comme cela pour "ajouter des pattes" à un ESP8266 en entrée et sortie avec le même 8574 et ça marche pile-poil.
L'interruption ne sert que si on veut être prévenu d'un changement.

Je viens de vérifier sur la datasheet du 8574 et du 8574A qu'il ont tous les 2 un générateur de courant de 100µA faisant office de pull-up en entrée, si la patte en question a bien été écrite à "1". La pull-up en entrée ne serait donc pas strictement nécessaire, mais cela ne fait de mal de la mettre.

Bonne bidouille,

Fred de MicroQuettas

Mais quand on en a un sous la main, on peut l'utiliser sans problème

Tout à fait d'accord avec ce cas de figure, mais il me semble que pour quelqu'un qui se lance dans le domaine c'est dommage de prendre des Ds1307 ou des PCF8574 tout comme des 7805, autant partir sur des bases plus actuelles, ce n'est qu'un avis.

68tjs:
Tout à fait d'accord avec ce cas de figure, mais il me semble que pour quelqu'un qui se lance dans le domaine c'est dommage de prendre des Ds1307 ou des PCF8574 tout comme des 7805, autant partir sur des bases plus actuelles, ce n'est qu'un avis.

+1
Quand tu a du stock et/ou l'habitude de les utiliser , çà ne pose pas de problémes
7805 çà m'arrive encore assez souvent par quasi réflexe pavlovien 8) (et ce n'est pas ce qu'il me manque en # boitiers)
PCF8574 je dois en avoir encore qq'uns qui trainent et je ne vais pas chercher à en approvisionner d'autres
DS1307 idem

Problème résolu en mettant en niveau "HIGH" avent de lire les pins

Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(0x20);
  Wire.write(0xff); // put a high level on pins
  Wire.endTransmission();

void readbouton()
 {
  byte _data;
  const int debounce = 225;
 
  Wire.begin();
 
  Wire.requestFrom(0x20, 1);
  if(Wire.available()) {
    _data = Wire.read();

    if (_data == 254){ Serial.println ("bouton S1");
    delay(debounce);}
//
//
}