我正在尝试与matlab和arduino Uno进行实时通信 . 我们的想法是用PWM发送电机命令,并读取传感器值 . 但首先我想要在串口/ USB上进行实时通信 .
因此,arduino代码正在等待来自matlab的调用,并且根据调用的类型,答案将被转发到电机(控制命令)或编码器值将被发送到笔记本电脑(读取命令) .
在matlab部分,我使用了串行对象,并以高波特率打开 . 当我使用分析器检查matlab中的时序时,看起来问题不是来自matlab方面,而是来自arduino /或串行通信 .
问题是由于某种原因,我需要一个非常小的采样时间大约0.004秒 . 但无论波特率有多大,我都无法做到这一点 . 为了加快沟通,我应该改变什么?重要的是要提到我需要实时控制 . 使用0.004,我得到一些非常嘈杂的数据,平均值约为0.015;但是如果我将它改为0.015,仍会出现一些峰值 .
为了更好地理解这里是arduino代码:
const byte numChars = 8;
char receivedChars[numChars]; // an array to store the received data
int numb = 0;
boolean newData = false;
void setup() {
Serial.begin(250000);
Serial.setTimeout(100);
}
void loop() {
recvWithEndMarker();
showNewData();
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
numb = atoi(receivedChars);
}
void showNewData() {
if (newData == true) {
if (numb==256)
Serial.println(numb);
newData = false;
}
}'
这是MATLAB代码
for k = 1:N,
% time(k)
alpha(k) = utread;
%simple constant input, here goes the control algorithm
% u(k) = (-1 + k/255);
u(k) = sign(mod(k,5)-2);
% for aaa=1:100
% 1+2;
% end
utwrite(u(k));
%synchronize, wait for next sample time
time(k+1) = toc;
while(time(k+1)<(time(k)+Ts))
time(k+1) = toc;
end
end
为简单起见,我只提出了最重要的部分 . 和utread是一个具有以下形式的函数:
utread.m
global utip
fprintf(utip.s,'256>');
dat = fscanf(utip.s,'%d');
while (isempty(dat)) % wait for data on the serial
fprintf(utip.s,'256>');
dat = fscanf(utip.s,'%d');
end
1 回答
这听起来像主机端的延迟计时器问题,默认值为16毫秒 . 你的USB串口芯片来自FTDI吗?如果是这样,您需要将LatencyTimer设置为最短的1ms . 然后OS将以1ms间隔而不是16ms间隔更新串行缓冲器 .
如果这是原因,您可以谷歌如何更改您的操作系统的延迟计时器 . 新的MAC OS可能根本没有好的解决方案 .