Pb I2C avec deux esclaves PCF8583p

Bonjour,

je rencontre des problèmes avec le bus I2C connecté à deux esclaves PCF8583p en utilisant la bibliothèque PCF8583-h de M PEREZ. Avant d'exposer mon problème, je souhaite préciser
1 avant chaque série de tests, j'exécute un scan I2C pour vérifier la connexion des l'esclaves et leur adresse.
2 j'ai commencé par faire des tests de la bibliothèque avec un seul esclave et un signal PWM. Le fonctionnement était satisfaisant.

Depuis que je fais des tests avec les deux esclaves, le bus I2C ne fonctionne plus ?
le code du test

#include "PCF8583.h"

// déclaration d'une instance de la bibliothèque PCF8583.h pour l'esclave à l'adresse 0x50
// (pin A0  connecté au  ground)
PCF8583 anemometre(0x50);  // Adresse en 7 bits

// déclaration d'une instance de la bibliothèque PCF8583.h pour l'esclave à l'adresse 0x51
// ((pin A0  connecté au 3,3 V)
PCF8583 pluviometre(0x51);  // Adresse en 7 bits

void setup() {

  // configure la liaison série pour le terminal de debogue
  Serial.begin(115200);

  Wire.begin();  // Obligatoire pour initialiser le bus I2C
  Wire.setClock(100000);  // fixe la fréquence du bus à 100 kHz

  //  PCF8583 paramètré en compteur d'évènements pour l'anémomètre avec remise à zéro
  anemometre.setMode(MODE_EVENT_COUNTER);
  anemometre.setCount(0);

  //  PCF8583 paramètré en compteur d'évènements pour le pluviomètre avec remise à zéro
  pluviometre.setMode(MODE_EVENT_COUNTER);
  pluviometre.setCount(0);
}

void loop() {

  // édition de la valeur du compteur de l'anémomètre à chaque période puis remise à zéro
  Serial.print("anemometre : ");
  Serial.println(anemometre.getCount());
  anemometre.setCount(0);

  // délai entre les deux lectures I2C
  delay(50);

  // édition de la valeur du compteur du pluviomètre à chaque période puis remise à zéro
  Serial.print("pluviometre : ");
  Serial.println(pluviometre.getCount());
  pluviometre.setCount(0);

 //une lecture des compeurs toutes les x secondes
  delay(1000);
}

trace du moniteur lors de l'exécution

anemometre : E (6300) i2c.master: I2C hardware NACK detected
E (6300) i2c.master: I2C transaction unexpected nack detected
E (6300) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (6307) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (6314) i2c.master: I2C hardware NACK detected
E (6318) i2c.master: I2C transaction unexpected nack detected
E (6323) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (6330) i2c.master: i2c_master_receive(1240) : I2C transaction failed
1666665
puis se répète à l'infini

J'ai essayé de baisser la fréquence du bus à 100 Hz, le résultat est identique.
J'ai ajouté un délai entre les deux lectures de compteur, le résultat est identique

Pour tenter un diagnostic, j'ai écrit un code de dé bogue avec un seul esclave et tout le code dans la fonction SET UP afin de l'exécuter qu'une seule fois.
le code

#include "PCF8583.h"

// déclaration d'une instance de la bibliothèque PCF8583.h pour l'esclave à l'adresse 0x50
// (pin A0  connecté au  ground)
PCF8583 anemometre(0x50);  // Adresse en 7 bits


void setup() {
  // configure la liaison série pour le terminal de debogue
  Serial.begin(115200);

  Wire.begin();  // Obligatoire pour initialiser le bus I2C
  Wire.setClock(100000);  // fixe la fréquence du bus à 100 kHz

  //  PCF8583 paramètré en compteur d'évènements pour l'anémomètre avec remise à zéro
  anemometre.setMode(MODE_EVENT_COUNTER);
  anemometre.setCount(0);

  // édition de la valeur du compteur de l'anémomètre à chaque période puis remise à zéro
  Serial.print("anemometre : ");
  Serial.println(anemometre.getCount());
  anemometre.setCount(0);
}

void loop() {
  
}

trace du moniteur pour ce code
E (327) i2c.master: i2c_master_receive(1240): I2C transaction failed
E (333) i2c.master: I2C hardware NACK detected
E (337) i2c.master: I2C transaction unexpected nack detected
E (342) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (349) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (357) i2c.master: I2C hardware NACK detected
E (361) i2c.master: I2C transaction unexpected nack detected
E (366) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (373) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (380) i2c.master: I2C hardware NACK detected
E (384) i2c.master: I2C transaction unexpected nack detected
E (390) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (397) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed
E (404) i2c.master: I2C hardware NACK detected
E (408) i2c.master: I2C transaction unexpected nack detected
E (413) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (420) i2c.master: i2c_master_receive(1240): I2C transaction failed
E (426) i2c.master: I2C hardware NACK detected
E (430) i2c.master: I2C transaction unexpected nack detected
E (436) i2c.master: s_i2c_synchronous_transaction(924): I2C transaction failed
E (443) i2c.master: i2c_master_multi_buffer_transmit(1186): I2C transaction failed.

pouvez-vous m'aider, cordialement

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Est- il faisable de mettre deux horloge/calendrier sur le meme bus I2C ?

Dans ce sujet

Tu arrivais à lire un esclave. Qu'as-tu changé entre temps?
Cela semble plus un problème matériel qu'un problème logiciel.

  • Quels modules utilises-tu, références, liens vers les produits?
  • Comment tout cela est-il interconnecté?

salut,
j'espère que la photo sera assez précise
cdlt

Oui, on peut donner 2 adresses différentes au PCF8583.

Pas vraiment, cela fait un peu plat de spaghetti.
Tu n'as pas un schéma même à main levée?

J'ai manqué quelque chose?

salut,
un schéma
cdlt

J'avais vu la pin A0 et le CI ne fait pas que calendrier.
Mais est-ce qu'il n'y a pas "des choses à faire" ?
Comme désactiver un calendrier par exemple.

Que disent les notes d'application Philips/Nxp ?

Non, effectivement. C'est moi qui ai manqué cela.
La librairie attend effectivement l'adresse sur 8 bits.

@086beru_nous
Il faut utiliser 0xA0 et 0XA2 comme adresse pour tes PCF.

C'est la méthode .setMode() de la librairie qui permet de sélectionner le mode de fonctionnement en calendrier ou en compteur.

sans oublier le côté hardware!

Si j'en crois son schéma, c'est bien pris en compte.

oui, c'est uniquement dans le sens il faut juste que le hardware corresponde au software

merci, voici un résumé qui pourrait être utile à d'autres

codage de l’adresse de l’esclave

Même si l’adresse de l’esclave PCF8583 est codé sur 7 bits ( voir ci aprés), la bibliothèque «PCF8583.h» attend une adresse sur 8 bits 0xA0 ou 0xA2, parce qu’elle décale dans son code cette adresse à droite de 1 bit pour en extraire l'adresse 7 bits.

Extrait de la datasheet

Bit A0 corresponds to hardware address pin A0. Connecting this pin to VDD or VSS allows the device to have one of two different addresses

Dans le code source sur GitHub «PCF8583.cpp», il est écrit :

// provide device address as a full 8 bit address (like the datasheet)
PCF8583::PCF8583(uint8_t address) {
_address = address >> 1; // convert to 7 bit so Wire doesn't choke
Wire.begin();
}

pour conclure l’utilisation de la bibliothèque n’écessite une adresse d’esclave codé sur 8 bits bien que celle ci dans le PCF8583 soit codé sur 7 bits

Non, et dire cela peut induire des débutants en erreur. Une adresse i2c est sur 8 bits que ce soit 0x50 (0101 0000) ou 0xA0 (1010 0000) c'est 8 bits et la bibliothèque PCF8583 ne déroge pas à cette règle.

Simplement 0xA0 (1010 0000) est l'adresse pour écrire dans le composant (c'est l'adresse par défaut) et 0xA1(1010 0001) l'adresse pour lire dans le composant. Le fabricant du composant donne la possibilité de modifier physiquement le bit 1 pour obtenir 0xA2 (1010 0010) en écriture et 0xA3 (1010 0011) en lecture.

Expliquer pourquoi il y a ce passage à 7 bits (interne à la bibliothèque) serait un peu long ici et sort du cadre d'Arduino qui se réclame d'une utilisation facile pour les débutants. Celui que ça intéresse peut toujours regarder la bibliothèque Arduino wire/utility/twi et sa relation avec les bibliothèques AVR avr/io.h et util/twi.h. Ceci nécessite de connaître l'usage des registres des micros ainsi que la manipulation des bits en C

Bonjour @le_viking

je préfère pour ma part en rester à la présentation du bus I2C dans cette spécification (et bien d'autres)
https://www.nxp.com/docs/en/user-guide/UM10204.pdf

adresse sur 7 bit , suivie d'un bit de direction (=même adresse en lecture et écriture)

Ici une intéressante liste d'adresses (7 bits) attribuées (par NXP) aux divers composants I2C
https://learn.adafruit.com/i2c-addresses/the-list

Cette façon de définir les adresses est celle des Data Sheet des composants que les débutants auront un jour ou l'autre besoin de consulter. Un évitement de cette 'subtilité' d'adressage me parait donc contre productif.

Je trouve logique que la doc de référence de WIre mentionne '7 ou 8 Bits'

Note: There are both 7 and 8-bit versions of I2C addresses. 7 bits identify the device, and the eighth bit determines if it’s being written to or read from. The Wire library uses 7 bit addresses throughout. If you have a datasheet or sample code that uses 8-bit address, you’ll want to drop the low bit (i.e. shift the value one bit to the right), yielding an address between 0 and 127. :

D'autant que NXP (anciennement Philips) est l'inventeur et le "patron" de l'I2C.

Une seule chose est sûre c'est qu'on envoie 1 octet.

Sûr ? En fait, absolument pas → la norme a été étendue pour augmenter le nombre d'adresses possibles.

Actuellement, vu le peu d'adresses possibles avec 7 bits, les adresses sont plus par fonctions génériques que par références produit ou fabricants.

Si on considère les composants avec le réglage A0, A1, A2, ce n'est plus 7 bits qui sont disponibles pour identifier la famille des composants, mais 4.

Sujet bien complexe, je délègue le travail à la bibliothèque qui gère l'I2C.

Bon résumé de la situation, car ce n'est pas vraiment le souci d'un utilisateur Arduino :wink: