Go Down

Topic: [Résolu] I2C PCF8574A (Read 729 times) previous topic - next topic

Microbulle

Oct 31, 2012, 02:37 pm Last Edit: Oct 31, 2012, 06:16 pm by Microbulle Reason: 1
Re bonjour,

Dans un autre registre et par ce que je n'ai pas trouver la solution, je cherche à communiquer avec un PCF8574A.

Si je respecte son adresse 0111 + A2 = 0 + A1 = 1 + A0 = 0 + 1 = Lecture soit B01110101
J'ai 4 boutons reliés à mon PCF. Je cherche donc à avoir leur état dans un Serial.println().

J'ai remarqué que je n'avais que -1 en permanence ! Du coup, je me suis dit, comment ça se fait ? Et là et bien j'ai beau regarder les tutoriels, je ne voie pas pourquoi !

- J'ouvre la connexion
- Je demande l'adresse B01110101
- ACK
- J'attends les données issue du port
- ACK
- Fin de connexion.

Au niveau code, j'ai fait ceci:
Code: [Select]

/*
 2 <- Interruption
 
 A4 -> SDA
 A5 -> SCL
*/
#include <Wire.h>

#define adresseBtn B01110101  //0111 010 1

void setup() {
 Serial.begin(9600);
 
 
}

void loop() {
 
 Wire.begin();
 Wire.beginTransmission(adresseBtn);
 
 Serial.println(Wire.read());
 
 Wire.endTransmission();  //Ferme la connexion sur SDA et SCL
 
 delay(1000);
}


Voila, s'il y en a qui peuvent m'indiquer ou ça pèche, je suis preneur.
Merci.

papybricol

Wire.requestFrom    avant  Wire.read    ?
exemple de lecture du bus I2C, dans http://arduino.cc/en/Tutorial/SFRRangerReader 
...
Code: [Select]
Wire.requestFrom(112, 2);    // request 2 bytes from slave device #112

  // step 5: receive reading from sensor
  if(2 <= Wire.available())    // if two bytes were received
  {
    reading = Wire.read();  // receive high byte (overwrites previous reading)
    reading = reading << 8;    // shift high byte to be high 8 bits
    reading |= Wire.read(); // receive low byte as lower 8 bits
    Serial.println(reading);   // print the reading
  }

...
...ils embarquèrent la logique, coupèrent les cordons, alors, libérés de leurs chaînes, une immensité s'ouvrait devant eux...

Microbulle

Justement, j'ai essayer sans succès !

C'est pour ça que je tourne mon code de façon à correspondre à la conversation du PCF avec la uno.

D'ailleurs, je voie pas pourquoi ils ajoutent ce Wire.requestFrom(). D'autant plus qu'on à un read() !

Ensuite, a quoi correspond 112 ?

barbudor

Comment sont cablés tes boutons ?
As tu lu la doc du PCF sur le fonctionnement des broche "quasi-bidirectionelles" ? c'est très spécial !
Voir section 7.3 de la datasheet ainsi que le schéma interne au début du chapitre 7

En gros : une broche I/O de PCF peut fonctionner soit en entrée, soit en sortie mais il n'y a pas de registre de direction comme sur les ports I/O de l'ATmega.

Pour utiliser une broche en entrée il faut préalablement écrire cette broche à 1 (état HAUT).
Alors la broche dispose d'un pull-up faible et peut être "drivée" par un signal externe.
Si elle n'est pas connectée ou reçoit un signal haut, elle sera lue à HIGH (1)
Si elle reçoit un signal bas, elle sera lue à LOW (0)

En sortie, tu peux écrire LOW ou HIGH sur la broche. Si tu écris LOW alors la pin sort un signal bas acceptant jusqu'à -25mA. Mais si tu écris un HIGH, alors la broche est dans l'état ci-dessus avec un pull-up faible ne pouvant fournir que 300µA.

En clair, il faut pratiquement considérer les broches d'un PCF comme des collecteurs ouverts.

En résumé, pour lire un bouton poussoir un seul montage fonctionne (une fois que tu as écris HIGH dans les broches correspondantes) : Pull-up vers VCC et bouton poussoir vers la masse.
Un bouton pressé se lit alors comme un LOW (0).

De même si tu souhaite allumer un LED sur une broche de PCF, il faut la relier au VCC (+résistance) et l'allumer par un LOW. Aucune chance de pouvoir l'allumer en la reliant vers le GND (+résistance) avec un HIGH.


Coté code, tu peux récupérer ou t'inspirer de ma lib ci-jointe ou de celle de Skywodd sur son blog.
Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Microbulle

Electroniquement parlant le montage à déjà fonctionné avec un PIC. Donc je part du principe que l'élec est OK !

Moi j'aimerais surtout savoir ce qu'envoie réelement sur le bus la commande Wire.requestFrom();

Car si tu lui met une adresse et qu'elle envoie pas ce qui faut, je peux toujours attendre un ACK !

papybricol

112 c'est l'adresse (pour l'I2C) du périphérique esclave à lire (le SFR08 dans l'exemple Arduino)

en réalité les 7 bits de poids fort de l'adresse réelle (224 pour le SFR08)
procédure imposée par le protocole I2C, lequel va joindre un bit LSb=1 pour lire ou LSb=0 pour écrire.

Pour les PCF8574A voir si l'adresse est celle réelle ou celle à déduire pour l'I2C (sur les 7bits de poids fort) souvent source de confusion! :smiley-roll-sweat:




   
...ils embarquèrent la logique, coupèrent les cordons, alors, libérés de leurs chaînes, une immensité s'ouvrait devant eux...

barbudor

Il ne faut pas prendre en compte le bit R/W dans l'adresse à fournir à la lib Wire.
Le bit de direction est ajouté automatiquement par le hardware.

Cf ma lib qui gère très bien les PCF8574 et PCF8574A (attention ce ne sont pas les mêmes adresses pour l'un et l'autre !!!)
Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Microbulle

Et bien voila ! J'ai trouvé !!! C'est le fameux 1 qui fichais le bazard.  :smiley-mr-green:

Code: [Select]

/*
  2 <- Interruption
 
  A4 -> SDA
  A5 -> SCL
*/
#include <Wire.h>

void setup() {
  Serial.begin(9600);
}

void loop() {
 
  byte _data;
 
  Wire.begin();
 
  Wire.requestFrom(B0111000, 1);
  if(Wire.available()) {
    _data = Wire.read();
  }
 
  Serial.println(_data);
 
  delay(1000);
}


C'est le code minimal. Par défaut ça renvoie 255 (tout est non appuyé) et si j'appuie sur le premier bouton 254, puis 253.

Ça marche ! Ça marche ! "mode sauter partout" !
Je plaisente hein  :smiley-mr-green:

skywodd

Bonjour,

Si tu veut un exemple (rudimentaire, il faudrait que je reprenne la librairie ...) de gestion des interruptions à la "sauce arduino" avec un PCF857x :
http://skyduino.wordpress.com/librairie-arduino-pcf8574-pcf8575/

Ps: dans ton code d'exemple tu n'est même pas obliger de stocker la valeur dans _data si tu veut faire moins de lignes ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Go Up