read datafile and update variables with the data values

Oliver
2017-06-19
2017-07-07
  • Oliver - 2017-06-19

    Hello,
    I'm looking for a way to read continously a datafile and then actualize the value of some variables in codesys. At the moment I'm using a webvisu to enter new values with mouse and keyboard (which works well), but I'd like to have another program (LabVIEW) changing the values. This should be easiest way of exchanging data between LabVIEW for Raspberry and Codesys, but I can't find some example code nor any documentation about reading data from a file into Codesys.
    Anyone has got a hint for me?
    Thanks and have a nice start into this week!
    Oliver

    edit: OK I can add an external file...at the moment I don't find the option to link this option to a local file on the Raspberry...but this could be the solution, because my first requirement (read continosly) is met with the properties "remember the link, embed and reload file automatically after changes".

     
  • Oliver - 2017-06-21

    Hello,
    it seems that I can use this information here:
    l viewtopic.php?t=6712 l
    It still needs some work, but I think I'm on the good way.
    Greetings!
    Oliver

     
  • Oliver - 2017-06-22

    Hello again,
    the code seems to work, but I've got a file error that might be specific for Linux file access. I created a testfile on the desktop of the pi, specified the path as follows:
    /home/pi/Desktop/test.txt
    During the connection I get an error that AM_READ input of the function SysFileOpen "is not specified", which could be an error due to a missing file. However the filepath seems to be correct, because I can follow it in the filemanager of the Raspi. Could it be, that the codesys project doesn't have any access rights?

    Oliver

     
  • Oliver - 2017-06-26

    Hello,
    it seems that I can't manage to find the file in the codesys application. I tried now to set the file to different loactions (/home/pi/Desktop, /home/root/Desktop, /root/Desktop and /)with all access rights to anyone, but I get always an error in my File Handle function during the download of the application.

    Does anyone has got an example of SysFileOpen to a valid path on the Raspberry?

    I modified the code from the topic viewtopic.php?t=6712 the way, that it can find the SysFile library correctly. The according variables seem to be defined correctly:

    PROGRAM readfile
    VAR CONSTANT
       MAX_BUFFER : __XWORD := 999;
    END_VAR
    VAR_INPUT
       FileName : STRING := '/inifile_GEL6110_parameters.txt';
    END_VAR
    VAR_OUTPUT
       Done : BOOL := FALSE;
       ErrCode : Data_Server.SysFile.SYS_FILE_STATUS := Data_Server.SysFile.SYS_FILE_STATUS.FS_NO_FILE;
       //xy_data : ARRAY[0..MAX_BUFFER, 0..MAX_BUFFER] OF BYTE;
       BytesRead : __XWORD := 0;
    END_VAR
    VAR
       pResult : POINTER TO Data_Server.SysFile.RTS_IEC_RESULT;
        FileHandle : Data_Server.SysFile.RTS_IEC_HANDLE;
        pFileData : POINTER TO BYTE := ADR(GVL.xy_data);
    END_VAR
    //try to open file => HERE I get the error that "AM_READ is not defined" as soon as I download
    FileHandle := Data_Server.SysFile.SysFileOpen(szFile:= FileName, am:= AM_READ,  pResult:= pResult);
    //verify found a file
    IF FileHandle = Data_Server.SysFile.RTS_INVALID_HANDLE THEN
    //no file found
        ErrCode := Data_Server.SysFile.SYS_FILE_STATUS.FS_NO_FILE;
        Done := TRUE;
    ELSE
    //try to read file out
       BytesRead := Data_Server.SysFile.SysFileRead(hFile:=FileHandle, pbyBuffer:=pFileData, ulSize:=MAX_BUFFER, pResult:=pResult);
    //check if actually read any bytes
    IF BytesRead > 0 THEN
       ErrCode := Data_Server.SysFile.SYS_FILE_STATUS.FS_OK;
       ELSE
          ErrCode := Data_Server.SysFile.SYS_FILE_STATUS.FS_NO_FILE;
       END_IF
       Done := TRUE;
    END_IF
    //close file!!!!
    Data_Server.SysFile.SysFileClose(hFile:=FileHandle);
    

    Can anyone give me a hint?
    Greetings!
    Oliver

     
  • Lo5tNet - 2017-06-26

    Oliver,
    I'm not sure I follow 100% what you have going on here because I don't understand where the "Data_Server" namespace is coming from. Have you tried pointing to the access_mode enum for AM_READ? "Data_Server.SysFile.AM_READ".

    Just a guess based off the error "AM_READ is not defined" you say you are getting.

     
  • Oliver - 2017-06-27

    @ Comingback4u:
    thank you very much for your guess that hits 100%! A missing pointer in the variable declaration section to Data_Server.SysFile.AM_READ solved my problem.

    Now I can access the data file in my codesys application. There is only a little issue remaining, that I want to read signed integer values out of a textfile into my array (GVL)...I'll search for examples

    The namespace "Data_Server" was given that way by the library "Data Server, 3.5.2.0". I didn't change it that way

    However, now I can already modify the textfile on the Raspberry and I read directly the modifications into my application, that sets a variable. That would be the base feature of my data exchange from LabVIEW to codesys.

    Thanks and have a nice day!
    Oliver

     
  • Lo5tNet - 2017-06-27

    Glad that worked. If you can't find an example post a quick idea of what it is you are trying to accomplish and I bet someone will know how.

     
  • Oliver - 2017-07-06

    hello again,
    many thanks for your help and I'm glad to find good ideas and examples here in the forum. However, I'm a bit spoiled by the graphical programming in LabVIEW...I can see here that must be a lot of code behind such simple string treatment functions like "find / replace all" or the numerous format transformation functions in LabVIEW.
    For my Codesys application, I found a simple but not the most elegant solution with 4 separate parameter files for 4 values instead of one single file and an array of values. With the STRING_TO_DINT function, I can transform the number from the string easily into a signed intereger, that I need to set my position and motor speed...not elegant is, that I have now 4 times more repeating code lines and 4 variables instead of one. But it works really fine. I can set a new positon of my x-y-drive simply by changing the value in the text file...and that's what my LabVIEW application is going to do in the next step. I have to combine parameters from different sources (measurement network with different dataloggers and weather forecast), in order to determine the right time and position for my x-y drive.
    Greetings!
    Oliver

     
  • Lo5tNet - 2017-07-07

    Oliver,
    I'm not sure if you are asking anything here but you have more options that you can work with. The two options I can think of are:
    1. Turn how you are getting your DINT value back into a function. You could pass in the file location/name as a string and your return could be the DINT value pulled from the file. You would then call this function for each file you are needing to read from. This would essentially be doing the same thing you are doing but in a much cleaner fashion which will make it easier to manage down the road.
    2. You could put all 4 values into one file and read each value. This will all depend on how you structure your file. For example if you separate the value by a ";" then you could put this in a loop something like:
    Sudo and not tested code

    iValue[iCount] := LEFT(buffer, FIND(buffer, ';') - 1);
    buffer := RIGHT(buffer, LEN(buffer) - FIND(buffer, ';'));
    

    You would tell the loop to run until buffer size is 0. iCount would be iterating as you go through your loop. This would only work if your buffer is smaller than 256 as the function LEFT, FIND, RIGHT will only do it for the default string size of 255. If you need a larger buffer you would need to use the string.util library or the string libraries from OSCAT.

     

Log in to post a comment.