Laden...

Werte vom COM-Port innerhalb einer Routine in die Felder schreiben

Erstellt von hruendel vor einem Jahr Letzter Beitrag vor einem Jahr 790 Views
H
hruendel Themenstarter:in
5 Beiträge seit 2012
vor einem Jahr
Werte vom COM-Port innerhalb einer Routine in die Felder schreiben

Hallo Gemeinde,

ich versuche ein Windowsprogramm für das Kalibrieren eines Sensors zu programmieren. Ich habe zwei COM-Ports (serialPortCalibrator, serialPortMultimeter) auf denen ich die Befehle an Kalibrator und Multimeter sende. Auslesen von COM-Ports tue ich mit einem getrennten Thread. Funktionieren tut alles ausser dass, ich die Messwerte (multimeterValueFloat1, multimeterValueFloat2) nicht in die textBoxen reinbekomme.

Wenn ich die Variablen von der calibrationRoutine die ich per Tastenclick aufrufe in der MessageBox ausgebe sind diese aktuell. Sie haben die richtigen und aktuellen Messwerte von dem Multimeter.

Mir ist verständlich dass, die Kalibrierroutinedie gewisse Schritte ausführt (anfragen, warten, COM-Ports lesen, werte in die Felder schreiben ) sich nicht für die aktualität der Variblen interessiert.

Wie kann ich die aktualieserten Variablen (multimeterValueFloat1, multimeterValueFloat2) zum Schluß in die Formular-Felder schreiben?

Das habe ich bischer ohne Erfolg probiert:* Werte direkt aus der Routine schreiben

  • Werte aus eine anderen Funktion schreibe.
  • Werte über Invoke schreiben (wie im Beispiel)

Relevanter Codeabschnitt...


public partial class MainForm : Form
{
	// Messdaten
	double multimeterValueFloat1 = 0.000;
	double multimeterValueFloat2 = 0.000;
		
	void calibrationRoutine(object sender, EventArgs e){
		
		// Calibrator -> 0%
		serialPortCalibrator.WriteLine(":ps 0\n\r");
		System.Threading.Thread.Sleep(10000);
		
		// Multimeter ablesen
		serialPortMultimeter.WriteLine("S?\r");
		System.Threading.Thread.Sleep(300);
		this.labelMesswert1Multimeter.Invoke (new MethodInvoker(calibrationWriteLabel1));
		
		// Calibrator -> 100%
		serialPortCalibrator.WriteLine(":ps 100\n\r");
		System.Threading.Thread.Sleep(10000);
		
		// Multimeter ablesen
		serialPortMultimeter.WriteLine("S?\r");
		System.Threading.Thread.Sleep(300);
		this.labelMesswert5Multimeter.Invoke (new MethodInvoker(calibrationWriteLabel2));
	}

	void calibrationWriteLabel1(){
		labelMesswert1Multimeter.Text = multimeterValueFloat1.ToString();
	}
	void calibrationWriteLabel2(){
		labelMesswert2Multimeter.Text = multimeterValueFloat2.ToString();
	}
}

4.938 Beiträge seit 2008
vor einem Jahr

Läuft die calibrationRoutine direkt im UI-Thread? Dann s. [FAQ] Warum blockiert mein GUI?

Du solltest das komplette Lesen und Schreiben vom COM-Port in eine eigene Klasse auslagern und mit Tasks arbeiten (anstatt direkten Threads).

Evtl. hilft dir auch Template SerialPort ?

H
hruendel Themenstarter:in
5 Beiträge seit 2012
vor einem Jahr

Danke für die Infos. ich werde die Template ausprobieren.

H
hruendel Themenstarter:in
5 Beiträge seit 2012
vor einem Jahr

Das Programm läuft in etwa wie erwünscht. Wollte etwas Feedback geben.

Das SerialTemplate funktioniert bei mir nicht. Auch die Exe aus dem Debug-Ordner empfängt bei mir keine Daten. Auserdem ist das Ding mir dem framework 3.0 etwas veraltet. Beim Versuch das Beispiel aus dem VisualStudio 2022 su starten kommt es zum Abbruch. Möglicherweise habe ich mich damit nicht ausgiebig genug beschäftigt.

[FAQ] Warum blockiert mein GUI? hat mich jedoch auf den Weg gebracht.

Folgendes habe ich gemacht:

  • Empfang von seriellen Daten in eigenen Thread ausgelagert.
  • Invoice beim Schreiben der Classen-Variablen
  • Die Schrittkette der Kalibrationsroutine ebenfalls in eigenen Thread ausgelagert.

Jetzt läuft alles sehr geschmeidig. Den Aufwand mit dem Seriellen Port in eigene Klasse auszulagern habe ich nicht gemacht. Bin auch so zufrieden.