How do I manage a storage buffer choke?

8 views (last 30 days)
Floris-Jan Nieuwenhuis
Floris-Jan Nieuwenhuis on 30 May 2022
Answered: Yousef on 15 Nov 2023
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 Comment
Alireza Golgouneh
Alireza Golgouneh on 7 Sep 2022
Hello Floris-Jan,
Have you found the solution to this problem? I'm getting the same error message when using Bno055 IMU?

Sign in to comment.

Answers (2)

Rishi
Rishi on 27 Oct 2023
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 on 15 Nov 2023
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.

Categories

Find more on Deployment, Integration, and Supported Hardware in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!