Wohin mit dem Problem ? also einfach mal hier rein:
Ich programmiere grade eine Software für meine elektronische Last KEL103 von KORAD.
Das Gerät kann mittels SCPI Kommandos ferngesteuert werden.
Dies tätige ich mittels RS232 (Juchu...Ich hab sowas noch auf meinem Motherboard....

Läuft aber auch über den USB des Gerätes (als virtuellen Comport COM8).
Die Grundfunktionen, Kommandos, sind jetzt gut getestet und laufen.
über den virtuellen Comport genauso wie über die originale RS232.
Nun möchte ich den Batterietestmodus überwachen, bzw. beim Entladen eines Akkus die Spannungskurve aufzeichnen und in "Echtzeit" darstellen.
Das Gerät soll mir also kontinuierlich die aktuelle Spannung zurück senden.
Da stellt sich schon das erste Problem: "kontinuierlich"
Mit kontinuierlich meinte ich eigentlich Zeitsynchron, aber das gibt es nicht wenn man ein Betriebssystem hat.
Beim TTimer habe ich eine minimalsten Intervall von 16 Millisekunden gemessen, egal was ich da einstelle.
Mal abgesehen davon, dass er Parkinson hat, das habe ich mir mit dem Oszilloskop angesehen...
Vor einige Zeit hatte ich mir aber schon eine Timer Komponente mittels MMSystem unter Windows gebaut und diese
funktioniert wesentlich genauer. (Meistens

Wie dem auch sei, beim experimentieren habe ich nun mehrfach einen Fehler erhalten, den ich irgendwie garnicht zuordnen kann:
Siehe Bild: dann der "merkwürdige" Code dazu: Der Fehler tritt meist so nach 14000 Messwerten auf, was natürlich ärgerlich ist, da war ich mitten in der Akkuentladung....
Meinen Code jetzt hier rein zu packen gibt meiner Meinung nach nicht wirklich Sinn, da hier so ziemlich alles aus eigenen
Komponenten besteht. Timer, Serielle, Kurvendarstellung...
Mich wundert nur wo der Fehler herkommt und so habe ich natürlich schon so Einges getestet
und dann lief es doch plötzlich über eine halbe Milion Meßwerte völlig einwanfrei.
Nach 600.000 Messungen (hab ich dann abgebrochen) und mehrfachen Akkutest ausgeführt, das Problem "scheint" behoben.
Das Wort "Scheint" gibt es aber bei mir nicht, also guckte ich, was ich denn verändert habe.
Eigentlich habe ich nur eine unnötige Testzeile ausgeklammert.
Also wieder rein damit und prüfen.
Jo, wieder Absturz

Die vermeintliche Testzeile ist folgende:
Form_Main.Label_Voltage.caption:=data;
klammere ich die aus, geht es einwandfrei, ist sie drin kommt ein zeitnaher Absturz.
Das Programm läuft jetz grad wieder schon seit 2 Stunden (800.000 Messwerte) völlig ohne Probleme ohne dieser Zeile
ich kann auch nebenbei im Internet surfen usw. Kein Problem.
So läuft das Programm grade weiter, während ich euch grade hier schreibe.
Das verblüffende ist ja, dass ich die "vermeintliche" Absturzzeile ähnlich sogar ein zweites Mal ausführe,
was aber anscheinend kein Problem darstellt. Oder umgekehrt, wenn ich zweimal auf den Label zugreife gibt es ein Problem ???
Deshalb mal doch noch etwas Code:
Code: Alles auswählen
//---------------------------------------------------------------------------
// Hier wird der Empfangsstring ausgewertet und zugeordnet
// Meine Vermutung: hier sollten keine Zugriffe auf andere Komponenten erfolgen,
// das führt unter Umständen zu abstürzen.
// der übergebene String hat bei Messwerten die Form : '1.2345V'
// das V für Volt wird rausgebastelt und der Wert in einen Float gewandelt und in den Kurvenspeicher übertragen
procedure DispatchRx(data:String);
var value:single; res:integer;
begin
if length(data) = 0 then exit; // Leerstring ignorieren
case DataMode of
Data_Unknown : ;
Data_Voltage : begin
// Form_Main.Label_Voltage.caption:=data; // <==== Problem, merkwürdiger Absturz ???
val(data,value,res); // versuchen in Zahl zu wandeln
if res > 0 then begin // hat nicht geklappt, dann
data:=copy(data,1,length(data)-1); // den String kopieren bis zum falschen Character
end; // damit sollte das "V" für Voltage verschwunden sein
val(data,value,res); // Die Zahlenwandlung sollte nun klappen
Form_Main.Label_Voltage.caption:=data; // <===== hier gibt es KEINE Probleme ?????
Form_Curve.Curve1.Add(value); // den Wert in den Kurvenspeicher übernehmen
end;
Data_Current : ;
Data_Input : ;
Data_Capacity : Form_Main.Label_Capacity.caption:=data;
Data_Time : Form_Main.Label_Time.caption:=data;
Data_Ident : Form_Main.Label_DeviceIdent.caption:=data;
end;
end;
//------------------------------------------------------------------------------------------
// wird von meiner seriellen Komponente aufgerufen, wenn sich Daten im Receivepuffer befinden
// hier wird solange der "globale" RxStr String zusammengesetzt bis ein LineFeed auftaucht
// dann wird dieser String der Procedure DispatchRx übergeben
procedure TFormMain.SerialRxData(RxCount: cardinal; TxCount: cardinal;
Error: DWORD);
var b:char;
begin
while RxCount > 0 do begin
Serial.ReadByte(b); // ein Byte aus dem Empfangspuffer laden
dec(RxCount); // Anzahl empfangener Bytes -1
if b = ' ' then continue; // Leerzeichen ignorieren
if b = chr($0D) then continue; // Carriage Return ignorieren
if b = LineFeed then begin // Endezeichen ($0A) erkannt, Empfangsstring ist komplett
DispatchRx(RxStr);
// ListBox1.Items.Add(RxStr); // Den String nun verarbeiten, speichern oder was auch immer
RxStr:=''; // !! muss sein, weil evtl. mehrere Strings getrennt mit LF existieren
end else begin
if length(RxStr) < 50 then RxStr:=RxStr+b // Empfangszeichen hinten anhängen, length Abfrage nur testweise
else Halt; // passierte nie auch nicht nach 600.000 Messwerten
end; // else
end;
end;
Übrigens was ist denn das für eine merkwürdige Softwarezeile in der Unit LazTracer ???
Siro