Füllstandsmessung mit US über COM-Schnittstelle

Hi

lade dir mal das Terminalprogramm herunter:
http://www.der-hammer.info/terminal/hterm.zip

Damit kannst Du die Daten direkt in hex anzeigen. Und dann poste mal ein Log.

Hab ich jetzt trotzdem mal beim neuen COM-Modul belassen.

Wichtig: Du musst in der RegisterVariable auf „append“ stellen, damit immer angehangen wird.

Aaaah! Hatte es auf „Overwrite“ und „(!IPS_SemaphoreEnter(„RegisterVariable_Log_run“,900))“ immer >1.

Datei jetzt:

16:12:36.79694600:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:37.81257100:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:38.76569500:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:39.79694600:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:40.81257100:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:41.82819500:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:42.85944600:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:43.89069500:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:44.84382100:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:45.87507100:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:46.89069600:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:47.92194600:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:48.87507000:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:49.89069500:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:50.92194600:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:51.98444500:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:52.96882000:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:54.00007100:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:54.98444500:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:55.98444600:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:57.00012200:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 
16:12:58.03132100:>00 f8 f8 00 f8 f8 80 00 f8 80 78 00 80 00 78 00 00 00 78 00 00 78 e0 

Ich werde es auch gleich nochmal mit dem „alten“ COM/LAN-Modul probieren.

Damit komme ich sogar nur auf 23 Bytes:eek:
Also kanns an IPS nicht liegen.
Die Bytefolge ist jedoch gleich…

Variiere mal die Baudrate. z.B. verdoppeln…

Mir ist aufgefallen, dass in der Schnittstellenbeschreibung was von 5V-Pegel auf der seriellen Leitung steht. Das ist nicht normgerecht. Einige Schnittstellen laufen zwar mit TTL-Pegel, aber nicht zuverlässig. Eventuell musst Du noch einen Treiber wie z.B. den MAX232 dazwischen hängen. Oder läuft die Originalsoftware noch einwandfrei?

Ein Verändern (Verkleinern/Vergrößern) der Baudrate bringt nur andere Byte-Kombinationen zum Vorschein.
Der Pegelwandler ist schon in der seriellen Zuleitung intergriert.

Die Originalsoftware funktioniert nach wie vor mit den Einstellungen 19200,8,N,1 und zeigt selben Werte, wie am Display.

Dir gehen die Ideen auch aus… gelle…:frowning: :frowning:

Dir gehen die Ideen auch aus… gelle…

Naja, für eine genauere Betrachtung müsste man wohl vor Ort sein. :confused: Du hast nicht zufällig einen Schnittstellentester mit LEDs? :o

Auf jeden Fall sieht die Datei schon mal gut aus -> so habe ich mir das vorgestellt. :smiley:

Ist es tatsächlich so, dass im Windows-eigenen Hyperterminal 12Byte angezeigt werden und im hterm 23? 23Byte liegen ja auch in der Datei.
Kannst Du nochmal ein Log mit beiden Programmen machen und mir schicken? Email-Adresse liegt im Profil.

An dem Bild für den Schnittstelllenadapter sieht man auch warum DTR an sein muss. Denn ohne pullup keine Signal.

Ich bin beruhigt:

In beiden Dateien steht das Gleiche! Es muss also irgendeine andere Ursache haben. Frag doch mal beim Hersteller an.

Frag doch mal beim Hersteller an.

Den Gedanke habe ich gerade mit mir rumgetragen…

In beiden Dateien steht das Gleiche!

Bei der Desktopausgabe sieht man 13 Zeichen und im Log stehen 23 …habe ich dann auch gesehen. Da werden die 00-Bytes nicht mit angezeigt.

Ich bedanke mich für deine Ausdauer bis hierher und melde mich wieder!!!

Ich hab´ noch bisschen mit den Baudraten experimentiert und siehe da, bei 4800 Baud komme ich zu den Werten, die passen.
Es sind zwar keine 12, sondern nur 11 Byte, die ich empfange, aber

dec 	232 	003 	055 	000 	115 	000 	194	 001 	068	 000 	040
hex 	E8 	03 	37 	00 	73 	00 	C2 	01 	44 	00 	28
bin 	11101000 00000011 00110111 00000000 01110011 00000000 11000010 00000001 01000100 00000000 00101000

D.h.
0 / Gerätekennung Low-Byte $E8
hex E8 / dec 232
1 / Gerätekennung High-Byte $03
hex 03 / dec 003
2 / Distanz Low-Byte
hex 37 / dec 055 (Laut Anzeige momentan 55cm =passt!)
3 / Distanz High-Byte
hex 00 / dec 000
4 / Füllhöhe Low-Byte
hex 73 / dec 115 (Laut Anzeige momentan 115cm =passt!)
5 / Füllhöhe High-Byte
hex 00 / dec 000
6 / Liter Low-Byte
hex C2 / dec 194
7 / Liter High-Byte --(Laut Anzeige momentan 4500 Liter =passt fast)
hex 01 / dec 001 —/
8 / Inhalt in Prozent
hex 44 / dec 068 (Laut Anzeige momentan 68% =passt!))
9 / Zustand der Ausgänge
hex 00 / dec 000
10 / Kontrollbyte Low-Byte
hex 28 / dec 28
11 / Kontrollbyte High-Byte
? ?

Somit passt alles, bis auf die Liter-Bytes, die 4500 ergeben sollten, aber nur 450 (errechnet) übermitteln.

Wie kann ich nun die Bytes „ausschnippeln“ und jeweils in einer Variable ausgeben. Zudem müsste ich den Literwert mit 10 multiplizieren.

Na das ist doch was! :smiley: Wie gesagt:Baudrate.

Zum Ausschneiden kannst Du die Bytenummer benutzen:
Beispiel:

ord($chunk{1})

schneidet das erste Byte aus usw. Die For-Schleife macht es genauso.

Erstmal müssen wir dafür sorgen, dass der Datenblock synchron einläuft. Dazu benutzen wir am besten die COM/LAN-Instanz und tragen als LeftCutChar die Gerätekennung E803 ein. Das sind zwei Zeichen. Diese erzeugt man am einfachsten mitder Eingabe per ASCII: den dezimalen Code bei gedrückter ALT-Taste mit dem Ziffernblock eingeben. Am besten geht das über Details. Rechte Maustaste und ADD…

Danach poste bitte nochmal ein Log. Wir müssen unbedingt sicherstellen, dass immer die gleichen Datenblöcke eingehen. Sonst funktioniert die Nummerierung nicht.

Also mit dem „alten“ COM/LAN-Modul habe ich keinen Erfolg.
Es kommt einfach nicht an „Register-Variable“ an, außer wenn ich „Just Forward“ einstelle. Ich hatte diese beiden ASCII´s auch schonmal probiert, bevor wir soweit waren, auch ohne Update von „RV“.

Nun habe ich das neue COM-Modul laufen und das Log sieht immer sehr gut aus:

18:29:43 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:44 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:45 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:46 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:47 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:48 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:49 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:50 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:51 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:52 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:53 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:54 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:55 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:56 > e8 03 37 00 73 00 c2 01 44 00 28 
18:29:57 > e8 03 37 00 73 00 c2 01 44 00 28

Ich habe mal die „microtime“ abgeschnitten und das Trennzeichen auf „>“ geändert. Hoffe, das stört nicht!?

Ausgehend vom letzten von Dir geposteten Script.

<? 
if (GetValueString("LEVELJET") == "") 
   return; 
if (!IPS_SemaphoreEnter("RegisterVariable_Log_run",900)) 
   return; 
//IPS_Sleep(300); 
$buffer=GetValueString("LEVELJET"); 
SetValueString("LEVELJET",""); 
list($usec, $sec) = explode(" ", microtime()); 
$start_time = strftime("%H:%M:%S",$sec).substr($usec,1); 

// open logfile 
$handle = fopen("H:/LevelJet/testlog.txt","a"); //$logfilepath definiert die Datei mit Pfad 

//Message verarbeiten 
$length = strlen($buffer); 
if ($length !== 0) 
{ 
   fwrite($handle,$start_time.":>"); 
   for ($i=0; $i<$length; $i++) 
   { 
      $dbyte = ord($buffer{$i}); 
      fwrite($handle, set_byte($dbyte)." "); 
   } 
   fwrite($handle,"
"); 
} 
fclose($handle); 

function set_byte($byte) 
{ 
   if ($byte < 16) 
      return "0".dechex($byte); 
   else 
      return dechex($byte); 
} 
IPS_SemaphoreLeave("RegisterVariable_Log_run"); 
?> 

Wäre ich für folgende Variante:

<? 
if (GetValueString("LEVELJET") == "") 
   return; 
if (!IPS_SemaphoreEnter("RegisterVariable_Log_run",900)) 
   return; 
//IPS_Sleep(300); 
$buffer=GetValueString("LEVELJET"); 
SetValueString("LEVELJET",""); 
list($usec, $sec) = explode(" ", microtime()); 
$start_time = strftime("%H:%M:%S",$sec).substr($usec,1); 
$ldebug = true;

// Datenblock zerlegen und Menge errechnen
$length = strlen($buffer);
if ($ldebug)
	echo "Länge: ". $length ."
";
if ($length == 11) 
{ 
	$high_byte = ord($buffer{7});
	$low_byte = ord($buffer{6});
	$menge = $high_byte * 256 *10 + $low_byte * 10;
	SetValueInteger("fuellmenge",$menge); //"fuellmenge" muss als Variable angepasst oder angelegt werden
}


if ($ldebug) //damit läuft diese Anzeige nur im debugmodus
{
	// open logfile 
	$handle = fopen("H:/LevelJet/testlog.txt","a"); //$logfilepath definiert die Datei mit Pfad 
	//Message verarbeiten 
	$length = strlen($buffer); 
	if ($length !== 0) 
	{ 
		fwrite($handle,$start_time.":>"); 
		for ($i=0; $i<$length; $i++) 
		{ 
			$dbyte = ord($buffer{$i}); 
			fwrite($handle, set_byte($dbyte)." "); 
		} 
		fwrite($handle,"
"); 
	} 
	fclose($handle); 
}

function set_byte($byte) 
{ 
   if ($byte < 16) 
      return "0".dechex($byte); 
   else 
      return dechex($byte); 
} 
IPS_SemaphoreLeave("RegisterVariable_Log_run"); 
?> 

bitte die Ausgabe posten.

Wow!

Ich habe meine Variable mit dem richtigen Wert … 4500 Liter!

Das Script:


<?
if (GetValueString("LEVELJET") == "")
   return;
if (!IPS_SemaphoreEnter("RegisterVariable_Log_run",1))
   return;
IPS_Sleep(800);
$buffer=GetValueString("LEVELJET");
SetValueString("LEVELJET","");
list($usec, $sec) = explode(" ", microtime());
$start_time = strftime("%H:%M:%S",$sec);
//$start_time = strftime("%H:%M:%S",$sec).substr($usec,1);
$ldebug = true;

// Datenblock zerlegen und Menge errechnen
$length = strlen($buffer);
if ($ldebug)
    echo "Länge: ". $length ."
";
if ($length == 11)
{
    $high_byte = ord($buffer{7});
    $low_byte = ord($buffer{6});
    $menge = $high_byte * 256 *10 + $low_byte * 10;
    SetValueInteger("HEIZOEL_FUELLMENGE",$menge); //"fuellmenge" muss als Variable angepasst oder angelegt werden
}


if ($ldebug) //damit läuft diese Anzeige nur im debugmodus
{
    // open logfile
    $handle = fopen("H:/LevelJet/testlog.txt","a"); //$logfilepath definiert die Datei mit Pfad
    //Message verarbeiten
    $length = strlen($buffer);
    if ($length !== 0)
    {
        fwrite($handle,$start_time." > ");
        for ($i=0; $i<$length; $i++)
        {
            $dbyte = ord($buffer{$i});
            fwrite($handle, set_byte($dbyte)." ");
        }
        fwrite($handle,"
");
    }
    fclose($handle);
}

function set_byte($byte)
{
   if ($byte < 16)
      return "0".dechex($byte);
   else
      return dechex($byte);
}
IPS_SemaphoreLeave("RegisterVariable_Log_run");
?>

Ich grübel den ganzen Sonntag, wie ich das hinbekomme und du (Fabian) guckst mal vorbei und schreibst auch gleich die passende Lösung …faszinierend und vielen, vielen Dank!

Ich denke, nun komme ich auch zurecht, wenn ich die anderen Statusmitteilungen noch als Variablenwert ausgeben möchte.

Ich wünsche noch einen wunderschönen Rest-Sonntag-Abend!

Ich muss nun auch wiedermal was für´n WAF tun;)

Ja das mit dem WAF ist so’ne Sache… :rolleyes:

Jetzt kann ich ja die Katze aus dem Sack lassen: Bis jetzt habe ich noch nie was mit dem COM-Port zu tun gehabt. :o
Das war sozusagen mein „erstes Mal“ und auch noch ganz virtuell :smiley: :smiley:

Auch so… eine Frage noch bitte!..

Wie regel ich das am besten, dass nur ein Eintrag zur vollen Stunde in Log geschrieben wird, bzw. nur die Literausgabe inkl. Logtime in eine Datei geschrieben wird?

Auch wenn es sich einfach anhört, es ist nicht so!

Da die Daten immer nur angehangen werden, muss die Variable geleert werden um einen Überlauf zu vermeiden. Will sagen, das Script muss - zumindest zum Löschen der Variablen - ständig laufen.
Am einfachsten wäre ein zweites Script, welches jede Stunde den Wert ausliest und „wegschreibt“.

Die ideale Lösung wäre ein Setzen und Zurücksetzen des DTR mittels IPS-Kommando, oder Öffnen und Schließen des COM-Ports.

Ich gebe die Frage gern an die anderen Forenteilnehmer ab. Denn selbst der sekündliche Dateneingang und das Löschen der Variable jede Sekunde lässt das IPS-log schnell anwachsen. :frowning:

OK, das kann ich regeln, indem ich das IPS-Log abschalte.
Habe heute schon ein LOG mit 700MB!:eek: gelöscht.

Trotzdem nochmals vielen Dank!

ehe ichs vergesse: die Variable $ldebug solltest Du auf false setzen, wenn es soweit funktioniert.

$ldebug = false;

dann hört auch die Dateischreiberei auf.

Das ist doch was!
War meine nächste Frage…