Come leggere i dati seriali dall'oscilloscopio


21

Ho un microcontrollore (PICAXE 20X2) e un misuratore di potenza. Ho programmato il micro in modo che invii qualsiasi cambiamento del potenziometro alla porta seriale del PC. Ovviamente si tratta di un ADC a 8 bit. Ora la cosa interessante per me è riuscire a decodificare questi dati seriali sull'oscilloscopio.

Ecco due immagini, la prima è quando il micro invia "0" al PC e la successiva è quando invia "255". I dati vengono trasmessi utilizzando 9600 Buad e posso riceverli sul terminale del PC.

Prima foto inserisci qui la descrizione dell'immagine

Seconda foto inserisci qui la descrizione dell'immagine

Quindi la mia domanda è: ho catturato i dati giusti sul mio ambito e secondo come si possono leggere e decodificare questi impulsi in un formato esadecimale o ascii. Intendo come leggere questo impulso crescente e decrescente (0/1).

Grazie.


3
le linee seriali sono inattive nello stato logico '1', quindi tieni presente di avere 1 in basso e 0 in alto qui. So che le persone si sono già bloccate su questo. Il mio commento ha lo scopo di guidare le future acquisizioni di dati seriali; puoi sondare le cose in modo che lo stato inattivo sia alto.
JustJeff

Risposte:


14

Prima cosa che Olin ha notato anche: i livelli sono il contrario di ciò che un microcontoller solitamente produce:

inserisci qui la descrizione dell'immagine

Niente di cui preoccuparsi, vedremo che possiamo leggerlo anche in questo modo. Dobbiamo solo ricordare che sull'ambito un bit di inizio sarà un 1e il bit di stop 0.

μμμ1μ0

0x001μ
0xFFμ

guesstimates:

0b11001111 = 0xCF
0b11110010 = 0xF2

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

modifica
Olin ha perfettamente ragione, questo è qualcosa come ASCII. È un dato di fatto è il complemento 1 di ASCII.

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

0xF2 ~ 0x0D = [CR]

Ciò conferma che la mia interpretazione degli screenshot è corretta.


modifica 2 (come interpreto i dati, su richiesta popolare :-))
Attenzione: questa è una lunga storia, perché è una trascrizione di ciò che accade nella mia testa quando provo a decodificare una cosa del genere. Leggilo solo se vuoi imparare un modo per affrontarlo.

Esempio: il secondo byte nel primo screenshot, a partire dai 2 impulsi stretti. Comincio con il secondo byte apposta perché ci sono più spigoli rispetto al primo byte, quindi sarà più facile farlo bene. Ciascuno degli impulsi stretti è circa 1/10 di una divisione, quindi potrebbe essere 1 bit alto ciascuno, con un bit basso nel mezzo. Inoltre non vedo nulla di più stretto di così, quindi immagino sia un po '. Questo è il nostro riferimento.
Quindi, dopo 101un periodo più lungo a basso livello. Sembra circa il doppio rispetto ai precedenti, quindi potrebbe essere 00. Il seguito alto che è di nuovo il doppio, quindi sarà 1111. Ora abbiamo 9 bit: un bit di inizio ( 1) più 8 bit di dati. Quindi il prossimo bit sarà il bit di stop, ma perché lo è0non è immediatamente visibile. Quindi abbiamo messo tutto insieme 1010011110, incluso start e stop bit. Se il bit di stop non fosse zero, avrei fatto una cattiva ipotesi da qualche parte!
Ricorda che un UART invia prima l'LSB (bit meno significativo), quindi dovremo invertire gli 8 bit di dati: 11110010= 0xF2.

Ora conosciamo la larghezza di un singolo bit, un doppio bit e una sequenza di 4 bit e diamo un'occhiata al primo byte. Il primo periodo alto (l'impulso largo) è leggermente più largo rispetto 1111al secondo byte, quindi sarà largo 5 bit. Il periodo basso e quello successivo che lo seguono sono ampi quanto il doppio bit nell'altro byte, quindi otteniamo 111110011. Ancora 9 bit, quindi il prossimo dovrebbe essere un bit basso, il bit di stop. Va bene, quindi se la nostra stima è corretta possiamo di nuovo invertire i bit di dati: 11001111= 0xCF.

Quindi abbiamo ricevuto un suggerimento da Olin. La prima comunicazione è lunga 2 byte, 2 byte più brevi della seconda. E "0" è anche 2 byte più corto di "255". Quindi è probabilmente qualcosa come ASCII, anche se non esattamente. Noto anche che il secondo e il terzo byte del "255" sono gli stessi. Fantastico, quello sarà il doppio "5". Stiamo andando bene! (Di tanto in tanto devi incoraggiarti.) Dopo aver decodificato "0", "2" e "5" noto che c'è una differenza di 2 tra i codici per i primi due e una differenza di 3 tra gli ultimi Due. E finalmente noto che 0xC_è il complemento di 0x3_, che è il modello per le cifre in ASCII.


Grazie per i suggerimenti, proverò a catturare la forma d'onda giusta e ad aggiornare la mia domanda.
Sean87,

Grazie, ti dispiacerebbe contrassegnare l'immagine come come trovi quei dati?
Sean87

1
@ Sean87 - È diventata una lunga storia, l'ho aggiunta alla mia risposta. Illustra il mio modo di farlo, altri possono seguire percorsi diversi. Non preoccuparti se pensi di non averne visto la metà; la maggior parte è solo esperienza e immaginazione. Non c'è nessuna intelligenza speciale coinvolta.
Stevenvh,

Risposte e domande molto belle, ma mi chiedo perché hai detto che l'oscilloscopio mostra l'inverso di ciò che realmente è. So che la linea inattiva è quasi sempre alta, ma l'oscilloscopio non dovrebbe catturare un'immagine esatta della cosa reale? Tranne se l'utente ha modificato un parametro delle impostazioni dell'oscilloscopio.
Nikos,

7

Qualcosa non si aggiunge. I segnali sembrano essere 3,3 V picco-picco, il che implica che sono usciti direttamente dal micro. Tuttavia, i livelli UART del microcontrollore sono (quasi) sempre inattivi e bassi attivi. I tuoi segnali sono invertiti da quello, il che non ha senso.

Per ottenere questi dati in un PC, devono essere convertiti ai livelli RS-232. Questo è ciò che una porta COM del PC si aspetta di vedere. RS-232 è inattivo basso e attivo alto, ma basso è inferiore a -5 V e alto è superiore a + 5 V. Fortunatamente ci sono chip per ciò che rendono facile la conversione tra i tipici segnali UART a livello logico del microcontrollore e RS-232. Questi chip contengono pompe di carica per produrre le tensioni RS-232 dall'alimentatore a 3,3 V. A volte questi chip vengono definiti genericamente "MAX232" perché quello era un numero di parte per un chip iniziale e popolare di quel tipo. Hai bisogno di una variante diversa poiché apparentemente stai usando un'alimentazione a 3,3 V, non a 5 V. Realizziamo un prodotto che è fondamentalmente uno di questi chip su una scheda con connettori. Vai a http://www.embedinc.com/products/rslink2 e guarda lo schema per vedere un esempio di come collegare un tale chip.

Un'altra cosa che non si somma è che entrambe le sequenze sembrano essere più di un byte, anche se dici che stai inviando solo 0 e 255. Questo tipo di dati seriali viene inviato con un bit iniziale, quindi gli 8 bit di dati, quindi un po 'di stop. Il bit di avvio è sempre alla polarità opposta rispetto al livello di inattività della linea. Nella maggior parte delle descrizioni, il livello di inattività della linea viene indicato come "spazio" e l'opposto come "segno". Quindi il bit di inizio è sempre nel segno. Lo scopo del bit di avvio è fornire la sincronizzazione dell'ora per i bit rimanenti. Dato che entrambe le parti sanno quanto è lungo, l'unica domanda è quando è l'inizio di un byte. Il bit di avvio fornisce queste informazioni. Il ricevitore essenzialmente avvia un clock sul bordo anteriore del bit di inizio e lo utilizza per sapere quando arriveranno i bit di dati.

I bit di dati vengono inviati almeno nell'ordine più significativo, con il segno 1 e lo spazio è 0. Viene aggiunto un bit di arresto a livello di spazio in modo che l'inizio del prossimo bit di inizio sia un nuovo fronte e che lasci un po 'di tempo tra byte. Ciò consente un piccolo errore tra il mittente e il destinatario. Se il ricevitore fosse anche più lento del mittente, altrimenti perderebbe l'inizio del successivo bit di inizio. Il ricevitore si reimposta e ricomincia a suonare ogni nuovo bit di avvio, per evitare che si accumulino errori di temporizzazione.

Quindi, da tutto ciò, dovresti essere in grado di vedere che la prima traccia sembra inviare almeno due byte e l'ultima sembra forse 5.

Sarebbe utile se si espandesse la scala temporale delle tracce. In questo modo è possibile misurare un po 'di tempo. Ciò ti consentirebbe di verificare che tu abbia davvero 9600 baud (104 µs / bit) e di decodificare i singoli bit di una cattura. Come è ora, non c'è abbastanza risoluzione per vedere dove sono i bit e quindi decodificare effettivamente ciò che viene inviato.

Inserito il:

Mi è appena venuto in mente che il tuo sistema potrebbe inviare i dati in formato ASCII anziché binario. Non è così che viene generalmente fatto poiché la conversione in ASCII nel piccolo sistema richiede più risorse limitate, utilizza la larghezza di banda in modo scarso ed è facile fare la conversione sul PC se si desidera visualizzare i dati a un utente. Tuttavia, se le tue trasmissioni sono caratteri ASCII che spiegherebbero perché le sequenze sono più di un byte, perché la seconda è più lunga ("255" è più caratteri di "0") e perché entrambe sembrano finire nello stesso byte. L'ultimo byte è probabilmente una sorta di carattere di fine riga, che di solito sarebbe un ritorno a capo o un avanzamento di riga.

In ogni caso, espandi la scala temporale e possiamo decodificare esattamente ciò che viene inviato.


1
Il bit di stop (ed essendo opposto al bit di start) forza anche un fronte all'inizio di una nuova trasmissione.
Stevenvh,

@steven: Sì, mi sono reso conto di averlo lasciato fuori rileggendo la mia risposta e l'ho aggiunta in una modifica, probabilmente mentre stavi scrivendo il tuo commento.
Olin Lathrop,

4
Mentre l'invio di ASCII è "inefficiente", può comunque essere un'ottima scelta. La maggior parte dei miei sistemi embedded non solo invia ASCII, ma riceve anche comandi ASCII, rendendo possibile sperimentare manualmente "conversando" con loro da un programma terminale. Lo standard SCPI (una sorta di miglioramento su GPIB, esteso ad altre interfacce elettriche) è un metodo molto formale che funziona in questo senso.
Chris Stratton,

4
Andare in forte disaccordo. Ascii prende una così piccola quantità di codice, anche eseguendo bare metal su un po 'di 8 bit. Certo, puoi scrivere un programma personalizzato, ma cosa succede tra 10 anni quando è perso e ci vorrebbe una macchina virtuale per eseguirlo anche se potesse essere trovato? E sicuramente, qualsiasi programmatore degno del suo sale può hackerare un terminale binario per decodificare qualcosa. Ma le interfacce leggibili dall'uomo valgono il piccolo sovraccarico nella maggior parte, ma nei sistemi con maggiore limitazione della memoria e prestazioni critiche. Inoltre, se si dispone della memoria, è possibile incorporare l'output di debug con un on / off.
Chris Stratton,

2
Devo dire che ho iniziato con le interfacce ASCII in quanto era un requisito del cliente ... ma le ho conservate per quanto siano utili. Potrei aggiungere un'idea come comando nel firmware e quindi testarla ovunque nella struttura. Senza dover distribuire un aggiornamento al client di configurazione ogni volta che ho pubblicato una versione del firmware sperimentale con extra per esaminare un problema che qualcuno stava avendo in un sistema complicato di cui era solo un modulo. Al telefono con un cliente, potrei far accendere un terminale e guidarli attraverso le funzioni di test di fabbrica non pubblicate.
Chris Stratton,

1

È necessario conoscere i dettagli completi: la velocità, se è presente un bit iniziale, il numero di bit di dati, se esiste un bit di stop e se esiste un bit di parità. Questa dovrebbe essere una funzione della configurazione dell'UART nel microcontrollore.

Se l'ambito Rigol non ha un'opzione di decodifica seriale (molti DSO lo fanno) è possibile utilizzare i cursori X per facilitare la decodifica. Posiziona il primo cursore sul bordo anteriore dei dati e sposta il secondo cursore attraverso il flusso di bit. Il delta tra i cursori può essere usato per determinare quale 'bit' al momento stai passando su una semplice aritmetica. Ignora i bit di avvio / arresto / parità, ovviamente.


C'è sempre un bit di inizio e sempre almeno un bit di stop. Potrebbero esserci dei bit di stop aggiuntivi, ma questi sono indistinguibili dal tempo morto tra i byte. I vecchi decodificatori meccanici a volte necessitavano di due bit di arresto per consentire il ripristino del meccanismo. Oggi ci sono quasi sempre 8 bit di dati e nessun bit di parità, ma come dici tu, questo può variare.
Olin Lathrop,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.