Comment lire les données série de l'oscilloscope


21

J'ai un microcontrôleur (PICAXE 20X2) et un pot mètre. J'ai programmé le micro pour qu'il envoie tout changement de potmètre au port série du PC. C'est évidemment un ADC 8 bits. Maintenant, la chose intéressante pour moi est de pouvoir décoder ces données en série sur l'oscilloscope.

Voici deux images, la première est lorsque le micro envoie "0" au PC et la suivante est quand il envoie "255". Les données sont transmises à l'aide de 9600 buad et je peux les recevoir au terminal PC.

Première photo entrez la description de l'image ici

Deuxième photo entrez la description de l'image ici

Donc ma question est, ai-je capturé les bonnes données sur mon oscilloscope, et deuxièmement comment on peut lire et décoder ces impulsions au format hexadécimal ou ascii. Je veux dire comment lire ces impulsions montantes et descendantes (0/1).

Merci.


3
les lignes série sont inactives dans l'état logique «1», alors sachez que vous avez 1 en bas et 0 en haut ici. Je sais que les gens s'y sont déjà accrochés. Mon commentaire est destiné à guider les futures saisies de la portée des données série; vous pouvez sonder les choses pour que l'état de veille soit élevé.
JustJeff

Réponses:


14

Tout d'abord, Olin a également remarqué: les niveaux sont l'inverse de ce qu'un microcontrôleur sort habituellement:

entrez la description de l'image ici

Ne vous inquiétez pas, nous verrons que nous pouvons également le lire de cette façon. Nous devons juste nous rappeler que sur l'oscilloscope un bit de début sera un 1bit d'arrêt 0.

μμμ1μ0

0x001μ
0xFFμ

estimations:

0b11001111 = 0xCF
0b11110010 = 0xF2

0b11001101 = 0xCD
0b11001010 = 0xCA
0b11001010 = 0xCA
0b11110010 = 0xF2

modifier
Olin a absolument raison, c'est quelque chose comme ASCII. En fait, c'est le complément 1 de ASCII.

0xCF ~ 0x30 = '0'
0xCE ~ 0x31 = '1'
0xCD ~ 0x32 = '2'
0xCC ~ 0x33 = '3'
0xCB ~ 0x34 = '4'
0xCA ~ 0x35 = '5'

0xF2 ~ 0x0D = [CR]

Cela confirme que mon interprétation des captures d'écran est correcte.


edit 2 (comment j'interprète les données, sur demande populaire :-))
Attention: c'est une longue histoire, car c'est une transcription de ce qui se passe dans ma tête quand j'essaie de décoder une chose comme ça. Ne le lisez que si vous voulez apprendre une façon de l'aborder.

Exemple: le deuxième octet sur la 1ère capture d'écran, en commençant par les 2 impulsions étroites. Je commence par le deuxième octet exprès car il y a plus de bords que dans le premier octet, il sera donc plus facile de bien faire les choses. Chacune des impulsions étroites est d'environ 1 / 10e de division, de sorte qu'elle peut avoir 1 bit de haut chacune, avec un bit bas entre les deux. Je ne vois rien de plus étroit que cela, donc je suppose que c'est un peu. Voilà notre référence.
Ensuite, après 101une période plus longue à faible niveau. Semble environ deux fois plus large que les précédents, ce qui pourrait être le cas 00. La suite élevée qui est encore deux fois plus large, ce sera le cas 1111. Nous avons maintenant 9 bits: un bit de début ( 1) plus 8 bits de données. Donc, le bit suivant sera le bit d'arrêt, mais parce qu'il est0ce n'est pas immédiatement visible. Donc, nous avons mis tout cela ensemble 1010011110, y compris le bit de démarrage et d'arrêt. Si le bit d'arrêt n'était pas nul, j'aurais fait une mauvaise hypothèse quelque part!
N'oubliez pas qu'un UART envoie le LSB (bit le moins significatif) en premier, donc nous devrons inverser les 8 bits de données: 11110010= 0xF2.

Nous connaissons maintenant la largeur d'un bit unique, d'un bit double et d'une séquence de 4 bits, et nous examinons le premier octet. La première période haute (l'impulsion large) est légèrement plus large que 1111dans le deuxième octet, ce qui fait 5 bits de large. La période basse et la période haute qui la suit sont aussi larges que le bit double dans l'autre octet, donc nous obtenons 111110011. Encore une fois 9 bits, donc le suivant devrait être un bit faible, le bit d'arrêt. C'est OK, donc si notre estimation est correcte, nous pouvons à nouveau inverser les bits de données: 11001111= 0xCF.

Ensuite, nous avons obtenu un indice d'Olin. La première communication est longue de 2 octets, 2 octets plus courte que la seconde. Et "0" est également 2 octets plus court que "255". C'est donc probablement quelque chose comme ASCII, mais pas exactement. Je note également que les deuxième et troisième octets du "255" sont identiques. Super, ce sera le double "5". Nous allons bien! (Vous devez vous encourager de temps en temps.) Après avoir décodé les "0", "2" et "5", je remarque qu'il y a une différence de 2 entre les codes pour les deux premiers, et une différence de 3 entre les derniers deux. Et enfin, je remarque que 0xC_c'est le complément de 0x3_, qui est le modèle de chiffres en ASCII.


Merci pour les conseils, je vais essayer de capturer la bonne forme d'onde et de mettre à jour ma question.
Sean87

Merci, pourriez-vous marquer l'image comme la façon dont vous trouvez ces données?
Sean87

1
@ Sean87 - C'est devenu une longue histoire, je l'ai ajouté à ma réponse. Cela illustre ma façon de procéder, d'autres peuvent suivre des chemins différents. Ne vous inquiétez pas si vous pensez que vous n'en auriez pas vu la moitié; l'essentiel n'est qu'expérience et imagination. Il n'y a aucune intelligence spéciale impliquée.
stevenvh

Très belles réponses et questions, mais je me demande pourquoi vous avez dit que l'oscilloscope montre l'inverse de ce qui est réellement. Je sais que la ligne inactive est presque toujours élevée, mais l'oscilloscope n'est-il pas censé capturer une image exacte de la réalité? Sauf si l'utilisateur a modifié un paramètre des réglages de l'oscilloscope.
Nikos

7

Quelque chose ne s'additionne pas. Vos signaux semblent être de 3,3 V crête à crête, ce qui implique qu'ils sont directement sortis du micro. Cependant, les niveaux UART du microcontrôleur sont (presque) toujours au ralenti haut et actif bas. Vos signaux en sont inversés, ce qui n'a pas de sens.

Pour finalement obtenir ces données dans un PC, elles doivent être converties en niveaux RS-232. C'est ce qu'un port COM PC s'attend à voir. RS-232 est au ralenti bas et actif haut, mais bas est inférieur à -5 V et haut est supérieur à + 5 V. Heureusement, il existe des puces pour cela qui facilitent la conversion entre les signaux UART de niveau logique du microcontrôleur typique et RS-232. Ces puces contiennent des pompes de charge pour faire les tensions RS-232 à partir de votre alimentation 3,3V. Parfois, ces puces sont appelées génériquement "MAX232" car il s'agissait d'un numéro de pièce pour une puce ancienne et populaire de ce type. Vous avez besoin d'une variante différente car vous utilisez apparemment une alimentation de 3,3 V, pas de 5 V. Nous fabriquons un produit qui est essentiellement l'une de ces puces sur une carte avec des connecteurs. Accédez à http://www.embedinc.com/products/rslink2et regardez le schéma pour voir un exemple de comment brancher une telle puce.

Une autre chose qui ne correspond pas est que les deux séquences semblent être plus d'un octet, même si vous dites que vous n'envoyez que 0 et 255. Ce type de données série est envoyé avec un bit de début, puis les 8 bits de données, puis un peu d'arrêt. Le bit de départ est toujours à la polarité opposée au niveau de ralenti de ligne. Dans la plupart des descriptions, le niveau d'inactivité de la ligne est appelé "espace" et l'inverse "marque". Ainsi, le bit de départ est toujours à la marque. Le bit de démarrage a pour but de fournir une synchronisation temporelle pour les bits restants. Étant donné que les deux côtés savent combien de temps un bit est, la seule question est de savoir quand le début d'un octet est. Le bit de départ fournit ces informations. Le récepteur démarre essentiellement une horloge au bord d'attaque du bit de départ et l'utilise pour savoir quand les bits de données arriveront.

Les bits de données sont envoyés au moins dans l'ordre le plus significatif, avec la marque 1 et l'espace 0. Un bit d'arrêt au niveau de l'espace est ajouté afin que le début du bit de début suivant soit un nouveau front, et pour laisser un peu de temps entre octets. Cela permet une petite erreur entre l'expéditeur et le destinataire. Si le récepteur était un peu plus lent que l'expéditeur, même un petit peu, il manquerait sinon le début du bit de démarrage suivant. Le récepteur se réinitialise et redémarre son horloge à chaque nouveau bit de démarrage, afin que les erreurs de synchronisation ne s'accumulent pas.

Donc, à partir de tout cela, vous devriez pouvoir voir que la première trace semble envoyer au moins deux octets, et la dernière ressemble peut-être à 5.

Il serait utile que vous augmentiez l'échelle de temps des traces. De cette façon, vous pourriez mesurer ce qu'est vraiment un peu de temps. Cela vous permettrait de vérifier que vous disposez bien de 9600 bauds (104 µs / bit) et de décoder des bits individuels d'une capture. Comme c'est le cas actuellement, il n'y a pas assez de résolution pour voir où sont les bits, et donc décoder réellement ce qui est envoyé.

Ajoutée:

Je viens de penser que votre système peut envoyer les données en ASCII plutôt qu'en binaire. Ce n'est pas ainsi que cela se fait généralement, car la conversion en ASCII dans le petit système prend plus de ressources limitées, utilise mal la bande passante et il est facile de faire la conversion sur le PC si vous souhaitez afficher les données à un utilisateur. Cependant, si vos transmissions sont des caractères ASCII qui expliqueraient pourquoi les séquences sont plus d'un octet, pourquoi la seconde est plus longue ("255" est plus de caractères que "0"), et pourquoi les deux semblent se terminer dans le même octet. Le dernier octet est probablement une sorte de caractère de fin de ligne, qui serait généralement un retour chariot ou un saut de ligne.

Quoi qu'il en soit, élargissez l'échelle de temps et nous pouvons décoder exactement ce qu'elle est envoyée.


1
Le bit d'arrêt (et étant opposé au bit de démarrage) force également un front au début d'une nouvelle transmission.
stevenvh

@steven: Oui, je me suis rendu compte que j'avais laissé cela de côté en relisant ma réponse et que je l'avais ajoutée dans un montage, probablement en même temps que vous écriviez votre commentaire.
Olin Lathrop

4
Bien que l'envoi d'ASCII soit «inefficace», il peut toujours être un très bon choix. La plupart de mes systèmes embarqués envoient non seulement de l'ASCII, mais ils reçoivent également des commandes ASCII, ce qui permet d'expérimenter manuellement en "ayant une conversation" avec eux à partir d'un programme de terminal. La norme SCPI (sorte d'amélioration du GPIB, étendue à d'autres interfaces électriques) est une méthode très formelle qui fonctionne dans ce sens.
Chris Stratton

4
Aller à fortement en désaccord. Ascii prend une si petite quantité de code, même en exécutant du métal nu sur un petit 8 bits. Bien sûr, vous pouvez écrire un programme personnalisé, mais que se passera-t-il dans 10 ans quand il sera perdu et qu'il faudrait une machine virtuelle pour l'exécuter même s'il pouvait être trouvé? Et bien sûr, tout programmeur digne de ce nom peut pirater un terminal binaire pour inverser quelque chose. Mais les interfaces lisibles par l'homme valent bien le petit surcoût dans la plupart des systèmes, mais les plus limités en termes de mémoire et de performances. De plus, si vous avez la mémoire, vous pouvez incorporer la sortie de débogage avec un on / off.
Chris Stratton

2
Je dois mentionner que j'ai commencé sur les interfaces ASCII car c'était une exigence du client ... mais je les ai gardées en raison de leur utilité. Je pourrais ajouter une idée en tant que commande dans le micrologiciel, puis la tester n'importe où dans l'installation. Sans avoir à déployer une mise à jour sur le client de configuration à chaque fois que je publiais une version expérimentale du firmware avec des extras pour étudier un problème que quelqu'un rencontrait dans un système compliqué dont il ne s'agissait que d'un module. Au téléphone avec un client, je pouvais leur faire allumer un terminal et les guider à l'aide de fonctions de test d'usine non publiées.
Chris Stratton

1

Vous devez connaître tous les détails: la vitesse, s'il y a un bit de départ, le nombre de bits de données, s'il y a un bit d'arrêt et s'il y a un bit de parité. Cela devrait être fonction de la configuration de l'UART dans le microcontrôleur.

Si la portée Rigol n'a pas d'option de décodage série (de nombreux DSO en ont), vous pouvez utiliser des curseurs X pour faciliter le décodage. Placez le premier curseur sur le bord d'attaque des données et déplacez le second curseur dans le flux binaire. Le delta entre les curseurs peut être utilisé pour déterminer le `` bit '' que vous survolez actuellement par simple arithmétique. Ignorez évidemment les bits de démarrage / arrêt / parité.


Il y a toujours un bit de démarrage et toujours au moins un bit d'arrêt. Il peut y avoir des bits d'arrêt supplémentaires, mais ceux-ci sont indiscernables du temps mort entre les octets. Les anciens décodeurs mécaniques avaient parfois besoin de deux bits d'arrêt pour laisser le temps au mécanisme de se réinitialiser. De nos jours, il y a presque toujours 8 bits de données et aucun bit de parité, mais comme vous le dites, cela peut varier.
Olin Lathrop
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.