Skip to content

Open and write into TXT File

edited August 2020 in PLCnext Engineer

Hi Team,

 

We have the controller AXC F 1152 with a little program.

Now we want to write a little error log into a text file.

I need some help how I can write the code therefore.

Maybe someone was creating something like this before and can give some tipps.

Thanks & BR

Bodo

 

Comments

  • Hi Bodo,

    Here is an example of how to write text to a file in in PLCnext Engineer.

    https://www.plcnext-community.net/en/discussions-2-offcanvas/example-for-saving-data-in-a-file.html

    The example uses Structured Text, but you can use the same FBs in other IEC 61131 languages, if you want.

    Hope this helps.

    ~ Martin.

  • Hi Martin,

     

    what a great and very fast solution.

    I've tried the code and it works fine. :)

    I have an other question. It is possible to write the file on a local PC System or maybe on file server?

     

    BR

    Bodo

  • Hi Bodo,

    I don't think there is a standard solution to this problem from PLCnext Engineer on its own, but this could probably be achieved using standard Linux utilities.

    Possibilites include:

    • Using rsync to copy the contents of local file(s) to a remote machine.
    • Using syslog-ng for decentralised system logging.
    • Using a cloud service to log messages (via MQTT, for example).
    • Looking for solutions from vendors in the PLCnext Store.

    You should be able to try most options on a standard Linux system, and once you have a solution working the way you want, you can try porting that solution to the PLCnext Control.

    Hope this helps.

    ~ Martin.

  • Hi Martin,

    Thanks again for your support.

    I have a last question fot this topic.

    How can collect a String ('hello World') with the actual date?

    Do you have an idea.

    BR

    Andy

  • Hi Andy,

    There is a function block called "RTC_S" that retrieves the current date and time as a string.

    ~ Martin.

  • Hi Martin,

    I have a last question (hope so).

    In your example : https://www.plcnext-community.net/en/discussions-2-offcanvas/example-for-saving-data-in-a-file.html

    I work with a ByteArray35 and if I understand right, that means no more characters like 34.

    Now I need the oppertunity for more characters - is this possible?

    Thanks

    Andy

  • Hi Andy,

    I only used ByteArray35 in that example because that was already a defined data type in PLCnext Engineer. But you can use a byte array of any length. To do that:

    • In a DataType worksheet, create a new data type as a byte array of any fixed length (the declaration templates - accessible using right-click - are handy for this).
    • In your program, declare a variable of that type, instead of type ByteArray35.

    Hope this helps.

    ~ Martin.

  • Hi Martin,

    sounds good, but I need more help.

    Did you have a short example for me?

    Thanks a lot for your support.

    BR
    Andy

  • Hi Andy,

    Hope this helps.



    (video has no sound)

    Note that the array actually contains 421 elements (0 to 420), so I could have called it ByteArray421, or else declared the array bounds as either [0 .. 419] or [1 .. 420]. 

    ~ Martin.

  • Hi Martin,

    That's great - it works fine. ?

    Thank you so much for your help.

    BR
    Andy

  • Hi Martin,

    Can I get that sample code? I want to do test with PLCnext 2152. Thank you,

    Jacob
  • Hi Jacob, unfortunately this new forum has broken all the links to old threads, and deleted all the attachments on those old threads.
    For the record, here is the new link to the old thread mentioned above:
    https://www.plcnext-community.net/forum/#/discussion/1446/example-for-saving-data-in-a-file
    ... but of course since the attachments are gone, that doesn't help.
    On Monday I will see if the site admins can restore the old attachments, otherwise I will try to recreate the example.
  • edited November 2021
    OK, the admins are looking at the option of restoring images in old forum posts.

    Here are the details of the earlier example, which writes a string to a text file on the PLC's file system:

    Program variables:
    // Name         Type
    FILE_OPEN1      FILE_OPEN
    STRING_TO_BUF1  STRING_TO_BUF
    FILE_WRITE1     FILE_WRITE
    FILE_CLOSE1     FILE_CLOSE
    OpenCommand     BOOL
    CreateByteArray BOOL
    WriteCommand    BOOL
    CloseCommand    BOOL
    FileHandle      UINT
    StringToWrite   STRING
    NumChars        INT
    CharsToWrite    ByteArray35
    

    Program code:
    // Here is the string we will write to file.
    StringToWrite := 'hello world';
    NumChars := LEN(StringToWrite);
    
    // Go online, open this program instance and 
    // set OpenCommand to TRUE.
    // This will open the file.
    FILE_OPEN1(
      Execute := OpenCommand,
      Name := '/opt/plcnext/my-file.txt',
      Done => CreateByteArray,  // Immediately create the byte array when the OPEN command is finished.
      Handle => FileHandle      // We need the file handle for other operations on this file.
    );
    
    // Convert the string to an array of bytes
    STRING_TO_BUF1(
      REQ := CreateByteArray,
      BUF_CNT := NumChars,
      DONE => WriteCommand,  // Immediately set WriteCommand when the buffer is ready.
      SRC := StringToWrite,
      BUFFER := CharsToWrite
    );
    
    // Add CR LF to the end of the string, just for the craic.
    CharsToWrite[NumChars] := BYTE#16#D;    // CR = 0x0D
    CharsToWrite[NumChars+1] := BYTE#16#A;  // LF = 0x0A
    
    // Write the array of bytes to file
    FILE_WRITE1(
      Execute := WriteCommand,
      Handle := FileHandle,
      Done => CloseCommand,   // Immediately set CloseCommand when the file write is finished.
      Buffer := CharsToWrite,
      Length := NumChars + 2  // Remember CR LF !
    );
    
    // Close the file
    FILE_CLOSE1(
      Execute := CloseCommand,
      Handle := FileHandle
    );
    
    // Now use ssh (or PuTTY) to check that the file has been created, and that it contains the expected text.
    
  • Hi Martin,
    I found "Data Logger" library on PLCnext store and it's working well. Also I tested the example code. Thank you,

    Jacob
  • Great, thanks for the feedback.
    If you're interested in the Datalogger library, you might also want to look at:
    - Simple Logger, which (as the name suggests) is a simpler version of the DataLogger library.
    - The built-in DataLogger, which stores data in a SQLite database rather than a text file.

    These are each useful for different scenarios, so hopefully one suits your project.
    -
  • How can i test the programm with putty? what is the needed configuration?

    Thank you.

  • file path '/opt/plcnext/my-file.txt'  can be changed or not?                      
    


  • Yes, the NAME parameter on the FILE_OPEN function block takes a STRING as a parameter, and this can be a literal or a variable.


  • (better late than never?)

    In the window shown in the screen shot, just enter the IP address of the PLC, and press the "Open" button. It should ask for the username and password, which are the same as the ones you used to send the PLCnext Engineer project to the PLC.

  • so ByteArray35 is a specific arbitrarily pre-defined array ?

    I haven't yet figured out how to declare arrays in general such as INT(2) WORD(5) etc...

    Does one require a secret incantation ? ;-)

    Is it correct to assume that a STRING is a byte array with the first element containing the string length ?

    I believe BASIC strings are like this

    And when the STRING_TO_BUF is executed, is the result a null-terminated "unix" string ?

    or an open-ended byte-array which requires the length to be specified in an external variable ?

  • Oh... I meant to also inquire about the mechanism of multiple sequential file writes...

    On the other platform I am familiar with, the actual WRITE command must be always executed

    and an ENABLE boolean controls the actual operation...

    To write multiple files sequentially, one had to one had to monitor the status of the currently active

    write command, and when it had completed, then disable that write command and enable the next one

    and sequentiallly propagate the enables while checking the statuses

    Is there an equivalent paradigm here ?

    One must create one write "package"/program for each filename and then juggle the enables ?

  • dwidwi
    edited January 30

    Hello Martin,

    I also tested your code, and it worked. However, I need to write multiple strings to the file for my application. Unfortunately, this hasn't worked as expected—only the first string is being written to the file.

    Here is the code I have so far. The StringsToSave[] array is already populated beforehand:

    // Datei öffnen

    FILE_OPEN(

        Execute := OpenCommand,

        Name := '/opt/plcnext/my-file.txt', // Pfad zur Datei

        Done => str_to_buf,

        Handle => FileHandle);


    // Strings in einer Schleife schreiben

    FOR i := 1 TO NumStrings DO

    // Länge des Strings ermitteln

        NumChars := LEN(StringsToSave[i]);


    // String in den Puffer umwandeln

        STRING_TO_BUF(

            REQ := str_to_buf,

            SRC := StringsToSave[i],

            BUF_CNT := NumChars,

            DONE => WriteCommand,

            BUFFER := CharsToWrite);


    // CRLF hinzufügen

        CharsToWrite[NumChars] := 16#0D; // CR

        CharsToWrite[NumChars + 1] := 16#0A; // LF


    // In die Datei schreiben

        FILE_WRITE(

            Execute := WriteCommand,

            Handle := FileHandle,

            Buffer := CharsToWrite,

            Done => write_done,

            Length := NumChars + 2); // Stringlänge + CRLF

    END_FOR


    // Datei schliessen

    FILE_CLOSE(

        Execute := CloseCommand,

        Handle := FileHandle,

        Done => file_closed);


     

  • Hello dwi,

    please try to combine the strings of the array with CONCAT blocks into one.

    The write commands may be sent faster than the Linux system can / may react.

  • Hello Tim,

    Thanks for your quick reply!

    I tried it with the concat block and it worked. 

    Thank you very much for your help!

    David

Sign In or Register to comment.