Befehle an Remote Xbee senden

Servus

Xbee werden hier ja hauptsächlich als Rs232 Verlängerung verwendet.
Die Teile können aber noch sehr sehr viel mehr.

Jedes XBee Modul hat ja auch noch mehrere Digitale I/O, PWM, und ADCs an Board.
Von direkt lokal per USB oder RS232 angeschlossene Module sind diese Funktionen recht einfach mit AT Befehlen ansprechbar.
-> siehe Xbee Doku bei digi.com (ich verlinke mal lieber nicht)

Bei über Funk im Xbee Netzwerk angebundenen Modulen geht das aber nicht so einfach, hier müssen die Befehle in einen binären Datenstrom mit Checksumme ect. verpackt und dann zum jeweiligen Modul gesendet werden.

IPS unterstützt dies aber leider nativ, drum hab ich mal ein Script dafür gebaut.

Vorbedingung:
Xbees lt. Anleitung von Rainer instalieren http://www.ip-symcon.de/forum/f33/xbee-ip-symcon-einbinden-8544/

Zusätzlich unbedingt per XCTU den API Modus enablen.
Bei allen Modulen auf gleichen Firmwarestand achten.
Ich habe mit 10E6 getestet.

Die Verwendung untenstehender Funktion sollte eigentlich selbsterklärend sein.
Hier wird zb. der DAC (PWM PIN0) von XBEE mit Adresse "2"auf „1023“ gesetzt.

{
#except $CMD all parameters need to be HEX,  
$CMD = "M0";   	#AT-Command -> see Xbee manual  page27 ff.
$Data = "3ff"; 	#Parameter  -> see Xbee manual  page27 ff.
$AdrLow = "02";   #LowByte Adress Xbee End Device
$AdrHigh= "00";   #HighByte Adress  XBee End Device


XBee_remote_Command($CMD,$Data,"00","02");
}

function Xbee_remote_Command($ATCMD,$CMDData,$AdrHigh,$AdrLow) {

$ID_CommPort=55219; #CommPort where Xbee Coordinator attached
#----------------------------------------------------------------------------
# Define Constants
# Start/Lenght/ApiID/FrameId/64BitAdr

$AC="02";
$start =chr(0x7E);
$ApiId= chr(0x17);
$FrameId=chr(0x01);
$Adr64Bit = chr(0x00).chr(0x00).chr(0x00).chr(0x00).chr(0x00).chr(0x00).chr(0x00).chr(0x00);

# add leading "0" to arguments
if ((strlen($CMDData))%2 >0) $CMDData = "0".$CMDData;
if ((strlen($AdrLow))%2 >0) $AdrLow = "0".$AdrLow;
if ((strlen($AdrHigh))%2 >0) $AdrHigh = "0".$AdrHigh;

# calc lenght of datastream
$lenght = strlen(pack("H*",$CMDData));
$lenght = dechex($lenght +15);
$lenght = chr(0x00).chr("0x".$lenght);

# calc checksumm
$chksum=hexdec("0x17")+hexdec("0x01")+crossfoot($AdrLow)+crossfoot($AdrHigh)+crossfoot($AC)+ord(substr($ATCMD,0,1))+ord(substr($ATCMD,1,1))+crossfoot($CMDData);
$chksum = 255 - ($chksum & 255);
$chksum =chr("0x".dechex($chksum));

# convert arguments from Ascii (Bytewise)
$AdrLow = pack("H*",$AdrLow);
$AdrHigh = pack("H*",$AdrHigh);
$CMDData = pack("H*",$CMDData);
$AC=pack("H*",$AC);

# concatenate final datastream
$data = $start.$lenght.$ApiId.$FrameId.$Adr64Bit.$AdrHigh.$AdrLow.$AC.$ATCMD.$CMDData.$chksum;

# send to Xbee
COMPort_SendText($ID_CommPort,$data);
#RegVar_SendText($IDXbee,$data);
}

function crossfoot($arg) {
$arr = str_split($arg,2);
      $r = 0;
      foreach($arr as $v) $r += hexdec($v);
return $r;
}

Hab das Script mal nur aus Bastelinteresse gemacht, Anwendung hab ich im Moment leider selbst keine dafür. - Suggestions are welcome.
Und wenn mir mal wieder langweilig ist so baue ich noch eines um Daten von beliebigen Xbees im Funknetz einzulesen.

gruß und gut funk
bb