警告:读取不成功:格式匹配失败
Warning: Unsuccessful read: Matching failure in format
我在从串行端口读取数据时遇到问题。
大多数时候,代码有效,我能够成功读取 z
和 y
的 1000 个数据点。
有时,没有从串口读取数据,有时从串口只读取了40个数据点,而不是预期的1000个。我在执行读取时收到此警告。
Warning: Unsuccessful read: Matching failure in format.. Subscripted assignment dimension mismatch.
这个警告是什么意思,我该如何更改下面的代码来防止它。
clk
clear all
delete(instrfindall);
b = serial('COM2','BaudRate',9600);
fopen(b);
k = 1;
n = 0;
while(n < 1000)
z(k) = fscanf(b, '%d');
y(k) = fscanf(b, '%d');
n = n + 1;
k = k + 1;
end
你说得对,时间问题是对的。该错误消息表明串行端口没有收到在超时之前创建具有您指定格式的值所需的字节数。对于简单的示例,您的代码可以正常工作,但正如您发现的那样,它并不健壮。
开始之前你必须知道两件事:
- 你的串口设备是否在"lines"中使用一条线发送数据
终止符,有没有?
- 你希望有多少字节
每次从串口读取数据时读取?
那么有两种做法:
A) 程序等待(更简单,更不可靠):在您的代码中添加一条语句,等待接收到一定数量的字节,然后读取它们。
numBytes = 10; % read this many bytes when ready
% make sure serial object input buffer is large enough
serialport = serial('COM100','InputBufferSize',numbytes*10);
fopen(serialport);
while 1
ba = serialport.BytesAvailable;
if ba > numBytes
mydata = fread(serialport, numBytes);
% do whatever with mydata
end
drawnow;
end
fclose(serialport);
B) 对象回调(更多advanced/complex,可能更健壮):定义了一个回调函数,只要满足特定条件就会执行。回调函数处理来自串行设备的数据。执行条件是:
- a) 已经接收到一定数量的字节
- b) 行终止符
字符已收到
以下示例使用条件 a)。它需要两个函数,一个用于您的主程序,一个用于回调。
function useserialdata
% this function is your main program
numBytes = 10; % read this many bytes when ready
% make sure serial object input buffer is large enough
serialport = serial('COM100','InputBufferSize',numbytes*10);
% assign the callback function to the serial port object
serialport.BytesAvailableFcnMode = 'byte';
serialport.BytesAvailableFcnCount = numBytes;
serialport.BytesAvailableFcn = {@getmydata,numBytes};
serialport.UserData.isnew = 0;
fopen(serialport);
while 1
if serialport.UserData.isnew > 0
newdata=ar.UserData.newdata; % get the data from the serial port
serialport.UserData.isnew=0; % indicate that data has been read
% use newdata for whatever
end
end
fclose(serialport);
function getmydata(obj,event,numBytes)
% this function is called when bytes are ready at the serial port
mydata = fread(obj, numBytes);
% return the data for plotting/processing
if obj.UserData.isnew==0
obj.UserData.isnew=1; % indicate that we have new data
obj.UserData.newdata = mydata;
else
obj.UserData.newdata=[obj.UserData.newdata; mydata];
end
显然,这些只是玩具示例,您还需要考虑许多其他细节,例如超时、错误处理、程序响应能力等,具体取决于串行设备工作方式的细节。有关详细信息,请参阅 "Serial Port Object Properties" 的 matlab 帮助文件。
我在从串行端口读取数据时遇到问题。
大多数时候,代码有效,我能够成功读取 z
和 y
的 1000 个数据点。
有时,没有从串口读取数据,有时从串口只读取了40个数据点,而不是预期的1000个。我在执行读取时收到此警告。
Warning: Unsuccessful read: Matching failure in format.. Subscripted assignment dimension mismatch.
这个警告是什么意思,我该如何更改下面的代码来防止它。
clk
clear all
delete(instrfindall);
b = serial('COM2','BaudRate',9600);
fopen(b);
k = 1;
n = 0;
while(n < 1000)
z(k) = fscanf(b, '%d');
y(k) = fscanf(b, '%d');
n = n + 1;
k = k + 1;
end
你说得对,时间问题是对的。该错误消息表明串行端口没有收到在超时之前创建具有您指定格式的值所需的字节数。对于简单的示例,您的代码可以正常工作,但正如您发现的那样,它并不健壮。
开始之前你必须知道两件事:
- 你的串口设备是否在"lines"中使用一条线发送数据 终止符,有没有?
- 你希望有多少字节 每次从串口读取数据时读取?
那么有两种做法:
A) 程序等待(更简单,更不可靠):在您的代码中添加一条语句,等待接收到一定数量的字节,然后读取它们。
numBytes = 10; % read this many bytes when ready
% make sure serial object input buffer is large enough
serialport = serial('COM100','InputBufferSize',numbytes*10);
fopen(serialport);
while 1
ba = serialport.BytesAvailable;
if ba > numBytes
mydata = fread(serialport, numBytes);
% do whatever with mydata
end
drawnow;
end
fclose(serialport);
B) 对象回调(更多advanced/complex,可能更健壮):定义了一个回调函数,只要满足特定条件就会执行。回调函数处理来自串行设备的数据。执行条件是:
- a) 已经接收到一定数量的字节
- b) 行终止符 字符已收到
以下示例使用条件 a)。它需要两个函数,一个用于您的主程序,一个用于回调。
function useserialdata
% this function is your main program
numBytes = 10; % read this many bytes when ready
% make sure serial object input buffer is large enough
serialport = serial('COM100','InputBufferSize',numbytes*10);
% assign the callback function to the serial port object
serialport.BytesAvailableFcnMode = 'byte';
serialport.BytesAvailableFcnCount = numBytes;
serialport.BytesAvailableFcn = {@getmydata,numBytes};
serialport.UserData.isnew = 0;
fopen(serialport);
while 1
if serialport.UserData.isnew > 0
newdata=ar.UserData.newdata; % get the data from the serial port
serialport.UserData.isnew=0; % indicate that data has been read
% use newdata for whatever
end
end
fclose(serialport);
function getmydata(obj,event,numBytes)
% this function is called when bytes are ready at the serial port
mydata = fread(obj, numBytes);
% return the data for plotting/processing
if obj.UserData.isnew==0
obj.UserData.isnew=1; % indicate that we have new data
obj.UserData.newdata = mydata;
else
obj.UserData.newdata=[obj.UserData.newdata; mydata];
end
显然,这些只是玩具示例,您还需要考虑许多其他细节,例如超时、错误处理、程序响应能力等,具体取决于串行设备工作方式的细节。有关详细信息,请参阅 "Serial Port Object Properties" 的 matlab 帮助文件。