Table des matières:

Arduino UNO Logic Sniffer : 8 étapes (avec photos)
Arduino UNO Logic Sniffer : 8 étapes (avec photos)

Vidéo: Arduino UNO Logic Sniffer : 8 étapes (avec photos)

Vidéo: Arduino UNO Logic Sniffer : 8 étapes (avec photos)
Vidéo: Top 3 Ideas With Arduino | 3 Awesome Arduino Projects 2024, Juillet
Anonim
Renifleur logique Arduino UNO
Renifleur logique Arduino UNO

Ce projet a commencé comme une simple expérience. Lors de mes recherches sur la fiche technique de l'ATMEGA328P pour un autre projet, j'ai trouvé quelque chose d'assez intéressant. L'unité de capture d'entrée Timer1. Il permet au microcontrôleur de notre Arduino UNO de détecter un front de signal, de stocker un horodatage et de déclencher une interruption, le tout dans le matériel.

Je me suis alors demandé dans quelle application cela pouvait être utile, et comment le tester. Comme je veux obtenir un analyseur logique depuis un certain temps maintenant, j'ai décidé d'essayer d'en implémenter un sur ma carte Arduino UNO, juste pour tester la fonctionnalité et voir si nous pouvons en tirer de bons résultats.

Je ne suis pas le seul à avoir eu cette idée, et vous en trouverez beaucoup en cherchant simplement sur Google "Arduino Logic Analyzer". Au début du projet, comme il s'agissait juste d'une expérience, je ne savais même pas que les gens l'avaient déjà fait, et j'ai été impressionné par les bons résultats qu'ils ont obtenus avec ce petit matériel. Cependant, je n'ai pas pu trouver un autre projet utilisant l'unité de capture d'entrée, donc si vous l'avez déjà vu, faites-le moi savoir !

Pour résumer, mon analyseur logique va:

  • Avoir un canal,
  • Avoir une interface graphique,
  • Communiquez avec l'interface via USB,
  • Fonctionne sur une carte Arduino UNO.

Il aura enfin une profondeur de mémoire de 800 échantillons et a réussi à capturer un message UART de 115200 bauds (je ne l'ai pas vraiment testé à des vitesses plus élevées).

Cette instructable contient à la fois les parties « comment ça marche » et « comment l'utiliser » de ce projet, donc pour ceux qui ne sont pas intéressés par le côté technique, vous pouvez directement passer à l'étape 4.

Fournitures

Je voulais garder l'analyseur aussi simple que possible, donc nécessitant très peu de matériel.

Tu auras besoin de:

  • Une carte Arduino UNO (ou équivalent tant qu'elle repose sur le MCU ATMEGA328P),
  • Un ordinateur,
  • Quelque chose à déboguer (une autre carte Arduino UNO fonctionne bien pour faire quelques tests).

Le code de l'Arduino UNO et de l'interface Web se trouve ici. Vous aurez également besoin du logiciel p5.serialcontrol et PulseView.

Étape 1: Principe de fonctionnement

Principe de fonctionnement
Principe de fonctionnement

L'idée est simple. Vous choisissez les paramètres de capture, et cliquez sur « acquérir ». L'interface Web les enverra au logiciel p5.serialcontrol, qui nous permet d'utiliser l'interface série depuis un navigateur, car il ne peut pas y accéder directement. Le logiciel p5.serialcontrol relaie ensuite les informations à la carte Arduino UNO, qui capture les données et les renvoie à l'interface par le même chemin.

Facile! Eh bien… Comme je ne suis pas vraiment doué en programmation d'interfaces Homme/Machine ou en technologies web, le mien est certainement un peu moche et buggé. Mais cela me permet de démarrer une capture et de récupérer mes données, ce pour quoi il a été conçu, donc je pense que ça va. Pour un travail d'analyse plus sérieux, j'importe mes enregistrements dans PulseView, qui est simple d'utilisation et offre un bon ensemble de fonctionnalités et de décodeurs de protocoles, comme nous le verrons plus tard.

L'unité de capture d'entrée de l'Arduino UNO peut être configurée pour utiliser différentes divisions d'horloge, réduisant ainsi la résolution, mais augmentant le délai avant débordement. Il peut également se déclencher sur les fronts montant, descendant ou les deux pour commencer à capturer les données.

Étape 2: Esquisse Arduino UNO

Esquisse Arduino UNO
Esquisse Arduino UNO

J'ai écrit et compilé le croquis avec l'IDE Arduino. J'ai d'abord commencé par configurer le Timer1 en mode de fonctionnement "Normal" en écrivant dans ses registres TCCR1A et TCCR1B dans le setup(). J'ai ensuite fait quelques fonctions pour faciliter un peu son utilisation à l'avenir, comme celle pour régler la division de l'horloge nommée "setTim1PSC()". J'ai également écrit des fonctions pour activer et désactiver l'unité de capture d'entrée Timer1 et les interruptions de débordement.

J'ai ajouté le tableau "samples", qui contiendra les données acquises. C'est un tableau global que j'ai mis sur "volatile" pour empêcher le compilateur de faire des optimisations et de le mettre en flash, comme il le faisait lors de mes premières compilations. Je l'ai défini comme un tableau "uint16_t", car le Timer1 est également en 16bit, avec une longueur de 810. On arrête la capture à 800 valeurs, mais comme le test se fait en dehors des interruptions pour des raisons évidentes de vitesse, j'ai choisi de garder 10 plus de valeurs pour éviter les débordements. Avec quelques variables supplémentaires pour le reste du code, l'esquisse utilise 1313 octets (88 %) de mémoire, ce qui nous laisse 235 octets de RAM libre. Nous sommes déjà à une utilisation élevée de la mémoire et je ne voulais pas ajouter plus de capacité d'échantillonnage, car cela pourrait provoquer des comportements étranges en raison d'un espace mémoire insuffisant.

Dans ma quête pour toujours augmenter la vitesse d'exécution, j'ai utilisé des pointeurs de fonction au lieu d'instructions if à l'intérieur des interruptions, pour réduire leur temps d'exécution au minimum. La broche de capture sera toujours le numéro Arduino UNO 8, car c'est la seule connectée à l'unité de capture d'entrée du Timer1.

Le processus de capture est illustré sur l'image ci-dessus. Il démarre lorsque l'Arduino UNO reçoit une trame de données UART valide, contenant les paramètres de capture souhaités. Nous traitons ensuite ces paramètres en configurant les bons registres à capturer sur le bord choisi et en utilisant la bonne division d'horloge. Nous activons ensuite l'interruption PCINT0 (changement de broche) pour détecter le premier front de signal. Lorsque nous l'obtenons, nous réinitialisons la valeur Timer1, désactivons l'interruption PCINT0 et activons l'interruption ICU (Input Capture Unit). A partir de ce moment, tout front descendant/montant du signal (selon la configuration choisie) déclenchera l'unité de capture d'entrée, enregistrant ainsi un horodatage de cet événement dans le registre ICR1 et exécutant une interruption. Dans cette interruption, nous mettons la valeur du registre ICR1 dans notre tableau "samples" et incrémentons l'index pour la prochaine capture. Lorsque le Timer1 ou le tableau déborde, nous désactivons l'interruption de capture et renvoyons les données à l'interface Web via UART.

J'ai décidé d'utiliser une interruption de changement de broche pour déclencher la capture, car l'unité de capture d'entrée ne permet de capturer que sur l'un ou l'autre bord, pas les deux. Cela pose également un problème lorsque vous souhaitez capturer les deux bords. Ma solution a alors été d'inverser le bit qui contrôle la sélection de front dans le registre de contrôle de capture d'entrée à chaque échantillon récupéré. De cette façon, nous perdons de la vitesse d'exécution, mais nous pouvons toujours utiliser les fonctionnalités de l'unité de capture d'entrée.

Ainsi, comme vous l'avez peut-être remarqué, nous ne capturons pas vraiment chaque échantillon à des intervalles de temps fixes, mais nous capturons le moment où une transition de signal se produit. Si nous avions capturé un échantillon à chaque cycle d'horloge, même avec la division d'horloge la plus élevée, nous aurions rempli le tampon en environ 0,1 s, en supposant que nous utilisions le type uint8_t, qui est le plus petit en mémoire sans utiliser de structs.

Étape 3: Interface Web et P5.js

Interface Web et P5.js
Interface Web et P5.js

Comme le titre l'indique, l'interface Web a été réalisée à l'aide de p5.js. Pour ceux qui ne le connaissent pas encore, je vous recommande vivement d'aller consulter le site, car c'est une très bonne bibliothèque. Il est basé sur Processing, est facile à utiliser, vous permet d'obtenir de bons résultats très rapidement et est bien documenté. C'est pour toutes ces raisons que j'ai choisi cette bibliothèque. J'ai également utilisé la bibliothèque quicksettings.js pour les menus, la bibliothèque grafica.js pour tracer mes données et la bibliothèque p5.serialport pour communiquer avec l'Arduino UNO.

Je ne passerai pas trop de temps sur l'interface, car je viens de la concevoir pour la prévisualisation des données et le contrôle des paramètres, et aussi parce que ce n'était pas du tout l'objet de mon expérimentation. J'expliquerai cependant dans les parties suivantes les différentes étapes pour utiliser l'ensemble du système, expliquant ainsi les différentes commandes disponibles.

Étape 4: Configuration du système

La première chose à faire est de télécharger l'Arduino UNO et le code d'interface ici si ce n'est déjà fait. Vous pouvez ensuite reprogrammer votre carte Arduino UNO avec le sketch "UNO_LS.ino" via l'IDE Arduino.

Vous devriez avoir téléchargé le logiciel p5.serialcontrol depuis son référentiel github. Vous devez obtenir le fichier zip correspondant à votre système d'exploitation (je ne l'ai testé que sous Windows). Extrayez le zip dans un dossier, démarrez l'exécutable qui s'y trouve et laissez-le comme ça. N'essayez pas de vous connecter à un port série, laissez-le simplement fonctionner en arrière-plan, il sera utilisé comme relais.

Ouvrez le dossier "Interface". Vous devriez trouver un fichier nommé "index.html". Ouvrez-le dans votre navigateur, c'est l'interface web.

Et c'est tout! Vous n'avez pas besoin de télécharger de bibliothèques supplémentaires, tout doit être inclus dans le package que j'ai fourni.

Étape 5: Connexion, configuration et acquisition

Connexion, configuration et acquisition
Connexion, configuration et acquisition

Pour connecter l'interface à la carte Arduino UNO, sélectionnez simplement le port correspondant dans la liste et appuyez sur le bouton "Ouvrir". Si l'opération a réussi, le message « état » doit afficher quelque chose comme « COMX ouvert ».

Vous pouvez maintenant choisir vos options de capture. La première est la sélection des bords. Je vous recommande de toujours utiliser "Both", car cela vous donnera la meilleure représentation du signal réel. Si le paramètre « Les deux » ne parvient pas à capturer le signal (si la fréquence du signal est trop élevée par exemple), vous pouvez essayer avec le paramètre de front « montant » ou « descendant », selon le signal que vous essayez de voir.

Le deuxième réglage est la division de l'horloge. Il vous donnera la résolution à laquelle vous pourrez capturer le signal. Vous pouvez choisir de définir le facteur de division par "8", "64", "256" et "1024". La carte Arduino UNO utilise un quartz 16MHz pour cadencer le microcontrôleur, donc la fréquence d'échantillonnage sera "16MHz/facteur de division". Soyez prudent avec ce paramètre, car il déterminera également pendant combien de temps vous pourrez capturer un signal. Comme le Timer1 est un timer de 16 bits, le temps de capture autorisé avant débordement sera "(2^16)*(division factor)/16MHz". Selon le réglage que vous avez choisi, il variera entre ~ 33 ms et 4,2 s. Gardez votre choix en tête, vous en aurez besoin plus tard.

Le dernier paramètre est le suppresseur de bruit. Je n'ai pas fait beaucoup de tests dessus, et vous n'en aurez pas besoin dans 99% des cas, alors laissez-le décoché. Pour ceux qui sont encore curieux à ce sujet, vous pouvez rechercher le suppresseur de bruit dans la section Timer/Counter1 de la fiche technique de l'ATMEGA328P.

N'oubliez pas de connecter la broche 8 de la carte Arduino UNO à votre signal et de câbler les masses ensemble pour avoir la même référence de tension pour le circuit de test et l'analyseur logique. Si vous avez besoin d'une isolation à la terre ou si vous devez mesurer des signaux avec des niveaux différents de 5V, vous devrez probablement ajouter un opto-isolateur à votre circuit.

Une fois que tout est configuré correctement, vous pouvez appuyer sur le bouton "Acquérir".

Étape 6: Capturez les résultats et exportez les données CSV

Capturez les résultats et exportez les données CSV
Capturez les résultats et exportez les données CSV

Une fois que votre Arduino UNO a terminé une capture, il renvoie automatiquement les données à l'interface Web, qui les tracera. Vous pouvez zoomer ou dézoomer avec le curseur de droite et parcourir les échantillons avec celui du bas.

Le tracé ne vous donne qu'un aperçu et ne dispose d'aucun outil d'analyse de données. Ainsi, afin de procéder à une analyse plus approfondie de vos données, vous devrez les importer dans PulseView.

La première étape consiste à exporter un fichier csv contenant toutes vos données. Pour cela, il vous suffit de cliquer sur le bouton "Exporter" de l'interface web. Enregistrez votre fichier dans un emplacement connu lorsque vous y êtes invité.

Ouvrez maintenant PulseView. Dans la barre de menu supérieure, cliquez sur « Ouvrir » (icône de dossier) et sélectionnez « Importer des valeurs séparées par des virgules… ». Sélectionnez le fichier csv généré précédemment contenant vos données.

Une petite fenêtre apparaîtra. Laissez le tout tel quel, il vous suffit de modifier le paramètre "Samplerate" en fonction du facteur de division d'horloge choisi pour la capture. Votre fréquence d'échantillonnage sera "16MHz/(facteur de division)". Cliquez ensuite sur "Ok", votre signal devrait apparaître à l'écran.

Étape 7: Analyse du signal PulseView

Analyse de signal PulseView
Analyse de signal PulseView

PulseView propose de nombreux décodeurs de protocole. Pour y accéder, cliquez sur "Ajouter un décodeur de protocole" dans la barre de menu supérieure (outil le plus à droite). Pour mon expérience, je viens d'envoyer un simple message UART à 9600 bauds, j'ai donc recherché "UART".

Il ajoutera un canal avec un tag sur sa gauche (comme celui pour vos données). En cliquant sur la balise, vous pouvez modifier les paramètres du décodeur. Après avoir choisi les bons, j'ai pu récupérer le même message que celui envoyé par mon appareil de test. Cela montre que l'ensemble du système fonctionne comme prévu.

Étape 8: Conclusion

Conclusion
Conclusion

Même si le projet était, au départ, une expérimentation, je suis content des résultats que j'ai obtenus. J'ai pu échantillonner des signaux UART jusqu'à 115200 bauds en mode "Both" sans aucun problème, et j'ai même réussi à monter jusqu'à 230400 bauds en mode "Falling". Vous pouvez voir ma configuration de test sur l'image ci-dessus.

Mon implémentation présente plusieurs inconvénients, à commencer par le fait qu'elle ne peut capturer qu'un signal à la fois, car seule la broche 8 de l'Arduino UNO est "capable de capture d'entrée". Si vous recherchez un analyseur logique Arduino avec plus de canaux, consultez celui de Catoblepas.

Vous ne pouvez pas vous attendre à ce qu'un Arduino UNO puisse capturer des signaux à hautes fréquences (quelques MHz), car il n'est cadencé qu'à 16 MHz (si quelqu'un le faisait, je serais intéressé de voir sa méthode). Cependant, je suis toujours impressionné par les résultats que nous pouvons obtenir de ce microcontrôleur ATMEGA328P.

Je ne pense pas que je vais faire beaucoup de travail sur le code. J'ai mené mes expériences et j'ai obtenu les résultats que je cherchais. Mais si quelqu'un veut contribuer, n'hésitez pas à modifier et redistribuer tout ou partie de mon code.

C'était mon premier Instructable, et un long je pense. J'espère que cela a été une lecture intéressante pour vous.

Faites-moi savoir si vous trouvez des erreurs, ou si vous avez des questions !

Conseillé: