Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
推動CDIO創新教學計算機程式語言 / 電子電路學
MATLAB for Arduino
Support Package 範例
1
Arduino/電阻/麵包板/LED/電壓量測簡介範例
電路板(麵包板)
【LazyTomato】Arduino #5 - 麵包板是什麼?好吃嗎?
3http://www.codedata.com.tw/java/java-embedded-6-raspberry-pi-gpio/
整行連通(視為同一接點)
整列連通(視為同一接點)
5 色環電阻(Arduino初學者套件搭配的電阻)
4
https://www.digikey.tw/zh/resources/conversion-calculators/conversion-calculator-resistor-color-code-5-band
LED簡介
LED的啟動電壓各不同,紅光約2點多伏特,白光約3點多伏特。
電阻的功能是限制電流以保護LED,避免 LED 燒毀。
為什麼LED連接時一定要串接一顆電阻?
【LazyTomato】Arduino #6 - LED 與電阻的必學之術!
Arduino小知識:為什麼LED需要串聯的電阻值是220 ohm?
5
LED 電路
這只是簡單的 LED 電路,透過Arduino 來供給電源,正極接在Arduino 的5V腳位,負極接在GND(ground)腳位,完成接線後 LED 就會亮起
6
220Ω(5色環)
5mm高亮LED
白發藍光
電路中的電流值為何 ?
LED 壓降 ?
220Ω電阻壓降 ?
7
V = I R
電壓(V伏特) 電流(mA毫安培) 電阻(Ω歐姆)
5 ?? 220
5V
220Ω
Arduino小知識:為什麼LED需要串聯的電阻值是220 ohm?
可利用Arduino來量測220Ω電阻端點電壓值後,計算電路中的電流與LED壓降
將LED負極連接至類比A0腳位,使用Arduino讀取電阻兩端的壓降值
8
220Ω
量測220Ω電阻兩端壓降
LED - Arduino接線線路
9
開始來寫個簡單的程式吧!
開啟MATLAB,將Arduino連接至電腦USB連接埠
命令視窗中(Command Window)會顯示Arduino Uno detected
命令視窗中同時敘述,MATLAB可使用MATLAB Support
Package for Arduino Hardware(MSPAH)或是Simulink Support
Package for Arduino Hardware(SSPAH)支援Arduino硬體
MSPAH是使用Script file(序列式程式)/SSPAH則是使用Block(圖形化程式)與Arduino搭配使用
點選 examples and other documentation接至MSPAH的Documentation頁面
10
可從Documentation中提供的說明內容,開始學習MATLAB
與Arduino的結合應用
點選 function,查閱MSPAH中的函示指令與功能
11
點選任一指令,查閱指令使用與設定方式,可參閱指令說明中提供的範例程式
再回到前一頁,點選examples
12
點選examples,進入範例程式頁面
13
選擇第一個範例資料夾
14
可以從這一個範例開始學習MATLAB與Arduino的應用
15
好,現在回到量測電壓值的範例
16
首先,因為是第一次使用Arduino板,所以先在命令視窗中鍵入以下的指令,連結MATLAB與Arduino ,完成後會顯示Arduino的相關訊息諸如板的形號/連接埠/
可用腳位/函式庫等資訊
17
>> a_board = arduino()
連接埠: COM3
板型: UNO
arduino(argument引數) : Connect to Arduino hardware
以上指令的目的是在建構MATLAB與Arduino的連結(溝通管道)
如果只接一個Arduino板,使用
如果接一個以上Arduino板,必須指定連接埠位置,以區隔不同的Arduino板,使用
如果還要指定特定的函式庫(Library),則需使用
18
a_board = arduino();
a_board = arduino(port,board);
a_board = arduino(port,board,Name,Value);
例如: a_board =
arduino('COM3','Uno','Libraries',{'Servo','ShiftRegister'};
例如: a_board = arduino('COM3','Uno');
a_board是使用者自訂的變數名稱,利用a_board = arduino()程式碼,將Arduino板這個物件的內容“指派”給a_board ,在程式碼中就可使用a_board代替Arduino板
readVoltage(argument引數): Read Arduino analog pin voltage
讀取Arduino板上類比腳位(analog pin)的電壓值
V_measured = readVoltage(a_board, pin)
V_measured是使用者自訂的變數名稱,利用a_board = readVoltage()程式碼,讀取連接至Arduino板上類比腳位(在此為A0)電壓值
19
例如: V_measured = readVoltage(a_board,'A0');
在這個範例中,還需用到另一個指令 readVoltage()用以讀取電路中的電壓值
20
讀取220Ω電阻(A0腳位)電壓值範例程式
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
tic % 計時器起始 終止為toc
while toc < 5 %時間小於5秒時,執行while迴圈V_measured = readVoltage(a_board, 'A0');
disp(['電阻壓降 = ', num2str(V_measured), ' V']);
pause(0.1);
end
tic and toc functions work together to measure elapsed timetic : Start a stopwatch timer.toc : Read the stopwatch timer.
執行結果
21
220Ω電阻壓降量測值約為 2.0 V
推測LED 驅動電壓約為 5 - 2 3 V
根據歐姆定律 V = IR 電流 2.0/220 = 0.009 A = 9 m
A
22
現在將上述資訊編寫為程式碼置入程式中.
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
tic % 計時器起始 終止為toc
R = 220; %電阻值V = 5; %電源供應電壓while toc < 5 %時間小於5秒時,執行while迴圈
V_measured = readVoltage(a_board, 'A0');
disp(['電阻壓降 = ', num2str(V_measured), ' V']);
I = V_measured / R; %電流值計算disp(['電路電流 = ', num2str(I), ' A']);
V_Forward_LED = V - V_measured; %LED驅動電壓disp(['LED驅動電壓= ', num2str(V_Forward_LED),' V']);
pause(0.1);
end
執行結果
23
試看看電阻串/並聯,觀察一下LED亮度變化.
繪出220Ω電阻壓降 vs. 時間圖
24
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
tic % 計時器起始 終止為toc
R = 220; %電阻值V = 5; %電源供應電壓t_no = 1; % 計數器-使用計數器建立 t(t_no)/V_measured(t_no)/I(t_no)陣列while toc < 5 %時間小於5秒時,執行while迴圈
t(t_no) = toc; %記錄每一時取點時間V_measured(t_no) = readVoltage(a_board, 'A0');%每一取點時間220Ω壓降disp(['電阻壓降 = ', num2str(V_measured(t_no)),' V']);
I(t_no) = V_measured(t_no) / R; %每一取點時間電流disp(['電路電流 = ', num2str(I(t_no)),' A']);
V_Forward_LED(t_no) = V - V_measured(t_no); %每一取點時間驅動電壓disp(['LED驅動電壓= ', num2str(V_Forward_LED(t_no)),' V']);
plot(t(1:t_no),V_measured(1:t_no),'-o',...
'MarkerSize',3,...
'MarkerEdgeColor','r',...
'MarkerFaceColor','g');
xlabel('t');
ylabel('電阻壓降 V')
title('220\Omega電阻壓降 vs. time')
pause(0.1);
t_no = t_no + 1; %計數器加1作為下一時取點的陣列引數end
執行結果
25
圖利用tic/toc 與axis()產生 x軸動畫效果
26
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
tic % 計時器起始 終止為toc
R = 220; %電阻值V = 5; %電源供應電壓t_no = 1; % 計數器-作為陣列索引,建立t(t_no)/V_measured(t_no)/I(t_no)陣列while toc < 20 %時間小於20秒時,執行while迴圈
t(t_no) = toc; %記錄每一時取點時間V_measured(t_no) = readVoltage(a_board, 'A0');%每一取點時間220Ω壓降disp(['電阻壓降 = ', num2str(V_measured(t_no)),' V']);
I(t_no) = V_measured(t_no) / R; %每一取點時間電流disp(['電路電流 = ', num2str(I(t_no)),' A']);
V_Forward_LED(t_no) = V - V_measured(t_no); %每一取點時間驅動電壓disp(['LED驅動電壓= ', num2str(V_Forward_LED(t_no)),' V']);
plot(t(1:t_no),V_measured(1:t_no),'-o',...
'MarkerSize',3,...
'MarkerEdgeColor','r',...
'MarkerFaceColor','g');
xlabel('t');ylabel('電阻壓降 V')
title('220\Omega電阻壓降 vs. time')
axis([max(0,toc-1), toc+0.2, -inf,inf]);%動態更改x軸繪圖範圍-時間軸動畫效果
pause(0.1);
t_no = t_no + 1; %計數器加1作為下一時取點的陣列引數end
執行結果
27
28
LED 範例
亮暗
閃爍
明亮度調整
前面的範例介紹給各位如何從Arduino板上的類比接腳(Analog pin : A0~A5)讀取量測電路中的資訊 –這通常可視為系統的輸入訊號(Input),使用者可依這輸入訊號來決定並調整輸出訊號(Output)以達成使用者設定的系統功能
接下來要介紹給各位的是如何利用Arduino板上的數位接腳(Digital pin :D0~D13) 傳輸訊號,以達成元件控制的目的
29
LED 亮與暗 / 閃爍 / 明亮度變化調整範例
在這個範例中,可使用以下幾個指令來調控輸出的電壓值
writeDigitalPin(argument引數): Write to digital pin on Arduino hardware,傳輸設定的訊號至Arduino板的數位接腳
writeDigitalPin(a, pin, value)
a : Arduino板的程式碼代號
pin : 連接至電路中的數位接腳
Value : 輸入值為 0(false) or 1(true),0代表低電位/ 1代表高電位,Arduino板的電壓值0~5V , Value = 0代表輸出0V,Value = 1代表輸出5V
30
範例:
writeDigitalPin(a_board,'D11',1);
表示在名為a_board的Arduino板上的D11腳位給予5V的電壓
1可用true / 0可用false代替,上述程式碼可改為:
writeDigitalPin(a_board,'D11',true);
writeDigitalPin()指令只能給予5V(Value = 1)與0V(Value
= 0),即開與關的選擇,至於介於0~5V間的電壓輸出則需使用writePWMDutyCycle(),脈衝寬度調變 (PWM)
的原理說明請參閱:
[Arduino] 脈衝寬度調變 (PWM) 與Arduino
31
writePWMDutyCycle(argument引數): Set digital pin PWM duty cycle,傳輸設定的訊號(PWM:0~1)至Arduino板的數位接腳
writePWMDutyCycle(a, pin, dutyCycle)
a : Arduino板的程式碼代號
pin : 連接至電路中的PWM數位接腳
dutyCycle : 輸入值介於為 0 ~ 1,同樣的0代表低電位/ 1代表高電位,Arduino板的電壓值0~5V , dutyCycle = 0代表輸出0V,dutyCycle= 1代表輸出5V,如果dutyCycle = 0.5表示其相對電壓輸出= 5V0.5 = 2.5V
32
範例:
writePWMDutyCycle(a_board,'D11',0.5);
表示在名為a_board的Arduino板上的D11數位腳位(PWM)給予5V0.5=2.5V的電壓
此外,MATLAB亦提供writePWMVoltage()指令,使用者可直接輸入0~5V電壓值:
writePWMVoltage(argument引數): Write digital pin PWM voltage value,傳輸設定的訊號(0~5V電壓值)至Arduino板的數位接腳
writePWMVoltage(a, pin, voltage)
a : Arduino板的程式碼代號
pin : 連接至電路中的PWM數位接腳
voltage : 輸入值介於為 0 ~ 5V
33
範例:
writePWMVoltage(a_board,'D11',3.5);
表示在名為a_board的Arduino板上的D11數位腳位(PWM)給予3.5V的電壓
再來寫幾個簡單的程式吧!
LED 亮與暗範例
將 LED 正極接在Arduino 的D11腳位,負極接在GND(ground)腳位
34
220Ω
Arduino接線線路
35
LED 亮/暗範例程式
也可將使用writePWMVoltage()達一樣效果
36
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
writeDigitalPin(a_board,'D11',1); %輸出5V,亮pause(2);
writeDigitalPin(a_board,'D11',0); %輸出0V,暗pause(2);
利用之前學過的readVoltage()讀取LED正極電位,看看是 ? V
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
writePWMVoltage(a_board,'D11',5); %輸出5V,亮pause(2);
writePWMVoltage(a_board,'D11',0); %輸出0V,暗pause(2);
將LED正極連接至類比A0腳位,使用Arduino讀取電阻兩端的壓降值
37
220Ω
量測兩端壓降
Arduino接線線路
38
LED 亮/暗 + 讀取電壓值資訊範例程式
39
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
writeDigitalPin(a_board,'D11',1); %輸出5V,亮V_m = readVoltage(a_board,'A0'); %A0腳位電壓disp(['電路電壓 = ', num2str(V_m), ' V']);
pause(2);
writeDigitalPin(a_board,'D11',0); %輸出0V,暗V_m = readVoltage(a_board, 'A0'); %A0腳位電壓disp(['電路電壓 = ', num2str(V_m), ' V']);
pause(2);
執行結果
40
以上程式碼只執行一次加上While 迴圈後就變成LED閃爍的程式了
LED 閃爍範例程式(while 迴圈)
41
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
tic % 計時器起始 終止為toc
while toc < 20 %時間小於20秒時,執行while迴圈writeDigitalPin(a_board,'D11',1); %輸出5V,亮V_m = readVoltage(a_board,'A0'); %A0腳位電壓disp(['電路電壓 = ', num2str(V_m), ' V']);
pause(1);
writeDigitalPin(a_board,'D11',0); %輸出0V,暗V_m = readVoltage(a_board, 'A0'); %A0腳位電壓disp(['電路電壓 = ', num2str(V_m), ' V']);
pause(1);
end
以上程式碼執行一次,LED會亮/暗一次,因有2次暫停1秒,如果連續執行,就變成LED每2秒會閃爍一次
執行結果
42
LED 明亮度變化調整範例
接下來利用writePWMDutyCycle(a, pin, dutyCycle) 與writePWMVoltage(a, pin, voltage)兩個指令進行LED明亮度變化調整
writePWMDutyCycle(a, pin, dutyCycle)指令引數dutyCycle的值介於0~1(0→0V / 1→5V ),我們可以利用linspace()指令將0~1區隔為數等份代表不同大小的輸入電壓,再利用for迴圈依順序執行就可達到LED明亮度變化效果
43
no = 30;
LED_br = linspace(1,0,no);%1~0間取no點,第1點1,最後一點0
%此for迴圈使LED由亮暗for i = 1 : no
%輸出LED_br(i)電壓writePWMDutyCycle(a_board,'D11',LED_br(i));
pause(0.1);
end
若要使LED由亮→暗後,再由暗→亮,其程式碼編可寫如下
44
no = 30;
LED_br = linspace(0,1,no);%1~0間取no點,第1點1,最後一點0
%此for迴圈使LED由亮→暗for i = 1 : no
%輸出LED_br(i)電壓writePWMDutyCycle(a_board,'D11',LED_br(i));
pause(0.1);
end
%此for迴圈使LED由暗→亮for i = 1 : no
%輸出LED_br(i)電壓writePWMDutyCycle(a_board,'D11',1-LED_br(i));
pause(0.1);
end
以上程式碼執加上while迴圈就完成了
LED明亮度變化調整範例程式writePWMDutyCycle()
45
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
no = 30;
LED_br = linspace(0,1,no);%1~0間取no點,第1點1,最後一點0
tic % 計時器起始 終止為toc
while toc < 30 %時間小於30秒時,執行while迴圈%此for迴圈使LED由亮→暗for i = 1 : no
%輸出LED_br(i)電壓writePWMDutyCycle(a_board,'D11',LED_br(i));
pause(0.1);
end
%此for迴圈使LED由暗→亮for i = 1 : no
%輸出LED_br(i)電壓writePWMDutyCycle(a_board,'D11',1-LED_br(i));
pause(0.1);
end
end
執行結果
46
writePWMVoltage(a, pin, voltage)指令引數voltage的值介
於0~5,如同writePWMDutyCycle(),可以利用linspace()指令將0~5區隔為數等份代表不同大小的輸入電壓,再利用for迴圈依順序執行就可達到LED明亮度變化效果
47
no = 30;
LED_br = linspace(5,0,no);%5~0間取no點,第1點5,最後一點0
%此for迴圈使LED由亮暗for i = 1 : no
%輸出LED_br(i)電壓writePWMVoltage(a_board,'D11',LED_br(i));
pause(0.1);
end
LED明亮度變化調整範例程式writePWMVoltage()
48
clear; clc;
a_board = arduino(); %指派Arduino板代號為a_board
no = 30;
LED_br = linspace(5,0,no);%5~0間取no點,第1點5,最後一點0
tic % 計時器起始 終止為toc
while toc < 30 %時間小於30秒時,執行while迴圈%此for迴圈使LED由亮→暗for i = 1 : no
%輸出LED_br(i)電壓writePWMVoltage(a_board,'D11',LED_br(i));
pause(0.1);
end
%此for迴圈使LED由暗→亮for i = 1 : no
%輸出LED_br(i)電壓writePWMVoltage(a_board,'D11',5-LED_br(i));
pause(0.1);
end
end
以上為LED相關的程式範例,先暖暖身,之後再介紹光敏電阻/熱敏電阻以及馬達控制板Motor shield v2(搭配直流馬達/伺服馬達/步進馬達)等應用範例
49