MATLAB与Arduino:串口通信实战记录

要点

  • arduino的Serial.setTimeout()函数
  • MATLAB2018版本前后函数有变化

cut-off

项目需求:MATLAB向arduino发送亮度和闪烁间隔的信息,arduino控制LED以该亮度和间隔闪烁。

硬件方面就是arduino连一个l298n模块驱动LED,用串口连接电脑。

关于MATLAB扩展包:MATLAB的arduino扩展包可以直接在MATLAB里面写arduino的函数,比如digitalWrite什么的。就好像是给MATLAB外接了一个硬件扩展。如果只是单纯串口通信,则不需要装这个包。

arduino端代码

//2023.4.5

String input = ""; //存储接收的数据,格式,I+间隔L+亮度,ex:‘I60L100’
int luminance = 50; //亮度,0~255,相对亮度,0为灭
int interval = 0; //闪烁间隔,0~∞ ms

//9-12脚为驱动器提供信号,其中9,12作为灯的负极,10,11作为正极
//通过调节正极电压控制相应灯亮度,给引脚起个对应的名字
const int led1 = 10;
const int led2 = 11;

void setup() {
  // 初始化设置,只运行一次
  //引脚初始化
  input.reserve(200);
  pinMode(9, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  digitalWrite(9, LOW);
  digitalWrite(12, LOW);

  //串口通信初始化
  Serial.begin(9600);
  Serial.setTimeout(10);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() {
  //串口接收程序
  //如果串口收到数据,把数据存入input
  if (Serial.available() > 0) {
    input = "";
    while (Serial.available() > 0) {
      char inChar = (char)Serial.read();
      input += inChar;
      delay(2);
    }

    //在收到的input字符串里搜索I L字符的位置,位置信息分别存到两个index变量里
    int indexI = input.indexOf('I');
    int indexL = input.indexOf('L');
    //根据位置,从’input’字符串里抽取interval和luminance的值分别转成int型,存到对应变量里
    String Cinterval = input.substring(indexI + 1, indexL);
    String Cluminance = input.substring(indexL + 1, input.length());
    interval = Cinterval.toInt();
    luminance = Cluminance.toInt();
  }

  //亮灯程序
  //如果interval是0,直接设置灯的正极为对应luminance值,即灯常亮
  if (interval == 0) {
    analogWrite(led1, luminance);
    analogWrite(led2, luminance);
  }
  //设置灯的正极为对应luminance值,另一个为0(灭),并在interval ms后反转,即灯交替闪烁
  else {
    analogWrite(led1, luminance);
    analogWrite(led2, 0);
    delay(interval);
    analogWrite(led1, 0);
    analogWrite(led2, luminance);
    delay(interval);
  }
}

在初始化的时候,有一句Serial.setTimeout(10); 是设置arduino收到消息后等待的时间。之前有一个项目需要高刷新率的串口通信,但发现arduino在收到数据后都会顿一下再进行下一步动作。这是arduino默认设置等待下一消息的时间比较长,而且在这段时间内他就等着,别的什么都不干。

MATLAB端代码

MATLAB2018版本后串口函数有一些改动,使用时候注意一下版本,要不然会疑惑到抓狂。

%%
% MATLAB2018前
% 这些放在程序开头执行一次即可
freeports = serialportlist("available");%自动搜索可用端口
arduino=serialport(freeports,9600);%建立端口对象,通信比特率9600
fopen(arduino);%打开端口,打开后可以一直用
pause(2);

% 发送格式:I+闪烁间隔,取值0 ~ +∞,单位ms;L+亮度,取值0 ~ 255,相对亮度
fprintf(arduino,'I60L150');%间隔60ms,亮度150

%放在程序结束时,关闭串口,否则下次运行程序会打不开串口
delete(arduino);%关闭串口

%%
%MATLAB2018后
s = serialport("COM3",9600);
pause(1.8);

%write(s, 'c', "char");
%data = readline(s);

flush(s,"output");
writeline(s,"I60L150");

% Flush output buffer
flush(s,"output");
writeline(s,"I0L0");

% Disconnect and clear serialport connection
delete(s);
clear s;

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空