Matlab Arduino实时串行通信,采样时间为0.004秒

时间:2017-09-27 16:37:00

标签: matlab real-time arduino-uno serial-communication

我正在尝试与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 个答案:

答案 0 :(得分:0)

这听起来像主机端的延迟计时器问题,默认值为16毫秒。你的USB串口芯片来自FTDI吗?如果是这样,您需要将LatencyTimer设置为最短的1ms。然后,OS将以1ms的间隔而不是16ms的间隔更新串行缓冲区。

如果这是原因,您可以谷歌如何更改操作系统的延迟计时器。新的MAC OS可能根本就没有好的解决方案。