Lean MES Open Source Manufacturing Execution System
Flexible Manufacturing Solutions through Open Standards and Free Software....

Balogh BIET-170 Communication Driver for OPTO22 PAC


Implements Read/Write/Fill BIET-170 commands for 1 channel over Ethernet TCP/IP.
Stable active production confirmed on: SNAP-PAC-R2, S1 (Rev.8.4a); LCE, ADS, M64 (Rev.7.2h).

Deployment/Test Instructions:
1. BIET-170 IP and PAC IP are configured ,preferably, on the same subnet. Both devices connected to the same physical network. (Removes unnecessary routing and reduce risk of failure).
2. Verify and update/set RFID unit configuration to use Ethernet TCP/IP communication protocol.
3. Download the ctEth_BaloghBIET170_RFIDxx.zip and extract files.
4. Copy and include files from extracted .\subroutines folder to strategy's subroutines folder
5. Import the extracted ctEth_BaloghBIET170_RFIDxx.cxf into strategy
   (Note! all tags are going to maintain their generic template names,
    for replication and reuse technique in PAC Control click here coming soon...).
6. Update chRFID01_tcp tag in PAC Control Communication Handles to have valid IP address, keep port 2001.
7. Compile strategy, load to PAC and click the Run Strategy button.
8. Run the driver flow(chart).
Verify nRFIDxx_CommSts ==1 (established).
9. To write; Apply desired value to  sRFIDxx_Tag_io, then apply value WRITE to sRFIDxx_CMD.
10. To read; Apply nr. of characters to read from PUCK memory to nRFIDxx_MemAddr, apply value READ to sRFIDxx_CMD.




//*****************************************************************************************
//BALOGH Biet-170 Ethernet Protocol Communication Driver for OPTO22 PACs
//Driver Chart
//Copyright (C) 2010  Peter Tiagunov peter.tiagunov@leanmes.net

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//--control scan/reconnect rate--------------------------
if(nRFIDxx_CommSts==0)then
    nRFIDxx_ScanRate=10000; //reconnect every 10 sec.
elseif(nRFIDxx_CommSts and nRFIDxx_ScanRate>=5000)then
    nRFIDxx_ScanRate=50; //set normal scan rate once
endif

//--keepalive timer-------------------------------
if (HasDownTimerExpired(tdRFIDxx_KeepAlive)) then
    if(nRFIDxx_CommSts==1)then
        nRFIDxx_keepalive=1;
    elseif(nRFIDxx_CommSts==0)then
        if(IsCommunicationOpen(chRFIDxx_tcp))then
            if(CloseCommunication(chRFIDxx_tcp)==0)then endif
        endif
        nRFIDxx_keepalive=-1;
    endif
    SetDownTimerPreset(20.0,tdRFIDxx_KeepAlive);
    StartTimer(tdRFIDxx_KeepAlive);
endif

if(srBIET170( chRFIDxx_tcp,        //  > in BIET communication handle
              1,                   //  > in R/W channel nr (1 or 2)
              100,                 //  > in command timeout, ms (resolution 10ms).
              nRFIDxx_keepalive,   //  <>io keepalive (1 -request, 0 -reset, -1 -initialize)
              sRFIDxx_CMD,         //  > in transmit Command Code
              sRFIDxx_Rx,          //  < out copy of receive buffer
              sRFIDxx_Tx,          //  < out copy of send buffer
              sRFIDxx_Tag_io,      //  <>io R/W TAG data 256 bytes
              nRFIDxx_MemAddr,     //  > in R/W TAG memory start address
              nRFIDxx_Length,      //  > in R   number of bytes to read from TAG memory
              nRFIDxx_CommSts,     //  < out communication status 1-on, 0-off
              nRFIDxx_error        //  < out error code
         )==0)then
endif

//--error log--------------------------------------------------------------------------------------------------------------
if(nRFIDxx_error<>0)then
    DateToStringDDMMYYYY(sDate);
    TimeToString(sTime);
    NumberToString(nRFIDxx_error,stRFIDxx_ErorLog[nRFIDxx_index]);
    stRFIDxx_ErorLog[nRFIDxx_index]=stRFIDxx_ErorLog[nRFIDxx_index]+"["+sDate+"-"+sTime+"] Rx:"+sRFIDxx_Rx+" Tx: "+sRFIDxx_Tx+" CMD: "+sRFIDxx_CMD;
    if(nRFIDxx_index==15)then
        nRFIDxx_index=0;
    else
        nRFIDxx_index=nRFIDxx_index+1;
    endif
endif

DelayMsec(nRFIDxx_ScanRate);





//******************************************************************************
//BALOGH Biet-170 Ethernet Protocol Communication Driver for OPTO22 PACs
//Subroutine srBIET170
//Copyright (C) 2010  Peter Tiagunov peter.tiagunov@leanmes.net

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

//--set channel-------------------------------------------------------
if(in_channel==1)then
    sChannel=Chr(0)+Chr(1);//00h 01h
elseif(in_channel==2)then
    sChannel=Chr(0)+Chr(2);//00h 02h
else
    //invalid channel
endif

//close active socket if error or initialization ---------------------
if(out_error>0 or in_CMD=="RESET")then
    if(IsCommunicationOpen(in_ch))then
        ClearCommunicationReceiveBuffer(in_ch);
        n32CommSts=CloseCommunication(in_ch);
        if(n32CommSts<>0)then
            out_error=7809;//close socket error
        endif
    endif
    in_CMD    ="";
    out_Rx    ="";
    out_Tx    ="";
    //io_data   ="";
    in_length =0;
    in_address=0;
    out_sts   =0;//communication lost
endif

//if communication closed then open communication --------------------
if(not(IsCommunicationOpen(in_ch)))then
    n32CommSts=OpenOutgoingCommunication(in_ch);
    if(n32CommSts==0 or n32CommSts==-47)then //socket created
        ClearCommunicationReceiveBuffer(in_ch);
        //====== 2009-09-21 ======>
        n32CommSts=SendCommunicationHandleCommand(in_ch, "set.to:1.0");
        if(n32CommSts==0)then
            out_error=0;
            //out_sts=1;//communication etablished
            io_keepalive=-1;//initialize keepalive
        else
            out_error=7812;//set socket timeout error
        endif
        //====== 2009-09-21 ======<
    else
        out_error=7800;//create socket error
    endif
endif

//--prepare parameters, when needed--------------------------------------------------------------------------------
if(not(IsCommunicationOpen(in_ch)) or out_error>0 or io_keepalive or GetStringLength(in_CMD)>0 and in_length>0)then
    //-- set address ----------------------------------------------------------------------------------------------
    NumberToHexString(in_address,sAddress);//get hex value of address integer (example: 10 -> A)
    //left pad sAddress with "0"'s (16-bit format), example: 1 - 0001 or 800 - 0800 or F0A - 0F0A...etc.
    if(GetStringLength(sAddress)<4)then
        while(GetStringLength(sAddress)<4)
            sAddress="0"+sAddress;
        wend
    endif
    //extract HI byte from a 16-bit value of sAddress, example: 08F0 - 08
    GetSubstring(sAddress, 0, 2, sByteHI); //high byte
    //extract LO byte from a 16-bit value of sAddress, example: 08F0 - F0
    GetSubstring(sAddress, 2, 2, sByteLO); //low byte
    sAddress=Chr(HexStringToNumber(sByteHI))+Chr(HexStringToNumber(sByteLO));

    //-- set length -------------------------------------------------------------------------------------
    NumberToHexString(in_length,sLength);//get hex value of address integer (example: 10 -> A)
    //left pad sAddress with "0"'s (16-bit format), example: 1 - 0001 or 800 - 0800 or F0A - 0F0A...etc.
    if(GetStringLength(sLength)<4)then
        while(GetStringLength(sLength)<4)
            sLength="0"+sLength;
        wend
    endif
    //extract HI byte from a 16-bit value of sLength, example: 08F0 - 08
    GetSubstring(sLength, 0, 2, sByteHI); //high byte
    //extract LO byte from a 16-bit value of sLength, example: 08F0 - F0
    GetSubstring(sLength, 2, 2, sByteLO); //low byte
    sLength=Chr(HexStringToNumber(sByteHI))+Chr(HexStringToNumber(sByteLO));

    //-- set timeout ------------------------------------------------------------------------------------
    NumberToHexString((in_timeout/10),sTimeout);//get hex value of address integer (example: 10 -> A)
    //left pad sAddress with "0"'s (16-bit format), example: 1 - 0001 or 800 - 0800 or F0A - 0F0A...etc.
    if(GetStringLength(sTimeout)<4)then
        while(GetStringLength(sTimeout)<4)
            sTimeout="0"+sTimeout;
        wend
    endif
    //extract HI byte from a 16-bit value of sLength, example: 08F0 - 08
    GetSubstring(sTimeout, 0, 2, sByteHI); //high byte
    //extract LO byte from a 16-bit value of sLength, example: 08F0 - F0
    GetSubstring(sTimeout, 2, 2, sByteLO); //low byte
    sTimeout=Chr(HexStringToNumber(sByteHI))+Chr(HexStringToNumber(sByteLO));

    //possible responces from server 
  /*sResponces =Chr(5)+Chr(128)+sChannel+Chr(255) //05h 80h 00h 0?h - reset complete no TAG present
               +Chr(5)+Chr(160)+sChannel+Chr(255) //05h A0h 00h 0?h - reset complete TAG present
               +Chr(0)+Chr(160)+sChannel+Chr(255) //00h A0h 00h 0?h - unsolicited event TAG appeared
               +Chr(0)+Chr(128)+sChannel+Chr(255) //00h 80h 00h 0?h - unsolicited event TAG disappeared
               +Chr(0)+Chr(161)+sChannel;         //00h A1h 00h 0?h - error*/
endif

in_timeout=2000;

if(IsCommunicationOpen(in_ch) and out_error==0)then

    n32CommSts=GetNumCharsWaiting(in_ch);//check if device sent any data

    if(n32CommSts==0 or io_keepalive==-1)then//no data available or initialization
        if(io_keepalive==1 or io_keepalive==-1)then//if keepalive or initialization
            //start communication, create channel Reset Request command
            //------cmd 00h 05h--         (--length----- --address---- --fillvalue-- --timeout----) -not used in Reset Request
            out_Tx=Chr(0)+Chr(5)+sChannel+Chr(0)+Chr(0)+Chr(0)+Chr(0)+Chr(0)+Chr(0)+Chr(0)+Chr(0);
            ClearCommunicationReceiveBuffer(in_ch);
            n32CommSts=TransmitString(out_Tx,in_ch);//send message
            if(n32CommSts==0)then //data transmisson success
                n32Timeout=in_timeout;
                out_Rx="";
                //wait for start communication acknowledge reply
                while(out_Rx=="" and n32Timeout>0)
                    //get number of characters in receive buffer
                    n32CommSts=GetNumCharsWaiting(in_ch);
                    if(n32CommSts>=4)then //receive data available, receive into internal receive buffer
                        n32CommSts=ReceiveNChars(out_Rx, n32CommSts, in_ch);
                        if(n32CommSts==0)then //receive success

                            //analyse responce, test for ok, TAG present
                            sString=Chr(5)+Chr(128)+sChannel; //05h 80h 00h 0?h - reset complete no TAG present
                            if(FindSubstringInString(sString,0,out_Rx)>=0)then
                                //out_Rx=sString;//set external buffer: 05h 80h 00h 0?h - reset complete no TAG present
                                out_error=0;//clear error
                                out_sts=1;//communication established
                                io_keepalive=0;//reset keepalive
                            else//test for ok, TAG not present
                                sString=Chr(5)+Chr(160)+sChannel; //set search string: 05h A0h 00h 0?h - reset complete TAG present
                                if(FindSubstringInString(sString,0,out_Rx)>=0)then
                                    out_Rx=sString;//set external buffer: 05h A0h 00h 0?h - reset complete TAG present
                                    out_error=0;//clear error
                                    out_sts=1;//communication established
                                    io_keepalive=0;//reset keepalive
                                else//unexpected responce/error
                                    //to do: update error log
                                    out_Rx=out_Rx;
                                    out_error=7708;//RFID Channel Reset Error;
                                    out_sts=0;//communication
                                    io_keepalive=0;//reset keepalive
                                endif
                            endif
                      
                        else
                            out_error=7805;//socket receive error
                        endif
                    elseif (n32CommSts<0)then
                        out_error=7804;//socket receive buffer error
                    endif
                    DelayMsec(5);
                    n32Timeout=n32Timeout-5;
                    //exit while on timeout or error
                    if(n32Timeout<=0)then
                        out_error=7803;//communication reply timeout
                    elseif(out_error>0)then
                        n32Timeout=0;//exit while
                    endif
                wend
            else
            out_error=7802;//socket send error
            endif
        endif
    elseif(n32CommSts>=4)then //unsolicited event data available
        n32CommSts=ReceiveNChars(out_Rx, n32CommSts, in_ch);
        if (n32CommSts==0)then //receive success
            //ClearCommunicationReceiveBuffer(in_ch);
            out_Rx=out_Rx;//set external buffer available for command(s)
            //out_error=0;
            out_sts=1;//communication established
            io_keepalive=0;//reset keepalive
        else
            out_error=7805;//socket receive error
        endif
    elseif(n32CommSts<0)then
        out_error=7804;//socket receive buffer error
    endif

    //-- handle command(s) when communication established, no error, on event/data present, command present, data length>0 -------------
    if(out_sts==1 and out_error==0 and GetStringLength(out_Rx)>0 and GetStringLength(in_CMD)>0 and in_length>0)then
        //create test substrings to check if TAG present event occured:
        //00h A0h 00h 0?h     FFh     05h A0h 00h 0?h     FFh     00h A1h 00h 0?h
        sString=Chr(0)+Chr(160)+sChannel+Chr(255)+Chr(5)+Chr(160)+sChannel+Chr(255)+Chr(0)+Chr(161)+sChannel;
        //if at least 1 match found in external buffer and read nr.of byte(s) to read >0
        if(FindSubstringInString(out_Rx,0,sString)>=0 and in_length>0)then
            //initialize TAG Block Read Command
            if(in_CMD=="READ")then
                //prepare TAG Block Read Command
                //------cmd 00h 02h--                           --not used---
                out_Tx=Chr(0)+Chr(2)+sChannel+sLength+sAddress+Chr(0)+Chr(0)+sTimeout;

            //initialize TAG Block Write Command if data available
            elseif(in_CMD=="WRITE" and GetStringLength(io_data)>0)then
                //trim data to write
                GetSubstring(io_data, 0, in_length, io_data);
                //prepare TAG Block Write Command
                //right pad io_data with null(s)
                if(GetStringLength(io_data)<in_length)then
                    while(GetStringLength(io_data)<in_length)
                        io_data=io_data+Chr(0);
                    wend
                endif
                //------cmd 00h 05h--                           --not used---
                out_Tx=Chr(0)+Chr(1)+sChannel+sLength+sAddress+Chr(0)+Chr(0)+sTimeout+io_data;

            //initialize TAG Fill Command
            elseif(in_CMD=="FILL")then
                //prepare TAG Block Fill Command
                //------cmd 00h 04h--                           --fillvalue--
                out_Tx=Chr(0)+Chr(4)+sChannel+sLength+sAddress+Chr(0)+Chr(0)+sTimeout;
            else//unsupported command
                out_Tx="";
                in_CMD="";
            endif

            //send command
            if(GetStringLength(out_Tx)>0)then
                ClearCommunicationReceiveBuffer(in_ch);
                n32CommSts=TransmitString(out_Tx,in_ch);
                if(n32CommSts==0)then //data transmisson success
                    n32Timeout=in_timeout;
                    //wait for reply
                    out_Rx="";
                    while(out_Rx=="" and n32Timeout>0)
                        n32CommSts=GetNumCharsWaiting(in_ch);
                        if(n32CommSts>=4)then //receive data available
                            n32CommSts=ReceiveNChars(out_Rx, n32CommSts, in_ch);
                            if(n32CommSts==0)then //receive success
                                if(in_CMD=="READ") then
                                    //check if READ successfull: 02h A0h 00h 0?
                                    sString=Chr(2)+Chr(160)+sChannel;
                                    if(FindSubstringInString(sString,0,out_Rx)>=0)then
                                        //get data only                               
                                        GetSubstring(out_Rx,4,(GetStringLength(out_Rx)-4),out_Rx);
                                        if(GetStringLength(out_Rx)>in_length)then
                                            GetSubstring(out_Rx,0,in_length,io_data);
                                        else
                                            io_data=out_Rx;
                                        endif
                                        in_CMD="";      //clear input command
                                    else
                                        out_error=7730;//RFID Read Command Error
                                    endif
                                elseif(in_CMD=="WRITE")then
                                   //check if WRITE successfull: 01h A0h 00h 0?
                                    sString=Chr(1)+Chr(160)+sChannel;
                                    if(FindSubstringInString(sString,0,out_Rx)>=0)then
                                        io_data="";
                                        in_CMD="";      //clear input command
                                    else
                                        out_error=7731;//RFID Write Command Error
                                    endif
                                elseif(in_CMD=="FILL") then
                                    //check if FILL successfull: 04h A0h 00h 0?
                                    sString=Chr(4)+Chr(160)+sChannel;
                                    if(FindSubstringInString(sString,0,out_Rx)>=0)then
                                        io_data="";
                                        in_CMD="";      //clear input command
                                    else
                                        out_error=7732;//RFID FILL Command Error
                                    endif
                                elseif(not(in_CMD=="RESET"))then//unsupported command
                                  io_data="";
                                  in_CMD="";//clear input command
                                endif
                                io_keepalive=0;//reset keepalive                               
                            else
                                out_error=7805;//socket receive error
                            endif
                        elseif(n32CommSts<0)then //no data
                            out_error=7804;//socket receive buffer error
                        endif
                        DelayMsec(5);
                        n32Timeout=n32Timeout-5;
                        //exit while on timeout or error
                        if(n32Timeout<=0)then
                            out_error=7803;//communication reply timeout
                        elseif(out_error>0)then
                            n32Timeout=0;//exit while
                        endif
                    wend
                else
                    out_error=7802;//socket send error
                endif
            endif
        else
            //tag not present or error
        endif
        //out_Rx="";//external buffer data consumed
    endif
endif