Pages: [1]   Go Down
Author Topic: [Résolu] I2C PCF8574A  (Read 608 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
  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.
« Last Edit: October 31, 2012, 12:16:20 pm by Microbulle » Logged

Bretagne
Offline Offline
Full Member
***
Karma: 2
Posts: 196
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wire.requestFrom    avant  Wire.read    ?
exemple de lecture du bus I2C, dans http://arduino.cc/en/Tutorial/SFRRangerReader 
...
Code:
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
  }

...
Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?
Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

* pcf8574.zip (2.39 KB - downloaded 5 times.)
Logged

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 ?

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 !
Logged

Bretagne
Offline Offline
Full Member
***
Karma: 2
Posts: 196
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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




     
Logged

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

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 !!!)
Logged

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 ?

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
/*
  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
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-wink
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pages: [1]   Go Up
Jump to: