Conseils de dépannage

par Vincent DEFERT, dernière mise à jour le 2026-03-17

Introduction

Vous allez obligatoirement être confronté à des difficultés lors de chaque mise en pratique et la résolution de ces problèmes fait partie des apprentissages à faire. La difficulté avec le développement embarqué est que les problèmes peuvent être logiciels ET matériels.

Pour les problèmes logiciels, vous avez à votre disposition les outils suivants :

  • Le debugger de MRS

  • printf() vers le terminal de MRS

  • Connecter des LED à des lignes de GPIO et les allumer à des points précis de votre code (dans certains cas, il se peut que printf() soit trop lent pour être utilisable).

Pour les problèmes matériels, vous avez votre cerveau et quelques instruments :

  • Votre multimètre vous permettra de vérifier tensions, courants et continuité.

  • Un analyseur logique bas de gamme couplé avec le logiciel libre PulseView peut rendre de grands services pour diagnostiquer des problèmes avec les protocoles SPI, UART, I2C, ou encore remplacer les LED évoquées plus haut pour analyser des problèmes de timing dans votre code.

  • Un oscilloscope devient incontournable dès que vous sortez du cadre des travaux pratiques bien délimités de ces cours. Il vous aidera à diagnostiquer des problèmes invisibles autrement tels qu'une ligne de GPIO endommagée ou mal configurée, un temps de montée trop long sur un signal d'entrée, etc.

Choix du matériel

N'investissez dans un analyseur logique et/ou un oscilloscope que si vous sentez que vous accrochez vraiment au développement embarqué et que vous souhaitez aller plus loin que ces cours. Ne dépensez pas non plus une fortune, vous n'auriez pas l'usage d'un matériel haut de gamme.

Analyseur logique

Pour l'analyseur logique, un clone de Saleae Logic dénommé "24MHz 8 canaux" sur AliExpress tel que celui-ci ou celui-là fera parfaitement l'affaire pour environ 5€. Ces analyseurs logiques sont parfaitement supportés par Sigrok/PulseView (driver fx2lafw).

Si vous avez un budget plus important, optez pour un le DreamSourceLab DSLogic Plus (environ 100€), qui offre des triggers (déclenchement de l'acquisition sur front ou niveau d'un signal). Le confort d'utilisation est incomparable ! Le logiciel qui va avec est open-source, ce qui signifie que vous pourrez l'utiliser quel que soit le système d'exploitation ou type d'ordinateur que vous aurez choisi d'utiliser. Pour l'utiliser sous Linux, vous devrez le compiler vous-même, mais ça ne pose aucune difficulté. Pour Windows ou Mac, vous pouvez télécharger des versions précompilées sur le site de DreamSourceLab.

Oscilloscope

Pour l'oscilloscope, si vous avez un budget extrêmement serré et êtes prêt à accepter une utilisation malaisée, vous pouvez opter pour un oscilloscope USB comme le Hantek 6022BE pour environ 60€. Il est parfaitement supporté par Sigrok/PulseView (driver hantek-6xxx) et peut être utilisé plus confortablement avec le logiciel libre OpenHantek6022. Pour environ 90€, vous avez aussi le OWON VDS1022, qui est de meilleure qualité. Il est fourni avec un logiciel OWON et il existe également un logiciel open source.

Un appareil de table - avec écran couleur et panneau de contrôle - offre cependant un confort d'utilisation infiniment supérieur à celui d'un oscilloscope USB. Quand vous avez déjà affaire à un problème récalcitrant, vous appréciez de ne pas avoir besoin de vous battre aussi contre votre matériel. :) De plus, un oscilloscope de table est bien plus riche sur le plan fonctionnel.

Avec un budget un peu plus important, autour de 180€, vous avez accès à des appareils, certes bas de gamme, mais cependant très corrects tels que ceux des marques HANMATEK (ex. DOS1102) ou OWON (ex. SDS1102).

Si vous avez un budget plus important, optez pour un modèle de table 70 ou 100 MHz 2 canaux autour de 400€ tels que ceux de RIGOL, qui offrent un excellent rapport qualité/prix.

J'utilise un RIGOL DS1102Z-E et j'en suis pleinement satisfait. RIGOL a également un site de vente directe avec des promotions très intéressantes.

Pour vous donner une idée de l'intérêt d'investir dans un oscilloscope, sachez que j'utilise le mien plus souvent que mon multimètre. Sans lui, je suis sourd et aveugle.

Certains recommandent un oscilloscope 4 canaux car ils l'utilisent comme analyseur logique. Je ne suis pas de cet avis car ça gonfle encore le prix et j'en trouve l'utilisation comme analyseur logique peu pratique. De plus, que faites-vous si vous avez besoin de 5 canaux ? Vous achetez un analyseur logique ? Donc autant le faire dès le départ. Un oscilloscope 4 canaux peut cependant être utile dans des cas particuliers - si vous développez des systèmes de commande pour certains types de moteurs, par exemple.

Si vous voulez pouvoir emporter votre matériel avec vous en déplacement, vous pourriez préférer acquérir un Digilent Analog Discovery. C'est un produit d'excellente qualité qui combine oscilloscope, générateur de signaux et analyseur logique. Il a l'inconvénient (de mon point de vue) de nécessiter l'utilisation d'un logiciel plutôt que de manipuler des boutons, mais en déplacement, c'est le top du top !

Conseils pour le dépannage et exemples

La plupart des pannes ont des causes très simples, très souvent liées aux problèmes posés par le câblage "volant". C'est à ce genre de pannes que vous serez confronté dans ces cours.

Les DuPont jumpers

Pour commencer, sachez que les DuPont jumpers sont la pire des calamités. Il faut souvent écraser un peu le connecteur femelle pour qu'il fasse vraiment contact - mais pas trop écraser quand même pour qu'il reste utilisable...

D'autre part, ils ont une fâcheuse tendance à se débiner sans prévenir, spécialement quand ils ont besoin d'un petit écrasement et que ça vous a échappé. Du coup, vous cherchez une erreur dans votre code alors qu'une connexion manque simplement à l'appel.

Ce peut être le cas par exemple quand vous ne voyez rien dans le terminal de MRS : un des jumpers peut tout bêtement être débranché ou ne pas faire contact.

L'alimentation

Quand quelque chose ne marche pas et que l'inspection visuelle ne révèle pas de jumper débranché, commencez par utiliser votre multimètre pour vérifier la tension d'alimentation.

Un exemple simple pour en démontrer l'utilité&bnsp;: supposons que vous ayez relié la sortie 3V3 de votre WCH-LinkE à votre carte CH32V003. La plupart des cours ne poseront aucun problème et vous ne vous en rendrez pas compte. Par contre, lorsque viendra le cours sur I2C et l'afficheur LCD, vous ne verrez strictement rien sur ce dernier car il a besoin d'une tension d'alimentation de 5V.

Il se peut aussi que suite à un problème de jumper, une partie de votre système ne soit pas du tout alimentée. Votre code ne fonctionnera donc pas, mais c'est normal...

La breadboard

Rien ne ressemble plus à un trou que son voisin. Si ça ne fonctionne pas, ce peut être parce que vous avez inséré la patte d'un composant dans le mauvais trou. Ça peut aussi être parce que la patte s'est un peu pliée au moment de l'insertion et qu'elle n'est pas rentrée dans le trou.

D'autre part, les pin headers des modules et cartes de développement sont un peu plus gros que des DuPont jumpers et beaucoup plus gros que des pattes de composants. Cela signifie qu'au bout d'un moment, vous aurez des faux contacts dans certains trous de la breadboard.

Moralité : avant de chercher un bug dans votre code, vérifiez le câblage avec votre multimètre en position testeur de continuité. Mais avant de faire cette vérification, offrez vous un café ou changez-vous les idées d'une autre façon. Certaines erreurs sautent aux yeux quand on les regarde avec un esprit frais. Ça vaut aussi pour les bugs dans le code.

Les maladresses et leurs conséquences

Il se peut qu'à la suite d'erreurs de câblage, vous ayez endommagé l'une ou l'autre ligne de GPIO. Il serait franchement bizarre que ça ne vous arrive pas au moins une fois.

Le symptôme en est alors que, bien que votre code envoie le bon niveau sur une sortie (et qu'elle soit bien configurée - je pense à la subtile différence entre GPIO_Mode_Out_PP et GPIO_Mode_AF_PP, par exemple), l'électronique connectée à cette sortie ne réagit pas.

Pour vérifier l'état de la sortie, déconnectez ladite électronique, faites un minuscule programme qui mettra la sortie à un niveau logique haut constant et mesurez la tension présente sur cette broche. Si elle diffère fortement de la tension d'alimentation, c'est que la sortie est grillée. Vous devrez alors modifier votre code pour en utiliser une autre si possible, ou remplacer la carte.

Par contre, si la tension est normale, ça signifie que le problème est dans l'électronique connectée à la sortie. Dans ce cas, vérifiez son câblage, en particulier la polarité de composants comme les diodes et transistors.

Si le problème concerne une entrée, déconnectez l'électronique qui y est reliée et mettez à la place une résistance pull-up (ex. 10kΩ), puis mesurez la tension sur l'entrée. Si elle est très différente de la tension d'alimentation, c'est que l'entrée est grillée. Même chose que pour la sortie, utilisez-en une autre si c'est possible ou remplacez la carte. Si la tension est normale, comme pour la sortie, vérifiez le câblage de l'électronique en amont de l'entrée.

Il peut aussi s'agir de maladresses logicielles. Un exemple : vous avez copié-collé le code gérant un esclave I2C dans un nouveau source pour gérer un autre périphérique, mais vous avez oublié de changer l'adresse I2C. Résultat : votre code va bloquer dès l'envoi de l'octet qui suit le Start puisque le périphérique avec l'ancienne adresse n'est pas présent sur le bus...

Ce que vos yeux ne peuvent pas voir

Dans certains cas, les yeux et le multimètre ne suffisent pas pour diagnostiquer le problème. Voici quelques exemples.

Vous envoyez un message en utilisant le protocole de télécommande infrarouge NEC mais le récepteur ne réagit pas. Vous devez donc vérifier la fréquence de la porteuse, le rapport cyclique des impulsions et le respect du format du message. Pour cela, vous avez besoin d'un oscilloscope.

Vous voulez vous interfacer avec un capteur de température DS18B20 utilisant le protocole 1-Wire, mais votre code réagit comme si le capteur n'était pas connecté. Vous ne pourrez comprendre que vous avez configuré la sortie du GPIO en mode push-pull au lieu de open drain que si vous visualisez le signal avec un oscilloscope.

C'est la même chose si vous avez utilisé une résistance pull-up trop élevée sur un bus I2C, vous ne pourrez voir son impact sur les temps de montée qu'avec un oscilloscope.

Enfin, si un MCP23S17 (I/O expander SPI) ne réagit pas correctement aux commandes que vous lui envoyez, un analyseur logique vous permettra de voir si vous avez paramétré correctement le périphérique SPI de votre CH32V003 en comparant les chronogrammes relevés à ceux de la documentation du MCP23S17.

Problèmes courants avec SPI

Peu de choses peuvent aller de travers avec SPI. Le premier cas de figure est une configuration incorrecte de périphérique SPI : mode (CPOL et CPHA), ordre des bits (MSB ou LSB en premier) et fréquence d'horloge (doit être inférieure ou égale à la fréquence maximale supportée par l'esclave). Comparer les chronogrammes relevés avec un analyseur logique à ceux de la data sheet de l'esclave vous permettra de lever vos doutes.

L'autre problème fréquemment rencontré est que CS# remonte trop tôt. CS# doit passer à 0 avant d'envoyer la première donnée de la transaction et ne remonter à 1 qu'après que le dernier bit de la dernière donnée ait été échantillonné. Classiquement, ça se fait en attendant que le flag BUSY (ou BSY) du périphérique SPI passe à 0 après avoi envoyé toutes les données de la transaction avant de remettre CS# à 1.

Cependant, certains périphériques SPI ont un tampon d'émission (TX FIFO), ce qui fait que si vous envoyez très peu de données (moins que la capacité du FIFO), vous pouvez avoir fini d'envoyer vos données avant que BUSY passe à 1 et donc faire remonter CS# beaucoup trop tôt. La solution est d'enchaîner 2 boucles, une pour attendre que BUSY passe à 1, puis une autre pour attendre qu'il repasse à 0.

Enfin, certains esclaves SPI utilisent le front montant de CS# pour charger les données reçues dans un registre. C'est indiqué, ou simplement suggéré, dans leur data sheet. Dans ce cas, vous devrez faire remonter CS# après chaque donnée, pas question d'enchaîner plusieurs modifications de suite car seule la dernière serait prise en compte.

Problèmes courants avec I2C

Résistances pull-up

Les lignes du bus I2C étant de type open-drain, la présence de résistances pull-up est indispensable, sinon les lignes resteront à zéro en permanence. Leur valeur est généralement comprise entre 2 et 10kΩ. Trop faible et votre signal ne descendra pas jusqu'à zéro, trop forte et il ne montera pas assez vite à 1.

Les cartes de développement à micro-contrôleur n'en ont en principe jamais et les modules en ont généralement toujours, mais il faut toujours le vérifier, par exemple avec votre multimètre numérique en position ohmmètre.

Avec les SBC (ex. Raspberry Pi 5, Orange Pi 5 Plus, WukongPi H3 Zero, etc), c'est le contraire, il y a presque toujours des résistances pull-up côté SBC et vous devrez donc généralement dessouder celles des modules. Mais là aussi, c'est à vérifier systématiquement.

Si vous mettez plusieurs modules sur le même bus I2C, leurs résistances pull-up seront en parallèle, donc il vous faudra calculer (ou mesurer) la résistance équivalente et si elle est trop faible, vous devrez en dessouder sur 1 ou 2 modules.

Synchronisation

La fréquence d'horloge de votre périphérique I2C doit être celle de l'esclave le plus lent connecté au bus. Si vous avez un esclave capable d'aller jusqu'à 100kHz et un autre jusqu'à 400kHz, vous devrez configurer votre périphérique I2C pour fonctionner à 100kHz.

Ensuite, vous devez toujours attendre que le bus I2C soit prêt avant de commencer une transaction. Concrètement, ça signifie attendre que le flag BUSY (ou BSY) de votre périphérique I2C passe à zéro avant de générer la condition de START. En effet, si vous enchaîniez immédiatement une nouvelle transaction sans attendre, vous tenteriez de générer une condition START alors que la condition STOP précédente n'est pas terminée.

Acquittements

Il est impossible de communiquer sur un bus I2C en l'absence de l'esclave concerné par la requête. Une requête commence toujours par l'envoi de l'adresse de l'esclave avec lequel le maître veut communiquer et l'esclave doit répondre présent par un ACK. Le maître bloquera en l'attendant, donc si votre code bloque, c'est vraisemblablement parce que l'esclave ne répond pas (oubli de le connecter, adresse incorrecte, faux contact avec le câblage volant).

Ensuite, lorsque vous envoyez des données à l'esclave, celui-ci doit répondre par un ACK si tout s'est bien passé, ou par un NAK en cas d'erreur. Dans la pratique, il est indispensable de les prendre en compte. Et si vous recevez un NAK, vous devez générer un STOP et arrêter la communication (et faire ce qu'il faut au niveau de votre application pour traiter l'erreur, évidemment).

Par exemple avec un module d'affichage OLED tel que celui utilisé sur ce site, vous pouvez recevoir un NAK si vous n'avez pas respecté le protocole de communication (envoi de l'octet Co avant la commande). Avec certains capteurs, le NAK peut vous indiquer qu'il n'est pas prêt à vous répondre et que vous devez réessayer plus tard. C'est la lecture attentive de la data sheet de l'esclave qui vous permettra de comprendre la situation et de la gérer de manière adéquate.


Copyright (c) 2024 Vincent DEFERT - Tous droits réservés