Failed to read "n" uint8 value(s) from the device error while reading serial information.

4 views (last 30 days)
Hello,
I am trying to read information from a scale that sends out a signal via an RS232 cable. I am reading this signal with a RS232 adapter that is connected to an Arduino Mega 2560. The connections are correct and we know this because we have gotten the code to run on multiple occasions.
The main issue is that the code occasionally will display the error message "failed to read "n" uint8 value(s) from the device" where "n" is the number of bits that the Arduino is trying to read from the scale. The baudrate on the scale and the code are both set to 19200, so we know this is not the issue.
Usually I use 63 for "n", but have also used 32 and other factors of 8. It has worked with 63, 32, and 56.
Here is the code I am using:
raw_data = zeros(3, 63);
g_finder = []; % Initialize as empty array
raw_weights = strings(1, 3); % Use strings to store raw weight data
for j = 1:4
if app.scale_list(j) ~= 0
raw_data(j, :) = read(Serial_Scale_list(j), 63);
g_finder = find(raw_data(j,:) == 103); % Assign new value to g_finder
% Process data for each scale
for k = 1:1
if numel(g_finder) >= 2 && g_finder(2) >= 8
raw_weights(k,1) = char(raw_data(k,(g_finder(2)-8):(g_finder(2)-1)));
% Convert the string to a number and append to mass_and_time_archives array
mass_archives(k, location) = str2double(raw_weights(k,1))/density_list(k);
time_archives(1, location) = (now - initial_time) * 24 * 3600; % Convert to seconds
% Calculate flow rate if there are at least two data points available
if location > 7
flowrate_archives(location, k) = (mass_archives(k, location) - mass_archives(k, location - 5)) / ...
((time_archives(1, location) - time_archives(1, location - 5)) / 60);
end
location = location + 1;
disp(raw_weights(k));
pause(1);
end
break; % Exit the loop after processing one set of data for this scale
end
end
end
Essentially, the scale outputs ASCII characters, that convert to something like the weight followed by a g, for example one output may be "1272 g" which has the raw ASCII value of "49 50 55 50 32 103 ". Since every weight has a "g" or a "103" at the end, I am finding in the output of the scale where the value 103 appears and reading a set amount of characters before that to get the weight output. Later the code determines the mass flow rate by taking the change in mass divided by the change in time.
This code is part of an app that I am building, although it returns the same issue when it is run independently (without the variables that are part of the rest of the app's code, of course), where it sometimes runs and sometimes does not while returning the same error message.
Like I said, the code occasionally works, which is why I am stumped as to what could be causing this problem. If anyone has any ideas they would be appreciated.
Thanks

Answers (1)

MULI
MULI on 21 Oct 2024
Hi Andrew,
I understand that you are experiencing intermittent errors when trying to read data from a scale via an RS232 connection using an Arduino Mega 2560.
The error message "failed to read 'n' uint8 value(s) from the device" indicates that the Arduino is not consistently receiving the expected amount of data.
  • The error message suggests a timing issue where the Arduino is attempting to read data before it's fully available. Consider adding a small delay before reading data to ensure the buffer is filled.
  • Increase the buffer size in the Arduino code to handle more incoming data, which might help if the data is being sent in bursts.
  • Implement error handling in your code to retry reading if an error occurs. This can help the system recover from transient communication errors.
  • Verify that the scale consistently sends data in the expected format. Any deviation might cause reading errors.
Here's a modified version of your code with added error handling and a delay:
raw_data = zeros(3, 63);
g_finder = [];
raw_weights = strings(1, 3);
for j = 1:4
if app.scale_list(j) ~= 0
% Retry mechanism for reading data
success = false;
attempts = 0;
while ~success && attempts < 3
try
pause(0.1); % Small delay before reading
raw_data(j, :) = read(Serial_Scale_list(j), 63);
success = true;
catch
attempts = attempts + 1;
disp('Failed to read data, retrying...');
end
end
if ~success
disp('Failed to read data after multiple attempts.');
continue;
end
g_finder = find(raw_data(j,:) == 103);
for k = 1:1
if numel(g_finder) >= 2 && g_finder(2) >= 8
raw_weights(k,1) = char(raw_data(k,(g_finder(2)-8):(g_finder(2)-1)));
mass_archives(k, location) = str2double(raw_weights(k,1))/density_list(k);
time_archives(1, location) = (now - initial_time) * 24 * 3600;
if location > 7
flowrate_archives(location, k) = (mass_archives(k, location) - mass_archives(k, location - 5)) / ...
((time_archives(1, location) - time_archives(1, location - 5)) / 60);
end
location = location + 1;
disp(raw_weights(k));
pause(1);
end
break;
end
end
end
You can refer to this example that shows how to enable callbacks to read streaming ASCII terminated data from an Arduino
Hope this answers your query!

Categories

Find more on MATLAB Support Package for Arduino Hardware in Help Center and File Exchange

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!