How could I run a while loop asynchronously and break it from a callback function receiving client input? Are there better alternatives?

3 次查看(过去 30 天)
I am currently using a client/server application where the MATLAB code acts as the server.
The server is meant to execute functions of a device connected to the computer that holds the server application.
Through an ethernet connection, the server receives integers from the python-based client application. The integers are interpreted as instructions for different functions of the device to be executed at the moment they are received. I placed a switch inside the callback function for the server to handle the functions assigned to each integer. The functions of the device run asynchronously.
The program has the following framework.
%Define device object.
%Define parameters for device function.
%Define tcp/ip server
function callbackClientConnection
%If client disconnects
- Clear device object
- Clear TCP/ICP server
function readClientData
%Read Client Data (integer)
swtich
case 0 : Don't do anything
case 1: Eval start device function in base workspace
case 2: Eval stop device function in base workspace
case 3: Eval change parameters of function in base workspace
Previously I only needed to execute the device function once when the server received number 1. This function would last for 4 seconds, and if number 2 was received within that time frame the device's function to stop previous function could be run with no issues, since these functions run asynchronously.
Currently, when I receive number 1 from the client, I need to execute a loop that runs the device's function several times, with a pause between each repetition. This time instead of using the stop device function, I would need for the loop to be broken either by a limit of number of repetetions or ideally by a boolean that changes to false once the server receives number 2 from the client. I've tried setting the while loop in a separate function in the script, and using a global boolean variable that changes to true when 1 is received and changes to false when 2 is received. However this did not work because the server won't read data from the client until the loop finishes running. I also tried using parpool and parfeval, but this did not work either.
The framework I'm trying to use looks like this:
.....
function readClientData
global continueLoop
%Read Client Data (integer)
swtich
case 0 : Don't do anything
case 1: continueLoop = true
deviceFunctionLoop()
case 2: continueLoop = false
case 3: Eval change parameters of function in base workspace
function deviceLoop
global continueLoop
numReps = 4;
i = 1;
while i < numReps & continueLoop
Eval start device function in base workspace
pause(0.250)
i = i +1;
end
Any ideas on how to be able to run this loop asynchronously and be able to break it when receiving number 2 from client?

回答(1 个)

Chetan
Chetan 2024-4-30
It seems like you want to run a loop to check for client commands, executing the loop asynchronously while being able to interrupt it based on client commands.
To address this issue, consider using MATLAB's `timer` objects.
A `timer` object can be set up to execute its callback function at specified intervals, allowing your server to periodically check for new client commands without blocking the main thread that listens for incoming data.
  1. Define a `timer` object for running the device function loop. This allows the main server thread to remain responsive to incoming client commands.
  2. Use the `timer` callback to execute the device function. Within this callback, check the global `continueLoop` variable to determine if the loop should continue or be stopped.
  3. Adjust the `timer` execution based on client commands. When a start command (1) is received, start or resume the timer. When a stop command (2) is received, stop the timer, effectively breaking the loop.
Here's a simplified example to illustrate this approach:
% Define global variable
global continueLoop;
% Define the timer object globally or in an appropriate scope
global deviceTimer;
deviceTimer = timer('ExecutionMode', 'fixedSpacing', ...
'Period', 0.250, ... % Adjust the period to match your device function's requirements
'TimerFcn', @deviceFunctionLoop);
function readClientData
global continueLoop;
global deviceTimer;
% Read Client Data (integer)
switch
case 0
% Don't do anything
case 1
continueLoop = true;
if strcmp(deviceTimer.Running, 'off')
start(deviceTimer);
end
case 2
continueLoop = false;
stop(deviceTimer); % This will allow the loop to be interrupted
case 3
% Eval change parameters of function in base workspace
end
end
function deviceFunctionLoop(~, ~)
global continueLoop;
if ~continueLoop
% Optionally, stop the timer here if you want to ensure it doesn't fire again
stop(deviceTimer);
return;
end
% Eval start device function in base workspace
end
Refer to the following MathWorks Documentation for more details:
Thanks,
Chetan

类别

Help CenterFile Exchange 中查找有关 Dialog Boxes 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by