1

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

nico25
  • 73
  • 6
  • Same question [here](https://stackoverflow.com/questions/51359582/twincat-3-block-stays-busy), but the solution there you did. You can try to copy that example to see if that runs for you. Did you get any error codes? It probably doesn't stay in `bBusy` forever. – Roald Apr 07 '22 at 06:14
  • No erros, it just stays in bBusy – nico25 Apr 07 '22 at 07:21
  • Are you calling your function block then? It is not possible that it stays in `bBusy`, unless you set `DEFAULT_ADS_TIMEOUT` to a very high value. The default timeout should be 5 seconds according to [this](https://infosys.beckhoff.com/content/1033/tf6100_tc3_opcua/537635979.html?id=2451162100290501637). – Roald Apr 07 '22 at 07:28
  • Something is not running correctly in your block. Are you sure there is not a method or something else that forces the states from the outside? It is peculiar, that FileOpen.bExecute=TRUE, while eWriteState=FILE_OPEN and this case explicitly sets bExecute=FALSE Does it do the same thing when inserting breakpoints and stepping through? – pboedker Apr 07 '22 at 07:33
  • Which POU are we looking at? Is it a body of a function block or a method? – Jacek Domański Apr 07 '22 at 09:49

2 Answers2

1

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=

ziga
  • 159
  • 1
  • 6
  • 1
    I tried inverting the trues and falses but had the same outcome with the behaviour of bBusy. Then I tried to but the execute := false in the declaration but that also didn´t work – nico25 Apr 07 '22 at 08:48
1

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.

nico25
  • 73
  • 6
  • 1
    OK, so what you're saying is that you only called this FB/code once, resulting in the online values shown (after only executing the TRIGGER_FILE_OPEN state once)? – pboedker Apr 07 '22 at 13:35
  • Exactly. Now i changed it to be called permanently and made the state machine stay in a certain step, where it waits for a new event to be written to the file. Now I´m stuck at writing a string to the file every 5 seconds, but that´s a different problem :D – nico25 Apr 08 '22 at 05:38
  • I stand corrected, not calling the function block prior to calling it for the first time with the input set to TRUE works (you learn something new every day). As for your new problem, I would suggest you just open the file and write data when required (instead of opening and closing it upon every new request). Another thing to keep in mind is the string size, if you are using longer strings make sure to set your variable type to `STRING(255);` otherwise you will be losing characters (happened to me when building the strings to be written exceeding the default size of 80 bytes) – ziga Apr 08 '22 at 10:25