1

What I'm trying to do:

Read ADC (Analog-to-Digital Converter) data transferred through serial ports (COM devices).

With the help of 'read' and 'serialport', I managed to get expected output (verified multiple times, proving that there is nothing wrong with the device or relevant configurations for serial communication).

Next, there's the need to read TWO ADC data SIMULTANEOUSLY, while MATLAB runs the code line by line. Then, I searched and found relevant solutions in Background Processing in Help Center. I uses 'parfeval' and 'fetchOutputs', here is my code:

s = serialport("COM5",4000000,"Timeout",15); % ADC #1 Port
s2 = serialport("COM6",4000000,"Timeout",15); % ADC2 #2 Port

RX2 = parfeval(backgroundPool,@read,1,s2,4e6,'uint8');
rawdata = read(s,4e6,"uint8"); 
rawdata_2 = fetchOutputs(RX2);

Error code

Error using parallel.Future/fetchOutputs
One or more futures resulted in an error.

Error in DualADC_Sample_Test (line 11)
rawdata_2 = fetchOutputs(RX2);

Caused by:
Undefined function 'read' for input arguments of type 'double'.

Another try

After changing the input argument 4e6 to "4000000" (as a string) in the "RX2 = ..." line above, it says:

Error using parallel.Future/fetchOutputs
One or more futures resulted in an error.

Error in DualADC_Sample_Test (line 11)
rawdata_2 = fetchOutputs(RX2);

Caused by:
Expected input number 2, count, to be one of these types:

double, single, uint8, uint16, uint32, uint64, int8, int16, int32, int64

Instead its type was string.

My Question

I also tried to transform the number into several other classes, including 'single', 'uint64' etc. All failed, showing Undefined function 'read' for input arguments of type 'single', 'uint64', etc.

From my attempts, it seems that the software's background processing recognizes the function 'read' correctly, but somehow does not accept this input argument. Is it a bug? or am I missing something here?

I've tried to submit a bug report but Mathwork simply replied 'please offer a valid license'. (Yes, I use a hacked one. I am not proud of that.)

Problem appears in both 2022b and 2023a.

nekomatic
  • 5,988
  • 1
  • 20
  • 27
Couponpon
  • 11
  • 2
  • Did you configure the parallel pool as thread-based or process-based? Thread-based pools have very limited functionality. Anyway, you probably want to use timers for this, not parfeval. – Cris Luengo Mar 27 '23 at 05:18
  • I have temporarily given up on doing this using MATLAB and have thought of two possible workarounds: #1 by using two serial reading software, selecting one port each; #2 by using python and pyserial, since I've seen similar demands in [this post](https://stackoverflow.com/questions/27484250/python-pyserial-read-data-form-multiple-serial-ports-at-same-time) on stackoverflow. – Couponpon Mar 28 '23 at 01:12
  • How often do you need to read data from each device, and what sort of protocol do the devices use to transfer the data - do they wait for a command and return a value, or are they continuously sending data? How is the data formatted and is there a termination character at the end of each reading? You can probably let the OS buffer the data arriving at each port and either read them alternately, or use [callbacks](https://uk.mathworks.com/help/matlab/ref/serialport.configurecallback.html). There's no such thing as 'simultaneously' unless the two devices are actually synchronised by hardware. – nekomatic Mar 29 '23 at 15:25

2 Answers2

1

This “undefined function” is the error message you see when a function isn’t supported in parallel processing. There’s not actually anything wrong with the types you’re using. The parallel execution environment simply can’t find the function. If you’re using a thread-based pool, try a process-based one (see Cris’s comment above). If you’re using a process-based pool and still see the error, there’s very little you can do; you’ll have to solve your programming task without using a parallel pool.

FragileX
  • 626
  • 1
  • 8
  • Error still after specifying a process-based one. Thanks anyway for saving my time by eliminating unnecessary troubleshooting. I'll think of other solutions. – Couponpon Mar 28 '23 at 01:08
0

Could this be related to the 'read' function not being recognized correctly in the 'parfeval' call.

I think an easy fix should be to use a wrapper function to resolve this issue.

See your updated code:

s = serialport("COM5", 4000000, "Timeout", 15); % ADC #1 Port
s2 = serialport("COM6", 4000000, "Timeout", 15); % ADC2 #2 Port

backgroundPool = gcp('nocreate');
if isempty(backgroundPool)
    backgroundPool = parpool('local');
end

RX2 = parfeval(backgroundPool, @readWrapper, 1, s2, 4e6, 'uint8');
rawdata = read(s, 4e6, "uint8");
rawdata_2 = fetchOutputs(RX2);
S30609
  • 65
  • 5
  • May I ask how to develop this wrapper function? I've written one ```function myout = myread(r1,r2,r3) myout = read(r1,r2,r3); end ``` The software still output error `Undefined function 'read' for input arguments of type 'double'.` – Couponpon Mar 27 '23 at 11:31
  • This answer is incomplete. What is `readWrapper` in this code? – Cris Luengo Mar 27 '23 at 13:13
  • This answer doesn’t actually work, because the parallel execution environment still needs to look inside the wrapper to execute it, and it still can’t find `read`. – FragileX Mar 27 '23 at 16:58