FB_FileOpen stays busy, Statemachine not working - TwinCat3

821 views Asked by At

i am trying to get into the beckhoff/twincat universe, therefore is was following along with some twincat tutorials. While programming a simple event-logger I encountered the following problem:

After executing FB_FileOpen, it´s bBusy variable stays True - therefore my statemachine won´t execute any further and is stuck in FILE_OPEN. Any idea, what I did wrong? Here is my code:

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

screenshot

2

There are 2 answers

3
nico25 On BEST ANSWER

I found the error. My mistake was, that I started the state machine with a positive edge from a start variable. Since I am running the task in a 1ms cycle, the whole thing would´ve needed to complete within 1ms then.

1
ziga On

The issue probably lies in how you call the function block. You need to make sure to call the function block with the input bExecute := FALSE and only after that calling it with bExecute := TRUE will trigger the function block execution. Caliing the fb with its "exectue" input to false after it has had the input triggered, will always work so just invert your order of TRUE and FALSE executes for all your states.

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

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

You could also follow the Beckhoff example provided on their website, not a fan of this, but calling the function block twice, back to back in a single PLC cycle :

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

Full example can be found here : https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclib_tc2_system/30977547.html&id=