reine PHP-Steuerung des M232-Interfaces

Hallo,

Aufgrund der aktuellen Probleme mit dem M232-Modul habe ich eine reine PHP-Implementation der angebotenen Funktionen gemacht. Diese sollten kompatibel zu den Original-Funktionen sein, bis auf die Instance-ID, die es hier natürlich nicht gibt. Die Ausführungsgeschwindigkeit ist aber schon durch die lange Minimalwartezeit von 1s wesentlich geringer.

Hier sieht man ganz gut, wie man ohne spezielle Module serielle Geräte ansprechen kann.
Vorraussetzung ist eine Instanz des ComPort-Moduls und des RegisterVariable-Splitters mit zugeordneter Stringvariable. Die IDs und der Name der Variable muss im Script in der define-section angepasst werden. Die echos können natürlich raus und sind nur zur Demo gedacht.

Der letzte Teil sind Demo-Anwendungen der zuvor definierten Funktionen.

Have Fun!
Tommi


<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : M232_PHP.ips.php
Trigger  : 
Interval : 
*/
/*
   PHP Implementation of the Delphi IPS M232-Modul
   (C) Februar 2006 by Tommi
   
 protocol
 <STH> (payload)<CR> without checksum
 answer:
 <DATA><ACK> OK
 <NAK> Error
   //defines
const STH =1;
const ACK =6;
const NAK =21;
const CR  =13;

//commands
const cmdGetCounter ='z'; //'z'  return 4Byte (0000-FFFF)
const cmdSetCounter ='Z'; //'Z'  p1=0(Counter off),1(Counter on/reset)
const cmdGetIOByte ='w'; //'w'  return p1=Byte (IO states 00-FF)
const cmdSetIOByte ='W'; //'W' p1=Byte (IO states 00-FF)
const cmdSetIOBit ='D'; //'s' p1=Bit (0..7), p2=state (0/1)
const cmdGetIOBit ='d'; //'s' p1=Bit (0..7) return p1=(0/1) (IO state)
const cmdGetAnalog ='a'; //'a' p1=Byte (Kanal 0..5) 4Byte (000-3FF)+1(aktuell),0(schon gelesen)
const cmdStartAnalog ='M'; //'Z'  p1=Byte(0=manuell, 1-6=anzahl Kanäle(0..5) automatisch)

*/
//const
define ('CR',13);
define ('STH',1);
define ('ACK',6);
define ('NAK',21);

//instance -IDs
define ('COM',29469);
define ('Register',13319);
define ('RegVar','ComResponse');

//store last command
$command='';
//store result;
$result=0;
function M232_SendData($data) {
   global $command;
   //command is the first character
   $command=$data{0};
   //add STH and CR frame
   $data=chr(STH).$data.chr(CR);
   //send data
   echo "Send ".$data."
";
   COMPort_SendText(COM,$data);
   //check answer and return this state
   return M232_ReceiveData();
}
function M232_ReceiveData() {
   global $command;
   global $result;
   //wait
   sleep(1);
   //get data
   $data=GetValueString(RegVar);
   echo "Found ".$data."
";
   //reset buffer
   SetValueString(RegVar,'');
   if (strlen($data)==0) {
      //no data
      $result=0;
      return false;
   }
   if ((strlen($data)==0) and ($data{0}==chr(NAK))) {
       //only NAK received,
      //command was not accepted
      $result=-1;
      echo "command was not accepted
";
      return false;
   }
   if (!($data{strlen($data)-1}==chr(ACK))) {
      //last char must be ACK
      //Protocol error
      $result=-2;
      echo "Protocol error: no ACK in last byte
";
      return false;
   }

   //now we decode the result string
   switch ($command) {
   case 'M':
   case 'D':
   case 'W':
   case 'Z':
      $result=1;
      break;
   case 'd'://$result=($data{0}=='1');
            $result=(int)($data{0});
            break;
   case 'w':$result=hexdec(substr($data,0,2));
            break;
   case 'z':$result=hexdec(substr($data,0,4));
            break;
   case 'a': $result=hexdec(substr($data,0,3));
            if ($data{3}=='0') {
               //old data will set Bit16
               $result=$result+65536;
            }
            break;
   default:
      return false;
      break;
   }
   return true;
}

function M232_SetIOByte_p($value) {
   //set IO Port all Bits
   $value=(int)$value;
   //value 8bit: 0..255
   $value=$value && 255;
   $data='W'.str_pad(dechex($value),2,'0',STR_PAD_RIGHT);
   M232_SendData($data);
}
function M232_SetIOBit_p($bit,$value){
   //set bit $bit on/off
   $value=((bool)$value)?'1':'0';
   //bit: 0..7
   $bit=((int)$bit) and 7;
   $data='D'.chr(48+$bit).$value;
   M232_SendData($data);
}
function M232_GetIOBit_p($bit) {
   //query Bit $bit of IO-Port
   global $result;
   $bit=((int)$bit) and 7;
   $data='d'.chr(48+$bit);
   M232_SendData($data);
   return (bool)$result;

}
function M232_GetIOByte_p() {
   //query IO Port
   global $result;
   $data='w';
   M232_SendData($data);
   return (int)$result;
}
function M232_GetCounter_p() {
   //query counter
   global $result;
   $data='z';
   M232_SendData($data);
   return (int)$result;
}
function M232_SetCounter_p($value) {
   //on or reset =1,off=0
   $value=((bool)$value)?'1':'0';
   $data='Z'.$value;
   return M232_SendData($data);

}
function M232_StartAnalog_p($channel=0) {
   //see M232 docu
   //channel 0 means manual mode
   //1..6 meens automatic mode for first x channels
   $channel=(int)$channel;
   if ($channel>6 or $channel<0) {
      return false;
   } else {
      $data='M'.chr(48+$channel);
      return M232_SendData($data);
   }

}
function M232_GetAnalog_p($channel) {
   global $result;
    $channel=(int)$channel;
    //channel 1..6, but 0..5 to query
   if ($channel>6 or $channel<1) {
      return false;
   } else {
      $data='a'.chr(48+$channel-1);
      M232_SendData($data);
      $value=$result;
      //strip old value bit
      if ($value >65535) {
         $value=$value-65535;
      }
      return $value;

   }
}
//reset IO-Port
M232_SetIOByte_p(0);
//Start Counter
M232_SetCounter_p(true);
// Start A/D
M232_StartAnalog_p();
//Ask Bit1
if (M232_GetIOBit_p(1)) {
   echo "Bit 1: Set";
} else {
   echo "Bit 1: not Set";
}
echo ":".  $result. "
" ;
//set Bit 1
M232_SetIOBit_p(1,true);
//Ask Bit1 again
if (M232_GetIOBit_p(1)) {
   echo "Bit 1: Set";
} else {
   echo "Bit 1: not Set";
}
echo ":".  $result. "
" ;
$value=M232_GetCounter_p();
echo "Counter:".$value."
";
//Ask A/D result
$value=M232_GetAnalog_p(1);
echo "AD:".$value."
";
?>