Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

USB Stick Detection

2020-09-10
2020-10-01
<< < 1 2 (Page 2 of 2)
  • Reinier Geers - 2020-09-24
    sUSB_STICK          :STRING := '/media/sda1';
    

    1: // check for USB Stick
    udiDirHandle := SysDirOpen(szDir:= sUSB_STICK, szDirEntry:= sDirEntry, diMaxDirEntry:= SIZEOF(sDirEntry),
    pDirInfo:= ADR(stDirInfo), pResult:= Fehler_Dir);
    b_Pugged:= udiDirHandle <> 16#FFFFFFFF; //Fehler_Dir = 0;
    udiCloseError := SysDirClose(hDir:= udiDirHandle);

     
  • Chris.O - 2020-09-24

    hmh I'm not sure if SysDirOpen function create his own file when the file is not there...

    Try CAA FIle library... I tried.. .it works!

    I programmed a quick and dirty solution for SD-Card and USB-Stick....may ther some bugs inside but it works

    code
    
    
    FUNCTION_BLOCK DetectUSB_SD_31
    VAR_INPUT
        xEnable: BOOL;
        tWaitTime:TIME:=T#1S;
    END_VAR
    VAR_OUTPUT
        xUSBisMounted: BOOL;
        xSDCardMounted: BOOL;
        sFilePathUSB:STRING;
        sFilePathSD:STRING;
    END_VAR
    VAR
        Open_Directory:File.DirOpen;
        xOpenDir: BOOL;
        sDirName: FILE.CAA.FILENAME:='/media';
        hHandle: FILE.CAA.HANDLE;
        eErrorOpen: FILE.ERROR;
        xBusyOpen: BOOL;
        xDoneOpen: BOOL;
        xErrorOpen: BOOL;
    
        List_Directory:File.DirList;
    
        xListDir: BOOL;
        xDoneList: BOOL;
        xBusyList: BOOL;
        eErrorList: FILE.ERROR;
        DirEntry: FILE.FILE_DIR_ENTRY;
        xErrorList:BOOL;
    
        DirClose:FILE.DirClose;
        xCloseDir: BOOL;
        xDoneClose: BOOL;
        xBusyClose: BOOL;
        xErrorClose: BOOL;
        eErrorClose: FILE.ERROR;
        xBusy: BOOL;
        xNewDetected: BOOL;
        xListDirStarted: BOOL;
        xNewDetectedUSB: BOOL;
    
        sDirUsb: STRING;
        sDirSD: STRING;
    
        xWait:BOOL;
        TP_Wait:TP;
    
    
    
    
    //If Detection is finished, wait till new detection starts
    TP_Wait(IN:=xWait, PT:=tWaitTime);
    xWait:=FALSE;
    
    
    IF xEnable AND NOT TP_Wait.Q THEN
        //Check if folders already are available
        IF NOT xListDirStarted THEN //Open directory as long as program does not search for SD-Card or USB-Stick folders
            xBusy:=TRUE;
            xOpenDir:=TRUE;
            Open_Directory(xExecute:=xOpenDir, sDirName:=sDirName, hDir=>hHandle, eError=>eErrorOpen, xBusy=>xBusyOpen, xDone=>xDoneOpen, xError=>xErrorOpen);
        END_IF
    
        IF xDoneOpen THEN //If Directory is opened, check content
            xListDirStarted:=TRUE;
            IF xListDir THEN //List_Directory must be executed 1 time for every entry iside the folder (till message no more entrys)
                xListDir:=FALSE;
            ELSIF NOT (eErrorList = 5106) THEN
                xListDir:=TRUE;
            END_IF
            List_Directory(xExecute:=xListDir, hDir:=hHandle, xDone=>xDoneList, xBusy=>xBusyList, xError=>xErrorList, eError=>eErrorList, deDirEntry=>DirEntry);
    
            //check if usb stick is mounted (will be mounted with sda, sda1 or sda2)
            IF (DirEntry.sEntry = 'sda') OR (DirEntry.sEntry = 'sda1') OR (DirEntry.sEntry = 'sda2') THEN 
                sDirUsb:=DirEntry.sEntry;
                xUSBisMounted:=TRUE;
                xNewDetectedUSB:=TRUE;      
            END_IF
    
            //check if sd card is mounted (will be mounted with sd)
            IF DirEntry.sEntry = 'sd' THEN
                sDirSD:='sd';
                xSDCardMounted:=TRUE;
                xNewDetected:=TRUE;
            END_IF
    
            //If no more entrys in folder /media available and no sd-card detected then no sd-card available
            IF (eErrorList = 5106) AND NOT xNewDetected THEN
                xSDCardMounted:=FALSE;
                sDirSD:='';
            END_IF
    
            //If no more entrys in folder /media available and no usb-stick detected then no usb-stick available
            IF (eErrorList = 5106) AND NOT xNewDetectedUSB THEN
                xUSBisMounted:=FALSE;
                sDirUSB:='';
            END_IF
    
            //If no more entrys in /media available then close directory and start again
            IF eErrorList = 5106 THEN
                xOpenDir:=FALSE;
                Open_Directory(xExecute:=FALSE);
                xListDir:=FALSE;
                DirClose(xExecute:=xCloseDir, hDir:=hHandle, xDone=>xDoneClose, xBusy=>xBusyClose, xError=>xErrorClose, eError=>eErrorClose);
                xNewDetected:=FALSE;
                xNewDetectedUSB:=FALSE;
                xListDirStarted:=FALSE;
                xBusy:=FALSE;
                xWait:=TRUE;
    
                IF sDirUSB <> '' THEN   
                    sFilePathUSB:=CONCAT(STR1:='/media/', STR2:=sDirUSB);
                END_IF
    
                IF sDirSD <> '' THEN
                    sFilePathSD:=CONCAT(STR1:='/media/', STR2:=sDirSD);
                END_IF
    
            END_IF
    
        END_IF
    
    END_IF
    
     
    • Morberis

      Morberis - 2020-09-25

      Hmmm. I'm testing it on an embedded windows PLC so I changed /media to /UsbStorage and changed it so that DirEntry.sEntry checks for 'System Volume Information' and it correctly detects whether there is a USB drive or not.

      However it seems to get stuck sometimes with DirOpen and doesn't reset if it hits an error.

       

      Last edit: Morberis 2020-09-25
  • Chris.O - 2020-09-29

    What Error is indicated? eErrorOpen should show some clear text.
    I think in principle is better to program a small state machine e.g. with case function.
    Than it's better to handle errors and so on.

     
  • Reinier Geers - 2020-09-29

    Isn't there a normal way to detect an USB stick ? If would expect that the hardware the stick detects and set a status .

     
  • Chris.O - 2020-09-29

    Inside Linux yes. You can see it with lsusb command.
    Inside CoDeSys I don't think that there is implemented something like this because this depends on the device.
    May your supplier of your sps has already a library for that.

    At the moment I'm trying to program code with "lsusb" to detect usb stick and sd-card.
    When I'm finished, I can share it if you want. (I think with lsusb is the safe way)

     
  • Chris.O - 2020-09-29

    I tested the following with a Linux-System. I used not lsusb but lsblk because I also want to see my sd-card.
    If you need you can additionally include then an error handling. May you can use this.

    code
    FUNCTION_BLOCK DetectUSB_SD_31
    VAR_INPUT
        xEnable: BOOL;
        tWaitTime:TIME:=T#1S;
    END_VAR
    VAR_OUTPUT
        xUSBisMounted: BOOL;
        xSDCardMounted: BOOL;
        sFilePathUSB:STRING;
        sFilePathSD:STRING;
    END_VAR
    VAR
        scmd:STRING:='lsusb | grep "Flash Drive"'; //for sd-Card = lsblk | grep "/media/sd" | grep -v "sda"
        sStdOut: STRING (1000);
        Result: SysProcess_Implementation.RTS_IEC_RESULT;
        iFindUSB: INT;
        xError: BOOL;
    
        xWait:BOOL;
        TP_Wait:TP;
    
        iState:INT:=10;
        iFindtemp1: INT;
        iFindtemp2: INT;
        iFindUsbPath: INT;
        iFindSD: INT;
        iRetry: INT;
    END_VAR
    
    //If Detection is finished, wait till new detection starts
    TP_Wait(IN:=xWait, PT:=tWaitTime);
    xWait:=FALSE;
    
    
    IF xEnable AND NOT TP_Wait.Q THEN
        CASE iState OF 
            10: //Cmd for USB-Stick mounted?
                scmd:= 'lsblk | grep "/media/sda" ; echo OK';(*'lsusb | grep "Flash Drive" ; echo OK';*) //echo ok must be done because when no string is at the output, this function get an error
                SysProcess.SysProcessExecuteCommand2(pszCommand:=scmd, pszStdOut:=sStdOut, udiStdOutLen:=SIZEOF(sStdOut), pResult:=ADR(Result));
                IF Result = 0 THEN
                    iState:=20;
                    xError:=FALSE;
                ELSE
                    xError:=TRUE;
                    sStdOut:='';
                    iState:=10;
                    iRetry:=iRetry+1;
                END_IF
    
                IF iRetry > 10 THEN
                    xError:=TRUE;
                    iState:=999;
                END_IF
    
            20: //Check return string. Is "/media/sda" inside the string? Min. 1 USB device mounted?
                IF sStdOut <> '' THEN
                    iFindUSB:=FIND(str1:=sStdOut, STR2:='/media/sda');(*iFindUSB:=FIND(str1:=sStdOut, STR2:='Flash Drive');*)
                    IF iFindUSB <> 0 THEN
                        xUSBisMounted:=TRUE;
                        iState:=30;
                    ELSE
                        xUSBisMounted:=FALSE;
                        iState:=30;
                    END_IF
                ELSE
                    xUSBisMounted:=FALSE;
                    iState:=30;
                END_IF
            30: // Check path of USB-Stick
                scmd:= 'lsblk | grep "/media/sda" ; echo OK';
                SysProcess.SysProcessExecuteCommand2(pszCommand:=scmd, pszStdOut:=sStdOut, udiStdOutLen:=SIZEOF(sStdOut), pResult:=ADR(Result));
    
                IF Result = 0 THEN
                    //Check if USB is mounted as sda or sda1 or sda2
                    iFindUsbPath:=FIND(STR1:=sStdOut, STR2:='/media/');
                    iFindtemp1:=FIND(STR1:=sStdOut, STR2:='sda1');
                    iFindtemp2:=FIND(STR1:=sStdOut, STR2:='sda2');
                    IF (iFindtemp1 <> 0) OR (iFindtemp2 <> 0) THEN
                        iFindUsbPath:=FIND(STR1:=sStdOut, STR2:='/media/');
                        //save USB-Path
                        sFilePathUSB:=MID(STR:=sStdOut, LEN:=11, POS:=iFindUsbPath);
                        iState:=40;
                    ELSE
                        //save USB-Path
                        sFilePathUSB:=MID(STR:=sStdOut, LEN:=10, POS:=iFindUsbPath);
                        iState:=40;
                    END_IF
                ELSE
                    xError:=TRUE;
                    sStdOut:='';
                    iState:=10;
                    iRetry:=iRetry+1;
                END_IF
    
                IF iRetry > 10 THEN
                    xError:=TRUE;
                    iState:=999;
                END_IF
    
            40: //cmd for SD-Card mounted
                scmd:= 'lsblk | grep "/media/sd" | grep -v "sda" ; echo OK';
                SysProcess.SysProcessExecuteCommand2(pszCommand:=scmd, pszStdOut:=sStdOut, udiStdOutLen:=SIZEOF(sStdOut), pResult:=ADR(Result));
                IF Result = 0 THEN
                    iState:=50;
                    xError:=FALSE;
                ELSE
                    xError:=TRUE;
                    sStdOut:='';
                    iState:=10;
                    iRetry:=iRetry+1;
                END_IF
    
                IF iRetry > 10 THEN
                    xError:=TRUE;
                    iState:=999;
                END_IF
    
            50: //Check return string. Is "/media/sd" inside the string? SD-card mounted?
                IF sStdOut <> '' THEN
                    iFindSD:=FIND(str1:=sStdOut, STR2:='/media/sd');
                    IF iFindSD <> 0 THEN
                        xSDCardMounted:=TRUE;
                        iState:=60;
                    ELSE
                        xSDCardMounted:=FALSE;
                        iState:=60;
                    END_IF
                ELSE
                    xSDCardMounted:=FALSE;
                    iState:=60;
                END_IF
    
            60: //Check path of SD-Card
                //Path is allways /medaia/sd
                IF xSDCardMounted THEN
                    sFilePathSD:='/media/sd';
                ELSE
                    sFilePathSD:='';
                END_IF
    
                iState:=100;
    
            100: //End
            iState:=10;
            xWait:=TRUE;
            iRetry:=0;
    
    
            999: //Error at writing command to linux console
            xWait:=TRUE;
            iState:=10;
            xSDCardMounted:=FALSE;
            xUSBisMounted:=FALSE;
            sFilePathSD:='';
            sFilePathUSB:='';
            iRetry:=0;
    
        END_CASE
    END_IF
    
     
    • Reinier Geers - 2020-09-29

      Thanks. But it looks like it doesn't know lsblk.

       
  • Morberis

    Morberis - 2020-09-29

    Sorry I can't believe that I didn't post that info.

    I've seen 2 errors
    5109 - wrong parameter
    5103 - invalid handle

    Your new code is using command prompt it seems? After talking with tech support I might not have equivalent commands available to me but they're going to get back to me on that.

    I'm using an Eaton XV303 and they do have a Library called EA_Service which looks like it might have some things that would work. For instance a Function called 'Service_GetUsbState' but it doesn't actually change when a usb device is present. Just it indicates whether the usb port has been enabled or disabled.

    I'll post back here when I have an answer.

     

    Last edit: Morberis 2020-09-29
  • Chris.O - 2020-09-30

    @ Reinier Geers: You Wrote:Thanks. But it looks like it doesn't know lsblk.

    Did you try the command directly inside a terminal e.g. Putty? If the command works there you should have a look if inside the CODESYSControl.cfg your command is allowed.
    Search at
    [SysProcess]
    Command=AllowAll

    or specific command:
    [SysProcess]
    Command.0=lsblk
    Command.1=echo

    @ Morberis:
    I think wrong parameter could be an error because of a wrong path. Invalid Parameter should then an error of DirList. DirOpen only creates an handle and DirList use this handle. But if you have a wrong path also the handle will be not valid.

    In my example above I added no error handling. You can add it on your own. May do the whole program with a state machine to be sure in which state you got the error.

    BTW I tried this with DirOpen and DirList on my SD-Card.. after a while it seems that the card is corrupted. Then the card needs to be formatted. May the command prompt is the better way.

    Hope this will help you.

    BR Chris

     

    Last edit: Chris.O 2020-09-30
    • Morberis

      Morberis - 2020-09-30

      Nah the path is definately correct. At least it's correct when the usb drive is inserted.

      For now I'm forgoing detection of a USB drive. If the copy operation fails or gets stuck that's all the feedback I need and it works consistently.

       
      • Chris.O - 2020-10-01

        If you need detection of USB drive I recommend to do it with the command lsblk (Like Reinier Geers) :-) It seems that it work very well.

         
        • Morberis

          Morberis - 2020-10-01

          I don't really need it thankfully. I do thank you for your help, as well everyone in this thread has been great. I'm just out of time for now.

           
<< < 1 2 (Page 2 of 2)

Log in to post a comment.