RWN
7. Dezember 2007 um 17:34
1
Hallo,
ich habe mir das E*v Bussystem HS485 zugelegt und bin nun zugange etwas auf die Beine zustellen.
Die Daten liegen vor, leider habert es beim aufsplitten:mad:
// Dateneingang Register Variable mit Log...
$daten = GetValueString("HS485_Daten");
//$daten = $IPS_VALUE;
$s = "";
for($i=0; $i<strlen($daten); $i++)
{
$s = $s.intval(ord(substr($daten,$i,1)))." ";
}
IPS_LogMessage("HS485:", $s);
hiermit sehe ich schon mal das alles korrekt ankommt. Bild der einkommenden Daten ist angehängt.
Ich möchte erst mal die einzelnen Bytes aufteilen und diese zuordnen.
Startzeichen = 1Byte
Zieladresse = 4Byte
Kontrollzeichen = 1Byte
Absenderadresse = 4Byte
Framelänge = 1Byte
Framedaten, max 64Byte
CRC = 2Byte
Wer hat denn einen kleinen Tip.
tommi
7. Dezember 2007 um 22:10
2
die unpack -Funktion wäre eine elegante Variante, ansonsten bleibt nur die Zahlen als Substrings an den passenden Stellen herauszuschneiden und zu wandeln.
Tommi
EHB
7. Dezember 2007 um 22:31
3
Hallo RWN - da hast Du ja was angefangen ! (Ich spreche aus Erfahrung!)
Hier mal ein paar Tips für den Anfang:
Zu erst musst du die Daten von ASCII in HEX umwandeln
z.B.:
$Byte = dechex(ord($Dec_Datensatz[$i])); // ASCII in Hex umwandeln
$Byte = str_repeat("0", 2 - strlen($Byte)).$Byte; // führende 0 einfügen
Als nächstes jedes eingelesene Byte auf Escapezeichen(„fc“) überprüfen. Falls ein Escapezeichen vorhanden, dann das nächste Byte lesen, und das höchstwertige Bit setzen.
z.B::
if ($Byte == "fc") // Escapezeichen vorhanden ?
{
$Escapezeichen++; // Anzahl der Escapezeichen um 1 erhöhen
$i++; // Zeichenzähler um 1 erhöhen und nächstes Zeichen lesen
$Byte = dechex(ord($Dec_Datensatz[$i])); // Ascii in Hex umwandeln
$Byte = str_repeat("0", 2 - strlen($Byte)).$Byte; // führende 0 einfügen
$Byte = dechex(hexdec($Byte) | 0x80); // Höchstwertiges Bit zusätzlich setzen
$ASCII_Datensatz .= chr(hexdec($Byte)); // Originaldaten übergeben
}
else
{
$ASCII_Datensatz .= $Dec_Datensatz[$i]; // Originaldaten übergeben
}
$Hex_Datensatz .= $Byte; // Hexdaten übergeben
Die einzelnen Bytes kannst Du folgendermaßen auswerten:
z.B.:
switch($Bi) // Inhalt des Datensatzes (Hex-Werte) an Variablen übergeben
{
case 0:
$HS485_Startzeichen = $Byte;
break;
case 1:
$HS485_Ziel = $Byte;
break;
case 2:
$HS485_Ziel .= $Byte;
break;
case 3:
$HS485_Ziel .= $Byte;
break;
case 4:
$HS485_Ziel .= $Byte;
break;
case 5:
$HS485_Kontrollbyte_Hex = $Byte;
$HS485_Kontrollbyte = decbin(hexdec($Byte));
// Kontrollbyte auf I-Frame prüfen
if (!($HS485_Kontrollbyte &1))
{
$HS485_Frametyp = "I"; // I-Frame
}
// Kontrollbyte auf Ack-Frame prüfen
if (($HS485_Kontrollbyte &1) && (!($HS485_Kontrollbyte &2)) && (!($HS485_Kontrollbyte &4)))
{
$HS485_Frametyp = "A"; // Ack-Frame
}
// Kontrollbyte auf Discovery-Frame prüfen
if (($HS485_Kontrollbyte &1) && ($HS485_Kontrollbyte &2) && (!($HS485_Kontrollbyte &4)))
{
$HS485_Frametyp = "D"; // Discovery-Frame
}
// Sendefolgennummer extrahieren
$HS485_Sendefolgenummer = ($HS485_Kontrollbyte & 0x06);
break;
case 6:
$HS485_Absender = $Byte;
break;
case 7:
$HS485_Absender .= $Byte;
break;
case 8:
$HS485_Absender .= $Byte;
break;
case 9:
$HS485_Absender .= $Byte;
break;
...
Was die Sache erschwert, ist die Tatsache, dass die empfangenen Datensätze eine unterschiedliche Länge haben.
Ich hoffe ich konnte Dir ein wenig weiterhelfen.
RWN
7. Dezember 2007 um 23:31
4
Hallo Ernst,
erst mal tausend Dank, das sieht ja alles sehr gut aus, übersteigt dann aber doch meine bescheidene Kenntniss in sachen PHP
Mir reicht es schon aus, wenn ich die Aktorenkennung den Aktor und den zugehörigen Zustand habe. Dieses habe ich ja in den empfangenen Daten.
Die wollt ich aufsplitten und entsprechenden Variablen zuordnen, sodaß ich über IPS auch mal schalten und auswerten kann.
Programmiert habe ich das ganze über die Software, schnell, einfach und komfortabel.