Examples - Remote IO

Top  Previous  Next

//-----------------------------------------------------------------------------
// Remote IO.vpl, created 2003-01-04 14:35
//
// This application will monitor upto 16 digital inputs. If any of these changes
// state, the application will send an SMS message to a predefined number containing
// information about which inputs has changed state. When the application receives
// such an SMS message, it will update its own outputs accordingly. The number
// which will receive the status changes, can be set with the "phone=xxx" SMS
// command (see below). All SMS messages can be sent in lower and/or uppercase
//
// Format of SMS messages:
//
// Snn=x;Smm=y;Skk=z
// Where nn,mm and kk is the input number (1..16) and x,y and z is the NEW state
// for the input (0/1).
//
// phone=xxxxxxxx
// Where xxxxxxxx is the number all status changes should be sent to, if blank
// no change of states are reported. The phonenumber will be saved at
// persistent memory location 1
//-----------------------------------------------------------------------------
INCLUDE rtcu.inc
 
// Input variables that can be configured via the configuration dialog (These are global)
VAR_INPUT
  DIn : ARRAY[1..16] OF BOOL; | Digital inputs
END_VAR;
 
// Output variables that can be configured via the configuration dialog (These are global)
VAR_OUTPUT
  DOut : ARRAY[1..16] OF BOOL; | Digital outputs
  gsmOK: BOOL; | TRUE if connected to GSM basestation (Blinks during startup)
END_VAR;
 
 
PROGRAM Remote_IO;
 
VAR
  command   : STRING;
  position   : INT;
  extract   : strGetValues;
  str       : STRING;       // Temporary string
  statestr   : STRING;       // Temporary string
  index     : SINT;         // Temporary SINT
  DIn_old   : ARRAY[1..16] OF BOOL; // Keeps a copy of the old state of the inputs
  sms       : gsmIncomingSMS;       // Receives incoming SMS messages
  pdu       : gsmIncomingPDU;
  pdubuf     : ARRAY[1..140] OF SINT;
  gsm_linsec : DINT;
END_VAR;
 
// Switch power on to GSM module
gsmPower(power:=TRUE);
 
// Wait for successful connect to the GSM network
WHILE NOT gsmConnected() DO
  Sleep(delay:=500);
  DebugMsg(message:="Waiting for connect to GSM network...");
  gsmOK:=NOT gsmOK; // The LED will blink during this
  UPDATEOUT;
END_WHILE;
 
gsm_linsec:=clockNow() + (24*60*60);
 
pdu(message:=ADDR(PDUbuf));
 
BEGIN
  // Update function blocks
  sms();
  pdu();
 
  IF pdu.status>0 THEN
    DebugFmt(message:="PDU received. \1",v1:=pdu.length);
    DebugFmt(message:=pdu.phonenumber);
  END_IF;
 
//---------------------------------------------------------------------------
// Check all inputs for state change
//---------------------------------------------------------------------------
  str:="";
  FOR index:=1 TO 16 DO
    // If the input has changed state since last time
    IF Din[index] <> Din_old[index] THEN
        // Build the "Snn=x;" string
        statestr:=strFormat(format:="S\1=\2;", v1:=index, v2:=SINT(Din[index]));
        // Add it to the command string we will send
        str:=strConcat(str1:=str, str2:=statestr);
        // Remember the new state
        Din_Old[index]:=Din[index];
    END_IF;
  END_FOR;
 
  // If any state changes, go send them
  IF strLen(str:=str)>0 THEN
     statestr:=LoadString(index:=1);
    // ...but only if phonenumber is defined
    IF strLen(str:=statestr)=0 THEN
        DebugMsg(message:="Phonenumber is empty, sending NO state change");
    ELSE
        DebugMsg(message:="Sending new state change:");
        DebugMsg(message:=str);
        gsmSendSMS(phonenumber:=statestr, message:=str);
    END_IF;
  END_IF;
 
 
  //---------------------------------------------------------------------------
  // See if any incoming SMS messages
  //---------------------------------------------------------------------------
  IF sms.status > 0 THEN
     position:=1;
    // Loop through the received message, and decode it
    WHILE TRUE DO
        // Find next ";" delimited command
        command:=strToken(str:=sms.message, delimiter:=";",index:=position);
        position:=position+1;
        DebugMsg(message:=command);
        // If empty, no more commands...
        IF strLen(str:=command)=0 THEN
          DebugMsg(message:="No more commands...");
          EXIT;
        END_IF;
 
        //---------------------------------------------------------------------------
        // See if it is a "Snn=x" command...
        // if we find a "S" at first position, and a "=" at position 3 or 4
        //---------------------------------------------------------------------------
        IF strFind(str1:=command, str2:="S")=1 AND
          (strFind(str1:=command, str2:="=")=3 OR strFind(str1:=command, str2:="=")=4) THEN
           extract(str:=command, format:="S\1=\2");
          IF extract.match THEN
              // extract.v1 contains input number, extract.v2 contains the new state
              IF extract.v1 >= 1 AND extract.v1 <= 16 THEN
                // Reflect the new state on the outputs
                 DOut[extract.v1]:=BOOL(extract.v2);
              END_IF;
          END_IF;
 
        //---------------------------------------------------------------------------
        // See if it's a "phone=xxxxx" command
        // If so, we save the new number, and sends back a confirmation to the sender
        //---------------------------------------------------------------------------
        ELSIF strFind(str1:=command, str2:="phone=")>0 THEN
          // Save the parameters
          SaveString(index:=1, str:=strMid(str:=command, start:=7));
           str:=strConcat(str1:="New receiver set, number=", str2:=LoadString(index:=1));
          gsmSendSMS(phonenumber:=sms.phonenumber, message:=str);
        END_IF;
    END_WHILE;
  END_IF;
 
  IF clockNow() > gsm_linsec THEN
    DebugMsg(message:="GSM Module turned OFF");
    gsmPower(power:=OFF);
    DebugMsg(message:="GSM Module turned ON");
    gsmPower(power:=ON);
     gsm_linsec:=clockNow() + (24*60*60);
 
    // Wait for successful connect to the GSM network
    WHILE NOT gsmConnected() DO
        Sleep(delay:=500);
        DebugMsg(message:="Waiting for connect to GSM network...");
    END_WHILE;
    DebugMsg(message:="Now connected to GSM network");
  END_IF;
 
  gsmOK:=gsmConnected();
END;
 
END_PROGRAM;