主要内容

使用串行端口通信从 Arduino 读取流数据

此示例说明如何使用 serialport 接口启用回调以从 Arduino® 板读取以 ASCII 字符结尾的流数据。

此示例使用 Arduino Due;不过应该支持大多数 Arduino 板。

将程序上传到 Arduino

将 Arduino 板插入您的计算机。

使用 Arduino IDE 将以下程序上传到 Arduino® 板。此程序输出连续正弦波点,然后是“回车”和“换行”终止符。

/*
 SineWavePoints
 
 Write sine wave points to the serial port, followed by the Carriage Return and LineFeed terminator.
 */

int i = 0;

// The setup routine runs once when you press reset:
void setup() {
  // Initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// The routine loops forever:
void loop() {
  // Write the sinewave points, followed by the terminator "Carriage Return" and "Linefeed".
  Serial.print(sin(i*50.0/360.0));
  Serial.write(13);
  Serial.write(10);
  i += 1;
}

与 Arduino 建立连接

在 MATLAB 中,关闭所有现有 serialport 连接。

delete(serialportfind);

找到 Arduino 连接到的串行端口。您可以从 Arduino IDE 中识别该端口。对于此示例,假设 Arduino IDE 指示连接位于端口 COM4 上。通过列出所有可用端口,确认您的计算机上存在该端口。

serialportlist("available")
ans = 1×2 string
    "COM3"    "COM4"

通过创建 serialport 对象连接到 Arduino Due。使用在 Arduino 代码中指定的端口和波特率。

serialObj = serialport("COM4",9600)
serialObj = 
  Serialport with properties:

                 Port: "COM4"
             BaudRate: 9600
                  Tag: ""
    NumBytesAvailable: 15

  Show all properties, functions

准备 serialport 对象以开始流式传输数据

通过配置 serialport 对象的属性并清空旧数据来配置该对象。

Terminator 属性设置为与您在 Arduino 代码中指定的终止符匹配。

configureTerminator(serialObj,"CR/LF");

清空 serialport 对象以删除所有旧数据。

flush(serialObj);

准备 UserData 属性来存储 Arduino 数据。在本例中,将 UserData 定义为结构体,其中 Data 字段包含正弦波值,Count 记录采集的数据点的数量。此结构体允许有组织和高效地访问与更新这些相关的信息片段。

serialObj.UserData = struct("Data",[],"Count",1)
serialObj = 
  Serialport with properties:

                 Port: "COM4"
             BaudRate: 9600
                  Tag: ""
    NumBytesAvailable: 0

  Show all properties, functions

在新 MATLAB 文件中,创建一个回调函数 readSineWaveData,它读取前 1000 个以 ASCII 字符结尾的正弦波数据点并绘制结果。此函数接受参量 maxDataPoints,该参量确定何时绘制数据。

function readSineWaveData(src, ~, maxDataPoints)

% Read the ASCII data from the serialport object.
data = readline(src);

% Convert the string data to numeric type and save it in the UserData
% property of the serialport object.
src.UserData.Data(end+1) = str2double(data);

% Update the Count value of the serialport object.
src.UserData.Count = src.UserData.Count + 1;

% If over maxDataPoints points have been collected from the Arduino, switch off the
% callbacks and plot the data, starting from the second point. 
if src.UserData.Count > maxDataPoints
    configureCallback(src, "off");
    plot(src.UserData.Data(2:end));
end
end

配置串行端口对象,以便每当有新数据(由终止符指示)可从 Arduino 读取时就执行 readSineWaveData 函数。以下 configureCallback 命令将 BytesAvailableFcnMode 设置为“terminator”,并将 BytesAvailableFcn 属性设置为 readSineWaveData 函数的句柄。

maxDataPoints = 1002; 
configureCallback(serialObj, "terminator", @(src,event) readSineWaveData(src,event,maxDataPoints))

该回调函数会打开 MATLAB 图窗,其中显示前 1000 个数据点的绘图。

figure.png