Как отправить большой массив (96000 сэмплов) на последовательный порт ESP32 через MATLAB? - PullRequest
0 голосов
/ 08 октября 2019

Короче говоря, я читаю файл .wav в MATLAB с целью отправки его в ESP32 для анализа FFT. Файл .wav, о котором идет речь, содержит запись эффекта Короны. Мой файл имеет 96223 сэмплов при вводе в MATLAB.

Пока я пытаюсь вернуть контрольную сумму, чтобы знать, что данные отправлены правильно.

Я уже пытался использовать код, который я написал для меньших размеров выборки. Например, я возвращаю правильную контрольную сумму, когда отправляю 200 образцов, хотя код занимает больше времени, чем я хочу, что не очень хорошо. Более того, и я никогда ничего не получаю из-за тайм-аутов.

Это мой код MATLAB:

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:

#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 должен обрабатывать мой файл, я не могу просто вставить весь файл в последовательный порт, потому что я получаю ошибку переполнения буфера. Есть ли решение для этого?

1 Ответ

1 голос
/ 08 октября 2019

Первый %5.9f не имеет смысла для меня.

Это минимум 5 символов с точностью до 9 цифр. Эти 5 не имеют смысла, так как вы всегда будете иметь по крайней мере 11 символов с точностью до 9 цифр

Тогда позвольте мне сделать некоторые математические расчеты для вас:

96000 сэмплов, 12 символов каждый (включая\n) - это всего 10368000 битов.

При скорости 9600 бод это 1080 секунд времени передачи. -> 18 минут.

Когда вы добавляете паузу 0,1 с после каждого сэмпла, вы добавляете к этому еще 9600 секунд.

В результате у вас остается 178 минут (3 часа) времени передачи. .

Что вы ожидаете?

Для 200 сэмплов это еще 22,25 с.

...