[RESOLU] Conflit I2C entre RTC et OLED

Bonsoir,

Mon projet comporte une horloge I2C et un écran OLED 128*64 pixels.
Les deux sont reliés en I2C à l’Arduino Pro Mini.

Mais lorsque je demande à mon programme d’aller chercher leurs dans le RTC, au démarrage, cela fait planter l’affichage (clignotement de l’affichage).
Alors que les deux modules ont des adresses différentes (OLED : 0x3C , RTC 0x68).

Voici ce que je déclare au début de mon programme :

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

#include <Wire.h>
#include <RTClib.h>
#include <Encoder.h>
#include <VirtualWire.h>//RF433
#include <EEPROM.h>
#include <TinyGPS++.h>

#define DS1307_ADDRESS 0x68

RTC_DS1307 RTC;
TinyGPSPlus gps;

(L’adresse du OLED est définit dans la librairie SSD1306 que j’utilise).

Avant l’arrivée du OLED, le module RTC fonctionnait très bien.

D’où pourrait venir le problème s’il ne vient pas des adresses ?

merci

Il ce peut que l’écran OLED ne relâche pas le bus I2C, a vérifier avec un analyseur logique.

Ou envoyer les ordres qui vont bien pour forcer à relacher le bus.
De mémoire dans la bibliothèque TwoWire( Wire) cette possiblité existe → lire la doc complètement

ok je vais me pencher sur ce problème : essayer de libérer le bus. Car une boussole en I2C doit venir compléter le tout. Donc si j'ai deux modules sur trois qui sont plantés par le troisième...

As-tu vérifié la présence de résistances de tirage sur les signaux du bus I²C? J'utilise un afficheur avec un driver SSD1306 depuis un moment et je n'ai jamais eu de verrouillage du bus. Les 2 périphériques sont bien en interface 5V?

Les deux périph sont en 5V. J'avais déjà entendu parler de ces résistance de pull-up mais il me semblait qu'elle était sur l'Arduino d'office non ?

Si ce n'est pas le cas, je dois donc intercaler une résistance entre SDA et 5V et une autre entre SCL et 5V, c'est ça ?

L’I2C fonctionne sur le principe des “collecteurs(ou drains) OUVERTS”.
C’est ce qui permet de relier tous les modules en parrallèle sur SDA et SCL.

Cela implique qui faut terminer le schéma en plaçant “au moins UNE” résistance sur SDA et sur SCL.

La bibliothèque Wire active les pull-up des sorties du micro mais leur valeur est trop élevée pour permettre un fonctionnement correct de l’I2C
Elles permettent juste de ne pas bloquer le programme si les “vraies” résistances ont été oubliées.

Généralement les modules que l’on achète possèdent déjà des résistances d’environ 10k.
Il faut simplement que tu vérifie que c’est le cas avant d’ajouter quoi que ce soit.

Merci pour l'explication.

Su l'écran, entre SDA et VCC, 7.87M Ohm, idem entre SCL et VCC. ça fait beaucoup non ?

Sur le module boussole, 2.16KOhms.

Est-ce que l'on peut considerer ça comme du pull up ? en regardant les circuits dans le détails, pas de résistance directement placée entre SDA et VCC ou entr SCL et VCC...

Ajoute une résistance sur chacun des signaux cela devrait aider.

Malokoxis: Su l'écran, entre SDA et VCC, 7.87M Ohm, idem entre SCL et VCC. ça fait beaucoup non ?

C'est énorme, mais je ne peut pas dire que cela peut causer un problème il faut voir les datasheet.

10KOhms pour le pull up ?

Oui. Si le câblage s'y prête tu en places sur SCL et SDA d'un seul module pour commencer (celui qui a les fils les plus longs de préférence).

Annexe technique (lecture facultative) :

Le point gênant dans l'I2C est la capacité parasite d'entrée des modules. Ces capacités se retrouvent toutes en parallèle et elles se somment. Elles ralentissent les fronts de montée du signal et si elles sont trop élevées elles peuvent écrouler les fronts.

Comme physiquement ce qui intervient dans le calcul c'est le produit RC (R = résistances de charges SDA ou SCL, C capacité totale) dans le cas "d'un grand nombre de modules en parallèle" on peut être amené à diminuer ces résistances de charges pour compenser l'augmentation de la capa. Cela peut se faire en équipant chaque module de résistance de charge sur SDA et SCL car dans ce cas les résistances se retrouvent en parallèle donc la résistance équivalente est plus faible.

Avec seulement 2 modules, AMHA, un seul jeu de résistance entre 4,7k et 10 k suffira. Le risque avec des résistances trop faibles est de faire débiter inutilement du courant dans les transistor de sortie de l'I2C.

merci. Donc j'ai mis les résistances de 10K, mais rien ne change, toujours le même problème au niveau de la ligne

RTC.begin();

A mon avis soit tu as fait une grosse ânerie, soit il y a incompatibilité entre les bibliothèques.

Comme par ailleurs cela fonctionne chez d'autres avec les mêmes bibliothèques ce ne peut être qu'une ânerie. Le plus dur sera de trouver où.

Perso : - je supprimerais tous les fichiers des bibliothèques incriminées et je les réinstallerai à partir de zéro. - je testerais chaque module un par un. Pour cela je supprimerais tout le câblage et je le recommencerais à partir de zéro pour chaque module. - si les deux modules sont individuelement fonctionnels je ferais le câblage complet et j'essaierai les deux modules ensembles.

C'est du systématique mais quand ça veut pas au final le systématique est souvent le plus rapide.

Je viens de tester le module RTC :
-je n’ai pas modifié le câblage sur la breadboard
-l’écran est donc toujours branché
-j’utilise le fichier d’exemple fournit avec la librairie RTClib
Résultat : le module me renvoie toute les informations que je lui demande.

L’écran marche très bien seul.

Librairies désinstallées et réinstallées (SSD1306 vient d’être mise à jour au passage).
Pas plus d’avancement.

Le problème vient peut-être des librairies… Je ne suis pourtant pas le seul à utiliser les librairies SSD1306 et RTC ensemble. Je dois mal m’y prendre.

Bon je vais aller me coucher pour ce soir reprendre ça quand j'aurai le temps et l'esprit reposer.... Je viens de télécharger ce projet qui utilise exactement les même module que moi : https://github.com/rydepier/Arduino-OLED-Clock/tree/master

Tout marche très bien avec son code... 68tjs tu avais raison, j'ai du faire une belle ânerie, à moi de la trouver :D

Sur ce, bonne nuit !

Bon… J’ai inversé les lignes :

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
RTC.begin

pour

RTC.begin
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

et tout fonctionne.

Par contre j’ai du repasser à l’ancienne version de la librairie Adafruit SSD1306 car la nouvelle reconnait mon écran comme un 12832 alors que c’est un 12864…

J’espère maintenant que la boussole pourra s’ajouter à tout ça sans problème.

Merci pour votre aide.

Il y a des #define au début du fichier SSD1306.h pour définir le type d'écran

#define SSD1306_I2C_ADDRESS   0x3C  // 011110+SA0+RW - 0x3C or 0x3D
// Address for 128x32 is 0x3C
// Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded)
/*=========================================================================
    SSD1306 Displays
    -----------------------------------------------------------------------
    The driver is used in multiple displays (128x64, 128x32, etc.).
    Select the appropriate display below to create an appropriately
    sized framebuffer, etc.
    SSD1306_128_64  128x64 pixel display
    SSD1306_128_32  128x32 pixel display
    SSD1306_96_16
    -----------------------------------------------------------------------*/
//   #define SSD1306_128_64
   #define SSD1306_128_32
//   #define SSD1306_96_16

oui j'ai tenter de le modifier mais ça n'a rien changé. L'écran affichait une ligne inscrite, une ligne noire. Du coup mon texte prenait le double en hauteur et l'affichage n'était pas entier forcément.

Ce qui est bizarre avec la RTC, c'est qu'en enlevant la ligne RTC.begin(), j'ai quand même l'heure d'affichée sur l'écran de mon arduino... et à jour.

Si tu regardes les sources de la librairie, tu verras que begin() ne fait qu'initialiser l'I²C et ne fait rien du coté de la RTC. Comme l'I²C est initialisé aussi par ton écran tu ne t'en aperçois pas.