PCF8574 sur I2C

Bonjour à tous,

Je vous poste ce message car je suis complétement perdu.

Je souhaite faire passer toutes les sorties de mon PCF8574 de l'état haut (+5V) à l'état bas (0V) juste pour tester son bon fonctionnement.

J'ai lui attentivement la datasheet de ce composant et j'ai bien fait attention à la différence d'adressage entre le PCF8574 et le PCF8574A.

Donc sur les pins :
1 (A0) : +5V
2 (A1) : +5V
3 (A2) : 0V
4 (P0) : NC
5 (P1) : NC
6 (P2) : NC
7 (P3) : NC
8 (Vss) : GND
9 (P4) : NC
10 (P5) : NC
11 (P6) : NC
12 (P7) : NC
13 (/INT) : NC
14 (SCL) : Arduino Analog pin 5
15 (SDA) : Arduino Anolog pin 4
16 (Vdd) : +5V

Et voici le code que j'ai implanté dans l'arduino Uno :

#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {

  //Toutes les sorties mises à 1
  digitalWrite(13, HIGH);
  Wire.beginTransmission(B0100011); // adresse sur 7 bits
  Wire.send(B11111111);
  Wire.endTransmission();
  delay(1000);
  
   //Toutes les sorties mises à 0
  digitalWrite(13, LOW);
  Wire.beginTransmission(B0100011); // adresse sur 7 bits
  Wire.send(B00000000);
  Wire.endTransmission();
  delay(1000);

  }

Je dispose d'un oscilloscope pour vérifier l'état de mes sorties et elles restent à +5V...

Si quelqu'un a une piste...

Merci d'avance
Romain

Utilise Wire.write à la place de Write.send !

Lit les modifs de va 1.0 :

  • The Wire library has also been modified to use the standard read() and
    write() functions instead of send() and receive(). You can also use
    print() and println() for outgoing data.

Bonjour,

rhum187:
J'ai lui attentivement la datasheet de ce composant et j'ai bien fait attention à la différence d'adressage entre le PCF8574 et le PCF8574A.

Je dispose d'un oscilloscope pour vérifier l'état de mes sorties et elles restent à +5V...

C'est un probléme d'adresse ! :wink:
D'après ton câblage tu as A0 = 1, A1 = 1, A2 = 0, soit 011 = 3.
Dans ton code tu utilise l'adresse 0x23, je suppose donc que tu utilise un PCF8574(P) (pas la version A).
L'adresse de base d'un PCF8574P est 0x20, sur un bus I2C il y a deux adresses par module, une de lecture et une d'écriture.
Donc :
N° -> adresse
1 : 0x20
2 : 0x22
3 : 0x24 // Ton code devrais utiliser celle ci
4 : 0x26
5 : 0x28
...

Voilelec:
Utilise Wire.write à la place de Write.send !

On ne sait même pas si il travaille sous arduino 1.0 pas la peine de s'emballer, surtout qu'il ne dit pas que le code ne compile pas :wink:

Cadeau
Une petite lib pour PCF8574

3 fonctions d'écriture pratique :
void Write( byte _data ); // écrit un octet entier
void WriteBit( byte _bit, byte _data ); // écrit un bit donné (_bit de 0 à 7, _data : la valeur du bit (0 ou 1)
void WriteMask( byte _mask, byte _data); // écrit un ensemble de bits spécifié par un masque (par exemple WriteMask( 0x55, 0x0F ) va positionner les bit 0 et 2 à 1 et les bits 4 et 6 à 0 laissant les autres intouchés)

pcf8574.zip (1.43 KB)

barbudor:
Cadeau
Une petite lib pour PCF8574

Je voulais pas faire de pub mais bon je m'y vois forcé :grin:

J'ai aussi une librairie pour le PCF8574 dans mes tiroirs :wink:

(Les fonctions sont équivalentes aux fonctions arduino standard, pinMode, digitalWrite, ...)

Comment on fait pour télécharger le ZIP ?
GoogleDocs ouvre le Zip et montre les contenus mais je n'arrive pas à le récupérer.

EDIT: Apparemment un fois qu'on l'a ouvert, il apparaît dans ses propres GoogleDocs et on peut le télécharger de là...

Bonjour et merci à tous pour vos réponses rapides.

Tu as vu juste Skyworld, j'utilise bien un PCF8574 (pas la version A). Mais pourquoi penses-tu que l'adresse à utiliser est la 0x24 ? D'après ce que j'ai pu lire dans la datasheet, le bit de lecture/écriture n'intervient pas dans l'adresse...

J'ai quand même essayer avec l'adresse 0x24, mais toujours la même chose : 5V sur les pins P0...P7 :

#include <Wire.h>

#define adressePCF 0x24

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {

  //Toutes les sorties mises à 1
  digitalWrite(13, HIGH);
  Wire.beginTransmission(adressePCF); // adresse sur 7 bits
  Wire.send(0xFF);
  Wire.endTransmission();
  delay(1000);
  
   //Toutes les sorties mises à 0
  digitalWrite(13, LOW);
  Wire.beginTransmission(adressePCF); // adresse sur 7 bits
  Wire.send(0x00);
  Wire.endTransmission();
  delay(1000);

  }

Je dispose aussi d'un PCF8574A. Dans le cas où les pins d'adressage (A0, A1 et A2) sont connectées de manière identiques, quelle adresse dois-je utilisé ? B1110110=0x76 ?

PS : Merci pour les librairies mais pour l'instant je ne souhaite pas en utiliser

Même si tu ne veux pas utiliser les libs regarde les code.
Notamment dans mon fichier H il y a une fonction qui retourne la bonne adresse de base à partir de la valeur A2/A1/A0
Dans ton cas A2:A1:A0 = 1:1:0 = 6
GetAddress( 6, false ) pour un 8754
GetAddress( 6, true ) pour un 8754A

Salut,

1 (A0) : +5V
2 (A1) : +5V
3 (A2) : 0V

Ouais, j'avais regardé mais ça n'est pas 6... c'est plutôt 3 avec une adresse de base de 0x20.

C'est la raison pour laquelle j'avais mis 0x23 au début...

J'ai essayé avec pas mal d'adresse et je n'ai toujours aucune réponse de mes PCF...

D'autres idées ? :slight_smile:

Pardon, j'avais lu les bits dans le mauvais sens 110 au lieu de 011 :frowning:
Tu as raison c'est 3

J'ai pas mon matos ici au bureau :wink:
Je revérifie ce soir sur breadboard si tu n'as pas trouvé d'ici là.

Ben ouais je veux bien c'est gentil car là ça fait 3 jours que je bloque complet sur le problème... je ne vois vraiment pas d'où ça peut venir... je penche pour un problème électrique car mon code a déjà fonctionné... c'est depuis un court-circuit sur un régulateur que mon PCF ne fonctionne plus (je l'ai bien sur changé c'est donc le neuf que je n'arrive pas à faire fonctionner)

Je confirme avec mon PCF8574P (donc non-A) avec

  • A0 pin 1 = VCC
  • A1 pin 2 = VCC
  • A2 pin 3 = GND
    Il répond très bien avec ton code à l'adresse 0x23 (code à peine modifié pour fonctionner avec l'IDE 1.0)
#include <Wire.h>


#define PCF8574P_ADDRESS(sub) (0x20+(sub))
#define PCF8574A_ADDRESS(sub) (0x38+(sub))

#define adressePCF PCF8574P_ADDRESS(0x3)

void setup()
{
  Wire.begin();
  Serial.begin(9600);
 Serial.print( "Adresse = " );
 Serial.println( adressePCF, HEX );
  pinMode(13, OUTPUT);
}

void loop() {

  //Toutes les sorties mises à 1
  digitalWrite(13, HIGH);
  Wire.beginTransmission(adressePCF); // adresse sur 7 bits
  Wire.write((byte)0xFF);
  Wire.endTransmission();
  delay(1000);
  
   //Toutes les sorties mises à 0
  digitalWrite(13, LOW);
  Wire.beginTransmission(adressePCF); // adresse sur 7 bits
  Wire.write((byte)0x00);
  Wire.endTransmission();
  delay(1000);

  }

rhum187:
Tu as vu juste Skyworld, j'utilise bien un PCF8574 (pas la version A). Mais pourquoi penses-tu que l'adresse à utiliser est la 0x24 ? D'après ce que j'ai pu lire dans la datasheet, le bit de lecture/écriture n'intervient pas dans l'adresse...

Ha ... j'ai toujours pensé qu'il fallait compter le bit R/W ... depuis le temps que j'ai pas touché à un PCF j'ai bien pu dire une boulette :grin:

barbudor:
Je confirme avec mon PCF8574P (donc non-A) avec

  • A0 pin 1 = VCC
  • A1 pin 2 = VCC
  • A2 pin 3 = GND
    Il répond très bien avec ton code à l'adresse 0x23 (code à peine modifié pour fonctionner avec l'IDE 1.0)

Bon bin oublie ce que j'ai dis ... si ça répond sur 0x23 pour barbudor c'est que c'est ça.

Bizarre va falloir que je relise the fucking manual :grin:

skywodd:
Bizarre va falloir que je relise the fucking manual :grin:

The Fucking Datasheet XD v--- ci dessous

Oui je me doutais que ça allait fonctionner chez toi sans problème... et que ça allait me laisser sans piste... je vais bosser dur dessus jusqu'en fin de semaine. Je vous tiens au courant si je trouve la solution.

Merci à tous.

Tu as plusieurs chips à essayer ?
Problème de câblage ? Une p'tite photo ?

Problème résolu !

Un PCF grillé relié par l'intermédiaire d'un autre carte... je ne l'avais pas vu...

Merci à tous de votre aide !

EDIT : Question annexe : Vous pensez que ,dans le cadre d'un robot à plusieurs modules contenant 1 pcb/module, le bus I2C était le mieux adapté pour communiquer ?

rhum187:
EDIT : Question annexe : Vous pensez que ,dans le cadre d'un robot à plusieurs modules contenant 1 pcb/module, le bus I2C était le mieux adapté pour communiquer ?

Sur des distances inférieur à 1m et dans le cadre d'une communication entre modules w/ adresses, le tout à "basse" vitesse, l'I2C est le choix le plus approprié.

Phillips n'as pas inventé l'I2C et ne la pas intégré dans ses téléviseurs pour rien :wink:

Bonjour à tous,

Le post est un peu vieux mais je souhaitais utilisé des PF8574. Mes 1er essaie était vraiment concluant mais la distance était relativement faible entre l'arduino et les 2 modules qui pilotait une carte avec 16 relais.

Mon problème: Sur un projet de gestion d'un aquarium, j'aimerais mette un arduino dans la rampe d'éclairage. Ge gere la rampe d’éclairage LED bien sur mais j'aimerais gérer tout le reste se trouvant lui sous l'aquarium. D’où l'utilisation des PCF8574. Seulement j'ai peur aux interférences au vous avez aussi évoqué. Surtout que les cartes électroniques étant rudimentaire ne sont pas forcement ce qu'il y a de mieux au niveau blindage.

J’aurais donc effectivement plus d'un mettre de câble I2C sur cordon type RJ11. J'ai donc peur du resultat.

J'avais pensé aussi à utiliser 2 arduino MEGA. L'un dans la rampe avec l’écran et l'autre sous le bac, autonome, mais récupérant les info du 1er pour se paramétrer et donner les mesures, en I2C aussi mais avec un contrôle par checksum par exemple pour limiter les erreurs. Mais ne serait t'il pas plus judicieux de le faire dans ce cas par un port série, peut être plus robuste. Surtout si l'on ajoute des MAX232 entre chaque.

Une idée

Tkt pas pour les interférences ... J'ai déjà fait des montages à plusieurs mettre d'écart en i2c, avec les pull up interne de l'Atmega de surcroît. Donc avec des "vraies" résistance de pull up à 1m tu ne devrais pas avoir de soucis, surtout que de base l'Arduino travaille en i2c "mode lent" donc on est immunisé contre pas mal de chose