简体   繁体   English

Arduino和Matlab之间的串行通信正在丢失数据

[英]Serial communication between Arduino and Matlab is losing data

I am now trying to establish the serial communication between Arduino and Matlab. 我现在正在尝试在Arduino和Matlab之间建立串行通信。 The script is very simple: 该脚本非常简单:

  1. Matlab send a number named as i to Arduino; Matlab向Arduino发送一个名为i的数字;

  2. Arduino receive this i , then send it back to Matlab; Arduino收到此i ,然后将其发送回Matlab;

Repeat step 1&2 for 10 times, ie, Matlab sends 1,2,...,10 to Arduino, then receive the 1,2,...,10 from Arduino. 重复步骤1&2 10次,即Matlab向Arduino发送1,2,...,10,然后从Arduino接收1,2,...,10。 However, Matlab only get back 3,4,...,10, while the first i=1 and i=2 are lost (I have already made the inputbuffersize=200 now, still not right). 但是,Matlab仅返回3,4,...,10,而第一个i = 1和i = 2丢失了(我现在已经使inputbuffersize = 200了,仍然不正确)。

Hereby is the code from Matlab: 特此是Matlab的代码:

clc,clear;
s=serial('COM16','BaudRate',9600); 
s.InputBufferSize = 200;    
fopen(s);
a=10;
rx = zeros(1, a); % rx is used to store the data send back by Arduino
ry = zeros(1, a); % ry is just helping me to see what happens in Serial
for i = 1:1:a
  fwrite(s, i); % Start to write the value "i" through serial to Arduino
  pause(0.5) % if no pause, the result is worse than now
  ry(i) = s.BytesAvailable; % check how many data are there in the Buffer
  if s.BytesAvailable>0
      rx(i) = fread(s, s.BytesAvailable); % Record the data send by Arduino
  end
end
fclose(s);

And the Arduino Code: 和Arduino代码:

char ibyte;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if(Serial.available()>0)
  {
    ibyte=Serial.read();
    Serial.write(ibyte);
  }
}

My reference link is: http://robocv.blogspot.com/2012/01/serial-communication-between-arduino.html 我的参考链接是: http : //robocv.blogspot.com/2012/01/serial-communication-between-arduino.html

The link you provide clearly notes that delay(2500); 您提供链接清楚地指出了delay(2500); needs to be added to the Arduino setup() code to allow time for rebooting, during which the device may "behave unpredictably" (like dropping sent data?). 需要添加到Arduino setup()代码中以留出时间来重新启动,在此期间设备可能“表现异常”(例如删除发送的数据?)。 You may need to pause the MATLAB code to accommodate for that as well, such as adding a pause(2.5) to your code after you open the serial connection (unless the fopen step already waits for the Arduino setup() to finish). 可能还需要暂停MATLAB代码以适应这种情况,例如在打开串行连接后在代码中添加pause(2.5) (除非fopen步骤已经等待Arduino setup()完成)。

Regarding your MATLAB code, one problem is that your code is set up so that it could possibly move ahead with sending more data before it has a chance to get the prior response. 关于您的MATLAB代码,一个问题是您的代码已设置为可以在有机会获得之前的响应之前继续发送更多数据。 In addition, you should specify the precision of the data you're sending, like 'uint8' for an unsigned 8-bit integer or 'double' for a double-precision number (as is your case). 另外,您应该指定要发送的数据的精度,例如'uint8'表示无符号的8位整数,或者'double'表示双精度数 (这是您的情况)。

What you probably want to do is just call fread without checking BytesAvailable first, since fread will block until it receives all of the data specified by the size argument (1 in this case). 您可能想要做的就是调用fread而不先检查BytesAvailable ,因为fread会阻塞直到接收到size参数指定的所有数据(本例中为1)。 Only after receiving will your loop move on to the next iteration/message: 只有在收到后,您的循环才会继续进行下一个迭代/消息:

for i = 1:1:a
  fwrite(s, i, 'double');
  rx(i) = fread(s, 1, 'double');
end

You could also try using only uint8 data: 您也可以尝试仅使用uint8数据:

rx = zeros(1, a, 'uint8');
for i = 1:1:a
  fwrite(s, uint8(i), 'uint8');
  rx(i) = fread(s, 1, 'uint8');
end

When you open the serial connection, the Arduino resets itself and the bootloader waits for potential sketch upload. 当您打开串行连接时,Arduino会重置自身,并且引导程序会等待潜在的草图上传。 This adds some delay before the sketch actually runs. 这会在草图实际运行之前增加一些延迟。

Add a pause after you open the serial connection. 打开串行连接后添加一个暂停。

fopen(s);
pause(3);

There are other options: 还有其他选择:

  1. Make the Arduino to announce when it's booted up, by sending something to the PC. 通过将东西发送到PC,使Arduino宣布启动时间。 For example you wait until the Arduino sends an S . 例如,您等到Arduino发送S

  2. I am not sure if this is possible with MATLAB, but if you disable the serial's DTR pin, the Arduino won't auto reset. 我不确定MATLAB是否可以实现此功能,但是如果您禁用串行的DTR引脚,则Arduino不会自动重置。

  3. Burn the code directly with the programmer, so the there is no bootloader which waits at boot. 直接与程序员一起刻录代码,因此没有引导程序在引导时等待。 But this also prevents you from uploading the sketch via the USB. 但这也阻止您通过USB上传草图。

  4. A hardware solution to prevent auto reset. 防止自动重置的硬件解决方案。 But this prevents the necessary reboot during the sketch uploading, so you have to time the reset manually. 但这会阻止在上载草图期间进行必要的重新引导,因此您必须手动设置重置时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM