(玩電子) 電子技術學習與研究
當前位置:單片機教程網 >> Arduino >> 瀏覽文章

Matlab和Arduino通信

作者:未知   來源:互聯網   點擊數:x  更新時間:2014年08月14日   【字體:

本文所有附件下載地址:http://www.112239.live/f/Arduino and Matlab.zip
Matlab是運用極廣的數學軟件。Arduino又是現在很火的開源硬件平臺。兩者連起來玩也是很爽的。
特別是現在Matlab出了Arduino支援套件以后,玩起來比以往的串口通信簡單多了。

第一部分 Matlab Arduino Support package
第二部分 Simulink Arduino Support package
第三部分 Matlab的串口通信
第三部分 Simulink的串口通信

堅持持續更新與編輯。

Part 1 Matlab Arduino Support package
這個支持包是為了實現Matlab與Arduino之間的串口通信;谠贏rduino板上提前燒寫的服務器程序(Server program),監聽串口的命令,需要的話可以返回結果。也就是說,Arduino板只需要提前燒寫一個程序,之后便可通過Matlab命令對其直接操 作。

該支援包支持學生版的Matlab。支持的控制板有UNO,Mega 2560,Duemilanove。
可以在Matlab官網下載,地址http://www.mathworks.de/hardware-support/arduino-matlab.html
點擊下方的Requirement框里的“MATLAB Support Package for Arduino”,在新打開的網頁中在右邊點擊Download Submission即可
也可以在本貼的附件直接下載ArduinoIO壓縮包

下載后解壓。把解壓文件里的pde/adiosrv/adiosrv.pde文件用Arduino IDE燒寫到Arduino控制板上。
把matlab的工作路徑修改到ArduinoIO文件夾。這樣配置就算完成了。

現在來實驗一下。用matlab完成一個簡易的usb示波器
首先建立arduino和matlab的連接,代碼如下
a = arduino('COM3');
matlab會用幾秒鐘的時間來建立連接

用一個1k歐的可調電阻串聯一個1k歐的電阻。如下圖連接,樓主用的是AnalogRead pin 5


將下面的代碼直接復制到Matlab命令框,即可運行。
interval = 10000;
passo = 1;
t = 1;
x = 0;
while(t<interval)
    b = a.analogRead(5)*10; % 把讀到的值放大10倍
    x = [x,b];
    plot(x);
    grid
    t = t+passo;
    drawnow;
end

從a5所讀的值會實時的畫在圖上,效果如下圖?梢宰约菏謩诱{整可調電阻阻值,即可在plot窗口觀察阻值變化。


下面來試一下把支援套件用到GUI點亮或熄滅led
這里為了使用digitalWrite(pin)設置了兩個pushbutton。標簽(tag)分別是led1和led2
在函數 _OpeningFcn 里設置全局變量,以及初始化。
global a;
global led1_state;
global led2_state;
a = arduino('COM3');
a.pinMode(3,'output');
a.pinMode(4,'output');
a.pinMode(5,'input'); % 5讀取3的狀態
a.pinMode(6,'input'); % 6讀取4的狀態
led1_state = 0;
led2_state = 0;


在函數 led1_Callback中添加如下代碼
global a;
global led1_state;
if led1_state == 0
    a.digitalWrite(3,1);
    led1_state = a.digitalRead(5);
    set(hObject, 'BackgroundColor',[0 0 1]);
else
    a.digitalWrite(3,0);
    led1_state = a.digitalRead(5);
    set(hObject, 'BackgroundColor',[1 1 0]);
end

根據變量led1_state設置led1的狀態。讀取led1狀態,更新變量led1_state。更改按鈕顏色
如果使用togglebutton,可以省略全局變量led1_state,可直接使用a.digitalWrite(3,(get(hObject,'Value')))進行狀態切換。
注意:如果第二次執行的時候沒有把語句 a = arduino('COM3')刪除,或者沒有清除變量a。都會出現錯誤
在函數led2_Callback中類似。完整代碼在附件

 

從上面的實例看出,a是一個arduino類。通過調用arduino類的函數對控制板進行操作。這時候的Arduino控制板看上去更像是執行機。
其實Matlab Support Package for Arduino的絕大部分操作函數都和Arduino IDE的編程很像。上手會很快,這部分就不做過多的實例了。
更多該支持包的操作函數可以參見文件夾ArduinoIO下面的arduino.m文件。
我會在這樓為大家整理一下,方便使用

Part2 Simulink Arduino Support package
這個套件其實就更好玩了。不用再費心費力的寫代碼。而是直接用simulink搭建好流程,運算關系,就可以直接燒寫到控制板上了,這就變成了模塊化編程?上У氖窃撎准恢С諹NO和Mega 2560。
安裝套件的過程稍微麻煩一點
打開下面的地址,點擊最下面的”Get Support Package Now“ 就會直接下載了。也可以在本樓的附件中下載。
http://www.mathworks.de/hardware-support/arduino-simulink.html
安裝方法:
解壓,點擊下圖的Get Hardware Support Packages。然后選擇剛才解壓的文件夾,下一步

也可以直接把壓縮包中的arduino.mlpkginstall直接拖到matla命令框中。
然后按提示開始安裝。
注意:安裝需要一個matlab賬號,建議大家提前注冊好,學生身份賬號就可以用了。

打開simulink library可以在左邊看到Simulink Support Package for Arduino Hardware


點擊就可以看到大家熟悉的函數的模塊了


現在放一個小實例。新建一個simulink項目,
選一個Digital Output和一個Pulse Generator(在simulink/sources里面)
如下圖連接好。


設置下Pulse Geneartor。更改自己需要的頻率,占空比等。
雙擊Digital Output修改相應的pin number

設置完以后可以開始燒寫了。按下圖打開配置窗口

選擇對應的控制板型號

然后設置端口(可以選自動,或手動)設置波特率(相當于IDE編程時setup()函數里的Serial.begin())

設置完成點擊保存。
回到simulink編輯窗口,按下圖點擊"Run"開始燒寫

如果配置的arduino型號或端口不正確,燒寫會出現錯誤,點擊"Run"下面的options重新配置。

Part 2也不做過多的介紹了,應該都是Arduino玩家熟悉的東西。

Simulink Support Package for Arduino:

Part 3 Matlab 串口通信
有的時候我們自己給Arduino編好了程序,又希望在Matlab中調用串口,讀取數據。此時 Matlab Support Package for Arduino顯然不合適了。這里我們要用到Matlab里的串口對象serial。比如當我們需要利用Matlab處理攝像頭畫面,結合攝像頭標定、攝像頭識別、3D掃描后建模等等。
還是以part1里面的簡易示波器為例。
Arduino代碼如下
int analogPin = 5;                              
int
val = 0;           

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  val = analogRead(analogPin);
  Serial.println(val);
}


這里還是要實現Matlab的即時讀取和畫圖。Matlab代碼如下
s = serial('COM3');  %定義串口對象
set(s,'BaudRate',9600);  %設置波特率s
fopen(s);  %打開串口對象s

interval = 10000;  %這里開始的代碼很Part1里的代碼類似
passo = 1;
t = 1;
x = 0;
while(t<interval)
    b = str2num(fgetl(s));  %用函數fget(s)從緩沖區讀取串口數據,當出現終止符(換行符)停止。
    x = [x,b];                       %所以在Arduino程序里要使用Serial.println()
    plot(x);
    grid
    t = t+passo;
    drawnow;
end
fclose(s);  %關閉串口對象s

其他關于串口對象serial的函數之后更新

 

Part 4 Simulink 串口通信
既然和matlab通信,處理信號當然算是用simulink更方便了。不論是做實驗還是研發都經常用到simulink和其他控制器來建模和采集數據分析。對于像我這樣的*絲,可能也希望能用simulink和Arduino一起玩。

先說下Simulink如何從Arduino實時接收數據。和simulink配合的重點應該是分析、處理數據,而不是控制部分。
我們還是沿用Part1里面的analogRead。
先打開simulink library。點擊左邊的Instrument Control ToolBox。見下圖

里面有Query Instrument、To Instrument、Serial Configuration、Serial Receive和Serial SendQuery Instrument和To Instrument配套使用
Serial Configuration、Serial Receive和Serial Send配套使用

先使用Serial Receive。選擇一個Serial Receive。在Simulink/Sinks里面選擇一個Display。如下圖連接并設置。


主要講下其中的幾個重要配置。
Header留空。Terminator是串口輸入的結尾控制符。因為Arduino程序里面用的是Serial.prinln(),也就是每個字符串都以換行符結 尾。所以這里我選擇CR('\r'),表示每組數據讀到結尾控制符,但不包含該控制符,也就是在CR('\r')之前的制定位數的數據會被讀取。 Datasize要定義一個臨時存放數據的矩陣。我使用的電位器為1k歐,電阻是一千歐,測量的是電阻兩端的電壓。也就是說測量范圍是5V到 2.5V,analogRead()的返回值范圍是0-1024對應0到5V,根據這里的情況,應該是1023到512。不包含'\r'的情況下,得到的 字符串應該是4到3位。所以暫時把Datasize(存放矩陣)矩陣設置為[4,1]。


Enable blocking mode勾選的情況下表示,讀取輸入數據時暫停其他模塊。如果勾選,Serial Receive模塊只有一個Output為Data,讀取過程大概是這樣,從Arduino發出的數據會不停的累積存到電腦緩存區。Serial Receive模塊會按照數據進入的順序讀取。因為其他的操作只能在兩次采樣之間進行,所以這時讀取數據不是實時的,而是有延遲的,隨著時間延時越來越長。如果不勾選,則有兩個Output為Data和Status,status只有兩種值1或0,1表示有可用的數據,0表是沒有可用的數據。因為不會暫停其他模塊,模塊意外的操作(模擬)可以看做是連續的,所以現在是實時的。

Action when data is unavailable(沒有可讀數據時的行為),有兩個選項,Output last received value(可理解為輸出最后進入緩存的數據)和Output Custom value(輸出自定義值,選擇該項時,可在下面的Custom Value進行設置,默認為零)。


設置完成后會出現提示框,是否立刻生成串口配置模塊(Serial Configuration),該模塊用通用的串口配置(Serial Receive和Serial Send)。如果不立刻生成,之后也要手動添加。


打開Serial Configuration可以進行波特率,串口號的設置。如下圖


大部分都不解釋了,都是基本的串口參數設置。
Flow Control管理數據傳輸速度),兩個選項none(沒有)和hardware(硬件控制)
Time Out(超時),在每個仿真步等待數據的最大時間量。


配置完成后,運行?梢园逊抡鏁r間(simulation stop time,播放鍵旁邊)設置大一點。


右邊的圖對應"1023",左邊的對應"714"。左邊圖中第一位是10,前面說過Arduino程序里使用的是Serial.println。每一行串口數據起始位為LF('\n'),結束位為CR('\r')。LF('\n')對應的ASCii碼就是10。更該Serial Receive模塊里的Header以及Terminator都沒有用。介紹一個比較偷懶的辦法,在Arduino中修改代碼:
val = analogRead(analogPin)
val = map(val, 5, 1023, 100, 999);  //把val的值修改到100至999的范圍之間

這樣就把值嚴格的控制在了3位。把datasize改為[3 1]。
現在來作圖。Serial receive的Output不能直接和Scop連接,否則看到的是ASCii碼的值被畫到圖中。按下圖操作


大家也可以在附件下載壓縮包。其中文件名為test1
可以把Serial receive里的Enable blocking mode勾選和不勾選,對比下效果。


相比之前的Serial receive現在使用的Query Instrument簡單的多了。按下圖連接下


打開Query Instrument的配置窗口。

三個標簽,Hardware Configuration、Query、Instrument Initialisation。有的設置和Serial Receive一的
Hardware Configuration不多說了,基本的串口設置,波特率、串口號、緩沖區大小等。有一點說明下,在Interface可以看到這里可以選擇通信方式,不止是Serial,例如還有TCPIP等等。Query Instrument是一個通用的接收查詢模塊。
Instrument Initialisation只在控制板需要一個初始信號的時候才需要
Query可以根據自己的需要選擇,ASCii、Binary,Binblock
都是些基礎知識,就不在帖子里多說了,不清楚的留言。(這個模塊真的是很簡單)

我們選擇默認設置,也就是ASCii碼。這樣輸出的是字符串,而且已經掐頭去尾了,不需要擔心數據位數。還能在簡單一點么
字符串在simulink正式以ASCii碼存放的,把所有元素按順序”拼“起來就得到了我們需要的相應的值。這里用simulink/math operations/sum of Elements就可以了。
注意:如果一開始的值是1023(analogread的最大值),有的時候運行simulink會出錯。目前還沒查出原因。
大家也可以在附件的壓縮包中找到對應的文件,文件名test

本文所有附件下載地址:http://www.112239.live/f/Arduino and Matlab.zip

發表評論】【告訴好友】【收藏此文】【關閉窗口

文章評論

相關文章

专注江西快三走势分析 山东十一选五人工计划 明日股市*走势分析 辽宁快乐12最大遗漏数据 快乐十分开奖即时 股票在线配资都看简配资放心 甘肃快3开奖结果查 bbin挂机软件 广东11选五走势图 秒速飞艇稳赢不输 炒股怎样融资·杨方配资开户