[进阶教程]Matlab和Arduino 精华

查看: 59659|回复: 52

[进阶教程] Matlab和Arduino

[复制链接]
如果大家附件下不了,请到百度网盘去下,每一楼的附件都能在下面这个链接里找到http://pan.baidu.com/s/1lDq5k
Matlab是运用极广的数学软件。Arduino又是现在很火的开源硬件平台。两者连起来玩也是很爽的。
特别是现在Matlab出了Arduino支援套件以后,玩起来比以往的串口通信简单多了。

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

坚持持续更新与编辑。

Part 1 Matlab Arduino Support package
这个支持包是为了实现Matlab与Arduino之间的串口通信。基于在Arduino板上提前烧写的服务器程序(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
WP_20131201_003.jpg

将下面的代码直接复制到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窗口观察阻值变化。
WP_20131201_002.jpg

下面来试一下把支援套件用到GUI点亮或熄灭led QQ图片20131203150232.jpg
这里为了使用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中类似。完整代码在附件

Matlab Support Packag for Arduino(Matlab支援套件):
ArduinoIO.zip (172.87 KB, 下载次数: 2551)

zjy  学徒

发表于 2017-9-1 00:16:02

“下载后解压。把解压文件里的pde/adiosrv/adiosrv.pde文件用Arduino IDE烧写到Arduino控制板上。把matlab的工作路径修改到ArduinoIO文件夹。这样配置就算完成了。


请问我怎么没找到  adiosrv 这个文件夹,只有 adio   adioe  adioes 这三个文件夹?
回复 支持 1 反对 0

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-3 22:55:46

本帖最后由 Fantc 于 2013-12-6 02:40 编辑

Part2 Simulink Arduino Support package
这个套件其实就更好玩了。不用再费心费力的写代码。而是直接用simulink搭建好流程,运算关系,就可以直接烧写到控制板上了,这就变成了模块化编程。可惜的是该套件只支持UNO和Mega 2560。
安装套件的过程稍微麻烦一点
打开下面的地址,点击最下面的”Get Support Package Now“ 就会直接下载了。也可以在本楼的附件中下载。
http://www.mathworks.de/hardware-support/arduino-simulink.html
安装方法:
解压,点击下图的Get Hardware Support Packages。然后选择刚才解压的文件夹,下一步
QQ截图20131203152806.png
也可以直接把压缩包中的arduino.mlpkginstall直接拖到matla命令框中。
然后按提示开始安装。
注意:安装需要一个matlab账号,建议大家提前注册好,学生身份账号就可以用了。

打开simulink library可以在左边看到Simulink Support Package for Arduino Hardware
QQ截图20131203153437.png

点击就可以看到大家熟悉的函数的模块了
QQ截图20131203153626.png

现在放一个小实例。新建一个simulink项目,
选一个Digital Output和一个Pulse Generator(在simulink/sources里面)
如下图连接好。
QQ截图20131203154003.png

设置下Pulse Geneartor。更改自己需要的频率,占空比等。
双击Digital Output修改相应的pin number

设置完以后可以开始烧写了。按下图打开配置窗口
QQ截图20131203154254.png
选择对应的控制板型号
QQ截图20131203154534.png
然后设置端口(可以选自动,或手动)设置波特率(相当于IDE编程时setup()函数里的Serial.begin())
QQ截图20131203154854.png
设置完成点击保存。
回到simulink编辑窗口,按下图点击"Run"开始烧写
QQ截图20131203155018.png
如果配置的arduino型号或端口不正确,烧写会出现错误,点击"Run"下面的options重新配置。

Part 2也不做过多的介绍了,应该都是Arduino玩家熟悉的东西。

Simulink Support Package for Arduino:
arduino.zip (6.17 KB, 下载次数: 2265)

点评

为什么“prepare to run...”后,设置完,再重新进入“Tools”,在“run on target hardware”中没有“run”呢?!?!  发表于 2015-11-9 21:47
回复 支持 1 反对 0

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-3 22:11:38

从上面的实例看出,a是一个arduino类。通过调用arduino类的函数对控制板进行操作。这时候的Arduino控制板看上去更像是执行机。
其实Matlab Support Package for Arduino的绝大部分操作函数都和Arduino IDE的编程很像。上手会很快,这部分就不做过多的实例了。
更多该支持包的操作函数可以参见文件夹ArduinoIO下面的arduino.m文件。
我会在这楼为大家整理一下,方便使用
回复 支持 反对

使用道具 举报

小米  学徒

发表于 2013-12-4 19:50:01

恩恩 顶顶 有用到东西
回复 支持 反对

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-5 02:23:51

本帖最后由 Fantc 于 2013-12-5 02:33 编辑

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的函数之后更新


回复 支持 反对

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-5 07:33:08

本帖最后由 Fantc 于 2013-12-6 02:42 编辑

Part 4 Simulink 串口通信
既然和matlab通信,处理信号当然算是用simulink更方便了。不论是做实验还是研发都经常用到simulink和其他控制器来建模和采集数据分析。对于像我这样的屌丝,可能也希望能用simulink和Arduino一起玩。

先说下Simulink如何从Arduino实时接收数据。和simulink配合的重点应该是分析、处理数据,而不是控制部分。
我们还是沿用Part1里面的analogRead。
先打开simulink library。点击左边的Instrument Control ToolBox。见下图
12.png
里面有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。如下图连接并设置。
QQ截图20131205123356.png

主要讲下其中的几个重要配置。
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可以进行波特率,串口号的设置。如下图
QQ截图20131205133211.png

大部分都不解释了,都是基本的串口参数设置。
Flow Control管理数据传输速度),两个选项none(没有)和hardware(硬件控制)
Time Out(超时),在每个仿真步等待数据的最大时间量。


配置完成后,运行。可以把仿真时间(simulation stop time,播放键旁边)设置大一点。
QQ截图20131205140620.png

右边的图对应"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码的值被画到图中。按下图操作
QQ截图20131205144036.png

大家也可以在附件下载压缩包。其中文件名为test1
可以把Serial receive里的Enable blocking mode勾选和不勾选,对比下效果。


相比之前的Serial receive现在使用的Query Instrument简单的多了。按下图连接下
QQ截图20131205144428.png

打开Query Instrument的配置窗口。
18.png
三个标签,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

simulink_serial_arduino.zip (26.75 KB, 下载次数: 2069)

点评

楼主,part4和part3也得要安装part1、2中的支持包吗?  发表于 2015-11-9 10:57
回复 支持 反对

使用道具 举报

xixiyu  中级技师

发表于 2013-12-5 13:32:39

耶,最喜欢教学贴了:lol
回复 支持 反对

使用道具 举报

何处不江南  初级技匠

发表于 2013-12-5 18:33:50

我擦 火钳刘明。 用matlab分析串口数据,绝对是高端应用而且非常有用。  之后好好研究下。
回复 支持 反对

使用道具 举报

lauren  高级技师

发表于 2013-12-5 18:37:56

我靠,楼主一看你的arduino主板就知道是资深玩家,玩arduino起码超过3年的老玩家啊!真暴力,技术贴给力。不知道有没有什么实际matlab和arduino的应用案例!?求分享= =:$
回复 支持 反对

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-5 18:40:13

lauren 发表于 2013-12-5 18:37
我靠,楼主一看你的arduino主板就知道是资深玩家,玩arduino起码超过3年的老玩家啊!真暴力,技术贴给力。 ...

谢谢。我挺好奇,怎么能看出我玩了两三年的。周末做个控速的模型跟大家分享。
回复 支持 反对

使用道具 举报

lauren  高级技师

发表于 2013-12-5 18:55:56

Fantc 发表于 2013-12-5 18:40
谢谢。我挺好奇,怎么能看出我玩了两三年的。周末做个控速的模型跟大家分享。 ...

你口袋里那片Duemilanove已经深深的出卖了你 :lol....期待控速贴,是电机控制吗= =?。
回复 支持 反对

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-5 19:27:02

lauren 发表于 2013-12-5 18:55
你口袋里那片Duemilanove已经深深的出卖了你 ....期待控速贴,是电机控制吗= =?。 ...

看来是因为我的板子很老吧。是直流电机的控制,在外部扭矩作用的情况下恒速控制。
回复 支持 反对

使用道具 举报

lauren  高级技师

发表于 2013-12-5 21:41:01

Fantc 发表于 2013-12-5 19:27
看来是因为我的板子很老吧。是直流电机的控制,在外部扭矩作用的情况下恒速控制。 ...

哦,闭环转速控制?matlab转速控制器,挺带感的呀。哥们哪里山头的(哪里干的)?:lol
回复 支持 反对

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-5 22:25:27

lauren 发表于 2013-12-5 21:41
哦,闭环转速控制?matlab转速控制器,挺带感的呀。哥们哪里山头的(哪里干的)? ...

学生党。无聊的时候喜欢玩点这些而已
回复 支持 反对

使用道具 举报

lauren  高级技师

发表于 2013-12-9 21:39:45

Fantc 发表于 2013-12-5 22:25
学生党。无聊的时候喜欢玩点这些而已

我擦,您现在做哪行?完全可以学以致用啊;P
回复 支持 反对

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2013-12-9 22:10:23

lauren 发表于 2013-12-9 21:39
我擦,您现在做哪行?完全可以学以致用啊

我学电气自动化的
回复 支持 反对

使用道具 举报

liulifuoliver  学徒

发表于 2014-1-17 02:21:41

哥们儿,请教个问题,如何通过simulink读取Arduino上连接的传感器的值?如何连接啊?能举一个简单的例子吗
回复 支持 反对

使用道具 举报

Fantc  初级技匠
 楼主|

发表于 2014-1-21 03:26:29

liulifuoliver 发表于 2014-1-17 02:21
哥们儿,请教个问题,如何通过simulink读取Arduino上连接的传感器的值?如何连接啊?能举一个简单的例子吗
...

这就要看你的传感器是什么的了。如果是数字传感器,应该有相应的通信协议,最简单的例子就是数字按钮,高电平或者低电平。复杂一点的比如气压传感器,颜色传感器。这类传感器的话,建议你先在arduino里把接收到的信息转换为数字,再通过串口跟simulink通信。如果是模拟传感器,就跟arduino上的annalog接口连接就可以了。
回复 支持 反对

使用道具 举报

liulifuoliver  学徒

发表于 2014-1-24 22:38:16

Fantc 发表于 2014-1-21 03:26
这就要看你的传感器是什么的了。如果是数字传感器,应该有相应的通信协议,最简单的例子就是数字按钮,高 ...

谢谢高手指点
回复 支持 反对

使用道具 举报

拉库玛  学徒

发表于 2014-3-1 22:31:04

大神,能加下qq么
回复 支持 反对

使用道具 举报

咖啡牛奶  学徒

发表于 2014-3-1 23:37:32

楼主给的好详细啊。收下了
回复 支持 反对

使用道具 举报

123下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
wifi气象站

硬件清单

btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2019 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail