【问题标题】:Matlab Arduino serial communication in real-time with 0.004 s samplingMatlab Arduino 实时串行通信,采样时间为 0.004 秒
【发布时间】:2018-03-09 05:55:37
【问题描述】:

我正在尝试与 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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答!我试图解决这个问题,但问题如下:arduino Uno 而不是 FTDI,使用 atmega16u 进行串行 USB 通信,更改 LatencyTimer 并不容易(无法从设备管理器直接访问)。
    • 所以它使用单芯片VUSB方案?
    • 嗯,它是一个单独的芯片,与Arduino使用的不同(2个atmega芯片:atmega 328p atmega16u)。
    • 您可以获得使用 FTDI 芯片的 USB-TTL 电缆,然后连接到 arduino 上的 UART 引脚。您不必为 VCP 使用板载 atmega16u。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 2017-11-14
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多