2011-02-24 41 views
8

嘿家伙,我想创建一个matlab脚本(m文件),它将由外部VBA脚本控制。控制一个matlab脚本(暂停,重置)

对于一定数量的循环,matlab脚本应该每次都执行相同的操作(即使params更改,但这种情况在这种情况下也不是这样)。此刻我的控制部分看起来像这样http://www.mathworks.de/help/techdoc/matlab_external/f135590.html#f133975

我的主要问题是如何实现这个问题的MATLAB一部分... ...: 如果我看到它,我可以使用MATLAB funktions在VBA这样

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'); 

同时通过脚本改变值,但是当我尝试手动“运行”或“重置”的值更改为任何其他值复位部分工作得非常细在我的工作空间里,什么也没有发生......我的脚本不会中止,重新也不会中止设置 - 如果它的工作... 在我看来,这个脚本不能识别工作区中的任何变化?!

后面的变量'run'和'reset'应该由VBA脚本设置或取消设置。 有什么合理的理由可以说明我为什么不能手工中止循环?

感谢您的任何建议!

映入眼帘,poeschlorn

编辑:

看来,脚本运行时开始之前加载变量一次,永远不会再...是否有可能有一个工作区变量明确的访问?

编辑2:

我用Matlab的2010年b,没有额外的工具箱目前

编辑3:

我发现,有几个 '工作区' 或RAM的在Matlab中。如果我的函数正在运行,变量将存储在'base'(?)工作区中,而不是您可以单击并更改每个值的matlab工作区。所以我必须进入这个不祥的“基地”空间,并将标志“运行”改为零。有任何想法吗?

+0

r.e.编辑3:没有什么不祥之处,函数有自己的变量堆栈,而工作空间另一个(你不希望用户函数改变你的工作空间变量,反之亦然!)。如果您需要跨工作区和用户函数全局访问变量,请在工作区和您使用的任何函数中使用** global **关键字,即'global run'' http://www.mathworks.com/ help/techdoc/matlab_prog/f0-38052.html#f0-38470 - 这是假设你的循环没有阻塞外部接口... – 2011-03-11 11:02:54

+0

@编辑3:有这样的功能:['assigning'](http: //www.mathworks.com/help/techdoc/ref/assignin.html),这是非常不推荐的。 – Juhl 2011-03-12 18:45:22

+0

@Juhl:为什么这个函数非常不推荐?我没有看到任何反对O.o – poeschlorn 2011-03-16 11:57:32

回答

1

您的脚本是脚本m文件还是函数?

如果它是一个函数,你将失去工作空间变量的范围,这就是为什么它不起作用。我把你的代码到这样的功能:

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 

然后,您可以设置运行的价值和重置evertime调用VBA中的功能。

如果您有脚本,请尝试从顶部删除运行和重置行,并在运行脚本之前在工作区中设置它们的值。我认为你通过运行脚本文件来覆盖你的工作区值。

+0

代码本身就是m文件的全部内容。我在理解你的代码时遇到了一点问题......如果我看到它的话,我必须调用函数processRun(...)一次?然后我可以在工作区中更改我的值? – poeschlorn 2011-02-24 14:38:33

+0

如果您没有函数定义,我认为您可能会覆盖脚本中的工作区变量。看我的编辑到我原来​​的答案。 – 2011-02-24 14:56:57

+0

在我看来,当且仅当由于某种原因在前一次检查和当前检查之间的时间间隔中它被改变为1时,'reset'变量被重置为0。这个原因是你的VBA脚本,我没有看到任何逻辑问题。对我来说是个谜。 – 2011-02-24 16:13:29

4

我假设你的问题只是你的循环阻塞了外部接口的执行。循环运行时,您无法访问其他接口。

我想做一个类似的事情 - 允许外部程序(Ruby或另一个matlab实例)控制一个matlab循环。到目前为止,最灵活的解决方案是使用UDP。有一个名为PNET的伟大工具箱,我认为VB也必须有一个套接字库。我只需在两边打开一个UDP端口,然后使用简单的文本命令来控制和提供反馈。

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 

这样我可以建立自己的可扩展的控制界面,而不用担心来自循环阻塞,它可以工作的跨平台,跨语言,可以在机器内或跨网络的工作。

更新: 要在两个UDP客户端之间通话,您需要设置两个免费的UDP端口,这两个端口都是客户端(本例全部在matlab中,假设obj在这里是一个结构,在我的情况下它是一个类环绕的原始神经外胚层肿瘤的功能):

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 
+0

哇,这是绝对真棒。你能告诉我,在哪里可以找到PNET库?似乎Mathworks在任何地方都没有整个工具箱,但一些非官方的工具箱已准备好加载......你能告诉我你正在使用哪一个吗? – poeschlorn 2011-03-01 07:27:41

+1

是的,我使用的是已经预编译好的pnet(对于Win,OS X和Linux),来自心理物理工具箱:[PTB](http://psychtoolbox.org/wikka.php?wakka=HomePage),你可以下载它并提取目录,或刮svn [这里](http://svn.berlios.de/wsvn/osxptb/trunk/Psychtoolbox/PsychHardware/iViewXToolbox/tcp_udp_ip/?#a92ec166f430377948ced499fe2456e27) - 工具箱本身被发现[ (http://www.mathworks.com/matlabcentral/fileexchange/345-tcpudpip-toolbox-2-0-6) - 你可以使用TCP(可靠性更高的开销)或UDP(无连接更快); UDP更容易设置。 – 2011-03-01 11:59:55

+1

注意,如果您有Instrument Control工具箱[此处有记录](http://www.mathworks.com/help/toolbox/instrument/f16-54297.html),则还可以在Matlab中直接使用UDP。我**更喜欢PNET,因为您不仅可以发送简单的数据类型,而且还可以发送matlab oop对象,否则这些对象几乎不可能通过网络进行序列化和发送(matlab本身的弱点)。还有一个matlab java接口替代PNET [here](http://www.mathworks.com/matlabcentral/fileexchange/24525-a-simple-udp-communications-application) – 2011-03-01 12:06:51

1

对不起,我没有足够的代表作出评论,所以我会在这里引用它:

@Adam利百特:谢谢,这是有道理的。我HABE麻烦的唯一的事情就是如何暂停(此复位后,然后恢复)脚本的时候它已经被运行开始=为PARAM ... 1 - poeschlorn 2月25日在7:17

如果你想一旦复位设置为1就跳出循环,然后等待循环再次继续一次run = 1,这几乎与刚刚重新开始一样?

function processRun() 
run = 1; 
while run ~= 1 
    run = doProcess(); 
end 

如果doProcess()回报0那么函数processRun()将结束(如行为,你想有复位时),下一次processRun把它叫做重新开始,以“重置” /默认值。

或者我错过了什么?

+0

如果你错过了什么,那我也是!我认为你在这里展示的是一个更加以Matlab为中心的代码方式,而不是我添加的功能。 – 2011-03-09 09:31:04

+0

嘿Juhl,你的代码是绝对清晰的,但我不相信你会解决我的问题。在这种情况下,doProcess()需要获取中止脚本或返回'0'的任何标准。这种情况必须来自外部来源。我的问题是如何访问外部中断。 – poeschlorn 2011-03-10 12:25:20