Upload
others
View
10
Download
0
Embed Size (px)
Citation preview
MATLAB App Designer 教程 19
1.4 App Designer 和硬件结合实例在1.1中提到, 笔者认为 App Designer 最⼤的优点之⼀,就是增加了和⼯业相关的控件,
⽐如1.3 中提到的 Gauge,Knob,Lamp 和 Switch,这给⼯程项⽬的 GUI 设计提供了⽆限的
可能性。本节举⼀个实际的例⼦,⽤这些⼯业控件去控制物理硬件,这⾥的硬件是 ArduinoUno, 通过 MATLAB 的 Hardware Support Package, 我们可以在 MATLAB 中的 GUI 中⽤
M 语⾔来控制 Arduino。
1.4.1 如何使用 MATLAB Arduino Support Package什么是 Arduino Support Package
Ardunio Support Packages 是 Mathworks 硬件 Support Package 家族的成员之⼀,它
帮我们省去了编写和编译 C 语⾔来控制 Controller 的⿇烦。⽤户可以直接通过 MATLAB和 Arduino 进⾏实时交互。⽐如下⾯两⾏代码中,我们先声明了⼀个 Arduino 对象,然后
指定它的 Digital Pin 13 输出⾼电位:
>> a = arduino;>> writeDigitalPin(a,'D13',1);
注意这⾥ * ⽤户 * 没有编译和上载任何程序,在 MATLAB 中,和 Arudion 的互动是简单
的,及时的。
如何安装 Arudino Support Package
Arudino Support Package 可以从这⾥免费下载
http://www.mathworks.com/hardware-support/arduino-matlab.html
该 Support Package 的安装过程中,会⾃动帮助下载 Arduino 所需的 Library 和配置 Arudino所需的运⾏环境。
如何控制 Arudino 的 Digital Out 和 Analog Out
⽤想和 Arudino 建⽴联系,⾸先要在 MATLAB 中调⽤ arduino 类的构造函数获得⼀个
Arduino 的对象
>> a = arduinoa =
arduino with properties:Port: '/dev/tty.usbmodem1421'Board: 'Uno'
AvailablePins: {'D2-D13', 'A0-A5'}Libraries: {'I2C', 'SPI', 'Servo'}
接下来调⽤ methods 函数查看 arduino 类⽀持的⽅法:
20 MATLAB 中⽂论坛技术专栏
>> methods(a)Methods for class arduino:
addon configureDigitalPin i2cdev readDigitalPinscanI2CBus spidev writePWMDutyCycleconfigureAnalogPin configurePin playTone readVoltageservo writeDigitalPin writePWMVoltage
Arduino ⼀共有 14 个数字输出 Port,调⽤ writeDigitalPin ⽅法,可以控制 arduino 的
Digital 输出:
>> writeDigitalPin(a,'D13',1); % Digital Pin 的输出只有 0 和 1 两种。
Arduino 没有 Analog Out 的 Pin, 但 Analog 信号的可以通过 PWM 来模拟 (PWM 通
过修改输出的 Duty Cycle 来达到模拟 Analog 输出的效果):dutyCycle = 1/5;for i = 1:5
writePWMDutyCycle(a, 'D3', i*dutyCycle);pause(1);
end
上⾯代码中,我们把 0 到 3.3V 分成了 5 份,每隔 1 秒钟,相当于给 D3 增加 1/5 的电压.
如何获得 Arduino 的 Digital In 和 Analog In
调⽤ readDigitalPin,获得 Digistal Pin 7 的输⼊
>> readDigitalPin(a,'D7')
Arduino 板⼦上,有 A0 到 A5 对应 5 个模拟信号的输⼊,下⾯通过调⽤ readVoltage获得 Analog 0 号 Pin 的输⼊电压:
>> readVoltage(a,'A0')
1.4.2 如何利用 App Designer 给 Arduino 设计 Dashboard(控制台)本例 Arduino Dashboard 设计如下:
MATLAB App Designer 教程 21
图 1.20
本例的需求是:+ ⽤左上的 Discrete Knob 来控制 Digital Out,其连接⼀个 LED ⼩
灯 + ⽤左下 Knob 来控制 Analog Out,来控制另⼀个 LED ⼩灯的亮度 + ⽤中间的 Gauge来表⽰ Analog In 的电压值,该值来⾃于⼀个物理旋钮 + ⽤右上的 90 ⾓ Gauge 来表⽰
Digital In 的电压值,该值来⾃于⼀个物理按钮 + 最后⽤右下的 Switch 来控制开启和关闭
Analog 和 Digital In 的状态
Discrete Knob 和 Knob 的刻度值可以在 Component Browser 中⾃⼰定制
图 1.21
这样两个 Gauge 在⼀开始的时候是灰⾊的,这是因为在设计中,我们需要⽤⼀个 timer函数来周期的从 DI,AI 那⾥获得收⼊的电压值,来即时的刷新 GUI 上仪表盘的显⽰。⽽我
们⽤ Switch 来控制这个 timer 的状态,在 timer 没有启动的时候,两个 Gauge 当然没有读
数,所以是 disable 的状态。我们需要在 Component Browser 中修改两个 Gauge 的默认值,
22 MATLAB 中⽂论坛技术专栏
enable = false
图 1.22
1.4.3 如何给 Arduino 连线本例使用到的电子元件
• Arduino Uno• 若⼲ jumper wire• 两个 LED ⼩灯
• 两个 1K 欧姆的电阻
• ⼀个按钮,⼀个旋钮
• ⾯包板
MATLAB App Designer 教程 23
Frizing 连线图
图 1.23
连线表
|---------+--------|| Arduino | ||---------+--------|| D13 | LED || D7 | Button || D3(PWM) | LED || A1 | Knob ||---------+--------|
实际连线图
图 1.24
24 MATLAB 中⽂论坛技术专栏
1.4.4 如何编写 Dashboard 的 callbackDigital Out 回调函数
该回调函数⽐较 Discrete Knob 的 Value,如果是 On, 控制 Arduino D13 Pin 输出 3.3V,
点亮 LED,否则输出 0function DO_callback(app)
value = app.DO.Value;if strcmp(value,'On')
writeDigitalPin(app.arduinoObj,'D13',1);else
writeDigitalPin(app.arduinoObj,'D13',0);end
end
MATLAB App Designer 教程 25
Analog Out 回调函数
该回调函数通过调整 PWM 的 duty Cycle 来控制 LED ⼩灯的量度,⼀共 10 级。
function AO_callback(app)writeDigitalPin(app.arduinoObj,'D3',0);value = app.AO.Value;dutyCycle = value/10;writePWMDutyCycle(app.arduinoObj, 'D3', dutyCycle);
end
Startup 函数和 timer 回调函数
在 GUI 初始化函数中,先设置好 timer, 其每个 0.5 秒执⾏⼀次 acquisionCallback 函数
function startupFcn(app)app.arduinoObj = arduino;app.acquisionTimer = timer('StartDelay', 0, 'Period', 0.5,...
'ExecutionMode', ...'fixedRate');
app.acquisionTimer.TimerFcn = @(obj,event)acquisionCallback(app);end
该 acquisionCallback 函数可以通过 toolstrip 上的 Add Function 加到类的定义中去
图 1.25
26 MATLAB 中⽂论坛技术专栏
⽅法实现如下
methods (Access = public)function acquisionCallback(app)
app.DI.Value = readDigitalPin(app.arduinoObj,'D7');app.AI.Value = readVoltage(app.arduinoObj,'A1');
% for debugs=sprintf('Debug: DI: %d AI %d\n',app.DI.Value,app.AI.Value);disp(s);
endend
其中我们⽤ readDigitalPin,readVoltage 获得 DI,AI 的输⼊,然后⽤其值去直接更新两个
Gauge 的显⽰。