Controlling a matlab script (Pause, Reset)
I am trying to create a matlab script (m-file) which shall be controlled by an external VBA script.
The matlab script shall do the same operation every time (even params change, but this is not the matter in this case) for a certain number of loops. If I see it right, I can use matlab funktions in VBA like this: http://www.mathworks.de/help/techdoc/matlab_external/f135590.html#f133975
My main problem is how to implement the matlab part of this problem...at the moment my control part looks like this:
start.m:
run = 1;
reset = 0;
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
doProcess();
pause(1)
end
disp('I am done');
The reset part works very fine while changing the value by the script, but when I manually try to change the value of 'run' or 'reset' to any other value in my workspace, nothing happens...my script doen't abort, neither does the reset-if do it's work... this seems to me that the script doesn't recognize any changes in the workspace?!
later the variables 'run' and 'reset' shall be set or unset by the VBA script. Is there any plausible reason why I can't abort the loop by hand?
Thanks for any advice!
greets, poeschlorn
开发者_JS百科Edit:
It seems that the script loads the variables once before starting and never again during runtime...is there a possibility to have explicit access to a workspace variable?
Edit 2:
I use Matlab 2010b with no additional Toolboxes at the moment
Edit 3:
I found out, that there are several 'workspaces' or RAMs in Matlab. If my function is running, the variables are stored in 'base' (?) workspace, which is not the matlab workspace on which you can click and change every value. So I have to get access to this ominous 'base' space and change the flag 'run' to zero.
I assume your problem is simply that your loop is blocking execution of the external interface. While the loop runs you cannot access the other interfaces.
I wanted to do a similar thing -- allow control of a matlab loop by an external program (either Ruby or another matlab instance). The most flexible solution by far was using UDP. There is a great toolbox called PNET for matlab, and I assume VB must have a socket library too. I simply open a UDP port on both sides, and use simple text commands to control and give feedback.
obj.conn = pnet('udpsocket', 9999);
command = '';
while run ~= 0
nBytes = pnet(obj.conn, 'readpacket');
if nBytes > 0
command = pnet(obj.conn, 'read', nBytes, 'string');
end
switch command
case '--reset--'
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
case '--abort--'
run = 0;
disp('Going to abort');
case '--echo--'
pnet(obj.conn, 'write', '--echo--');
pnet(obj.conn, 'writepacket', remoteAddress, remotePort);
end
doProcess();
end
This way I can build my own extensible control interface without worrying about blocking from the loop, it can work cross-platform and cross-language, can work within a machine or across the network.
UPDATE: To talk between two UDP clients, you need to set up two complimentary UDP ports, both are clients (this example is all in matlab, pretend obj here is a structure, in my case it is a class i wrap around the pnet functionality):
obj = struct();
obj.success = 0;
obj.client1Port = 9999;
obj.client2Port = 9998;
obj.client1Address = '127.0.0.1';
obj.client2Address = '127.0.0.1';
obj.conn1 = pnet('udpsocket', obj.client1Port);
obj.conn2 = pnet('udpsocket', obj.client2Port);
pnet(obj.conn1, 'write', '--echo--')
pnet(obj.conn1, 'writepacket', obj.client2Address, obj.client2Port);
nBytes = pnet(obj.conn2, 'readpacket');
if nBytes > 0
command = pnet(obj.conn2, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 2 recieved this message: %s\n',command);
pnet(obj.conn2, 'write', '--echo--')
pnet(obj.conn2, 'writepacket', obj.client1Address, obj.client1Port);
end
end
nBytes = pnet(obj.conn1, 'readpacket');
if nBytes > 0
command = pnet(obj.conn1, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 1 got this back: %s\n',command);
end
end
if obj.success == 2
fprintf('\nWe both sent and received messages!\n');
end
Is your script a script m-file or a function?
If it's a function, you'll be losing the scope of the workspace variables which is why it's not working. I'd turn your code into a function like this:
function processRun(run,reset)
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset; % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
[run,reset] = doProcess;
pause(1)
end
You can then set the values of run and reset evertime you call the function from VBA.
If you have a script, try removing the run and reset lines from the top, and set their values in the workspace before you run the script. I think you're overwriting your workspace values by running the script file.
Sorry, I don't have enough rep to make a comment so I'll quote it here:
@Adam Leadbetter: Thanks, this makes sense. The only thing I habe trouble with is how to pause (after this reset and then resume) the script when it has been started by run=1 as param... – poeschlorn Feb 25 at 7:17
If you want to break out of the loop once reset has been set to one, and then wait for the loop to continue again once run = 1
that is pretty much the same as just starting over again?
function processRun()
run = 1;
while run ~= 1
run = doProcess();
end
if doProcess()
returns 0
then the function processRun()
will end (like the behaviour you want to have when reset), the next time processRun
is called it starts over, with "reset"/default values.
Or am I missing something?
精彩评论