将浮点数数组从 MATLAB 发送到 Arduino



我想从MATLAB向Arduino发送一个由三个浮点数组成的数组。我正在尝试通过将这些值从Arduino发送回MATLAB来检查Arduino是否已收到这些值。似乎Arduino只能正确读取数组中的第一个元素。

我的数组"参数"是:

measurement_interval = 5.0;
ec_ref_thickness = 2.0;
e_ref_thickness = 3.0;
parameters = [measurement_interval ec_ref_thickness e_ref_thickness];

我与Arduino建立了沟通,因为:

arduino = serial('COM4');
set(arduino,'DataBits',8);
set(arduino,'StopBits',1);
set(arduino,'BaudRate',9600);
set(arduino,'Parity','none');
fopen(arduino);

我使用以下方法将其发送到Arduino:

fprintf(arduino, '%f', parameters);
fprintf(arduino, 'n');

在Arduino中,我有:

float parameters[3]
void setup()
 {
    Serial.begin(9600);
    while (Serial.available() == 0)
    {
    }
    if (Serial.available() > 0)
    {
      for (int i=0; i < 3 ; i++)
      {
          parameters[i] = Serial.parseFloat();
      }
      Serial.flush();
    }

我通过串行端口从Arduino发回:

void loop()
{
  Serial.print(parameters[0])
  Serial.print("  ");
  Serial.print(parameters[1]);
  Serial.print("  ");
  Serial.print(parameters[2]);
}

并在 MATLAB 中读作:

output = fscanf(arduino);

"输出"应为 [5.0 2.0 1.0]。但是,我得到的是 [5.00 0.00 0.00]

因此,只有第一个元素"5.0"被正确返回。如何调整它以读取数组中的所有数字?

首先,如果您尝试将参数作为浮点数传递,则可能应该使用 '%f' 作为 MATLAB 代码中的格式说明符。

接下来,您需要等待串行数据可用,然后再尝试解析浮点数。

float parameters[3];
void setup(){
  Serial.begin(9600);
  while(!Serial || Serial.available() <= 0);
  for (int i=0; i<3; i++){
    parameters[i] = Serial.parseFloat();
  }
}
void loop(){
  for(size_t i=0; i<3; ++i){
    Serial.print(parameters[i]);
    Serial.print(i<2 ? 't' : 'n');
  }
}

如果由于某种原因仍然不起作用,您可以尝试检查您的串行数据是否正确到达arduino:

void setup(){
  Serial.begin(9600);
  while(!Serial || Serial.available() <= 0);
  while(Serial.available() > 0){
    Serial.print(Serial.read());
  }
}
void loop(){}

如果由于某种奇怪的原因仍然不起作用,您可以随时尝试以另一种方式将数据解析为浮点数。下面是一个简单的示例:

float parameters[3];
void setup(){
  Serial.begin(9600);
  while(!Serial);
  while(Serial.available() <= 0);
  for(int i=0; i<3; ++i){
    String param_string = "";
    int c;
    while( (c = Serial.read()) >= 0 ){
      if((char)c == 'n') break;
      param_string += (char)c;
    }
    parameters[i] = param_string.toFloat();
  }
}
void loop(){
  for(size_t i=0; i<3; ++i){
    Serial.print(parameters[i]);
    Serial.print(i<2 ? 't' : 'n');
  }
}

@JeffreyCash的答案非常好,我认为它需要 100% 处理 Arduino 方面的代码。但是,由于您仍然有问题,我想发布此内容以涵盖 Matlab 方面。


我在你的问题中读到你从 Matlab 发送值

fprintf(arduino, '%d', parameters);

然而:

  • 您应该使用%f打印float
  • 据我所知,使用此指令,您只发送一个值,这就是为什么当您运行 JeffreyCash 的代码时,您只成功打印了一个float

也许你应该写

fprintf(arduino, '%fn', parameters(1));
fprintf(arduino, '%fn', parameters(2));
fprintf(arduino, '%fn', parameters(3));

fprintf(arduino, '%fn%fn%fn', parameters(1),
        parameters(2), parameters(3));

首先尝试在 matlab 中的 fopenf(arduino( 之后放置一些延迟约 3 秒即

fopen(arduino);
pause(3);

其次,一次发送一个参数数组,即

for i = 1:4
   fprintf(arduino, '%5.3fn', parameters (i)); 
   pause(0.5);       
end

这应该可以正常工作,最后在 arduino 方面,您的设置看起来不错,但是您尝试将数组发送回 matlab 的循环尝试执行

 void loop()
{ for (int i = 0; i < 3; i++){
  Serial.println(parameters[0]);  //sends data back in every new line 
  delay (20);

}

是的,尝试在 Matlab 端创建一个零数组来存储从 Arduino 接收的值,即

receiveData = zeros (1, 4);
  for i = 1:4
  output = fscanf(arduino, '%f');
  receiveData =output;
 end

这应该适合您干杯

我在添加小修改后测试了您的代码,效果很好。

MATLAB 代码:

measurement_interval = 5.0;
ec_ref_thickness = 2.0;
e_ref_thickness = 3.0;
parameters = [measurement_interval ec_ref_thickness e_ref_thickness];
arduino = serial('COM3');
set(arduino,'DataBits',8);
set(arduino,'StopBits',1);
set(arduino,'BaudRate',9600);
set(arduino,'Parity','none');
fopen(arduino);
pause(2)
fprintf(arduino, '%f %f %f', parameters);

line = fgets(arduino);
values = strsplit(line, ",");
Final_values = str2double(values)

Arduino 代码:

float parameters[3];
void setup(){
Serial.begin(9600);
}
void loop(){
while(!Serial || Serial.available() <= 0);
for (int i = 0; i < 3; i++) {
parameters[i] = Serial.parseFloat();
}
Serial.print(parameters[0]);
Serial.print(",");
Serial.print(parameters[1]);
Serial.print(",");
Serial.print(parameters[2]);
}

最新更新