How do I manage a storage buffer choke?

조회 수: 10 (최근 30일)
Floris-Jan Nieuwenhuis
Floris-Jan Nieuwenhuis 2022년 5월 30일
답변: Yousef 2023년 11월 15일
I'm running an arduino uno with four hall-effect sensors and an imu into MATLAB (and eventually the app designer). The data is displayed (after brief calculations) into four live feed plots. I've been working on increasing the speed of the while loop code but have run into an ill-documented problem. Right now I have three seperate "read" commands for each aspect of the IMU as seen below:
accel = readAcceleration(imu1);
gyro = readAngularVelocity(imu1);
magn = readMagneticField(imu1);
I've discovered that combining those three commands into one (as shown below) significantly increases the loop speed.
imu1.OutputFormat = 'matrix';
[accel,gyro,magn] = read(imu1);
However, after running for about 10 seconds, Matlab stops what it is doing and displays "Receive on demand storage full" in the command window:
Error using SpeedTest (line 67)
Receive on demand storage buffer is full.
The error message specifies that it runs into this issue when it tries to read the voltage of one of the hall-effect sensors (as shown below, line 67 is the line that defines v_A3). The offset and c1 are multiplication coefficients for calculations later on.
v_A3 = (readVoltage(a,"A3")-A3_offset);
v_A0 = (readVoltage(a,"A0")-A0_offset)*2*c1;
v_A1 = (readVoltage(a,"A1")-A1_offset)*c1;
v_A2 = (readVoltage(a,"A2")-A2_offset)*c1;
My question is in two parts:
  1. Is it possible to circumvent this error? Can the storage buffer be flushed once per loop iteration once all of the necesary data is read from the arduino?
  2. Is there a way to read the voltages of 4 seperate pins with a single command? If it isn't possible to use the read(imu1) command instead of the three seperate "read" commands (due to the storage buffer choke), is there another way of reading them all at once? The profiler indicates that the 7 "read" commands are time consuming commands, so reducing the number of times they're called would go a long way to increasing loop speed.
Should you need more information or lines of code, let me know and I'll append the question with the necessary information.
Many thanks!
  댓글 수: 1
Alireza Golgouneh
Alireza Golgouneh 2022년 9월 7일
Hello Floris-Jan,
Have you found the solution to this problem? I'm getting the same error message when using Bno055 IMU?

댓글을 달려면 로그인하십시오.

답변 (2개)

Rishi
Rishi 2023년 10월 27일
Hi Jan,
I understand that you are getting an error “Receive on demand storage full” after your code runs for some time. This occurs when the buffer in MATLAB is full and cannot handle any more data.
To circumvent this error, you can flush your input buffer after every loop using ‘flushinput’. You can learn more about it from the below documentation:
You can also try increasing the buffer size in MATLAB using the ‘inputBufferSize’ property. You can learn more about it from the below documentation:
It is possible to read multiple values at once from the ‘read’ command, as is shown in the below documentation:
Hope this helps.

Yousef
Yousef 2023년 11월 15일
MATLAB-Side Parsing: In MATLAB, read the entire concatenated string and then parse the voltages from it. This way, you reduce the number of read operations.
Here's a rough sketch of what the Arduino code might look like:
void loop() {
// Read voltages
int v_A0 = analogRead(A0);
int v_A1 = analogRead(A1);
int v_A2 = analogRead(A2);
int v_A3 = analogRead(A3);
// Send as a comma-separated string
Serial.print(v_A0);
Serial.print(",");
Serial.print(v_A1);
Serial.print(",");
Serial.print(v_A2);
Serial.print(",");
Serial.println(v_A3);
// Other code...
delay(10); // Adjust the delay to match MATLAB's processing speed
}
And the MATLAB code to read and parse:
% Read the serial data
dataString = readline(a); % Assuming 'a' is your serial object
dataValues = str2double(split(dataString, ','));
% Assign to variables and scale as needed
v_A0 = (dataValues(1) * 5 / 1023 - A0_offset) * 2 * c1;
v_A1 = (dataValues(2) * 5 / 1023 - A1_offset) * c1;
v_A2 = (dataValues(3) * 5 / 1023 - A2_offset) * c1;
v_A3 = (dataValues(4) * 5 / 1023 - A3_offset);
Keep in mind that serial communication is inherently sequential, but by sending all the data at once, you reduce the overhead of multiple read calls.
Lastly, using the MATLAB Profiler to identify the slow parts of your code is a good approach. You should continue to look for ways to optimize those sections to improve the overall loop execution time.

카테고리

Help CenterFile Exchange에서 Deployment, Integration, and Supported Hardware에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by