kSerial 在微控制器上將資料實時傳到 MATLAB 顯示分析
github https://github.com/KitSprout/kSerial
[2015/12/04] 在 MATLAB 上實現一個 UART 數位波型顯示器
http://kitsprout.logdown.com/posts/335401
[2016/09/17] MATLAB 新版本 Serial 示波器
最近一直在寫 MATLAB,用越久 MATLAB 越了解 MATLAB 的方便與強大,上研究所前對 MATLAB 的熟悉就只是高級工程計算機的概念,反而是 MATHEMATICA 還比較常用,在符號的運算與公式的推導上非常有優勢,但到了研究所後,很多的東西都要做模擬與驗證,不知不覺接觸 MATLAB 的時間就越來越多,以微控制器開發為主的我,熟悉了即時繪圖與 serial 之後更是變成一個不可或缺的工具,在電腦與微控制器之間的通訊非常簡單,後續的資料處理與分析也非常的便利
近幾個禮拜接觸了 MATLAB 上的 classdef 後,就把之前寫的 serialOscilloscope 改版了,並請重新改寫 serial 的接收封包格式,目前沒有沒有丟包的問題,更新頻率測試過鮑率 256000 下 400Hz 都沒有問題,主要受限於 MATLAB 的鮑率與微控制器的傳輸速度。
在波型顯示的部分則改用 object 與 delete 的方法,目前不會依運行時間長而導致延遲的情況,之後會嘗試加入 GUI 功能,這樣對於切換不同的資料顯示上也會方便許多
[2017/04/16]
kSerial 的設計最主要就是在 MATLAB 與微控制器之間建立一個傳輸的連結,讓微控制器可以透過 kSerial 將資料傳到 MATLAB 上做顯示與分析,並且在此基礎上可以擴充不同的應用像是波形顯示、分析等等。使用自己寫的 kSerial 也有好幾個月的時間了,中間有過不少大大小小的修改,這幾天對 kSerial 做了一些整理,之後打算再實現雙向通訊的部分以及 GUI 的介面。
[2017/06/20]
這次改版內容比較大,距離第一個雛形版本也有 2 年了,第一次維護與改進一個小程式這麼久,覺得很特別。
- 調整通訊封包格式,去除 sequence number 功能,改為 parameter 功能,最小長度 8-byte,最大長度 255-byte。
- 重新改善接收封包方法,比起改版前約增加 10% 速度,傳最小封包速度最高可達約 3KHz。
- MATLAB 端簡化設定,自動判別封包的資料長度與種類。
- 加入雙向通訊功能,已與微控制器相互驗證。
- 完善封包更新頻率估算功能,原本必須要傳時間資訊至電腦,目前亦可以僅透過系統時間做估算。
[2019/01/01]
封包格式小改版
- 調整通訊封包格式,去除尾端 '\n' 字元,改為 checksum 功能。
[2019/12/18]
最近在 Windows 上實現一個 UART to i2c 功能的小工具,使用了之前設計的封包格式,因為之前的格式只能支援到 255-byte,所以就針對封包格式做調整。
- 壓縮 type 訊息,擴展 length 大小。
- 新增 MATLAB kTwi class,在 MATLAB 實現 i2c 讀取功能。
現階段實現了幾種應用功能:
- serialPacket, 基本的資料顯示
- serialOscilloscope, 類示波器的資料顯示
- serialFFT, 頻域顯示(尚未完善)
- serialCube, 配合四元數的姿態顯示(尚未完善)
YOUTUBE DEMO 影片
傳輸的封包格式定義如下
- kSerial packet format
byte 1 | byte 2 | byte 3 | byte 4 | byte 5 | byte 6 | byte 7 | ... | byte L + 8 |
---|---|---|---|---|---|---|---|---|
HK | HS | L | T | P1 | P2 | CK | DN | ER |
name | information |
---|---|
HK | header 'K' (75) |
HS | header 'S' (83) |
L | data length (12-bit, 0~4095) |
T | data type (4-bit) |
P1 | parameter 1 |
P2 | parameter 2 |
CK | checksum |
... | ... |
DN | data |
ER | finish '\r' (13) |
type | binrary |
---|---|
uint8 | 0x0, 4'b0000 |
uint16 | 0x1, 4'b0001 |
uint32 | 0x2, 4'b0010 |
uint64 | 0x3, 4'b0011 |
int8 | 0x4, 4'b0100 |
int16 | 0x5, 4'b0101 |
int32 | 0x6, 4'b0110 |
int64 | 0x7, 4'b0111 |
half | 0x9, 4'b1001 |
float | 0xA, 4'b1010 |
double | 0xB, 4'b1011 |
R0 | 0x8, 4'b1000 |
R1 | 0xC, 4'b1100 |
R2 | 0xD, 4'b1101 |
R3 | 0xE, 4'b1110 |
R4 | 0xF, 4'b1111 |
下面說明為 [2019/01/01] 改版之前範例
% 幾種建立與初始化 kSerial 方法,port = 'COMx', 'auto', 'select', max baudRate is 256000
s = kSerial() -> port = 'auto', baudRate = 115200, no delete instrfindall
s = kSerial(baudRate) -> port = 'auto', set baudRate, no delete instrfindall
s = kSerial(port, baudRate) -> set port, set baudRate, no delete instrfindall
s = kSerial(baudRate, 'clear') -> port = 'auto', delete instrfindall
s = kSerial(port, baudRate, 'clear') -> set port, set baudRate, delete instrfindall
% 開啟與關閉 kSerial 功能
s.open()
s.close()
% 讀寫 kSerial 功能
data = s.read( bytes, type )
bytes = s.write( data, type )
% 延遲功能
s.delay( delay )
% 簡單的設定 kSerial 的鮑率與輸入暫存器大小
s.setBaudRate( baudRate )
s.setInputBufferSize( bufferSize )
s.setRecordBufferSize( bufferSize )
% 設定解算封包之接收閥值,threshold 表示收到該數目資資料才會解封包
s.setRecvThreshold( threshold )
% 依自訂定封包接收,封包資料與封包數目
[packetData, packetInfo, packetLens] = s.packetRecv()
% 依自訂定封包發送
bytes = s.packetSend(); -> null
bytes = s.packetSend(command); -> only send parameter
bytes = s.packetSend(command, data); -> automatic detect data type
bytes = s.packetSend(command, data, type); -> user define data type
% 獲取資料更新頻率,分成用系統時間計算與接收時間資訊計算
freq = s.getFreq(unit); -> use system clock to calculate freq
freq = s.getFreq(index, lengrh, unit); -> use packet sec/msc to calculate freq
% 獲取時間,目前必須要傳送時間資訊才可以使用
time = s.getTime(index, type, unit); -> type ~= 0 : return total seconds
-> type = 0 : return [min, sec, msc]
% 獲取內部暫存器接收資料與資訊
data = s.getRecordData()
data = s.getRecordInfo()
% 儲存接收資料,檔案名稱 'NAME'_TIME
s.save2mat( name, index )
% 建立 kSerialOscilloscope
osc = kSerialOscilloscope()
% 設定示波器 X, Y 顯示刻度
setWindow( ymax, ymin, width )
% 設定畫板,並初始化 kSerialOscilloscope
initOscilloscope( fig )
% 顯示波形
updateOscilloscope( s )
% 建立 kSerialCube
cube = kSerialCube( origin, scale, window )
% 設定畫板與視角,並初始化 kSerialCube
initCube( fig, v )
% 顯示姿態
plotCube( p, q )
% 獲取尤拉角
att = getAttitude( cube, q )