Daten über Com-Port einlesen

Hallo computerpap,

leider sind wir zur Zeit sehr busy und ich denke, daß wir es auch nicht (schnell) schaffen werden - wegen mangelnder DoKu.

Beispiel:

Oder- Verknüpfung aller Byte inclusive Kennung, exclusice CS

halte ich für „Blödsinn“ > gibt (fast) immer 255 (normal wäre z.B. XOR)

MST

Hallo Ihr beiden,

habe mich auch mit dem Geraet mal kurz beschaeftigt, weil ich auch etwas fuer mein Meerwasserhobby noch suche - leider wird die Box nicht mehr produziert und es gibt keinerlei Schaltungsunterlagen - die PDF Dok ist das einzigste, was noch verfuegbar ist.

Ich habe mich nun damit abgefunden, etwas selbst zu entwickeln, das wird aber noch eine ganze Weile dauern.

Gruss Torro

Hallo,

stell doch mal ein bisschen Code ein. Eine Funktion wie es denn gehen soll wäre auch nicht schlecht.
So wie ich das Forum kenne, gibt es eigentlich nichts, was nicht geht.

Man sollte aber auch nichts über das Knie brechen.

HJH ist da ein heisser TIP. unmögliches wird möglich gemacht für uns Laien :slight_smile:

… muss es nicht heißen: HJH ist ein heisser Typ :confused:

MST :wink:

meine Tochter würde jetzt sagen babba hdl.

Des war hessich, net valsch verstehe.

jetzt waste acwarim babba,babba heisst.

Nur den zusammenhang mit HJH hab ich nicht verstanden.

:smiley:

Hallo

Heute hab ich’s geschafft aus der Science-Box Daten (PH-Wert) auszulesen. Allerdings nur mit der Demosoftware "AK Analytik32.Net. Diese Software benötigt wiederum als Grundlage zur Kommunikation die Software „EconNSoft Core Components“. Kennt sich jemand mit dieser Software aus, um eventuell sich was ableiten zu können, dass die Science-Box doch noch unter IPS läuft?
Torro hat recht, die Box wird nicht mehr produziert und auch nicht mehr supported. Allerdings wäre das genau das richtige Teil für mein Meerwasseraquarium und da ich die Visualisierung über IPS machen möchte, wäre es halt Klasse wenn es irgendwie zum laufen kommt!
Ich bin für jegliche Ideen dankbar.

MfG
computerpap

Hallo

Wie kann ich einen Hex-code( 50 00 00 38 00 FF 80 00 01 16 ) über den Comport rausschicken. Ich glaube der muß vorher in einen ASCII-String umgewandelt werden, oder? Wenn ja, wie wandel ich diesen Code um?

MfG
computerpap

Hallo computerpap,

da die ScienceBox über die serielle Schnittstelle kommuniziert, kann sie selbstverständlich direkt mit IP-Symcon Daten austauschen. Es wird keine Zusatz-Software benötigt.

Allerdings sind die Angaben zum Protokoll der ScienceBox unvollständig und teilweise sogar falsch.
So ist z.B. nirgendwo erwähnt, ob bei Werten, die aus mehreren Bytes bestehen, das Hi- oder Lo-Byte zuerst gesendet wird.
Die Beschreibung der Checksumme ist falsch. Es handelt sich hier eindeutig nicht um eine OR- sondern um eine EXOR-Verknüpfung.

Die Daten, die gesendet oder empfangen werden, sind binäre Zeichen, also keine lesbaren Text-Zeichen (keine ASCII-Zeichen).

Die von Dir als Beispiel angeführte Datensequenz würde also so versendet werden:

$data = chr(0x50). chr(0x00). chr(0x00). chr(0x38). chr(0x00). chr(0xFF). chr(0x80). chr(0x00). chr(0x01). chr(0x16);
ComPort_SendText($InstID, $data);

oder

$data = "\x50\x00\x00\x38\x00\xFF\x80\x00\x01\x16";
ComPort_SendText($InstID, $data);

Beide $data-Zuweisungen erfüllen denselben Zweck.

Einen Messwert (nur Integer) kann man auf folgende Weise umwandeln:

$val = 1234;                      // Beispielwert
$loval = $val & 0xff;             // Low-Byte extrahieren
$hival = ($val & 0xff00) >> 8;    // High-Byte extrahieren
$data = chr($hival). chr($loval); // Reihenfolge evtl. umkehren

Wie oben schon erwähnt, kann die Reihenfolge von Lo und Hi auch umgekehrt sein. Das muss man ausprobieren.

Gruß
HJH

Hallo HJH

Danke für die schnelle Antwort. Ich werd mal sehen ob ich aus dem Teil paar Daten rausholen kann. Für mein Meerwasseraquarium ist die Box optimal. Ich hab in den letzten Tagen mich mit einer anderen Software testweise beschäftigt und da klappt der Datenaustausch perfekt. Ich möchte aber die Box unbedingt mit IPS zum laufen bringen.

Mfg
computerpap

Hallo

Die Kommunikation funzt einwandfrei. Folgende Frage hab ich noch:
In der Datensequenz steht ein \x80\x00. Mit den ersten 2 Byte wird Relais 1 angesteuert und mit den zweiten 2 Byte das Relais 2. In diesen Bsp. ist Relais 1 an und Relais 2 aus. Wie kann ich das programmieren, damit ich z.B. im Designer per Button diese Bytes bzw. die Datensequenz von x80 auf x00 ändern kann und gleichzeitig sich die Checksumme neu berechnet.

MfG
computerpap

Hallo,

Glueckwunsch. Leider gibts das Ding nicht mehr, so dass ich nun mit Profilux einsteige. Ich hole mir da alle Daten per Socket Schnittstelle und kann natuerlich auch schreibend darauf zugreifen. Dort findet das SMBus Protokoll Verwendung, dass muss ich natuerlich erst noch umsetzen…ich brauche mehr Zeit, hat die jemand im Ueberfluss ?

Gruss Torro

Hallo Torro

Ich bin heilfroh, dass die Kommunikation dank HJH’s Hilfe jetzt doch noch funzt. Für 50 Euro’s war die Box wirklich ein Schnäppchen. Jetzt versuch ich noch das Programm hinzubekommen. Wenn ich soweit bin, werd ich es mal reinstellen, vielleicht interessiert es den einen oder anderen. Für dein Projekt wünsch ich dir viel Erfolg.

MfG
computerpap

Hallo computerpap,

es freut mich, dass die Kommunikation jetzt funktioniert.

Deine Beispiel-Datensequenz enthält folgende Information (dezimal, hexadezimal, character, binär, ASCII):
80 = 0x50 = „\x50“ = 0b01010000 = „P“ : Präfix für Polling
0 = 0x00 = „\x00“ = 0b00000000 : Adresse 1. Byte, alle Bits ohne Bedeutung
0 = 0x00 = „\x00“ = 0b00000000 : Adresse 2. Byte, alle Bits ohne Bedeutung
56 = 0x38 = „\x38“ = 0b00111000 : Analog-Ausgang 1. Byte (wahrscheinlich Lo-Byte)
0 = 0x00 = „\x00“ = 0b00000000 : Analog-Ausgang 2. Byte (wahrscheinlich Hi-Byte)
255 = 0xff = „\xff“ = 0b11111111 : Reset Tropfenzähler 1+2 (Bit7 und Bit6), Bits 5…0 ohne Bedeutung
128 = 0x80 = „\x80“ = 0b10000000 : Relais 1 ein (Bit7), Bits 6…0 ohne Bedeutung
0 = 0x00 = „\x00“ = 0b00000000 : Relais 2 aus (Bit7), Bits 6…0 ohne Bedeutung
1 = 0x01 = „\x01“ = 0b00000001 : Relais 3 aus (Bit7), Bits 6…0 ohne Bedeutung
22 = 0x16 = „\x16“ = 0b00010110 : Checksumme

Bits ohne Bedeutung können 0 oder 1 sein. Sie haben keinen Einfluss, müssen aber bei der Checksummenberechnung berücksichtigt werden. Es ist also am einfachsten solche Bits immer auf 0 zu setzen.

Wie man sieht wird für jedes Relais jeweils nur ein Bit eines Bytes verwendet, nämlich Bit7, also das höchstwertige. Daraus folgt, dass das zugehörige Byte nur den Zustand 128 (0x80) für EIN oder 0 (0x00) für AUS annehmen kann.
Im Beispiel ist für das Relais 3 das niederwertigste Bit (Bit0) gesetzt, was zu einen Wert von 1 (0x01) führt. Dieser hat aber keine Bedeutung und somit auch keine Wirkung, womit dieser Wert unsinnig ist.

Hier ein ungetestetes Skript, das den Ablauf verdeutlichen soll:

// Definition einiger Konstanten
define("EIN", "\x80");  // Relais ein
define("AUS", "\x00");  // Relais aus
define("RTZ1", "\x80"); // Reset Tropfenzähler 1
define("RTZ2", "\x40"); // Reset Tropfenzähler 2

// Analog-Ausgang aufbereiten
$val = 1234;                      // Beispielwert für Analog-Ausgang
$loval = $val & 0xff;             // Low-Byte extrahieren
$hival = ($val & 0xff00) >> 8;    // High-Byte extrahieren

// Reset eines oder beider Tropfenzähler
$rtz = RTZ1;        // Tropfenzähler 1 rücksetzen oder
$rtz = RTZ2;        // Tropfenzähler 2 rücksetzen oder
$rtz = RTZ1 + RTZ2; // beide Tropfenzähler rücksetzen

// Relais 1..3 ein- oder ausschalten
$rel1 = EIN;
$rel2 = AUS;
$rel3 = AUS;

// Datensequenz zusammensetzen
$data = "P". "\x00\x00". chr($loval). chr($hival). $rtz. $rel1. $rel2. $rel3;

// Checksumme berechnen
$csum = 0;
for ($i=0; $i<strlen($data); $i++)
  $csum ^= $data[$i];

// Checksumme an Datensequenz anfügen
$data .= $csum;

// Datensequenz senden
ComPort_SendText($InstID, $data);

Gruß
HJH

Hallo HJH

Vielen Dank für deine Mühe, aber leider bring ich das Programm nicht zum laufen.
Ich denke das irgendwas mit der Berrechnung der Checksumme nicht in Ordnung ist.
Ich hab mal ein Testprogramm geschrieben, das läuft zwar auch nicht, aber vielleicht kann mir einer sagen, wo der Fehler ist. Die Checksumme, die ich ausgegeben bekomme ist meiner Meinung nach richtig.


/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : Science_Box.ips.php
Trigger  :
Interval :
*/
//Bytes definieren
$Kennung = 0x50;
$AdresseByte0 = 0x00;
$AdresseByte1 = 0x00;
$AnalogByte0 = 0x00;
$AnalogByte1 = 0x00;
$Tropfen = 0x00;
$Rel1 = 0x00;
$Rel2 = 0x00;
$Rel3 = 0x00;


// Datensequenz zusammensetzen
$data = chr(0x50).  chr(0x00). chr(0x00). chr(0x00). chr(0x00). chr (0x00). chr (0x00). chr (0x00). chr (0x00);

// Checksumme berechnen
$csum = $Kennung ^ $AdresseByte0 ^ $AdresseByte1 ^$AnalogByte0 ^ $AnalogByte1 ^ $Tropfen ^ $Rel1 ^ $Rel2 ^ $Rel3;

// Checksumme an Datensequenz anfügen
$data .= $csum;

// Datensequenz senden
ComPort_SendText(62305, $data);

echo $csum;



Ich hab den Fehler gefunden, folgende Zeile muß so aussehen:

// Checksumme an Datensequenz anfügen
$data .= chr ($csum); 

Hallo

Ich hab das Programm jetzt nochmals geändert und jetzt funzt es auch, ich denke so oder ähnlich hat es auch HJH gemeint.
Mein Problem ist jetzt nur noch, das ich die Variablen $Rel1 und $Rel2 nur über eine Konstante steuern kann. Ich möchte aber das ich sie per Button im Designer steuern kann.


<?
/*
*******************************
 IP-SYMCON Event Scripting
*******************************
File     : Science1.ips.php
Trigger  : 
Interval : 
*/
//Bytes definieren
$Kennung = 0x50;
$AdresseByte0 = 0x00;
$AdresseByte1 = 0x00;
$AnalogByte0 = 0x00;
$AnalogByte1 = 0x00;
$Tropfen = 0x00;


// Definition einiger Konstanten
define("EIN", 0x80);  // Relais ein
define("AUS", 0x00);  // Relais aus

// Analog-Ausgang aufbereiten
$val = 1234;                      // Beispielwert für Analog-Ausgang
$loval = $val & 0xff;             // Low-Byte extrahieren
$hival = ($val & 0xff00) >> 8;    // High-Byte extrahieren

// Relais 1..3 ein- oder ausschalten
$rel1 = AUS;
$rel2 = AUS;
$rel3 = AUS;

// Datensequenz zusammensetzen
$data = chr($Kennung). chr($AdresseByte0). chr($AdresseByte1). chr($AnalogByte0). chr($AnalogByte1). chr($Tropfen). chr($rel1). chr($rel2). chr($rel3);

// Checksumme berechnen
$csum = $Kennung ^ $AdresseByte0 ^ $AdresseByte1 ^$AnalogByte0 ^ $AnalogByte1 ^ $Tropfen ^ $rel1 ^ $rel2 ^ $rel3;

// Checksumme an Datensequenz anfügen
$data .= chr ($csum);

echo $csum;
// Datensequenz senden
ComPort_SendText(62305, $data);


?>

Mfg
computerpap

Hallo
Das Ansteuern der Relais per Designer ist nun auch gelöst.
Hilfe bräuchte ich aber beim Auslesen der Daten per Comport. Egal was ich bei der RegisterVariable einstelle, ich bekomme immer nur 2 Zeichen in der Variable $Wert angezeigt. CutCharts hatte ich auch schon vor die RegisterVariable gehängt, brachte aber auch nichts. Wie kann ich mir die konplette Zeichenkette anzeigen lassen?

Wie kann ich mir die konplette Zeichenkette anzeigen lassen?

Wie sieht denn die Zeichenkette aus, die über den Comport empfangen wird.

Hallo computerpap,

das Fehlen der chr(…)-Funktion beim Anfügen der Checksumme hattest Du ja schon selbst gefunden. Ich habe aber noch einen weiteren Fehler bei der Berechnung entdeckt. Bei der Verknüpfung hat die ord(…)-Funktion gefehlt. So ist es richtig:

// Checksumme berechnen
$csum = 0;
for ($i=0; $i<strlen($data); $i++)
  $csum ^= ord($data[$i]);

// Checksumme an Datensequenz anfügen
$data .= chr($csum); 

Nun zur Auswertung der Rückantwort:
Der ComPort muss direkt mit einer Registervariablen verbunden werden. Es ist nicht möglich hier mit CutChars zu arbeiten, weil es keine konstanten Trennzeichen gibt, die hierfür in Frage kämen.
Die Registervariable bekommt von Windows den Datenstrom meist in 8 Byte großen Häppchen übermittelt. Daran kann IPS nichts ändern. Daher sollte die Registervariable im AppendMode betrieben werden, da sonst die Fragmente erst wieder mühsam zusammengesetzt werden müssen. Wenn der String vollständig empfangen ist, muss dann aber die Variable von Hand gelöscht werden. Zweckmäßigerweise lässt man das Skript von der Registervariablen triggern und prüft dann, ob der Datenstring vollständig ist:

$regvar = "NameDerRegisterVariablen";
if ($IPS_SENDER == "Variable" && $IPS_VARIABLE == $regvar && strlen($IPS_VALUE) >= 28) // Antwort muss 28 Byte lang sein
{
  $data = $IPS_VALUE;                // Registervariable auslesen
  SetValueString($IPS_VARIABLE, ""); // Registervariable löschen
}
else
  return;                            // Empfang läuft noch, Daten noch nicht vollständig


// Checksumme berechnen
$csum = 0;
for ($i=0; $i<strlen($data); $i++)
  $csum ^= ord($data[$i]);           // ein String kann wie ein Array behandelt werden

// Checksumme prüfen
if ($csum != 0)                      // Beim Empfang muss die Checksumme 0 sein!
{
  // Fehlerbehandlung
}

// Inhalt verarbeiten                // Beispiel: Raumtemperatur (16bit) steht an Position 23 und 24 (Zählung beginnt bei 0)
$raumtemplobyte = ord($data[23]);
$raumtemphibyte = ord($data[24]);
$raumtemp = ($raumtemphibyte << 8)+ $raumtemplobyte ;

Gruß
HJH

Hallo HJH

Sorry, dass ich mich jetzt erst melde, war beruflich unterwegs.
Ich werd das heute mal ausprobieren, wäre super wenn das klappt, und vielen Dank.

Mfg
computerpap