FB_FileOpen 保持忙碌,状态机不工作 - TwinCat3

问题描述 投票:0回答:3

我正在尝试进入 Beckhoff/Twincat 宇宙,因此正在遵循一些 twincat 教程。在编写一个简单的事件记录器时,我遇到了以下问题:

执行 FB_FileOpen 后,bBusy 变量保持 True - 因此我的状态机不会进一步执行并卡在 FILE_OPEN 中。知道吗,我做错了什么?这是我的代码:

VAR
    
FileOpen : FB_FileOpen := (sPathName := 'C:\Events-log.txt', nMode := FOPEN_MODEAPPEND OR FOPEN_MODETEXT);
FileClose :FB_FileClose;
FilePuts : FB_FilePuts;
stEventWrittenToFile : ST_Event;
CsvString : T_MaxString;

eWriteState :(TRIGGER_FILE_OPEN, FILE_OPEN, WAIT_FOR_EVENT,TRIGGER_WRITE_EVENT, WRITE_EVENT, FILE_CLOSE, ERROR);

END_VAR


CASE eWriteState OF 

    TRIGGER_FILE_OPEN : 
        FileOpen(bExecute := TRUE); 
        eWriteState := FILE_OPEN;
        

    FILE_OPEN :
            
        FileOpen(bExecute := FALSE);
        IF FileOpen.bError THEN
            eWriteState := ERROR;
        ELSIF NOT FileOpen.bBusy AND FileOpen.hFile <> 0 THEN
            eWriteState := WAIT_FOR_EVENT;
        END_IF
            
    WAIT_FOR_EVENT :

        //Do nothing, triggered externally by method
        
    TRIGGER_WRITE_EVENT :
            CsvString := ConvertStructureToString(stEvent := stEventWrittenToFile); 
            FilePuts(   sLine:= CsvString,
                        hFile := FileOpen.hFile,
                                bExecute := TRUE,); 
            eWriteState := WRITE_EVENT;
        
    WRITE_EVENT : 
        FilePuts(bExecute := FALSE);
        IF FilePuts.bError THEN
            eWriteState := ERROR;
        ELSIF NOT FilePuts.bBusy THEN
            eWriteState := FILE_CLOSE;
        END_IF
    

    FILE_CLOSE :
        FileClose(  hFile := FileOpen.hFile,
                    bExecute := TRUE);
        IF FileClose.bError = TRUE THEN
            FileClose.bExecute := FALSE;
            eWriteState := ERROR;
        ELSIF NOT FileClose.bBusy THEN
            FileClose.bExecute := FALSE;
            eWriteState := TRIGGER_FILE_OPEN;
        END_IF          
    
    ERROR : // Do nothing





END_CASE

plc twincat st structured-text
3个回答
1
投票

问题可能在于如何调用功能块。您需要确保使用输入 bExecute := FALSE 调用功能块,并且只有在使用 bExecute := TRUE 调用它之后才会触发功能块执行。将 fb 的“exectue”输入设置为 false after 它已触发输入,将始终有效,因此只需反转所有状态的 TRUE 和 FALSE 执行顺序即可。

TRIGGER_FILE_OPEN:
    fileOpen(bExecute := FALSE);
    eWriteState := FILE_OPEN;

FILE_OPEN:
    fileOpen(bExecute := TRUE);
...

您也可以按照他们网站上提供的 Beckhoff 示例进行操作,但不喜欢此示例,而是在单个 PLC 周期中连续调用该功能块两次:

  (* Open source file *) 
          fbFileOpen( bExecute := FALSE ); 
          fbFileOpen( sNetId := sSrcNetId, 
                      sPathName := sSrcPathName, 
                      nMode := FOPEN_MODEREAD OR FOPEN_MODEBINARY, 
                      ePath := PATH_GENERIC, 
                      tTimeout := tTimeOut, 
                      bExecute := TRUE ); 

完整示例可在此处找到:https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclib_tc2_system/30977547.html&id=


1
投票

我发现了错误。 我的错误是,我从起始变量的上升沿启动了状态机。由于我以 1 毫秒为周期运行任务,因此整个任务需要在 1 毫秒内完成。


0
投票

您能分享一下您的代码吗?我没有得到你的答复。

© www.soinside.com 2019 - 2024. All rights reserved.