Home Contact us


Remote IO



//-----------------------------------------------------------------------------
// 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 it's 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 successfull 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
   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 thru 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 successfull 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;