Daten aus Protokollrahmen aufsplitten

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.

HS485.jpg

die unpack -Funktion wäre eine elegante Variante, ansonsten bleibt nur die Zahlen als Substrings an den passenden Stellen herauszuschneiden und zu wandeln.

Tommi

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.

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.