USB Stick Detection

2020-09-10
43 minutes ago
1 2 > >> (Page 1 of 2)
  • Reinier Geers

    Reinier Geers - 2020-09-10

    How can i detect that there is an USB Stick ? With windows is read the directory. But now they changed to LINUX. That doesn't work that way.

     
  • Chris.O

    Chris.O - 2020-09-23

    Hi,... quick and dirty... maybe something like this

    code
    
    VAR_INPUT
        xEnable: BOOL;
    END_VAR
    VAR_OUTPUT
        xUSBisMounted: BOOL;
    END_VAR
    VAR
        scmd:STRING:='lsusb';
        sStdOut: STRING (1000);
        Result: SysProcess_Implementation.RTS_IEC_RESULT;
        iFindUSB: INT;
        xError: BOOL;
    END_VAR
    
    IF xEnable THEN
    
        SysProcess.SysProcessExecuteCommand2(pszCommand:=scmd, pszStdOut:=sStdOut, udiStdOutLen:=SIZEOF(sStdOut), pResult:=ADR(Result));
    
    
            //Check if min. 1 USB device is mounted
            IF sStdOut <> 'Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub$NBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub$N' THEN
                iFindUSB:=FIND(str1:=sStdOut, STR2:='Flash Drive');
                IF iFindUSB <> 0 THEN
                    xUSBisMounted:=TRUE;
                ELSE
                    xUSBisMounted:=FALSE;
                END_IF
            ELSE
                xUSBisMounted:=FALSE;
            END_IF
    
            IF Result <> 0 THEN
                xError:=TRUE;
                sStdOut:='';
            ELSE
                xError:=FALSE;
            END_IF
     END_IF
    
     
    👍
    1

    Last edit: Chris.O 2020-09-23
    • nothinrandom

      nothinrandom - 6 days ago

      I would recommend just process everything via SysProcessExecuteCommand2, so you don't need to do post processing in CoDeSys. Example command could be something like this to exclude "Linux Foundation" and include "Flash Drive":

      scmd:STRING:='lsusb | grep -v "Linux Foundation" | grep "Flash Drive"';

       
    • Reinier Geers

      Reinier Geers - 6 days ago

      Thanks. i will try it.

       
    • Reinier Geers

      Reinier Geers - 15 hours ago

      Thats working. But not every stick responce with :"Flash Drive"

       
    • Reinier Geers

      Reinier Geers - 3 hours ago

      Im testing it. but its one long string. So i tried to set it to an array. But commands like LEFT en RIGHT are limmited to 255. is there an other way ?

       
      • Chris.O

        Chris.O - 2 hours ago

        What do you mean with long string? If you use the "grep" parameter it should't be so long.
        If string is longer than may try to delete the first part of the string which you do not need...
        Or you try to program your own String functions ;-)

         
        • Reinier Geers

          Reinier Geers - 2 hours ago

          sStdOut is 1000. So to long for LEFT or RIGHT. Limits from codesys.
          I try Everythink. Also Lookt for an Linux Cource. But a Cource would help me at the moment.

           
          • Chris.O

            Chris.O - 2 hours ago

            You can also limit sStdOut to 255.
            If you use
            'lsblk | grep "/media/sda" ; echo OK';

            you should get a string with something like that:
            └─sda1 8:1 1 14.7G 0 part /media/sda1
            OK

            This would be a string with 51 Characters... so no problem

            If you use LEFT / RIGHT / MID with a String (1000) I think it will only use the fist 255 characters... so should also work.

             
            • Reinier Geers

              Reinier Geers - 2 hours ago

              LSblk gives only OK$N with or without an stick.

               
              • Chris.O

                Chris.O - 2 hours ago

                Can you try the command inside a terminal like putty?
                What result is there?
                And If you try only lsblk? Is there nothing... or what is the return from linux?

                 

                Last edit: Chris.O 2 hours ago
                • Reinier Geers

                  Reinier Geers - 2 hours ago

                  Never used putty. i look into it. I tried to shut down codesys to get to linux. But that doesn't work the way like in Windows.

                   
                  • Chris.O

                    Chris.O - 2 hours ago

                    OK, then may install putty to your desktop-pc and connect your sps to your desktop pc... with putty you will get connection to your sps (with the ip-adress) then you can log in with user and password (e.g. user = root and PW = root or something like this). THen please try your command lsblk

                     
                    • Reinier Geers

                      Reinier Geers - 52 minutes ago

                      putty gives : -sh: lsblk: command not found

                       
                      • Chris.O

                        Chris.O - 43 minutes ago

                        Ok.... may command df -h is working?

                        Should give you something like this:
                        Filesystem Size Used Avail Use% Mounted on
                        udev 1.9G 0 1.9G 0% /dev
                        tmpfs 383M 5.9M 377M 2% /run
                        /dev/mmcblk0p2 27G 5.5G 20G 23% /
                        tmpfs 1.9G 1.5M 1.9G 1% /dev/shm
                        tmpfs 5.0M 0 5.0M 0% /run/lock
                        tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
                        tmpfs 70M 360K 70M 1% /var/log
                        /dev/mmcblk0p1 511M 5.1M 506M 1% /boot/efi
                        /dev/mmcblk1 30G 43M 29G 1% /media/sd
                        tmpfs 383M 0 383M 0% /run/user/0
                        none 120M 40K 120M 1% /mnt/ramdisk
                        /dev/sda 16G 4.8G 11G 32% /media/sda

                        In my case here /dev/mmcblk1 is my sd-card (mounted at /media/sd
                        and /dev/sda is my usb-stick (mounted at /medai/sda)

                        with command df -h grep /media/sda
                        you should get
                        Filesystem Size Used Avail Use% Mounted on
                        /dev/sda 16G 4.8G 11G 32% /media/sda

                        THis are 96 characters and you can search for /media/sda...or your usb-directory

                         
  • nothinrandom

    nothinrandom - 2020-09-17

    Are you planning to do anything with the USB drive (i.e. read/write to it)? Just to list usb devices, you just need to run command lsusb. To read/write from it, I would recommend that you set up partition automount so that it will appear automatically after reboot/startup. I am not sure of your experience with Linux, so more information is needed.

     
    • Reinier Geers

      Reinier Geers - 6 days ago

      I dont know nothing about Linux. Thats the problem. They changed from Windows CE to Linux. Most of it is working. But if i read a directory its not up to date. Pull out the stick. Then read the stick. it still shows a directory !!

       
  • Reinier Geers

    Reinier Geers - 2020-09-18

    Isusb ?? is that a codesys command ? I programm Codesys. Than i want to detect if there's a stick inserted. Ive there it should show the directory. But somehowe linux is not up to date. If i read a directory. then pul out the stick. Then read the diretory. It still shows the directory even if the stick is pulled out.

     
  • Chris.O

    Chris.O - 6 days ago

    Alternative way would be to detect the mounted folder of the usb-Stick.
    In my case the linux system mount the usb-stick with "sda" inside the folder /media.
    Means my path would be "/media/sda".

    Then may be something like this: (In the programming part I think best would be a state machine)

    code
    
    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;
    END_VAR
    
    //First open the directory "/media"
    Open_Directory(xExecute:=xOpenDir, sDirName:=sDirName, hDir=>hHandle, eError=>eErrorOpen, xBusy=>xBusyOpen, xDone=>xDoneOpen, xError=>xErrorOpen);
    
    //If directory is opened, check what folders are inside (note that DirList ned rising edge for every folder)
    List_Directory(xExecute:=xListDir, hDir:=hHandle, xDone=>xDoneList, xBusy=>xBusyList, xError=>xErrorList, eError=>eErrorList, deDirEntry=>DirEntry);
    
    //Then you need programming part where you search for the string "sda" or "sda1"... depending on your stick
    //If you found it, stick is plugged. If you unplug your stick, usually linux will delete the folder "sda" or "sda1"
    
    //At the end close the directory
    DirClose(xExecute:=xCloseDir, hDir:=hHandle, xDone=>xDoneClose, xBusy=>xBusyClose, xError=>xErrorClose, eError=>eErrorClose);
    

    Only an idea :-)

     
    • Reinier Geers

      Reinier Geers - 6 days ago

      Thats the way i did it. open the director. If its shows an Error, then there is no stick. But the problem is . if i read a directory its not up to date. Pull out the stick. Then read the stick. it still shows a directory !!

       
  • Chris.O

    Chris.O - 6 days ago

    Can you post your code?

     
    • Reinier Geers

      Reinier Geers - 6 days ago
      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

    Chris.O - 6 days ago

    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 - 5 days ago

      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 4 days ago
  • Chris.O

    Chris.O - 1 day ago

    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.

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.