我正在尝试与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
答案 0 :(得分:0)
这听起来像主机端的延迟计时器问题,默认值为16毫秒。你的USB串口芯片来自FTDI吗?如果是这样,您需要将LatencyTimer设置为最短的1ms。然后,OS将以1ms的间隔而不是16ms的间隔更新串行缓冲区。
如果这是原因,您可以谷歌如何更改操作系统的延迟计时器。新的MAC OS可能根本就没有好的解决方案。