I2CDriver - Un outil fiable pour espionner le bus I2C ?

Bonjour,

Cela faisait un petit moment, que je voulais écrire un article sur l'I2C Driver d'Excamera

J'en ai eu besoin, c'est donc l'occasion d'en faire une revue.
C'est un outil intéressant... mais qui peu néanmoins réserver de mauvaises surprises dans certaines conditions, ce qui fut le cas de ma toute première expérience (voir le développement de ce point plus bas).

Révision de l'article: après tests complémentaires (voir plus bas) et l'utilisation d'un LTC4311 pour rectifier les signaux, la capture reste toujours incorrecte.
Je ne recommande pas l'achat de ce produit compte tenu de son manque évident de fiabilité. Que pouvait-on espérer pour 30$?

Revue de l'I2CDriver

C'est un outil 3.3V que vous pouvez connecter sur votre bus I2C et qui permet d'espionner les adresses active et même de voir le trafic I2C.

Ce module est accompagné d'un logiciel Windows/Mac et Linux (sous Python)  offre des possibilités intéressantes.

Le module en lui-même permet:

  • Il permet de voir quel périphérique I2C est présent sur le bus. Branchez en un périphérique I2C et son adresse s'illumine instantanément sur le pavé.
  • Identifie le périphérique actif sur le bus (couleur)
  • Permet de suivre les échanges de données (ligne du bas).
  • Surveille la tension d'entrée (sur le port USB)
  • Surveille le courant fournit au périphériques I2C via la broche VCC (à 3.3V)... si celle ci est utilisée.

La partie logicielle

Cet outil ouvre un port Serial-USB qui permet à un ordinateur hôte de dialoguer avec le périphérique I2CDriver.
La page du site dispose d'un outil pour Window et Mac. Les accros Linux (ou du Raspberry-Pi) dispose également d'un outil graphique i2cgui.py basé sur Python et très facile à installer grâce à un dépôt PIP : sudo pip install i2cdriver .


Le logiciel permet configurer différents éléments comme les résistances pull-up et la vitesse du bus (100 KHz/400 KHz) sur le bus I2C pour le cas où vous envoyez des instructions directement sur le bus).

Les 4 principales options sont:

  • Réinitialiser le bus I2C
  • D: Faire une opération de lecture / écriture (read/write) "Direct" sur le bus grâce au deux zone de saisie en bas de l'écran et à la sélection de l'adresse du périphérique.  Un grand D est enfiché en hait à gauche de l'écran.
  • M: Activer le mode "Monitor" qui est le mode de fonctionnement par défaut du périphérique (un grand M est affiché en hait à gauche de l'écran).
  • C: Activer le mode "Capture" qui enregistre tous les événements du bus I2C dans un fichier texte sur le PC. Le fichier est écrit sur le disque lorsque le mode Capture est désactivé (en re-cliquant sur le bouton). L'écran affiche un grand C en haut à gauche sur l'écran.

Le mode "Direct" permet de faire des tests sur un périphérique I2C directement depuis l'interface graphique. Un petit outils qui pourrait être utile selon les circonstances.

Le mode Capture est le plus intéressant puisqu'il permet d'espionner les échanges entre un microcontrôleur / nano-ordinateur et un (ou plusieurs) périphériques I2C. Très pratique pour déboguer une situation ennuyeuse.

Voici le contenu (partiel) d'une session de capture.

START,WRITE,73,ACK
BYTE,WRITE,1,ACK
START,WRITE,19,ACK
BYTE,WRITE,0,ACK
STOP,,,
START,WRITE,73,ACK
BYTE,WRITE,1,ACK
START,WRITE,0,ACK
STOP,,,
START,WRITE,83,ACK
BYTE,WRITE,224,ACK
START,READ,29,NACK
BYTE,READ,251,NACK
BYTE,READ,251,NACK
BYTE,READ,251,NACK
BYTE,READ,251,NACK
BYTE,READ,251,NACK
BYTE,READ,251,NACK
BYTE,READ,251,NACK
STOP,,,

L'API - Interface de programmation

Cet outil dispose d'une API permettant de l'exploiter à partir de différents langages de programmation:

  • C
  • C++
  • Python 2
  • Python 3
Cet API étant par ailleurs utilisée par l'interface Graphique i2cguy.py mais aussi l'outil en ligne de commande i2ccl .

I2CDriver par la pratique -> Mauvaise surprise

Dans mes petites tribulation, j'essaye de porter le pilote du voltmètre de M5Stack (module Grove, interface I2C, voir lien U087 chez M5Stack).

voltmètre de M5Stack - Interface Grove

C'est qu'en plus de disposer d'une isolation galvanique et d'une large plage de mesure (jusqu'à 36V), ce module dispose aussi d'une EEPROM avec des données de calibration. Tout ce qu'il faut pour réaliser un outil de qualité.

J'ai donc réaliser un petit montage à partir d'un Raspberry-Pi Pico pour porter le pilote Arduino de M5Stack vers MicroPython.
Vous noterez au passage la longueur des fils du bus I2C.


Et comme je n'obtenais pas les résultats  attendu, j'ai testé le Voltmètre avec un M5Stack Core (sous Arduino IDE).

Et comme tout fonctionne parfaitement, le problème provenait donc du code MicroPython en cours d'écriture.

Je me suis donc dit que ce serait le moment de sortir l' I2CDriver pour comparer les messages I2C entre l'implémentation Arduino et le port MicroPython (avec le mode capture)... histoire de voir ce qui diverge.

Je l'ai donc branché en parallèle sur le port I2C de mon Raspberry-Pico et immédiatement constaté que le contenu affiché dans la capture (et l' I2CDriver) ne correspondent pas à ce qui est lu par le micro-contrôleur sur le bus I2C!!!

Au fur et à mesure des essais, j'isole un simple appel en MicroPython.


Qui lit les deux octets depuis le registre 1 du périphérique I2C 0x53.

La réponse retournée est invariablement deux octets de 255 (soit 0xFF deux fois).

Mais l'I2CDriver indique tout autre-chose :

 

Où l'on peut y lire la requête (0x53 0x01) sur la ligne du bas, suivit de la réponse 0x1D 0xFB... donc rien à voir avec 0xFF 0xFF lu par le MicroContrôleur!

Ce que confirme l'un ou l'autre des extrait du mode de capture (affiche les valeur en décimale 0x53 = 83d).

START,WRITE,83,ACK
BYTE,WRITE,1,ACK
STOP,,,
START,WRITE,39,NACK
BYTE,WRITE,254,NACK
STOP,,,

Comment se fait-il que la valeur lue sur le MicroContrôleur soit incorrect?

Après de nombreuses vérifications dans le code, je fini par sortir l'oscilloscope (un Rigol DS1054) et active le mode décodage I2C.
 

Et là, je tombe de haut! car lui aussi indique que c'est un 0xFF 0xFF qui est retourné sur le bus I2C! C'est l' I2CDriver qui retourne le mauvais résultat.

Voici la capture des signaux de la réponse:


Cette capture indique que le signal d'horloge (en jaune) présente des crêtes courbés.

Le signal de donnée (des valeurs 0xFF 0xFF) présente des parasites assez marqués avec une tendance à revenir vers la masse (parfois de 1 volt). C'est du cross-talking... les flancs descendants (et montants) du signal d'horloge (jaune) qui induit une perturbation dans le signal de la ligne de donnée.

En agrandissant le signal sur l'oscilloscope, nous pouvons constater que l'effet capacitif de la ligne déforme également les flancs montants.


Vu la longueur des fils du bus I2C, ce n'est pas très étonnant d'avoir de telles déformations dans les signaux du bus.

Cela sera pourrait expliquer pourquoi l' I2CDriver retourne un résultat différent.

Test plus poussé

Pour rectifier les signaux, je vais placer un LTC4311 sur le bus pour améliorer l'état des signaux SCL et SDA du bus. Ce composant est disponible en breakout chez Adafruit (voir détails du breakout TLC4311 en Français chez MCHobby).

breakout TLC4311 - terminaison active pour bus I2C.
 
Comme recommandé par Adafruit, cet élément fût placé en sortie du bus I2C directement en sortie du MicroContrôleur (donc en début de bus).

Cette fois, les signaux SDA et SCL sont nettement plus dans la norme.

Signaux SCL (jaune) et SDA (bleu) avec un LTC4311 (terminateur actif de bus I2C)
 
Malheureusement, la capture de multiples appels a __read_u16( 0x53, 0x01 ) retourne toujours 0xFF, 0xFF sur l'oscilloscope et sur le MicroContrôleur mais pas sur l'I2CDriver!

Pour preuve, voici le résultat de la capture:

START,WRITE,83,ACK
BYTE,WRITE,1,ACK
STOP,,,
START,READ,29,NACK
BYTE,READ,251,NACK
STOP,,,
START,WRITE,83,ACK
BYTE,WRITE,1,ACK
STOP,,,
START,READ,83,ACK
BYTE,READ,255,ACK
STOP,,,
START,WRITE,83,ACK
BYTE,WRITE,1,ACK
STOP,,,
START,READ,29,NACK
BYTE,READ,251,NACK
STOP,,,

Les réponses successives sont:

  • 29d, 251d
  • 83d, 255d
  • 29d, 251d
Un comble d'instabilité pour un produit dont le job est de décoder le traffic sur le bus a éviter.

Conclusion sur l'I2CDriver

PRODUIT A EVITER! Optez pour une solution orienté PRO et fiable.

A l'évidence, l'I2CDriver est sensible aux signaux déformés sur le bus (même peu déformés).

Cette sensibilité conduit à une interprétation erronée des informations là où un microcontrôleur (Raspberry-Pi Pico) et un oscilloscope (Rigol) présentent des informations correctement décodées.

Ce qui est vraiment gênant, c'est qu'a moins d'utiliser un oscilloscope, il est impossible de savoir si les données affichées/capturée par l'I2CDriver sont fiables ou erronées! Gloups!

 

Aucun commentaire