首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过MATLAB向ESP32串口发送一个大数组(96000个样本)?

如何通过MATLAB向ESP32串口发送一个大数组(96000个样本)?
EN

Stack Overflow用户
提问于 2019-10-08 16:14:39
回答 1查看 731关注 0票数 0

简而言之,我正在读取MATLAB中的一个.wav文件,目的是将其发送到ESP32进行快速傅立叶变换分析。有问题的.wav文件包含一段日晕效果的记录。我的文件在输入MATLAB时有96223个样本。

现在,我只想得到一个校验和,这样我就可以知道数据是正确发送的。

我已经尝试使用我为较小样本大小编写的代码。例如,当我发送200个样本时,我得到了正确的校验和,尽管代码花费的时间比我希望的要长,这是不好的。不仅如此,由于超时,我再也拿不到任何东西了。

这是我的MATLAB代码:

代码语言:javascript
运行
复制
esp = serial('COM3');
set(esp, 'DataBits' , 8);
set(esp, 'StopBits', 1);
set(esp, 'BaudRate', 9600);
set(esp, 'Parity', 'none');
set(esp, 'terminator', 'LF');

%filename = 'test100.wav';
%corona = audioread(filename);

load('corona')
fopen(esp);
pause(0.1)
for i = 1:200
   fprintf(esp, '%5.9f\n', corona(i,1)); 
   pause(0.1);       
end
output = fscanf(esp, '%f\n') %read the checksum
fclose(instrfind);

这是我的Arduino代码:

代码语言:javascript
运行
复制
#include <Arduino.h>
float sentData[200]; //initialize data array
int i = 0;
const int ledPin = 26;
float checksum = 0;
int CNT = 0;

void printFloat(float value, int places);

void setup()
{
  Serial.begin(9600);

  pinMode(ledPin, OUTPUT);

  while (Serial.available() < 200)
  {
    digitalWrite(ledPin, HIGH); //keep the LED on while the data is being sent
  }

  while (Serial.available() != 0)
  {
    sentData[i] = Serial.parseFloat(); //parse the data to the array
    i++;
  }
  Serial.flush();
  delay(500);
  digitalWrite(ledPin, LOW); //turn off the LED when data is fully parsed

  for (size_t x = 0; x < 200; ++x)
  {
    checksum += sentData[x]; //calculate the sum of all elements in the sentData array
  }
  printFloat(checksum, 10); //send the checksum to the serial port for reading
}
void loop()
{
}

void printFloat(float value, int places)
{
  // this is used to cast digits
  int digit;
  float tens = 0.1;
  int tenscount = 0;
  int i;
  float tempfloat = value;

  // if this rounding step isn't here, the value  54.321 prints as 54.3209

  // calculate rounding term d:   0.5/pow(10,places)
  float d = 0.5;
  if (value < 0)
    d *= -1.0;
  // divide by ten for each decimal place
  for (i = 0; i < places; i++)
    d /= 10.0;
  tempfloat += d;

  // first get value tens to be the large power of ten less than value

  if (value < 0)
    tempfloat *= -1.0;
  while ((tens * 10.0) <= tempfloat)
  {
    tens *= 10.0;
    tenscount += 1;
  }

  // write out the negative if needed
  if (value < 0)
    Serial.print('-');

  if (tenscount == 0)
    Serial.print(0, DEC);

  for (i = 0; i < tenscount; i++)
  {
    digit = (int)(tempfloat / tens);
    Serial.print(digit, DEC);
    tempfloat = tempfloat - ((float)digit * tens);
    tens /= 10.0;
  }

  // if no places after decimal, stop now and return
  if (places <= 0)
    return;

  // otherwise, write the point and continue on
  Serial.print('.');

  // now write out each decimal place by shifting digits one by one into the ones place and writing the truncated value
  for (i = 0; i < places; i++)
  {
    tempfloat *= 10.0;
    digit = (int)tempfloat;
    Serial.print(digit, DEC);
    // once written, subtract off that digit
    tempfloat = tempfloat - (float)digit;
  }
}

我希望得到一个校验和,但当我使用非常大的样本量时,我得到了超时。我还应该补充说,即使ESP32应该能够处理我的文件,我也不能只是将整个文件推送到串行端口,因为我得到了一个缓冲区溢出错误。对此有解决方案吗?

EN

回答 1

Stack Overflow用户

发布于 2019-10-08 16:37:05

首先,%5.9f对我来说没有任何意义。

这是最少5个字符,精度为9位。5没有任何意义,因为您始终至少有11个字符,精度为9位

然后让我为你做一些数学计算:

96000个样本,每个样本12个字符(包括\n),总共是10368000位。

在9600波特率时,传输时间为1080秒。-> 18分钟。

当您在每个样本之后添加0.1s暂停时,您将在此基础上再添加9600秒。

这样,您总共只有178分钟(3小时)的传输时间。

你能指望什么?

对于200个样本,它仍然是22,25秒。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58282513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档