[Arduino] 使用示波器來看Arduino的UART, Inverted Software serial及RS-232訊號並對其進行解碼
主題: 使用示波器來看Arduino的UART訊號及Inverted Software Serial的波形,及這些訊號轉換成RS-232訊號後的波形,並對其進行ASCII code解碼。
本次測試使用器材為
- Arduino MEGA 2560 Rev3 (可參考Po文: [Arduino] 欣賞官方版Arduino MEGA 2560 Rev3 )
- TTL to RS-232模組。(這個市面上有N種,本次使用MAX3232 ESE+DN20晶片。)
- Keysight 2002A示波器 (關於如何學習該款示波器,可參考Po文: [儀器學習] Keysight DSOX2002A Oscilloscope 示波器 )
PS1: 其他Arduino開發版也可適用此案例,例如: Arduino UNO Rev3, Arduino UNO SMD
UART and RS-232基本認知
兩者的邏輯訊號的電壓不同,請見下表。
其中UART採用正邏輯,而RS-232採用負邏輯,因此兩者的波形相反(當然電壓也不同)。
序列通訊(Serial Communication)傳輸速度與傳輸封包結構
不管是UART或是RS-232的序列通訊,在此測試中都使用相同的傳輸速度與傳輸封包結構。
關於傳輸速度與傳輸封包結構,由於已行之有年,業界通常都講得非常簡略,也成為了一種默契。
業界行話:
- Baud rate 2400 bps。
- 8N1 (詳細請見參考資料)。
這個行話,簡單來說:
- 每秒會傳送2400個Bit。表示資料傳輸速度。
- 會看到訊號長成10個格子的樣子,如下圖所示。
其中Start (第1個Bit)會用Logic 0表示,Stop (第10個Bit)會用Logic 1表示,這兩個都是固定不變。
D0~D7這8個Bit就是存放資料的地方(灰色區域),Logic可以是0或1,看你放什麼資料。
當封包結構解開後(10碼結構),解碼主要就是解這塊(8碼灰色區域)。
Arduino UART
獻慶寫了一個Arduino的code,請Arduino每秒從第16 pin輸出訊號 (Tx2,第3組Serial channel)。
示波器的探棒兩端則對Arduino的第16 pin及GND偵測。
調整示波器至可看到訊號波形( [儀器學習] Keysight DSOX2002A Oscilloscope 示波器 ),會看到一堆凹凸的方塊波,長度不一。
第一次看到,會慌,不用擔心,我們一步一步做下去。
UART訊號波型。 |
先檢查訊號電壓。低電壓為10 mV,表示邏輯0,高電壓為4.91 V,表示邏輯1。電壓差為4.9 V。
這點與Arduino規格上的Vcc=5V有接近,差值可能來自於線損。
檢查訊號電壓。 |
請看出訊號中"最窄的凹凸","最窄的凹凸"的寬度表示1個Bit的傳輸時間。這裡寬度量得為416.60 μs (μs通常顯示為us,因為μ這個希臘字不容易顯示),倒數後換算成傳輸速度(Bit Rate)則是2400.4 bps (圖中顯示2.4004 kbps)。此數值與訊號傳輸的Baud rate設定值幾乎吻合,表示找對的訊號來計算。
PS1:
傳輸速度(Bit Rate)計算方式,就是用"頻率(f)=1/週期(period)"這個耳熟能詳的式子來計算,傳輸速度就是頻率值。
其中,週期period量得為416.60 μs = 416.60 × 10−6 s
傳輸速度 = 1/週期period = 1 / (416.60 × 10−6 s) = 0.0024004 × 106 = 2400.4 (bps)
PS2: 若找錯訊號計算,則計算值可能會低於設定值幾倍。而如果在這個錯誤下硬去解碼,則是會產生很多解碼問題。例如: 訊號實際波形與傳輸封包結構不匹配。
PS3: 老手可跳過這步。反正只要猜到哪個是1個Bit的寬度(最窄的凹凸),就可以開始解碼了。另外,新式的示波器,也可把自動量測Bit Rate的選項打開,直接看到數值。
計算Bit rate。 |
根據serial communication的封包結構,可先用10 bit的寬度將原始訊號切開。
訊號切開的起始點,其實很好判斷。沒訊號時,會看到訊號基本上維持同一個電壓,一旦電壓開始改變,就是訊號進來了。另外一種說法,長時間都是Logic 1的訊號,一旦開始變成Logic 0,表示訊號進來了。
原始訊號切開後,可切得4個區塊。
每個區塊中,由左側數過來,第1個Bit為Logic 0,表示Start,第10個Bit為Logic 1,表示Stop,這兩個都是固定不變。
D0~D7這8個Bit就是存放資料的地方(灰色區域),Logic可以是0或1,看你放什麼資料。
先將Logic根據實際訊號狀況分析出來,也就是把圖中的黃字填上。記得在UART Serial communication中,低電壓表示Logic 0,高電壓表示Logic 1。
UART分析訊號並解碼。 |
封包結構分析完畢後,接著就是要解碼了。
解碼其實是要有密碼對照表或演算法。但這裡獻慶很單純的就是用ASCII code來解碼。下表列出本次用到的code。
使用該對照表可解碼,其中原始訊號中的第1個區塊解碼為R,第2個區塊解碼為V,第3個區塊解碼為V,第4個區塊解碼為\r。
得到訊號為 RVA\r
本文中的測試訊號就是預設為這個,從頭到尾不變,方便各位進行波形比對。
PS: 這裡Binary code的順序為D7~D0,得左右顛倒唸,才比較方便比對。例如: 表上的"00001101",左右顛倒後為"10110000",可對到原始訊號中的區塊4的信號。
完整對照表請參考資料: ASCII Table
Arduino UART to RS-232
先請Arduino每秒從第16 pin輸出序列訊號 (Tx2,第3組serial channel),透過"TTL to RS-232模組",將UART的訊號轉成RS-232的訊號。
示波器則對轉換後的Tx訊號進行偵測。
調整示波器至可看到訊號波形,會看到一堆凹凸的方塊波,長度不一。
我們一步一步做下去。
RS-232訊號波型。 |
先檢查訊號電壓。低電壓為-8.8 V,表示邏輯1,高電壓為8.9 V,表示邏輯0。電壓差為17.7 V。
PS: 從這個檢查中,得知電壓差為17.7 V,若此訊號直接接到Arduino上,可能會造成Arduino燒毀,因此為了避免燒毀,需要電壓轉換模組,也就是本次使用的"TTL to RS-232模組。
檢查訊號電壓。 |
請看出訊號中"最窄的凹凸","最窄的凹凸"的寬度表示1個Bit的傳輸時間。這裡寬度量得為416.96 μs (μs通常顯示為us,因為μ這個希臘字不容易顯示),倒數後換算成傳輸速度(Bit Rate)則是2398.3 bps (圖中顯示2.3983 kbps)。此數值與訊號傳輸的Baud rate設定值幾乎吻合,表示找對訊號來計算。
計算Bit rate。 |
根據serial communication的封包結構,可先用10 bit的寬度將原始訊號切開。
訊號切開的起始點,其實很好判斷。沒訊號時,會看到訊號基本上維持同一個電壓,一旦電壓開始改變,就是訊號進來了。另外一種說法,長時間都是Logic 1的訊號,一旦開始變成Logic 0,表示訊號進來了。
原始訊號切開後,可切得4個區塊。
每個區塊中,由左側數過來,第1個Bit為Logic 0,表示Start,第10個Bit為Logic 1,表示Stop,這兩個都是固定不變。
D0~D7這8個Bit就是存放資料的地方(灰色區域),Logic可以是0或1,看你放什麼資料。
先將Logic根據實際訊號狀況分析出來,也就是把圖中的黃字填上。記得在RS-232 Serial communication中,高電壓表示Logic 0,低電壓表示Logic 1 (請注意,RS-232跟UART的電壓邏輯顛倒)。
RS-232分析訊號並解碼。 |
封包結構分析完畢後,接著就是要解碼了。
解碼其實是要有密碼對照表或演算法。但這裡獻慶很單純的就是用ASCII code來解碼。下表列出本次用到的code。
使用該對照表可解碼,其中原始訊號中的第1個區塊解碼為R,第2個區塊解碼為V,第3個區塊解碼為V,第4個區塊解碼為\r。
得到訊號為 RVA\r
PS: 這裡Binary code的順序為D7~D0,得左右顛倒唸,才比較方便比對。例如: 表上的"00001101",左右顛倒後為"10110000",可對到原始訊號中的區塊4的信號。
完整對照表請參考資料: ASCII Table
獻慶這裡將UART與RS-232輸出的訊號放在一起,方便各位比較。
(由於手上只有一根探棒,無法同時取得並顯兩組訊號,此圖是分別取得訊號後,在後製拼圖)
Arduino的UART與RS-232輸出的訊號比較與分析。 |
Arduino Inverted Software Serial
以下會帶一下何謂Software serial,何謂Inverted software serial,還有案例的示波器訊號。
關於Software Serial
Arduino除了部分pin提供硬體序列功能外,也在其他特定pin提供軟體序列功能(Software serial)。這樣可以提供更多的序列通訊通道,補強Arduino序列通道不足的問題。
Software serial有提升A序列通訊數量的優點,但也有些缺點,例如: (1) 每提供1個通道的軟體序列通訊,則會少掉2個pin供其他輸出入應用。(2) 軟體序列通訊的最高傳輸速率遠低於硬體序列通訊的最高傳輸速率。如果有高速通訊的需求,就得考慮這點。
詳細內容,請見參考資料:
關於Inverted Software serial
既然都已經使用Software serial,怎麼前面還要加一個"Inverted"?
Inverted 表示反向
在Arduino的SoftwareSerial語法中,可透過inverse_logic來更改邏輯方向。
SoftwareSerial(rxPin, txPin, inverse_logic)
inverse_logic: 預設是0,或者就不要寫這個選項。設為1時,就會反向,也就是可以處理邏輯反向的訊號。
只是邏輯電壓顛倒,這個看似多餘的功能,卻意外地在實際應用時幫得上忙。
PS:
但為何一開始有學software serial的人,卻不知道有開啟反向邏輯設定?
因為很多Arduino的software serial程式範例是長這樣
SoftwareSerial(rxPin, txPin)
所以很多人不知道後面還有開啟反向邏輯設定
要另外去完整的語法介紹頁面,才會看到
SoftwareSerial(rxPin, txPin, inverse_logic)
參考資料:
示波器Data
以下是從示波器量測Inverted software serial獲得的訊號,各位可以使用"Arduino UART"這節提供的方法來進行分析。
要注意,電壓有上下顛倒。
Inverted software serial, 原始波型。 |
Inverted software serial, 檢查高低電壓用。 |
Inverted software serial, 計算傳輸速率。 |
Arduino Inverted Software Serial to RS-232
以下是從示波器量測Inverted software serial轉成RS-232後獲得的訊號,各位可以使用"Arduino UART to RS-232"這節提供的方法來進行分析。
要注意,電壓有上下顛倒。
Inverted software serial to RS-232, 原始波型。 |
Inverted software serial to RS-232, 檢查高低電壓用。 |
Inverted software serial to RS-232, 計算傳輸速率。 |
Hardware vs Software Serial
既然有示波器,那我們可以來看看硬體跟軟體序列通訊的差異性。
在通訊速度Bit rate 2400 bps的狀態下,兩者基本上看不太出差異。
不管是大致上的波形(下圖(a)及(b)),由低電壓至高電壓的波形放大圖(下圖(c)及(d)),由高電壓至低電壓的波形放大圖(下圖(e)及(f)),都大致相同。
眼尖的朋友會注意到,訊號變換時,電壓的變化並不是穩定的,而是看起來有衝過頭的狀況。此現象在電路學中有個名詞,叫overshooting。發生的時間很短,解析度高的示波器比較可捕捉到。在本案例中,每次電壓轉都會出現overshooting的現象,但在上圖(a)及(b)中,卻只看到其僅出現在某些轉換。這台示波器提供了"Peak Detect"的功能,能保留一定時間內波型的最大最小值,使我們在示波器訊號解析度不足的狀況下,也能看到每個電壓轉換時出現的overshooting現象,如下圖所示。
示波器的"Peak Detect"功能,使得每個電壓轉換時出現的overshooting現象,得以顯現。訊號源: Inverted software serial。 |
在Arduino官方對Software serial的介紹中 (Arduino - SoftwareSerial Library),有提到
It is possible to have multiple software serial ports with speeds up to 115200 bps.
那我們就來看看實際波形到底會如何。
在經過許多不同傳輸速度的測試後,獻慶發現,訊號不穩定的狀況,主要來自延遲輸出,造成訊號錯誤。儘管不是每個訊號都延遲輸出,但出現的頻率越高,表示訊號越不穩定,也越容易造成讀寫錯誤的狀況發生。
為了捕捉這個延遲輸出,開啟示波器的波形保留功能,來捕捉這個狀況。比較亮的波形就是實際訊號波型,而有點暗的波形(或稱殘影)就是有延遲輸出的波形(波形保留的測試時間大概2分鐘左右)。如下圖所示。
開啟示波器的波形保留功能,來捕捉輸出延遲的狀況。 |
在Inverted software serial的訊號中,隨著設定傳輸速度越來越大,殘影的狀況越來越嚴重,在19200 bps時就有明顯的感覺。而9600 bps則是看起來不明顯,難怪業界都喜歡選這個數值。
另外,隨著設定傳輸速度越來越大,實際輸出的傳輸速度與設定值的落差會增大。例如: 設定傳輸速度為1500000 bps時,實際傳輸速度只有842100 bps (如圖(w)所示,842.1 kbps)。
不管是訊號延遲或是速度落差都會造成通訊失效。
Inverted software serial訊號在各個設定傳輸速度下的實際波形。 |
接下來看看硬體輸出的UART訊號,9600 bps當然沒問題,然後就一路沒問題,到512000 bps也都沒問題,只是傳輸速度有些許落差。與軟體序列傳輸比起來,這個狀況好太多了,難怪大家說"有硬體的一定要用硬體的"。
設定傳輸速度1024000 bps時,開始出現殘影(傳輸延遲)。設定傳輸速度越高,殘影狀況越嚴重。
有趣的是,設定傳輸速度1500000 bps及3000000 bps時,實際傳輸速度都是2000000 bps (2.000 Mbps)。
UART訊號在各個設定傳輸速度下的實際波形。 |
TTL to RS-232模組的轉換效果
由下圖可看出,原本的UART訊號(圖(a))轉換為RS-232訊號後,overshooting的現象消失了(圖(b))。看起來是個優點。
但轉換時間變長了,從6 ns (圖(c)及(e))到350 ns (圖(d)及(f))。看起來是個問題。這樣會造成轉換後的RS-232訊號,沒辦法支援很高的傳輸速度。
如下圖所示,
設定傳輸速度為9600 bps時(圖(a)~(d))。每個bit的凹凸形狀都非常銳利,呈現90度變化,實際傳輸速度與設定速度也幾乎吻合(圖(b)及(c))。沒有看到殘影發生(圖(d))。
設定傳輸速度為115200 bps時(圖(e)~(h))。每個bit的凹凸形狀就沒那麼銳利,有些歪斜,實際傳輸速度與設定速度仍吻合(圖(f)及(g))。沒有看到殘影發生(圖(h))。
設定傳輸速度為256000 bps時(圖(i)~(l))。每個bit的凹凸形狀就更不銳利,歪斜加重,實際傳輸速度與設定速度已不吻合(圖(j)及(k))。沒有看到殘影發生(圖(l))。
設定傳輸速度為512000 bps時(圖(m)~(p))。每個bit的凹凸形狀就更不銳利,歪斜再度加重,實際傳輸速度與設定速度已不吻合(圖(n)及(o))。沒有看到殘影發生(圖(p))。
設定傳輸速度為1024000 bps時(圖(q)~(t))。每個bit的凹凸形狀就更不銳利,歪斜非常加重,實際傳輸速度與設定速度已極度不吻合(圖(r)及(s))。有看到殘影發生(圖(t))。表示繼承了UART原始波型的殘影。至於實際波形就更慘了,很多方塊波看起來都快變成三角波了。
經過測試,轉換後的RS-232訊號,沒辦法支援很高的傳輸速度,大約穩定的速度為115200 bps。而造成此結果的主因,確實來自於訊號轉換時間變長。
UART訊號轉成RS-232訊號後,在各個設定傳輸速度下的實際波形。 |
感想
1.
記得高中老師說過:
示波器的最高境界是量序列埠的訊號,也就是可以監聽序列埠訊號,分析包率、邏輯0,1、破解資料。現在跟你們講這些還太早... 我們還是先用示波器來看sine波好了...
現在可以認真回應老師: 有看到序列埠了歐! 讚! ^_^
2.
駭客入侵手段
記得之前在看駭客的攻擊手段時,除了大家印象中那種寫程式的駭客外,還有一種駭客手段就是所謂的"實體侵入"。
以這個案例來看,利用示波器配合其他分析器,就可以在序列埠的實體線路上達成監聽訊號的目的。訊號解析完畢後,還可以偽裝官方發送指令碼。看來可以做的事也不少了...
3.
在之前的Po文中( [Arduino] 解決RS-232轉TTL的邏輯反向問題 (亂碼問題) ),獻慶猜到了反向邏輯的某些解決方式。不過當時沒有辦法去看到實際訊號,來進行驗證。
這次的測試給足了驗證機會。
4.
很多時候,儀器設備是不會完美的。這次量測時,由於探棒只有一根,沒辦法同時顯示UART跟經過轉換後的RS-232兩組訊號。
沒有兩根探棒 那就分開量測,還是可以有一定的效果。
當然,有兩根會更棒,也許可以看到兩組訊號間的延遲狀況。
5.
由沒有license,無法開啟示波器的序列訊號分析功能,所以應用更多示波器的基本功,也學到更多。
這台示波器有分析UART跟RS-232的功能,只是需要license。原廠的說明如下:
To complete this lab, your scope must be licensed with the RS232/UART trigger and decode option (Option COMP).
但在沒用這些延伸功能的狀況下,仍然應用基本功量得訊號,也成功進行分析。
這樣反而對示波器的基本操作更扎實,而且對於訊號結構及解碼有更深入的理解。賺到! ^_^
原廠示範UART跟RS-232的訊號分析功能。 |
感謝
感謝好友阿峪提供示波器,讓獻慶有機會來自己做測試,看到UART跟RS-2322的實際波型,並解決開發上的困擾。
感謝超倍能科技林榮豐董事長鼎力相挺,提供獻慶許多資源與時間去學習示波器,練習解碼,達成開發案的完成。
感謝楊孝文老師,提供許多開發上的硬體,還有點子。
感謝羅彥凱,討論研發過程。
相關Po文
RS-232反向問題
示波器學習
Arduino
相關連結
Bit Numbering
Electronic – UART in the code transmits a character, yet on the oscilloscope I find it gave me another signal
What's the difference between MSB and LSB?
SERIAL DATA TRANSMISSION
GOOD! ^_^
回覆刪除