Forum: PC-Programmierung C#: Serielle Schnittstelle lesen


von Daniel (Gast)


Lesenswert?

Hallo!

Ich möchte eine PC-Steuerung für einen Transceiver programmieren (Ich 
weiß, da gibt es schon einige, aber ich möchte meine Programmier- 
Kenntnisse erweitern.)

Zwei unterschiedliche Aufgaben möchte ich lösen:
- schreiben (gelöst)
- lesen (offen)

Also die Aufgabe schreiben, habe ich schon gelöst.

C#:
private void button20_Click(object sender, EventArgs e)
{
   string str = "fe fe 5e e0 00 00 00 90 24 00 fd";
   byte[] bytes = str.Split(' ').Select(s => 
Convert.ToByte(s,16)).ToArray();
   Serial.Write(bytes, 0, bytes.Length);
   textBox3.Text = "024 900 000 Hz";
} // also es wird der notwendige String- Befehl für den Transceiver 
umgewandelt und über die write-Methode übertragen. Dadurch kann ich über 
den PC Einstellungen am Transceiver ändern.

Beim Lösen habe ich dennoch meine Probleme. Wenn ich etwas lesen will, 
dann muss ich zuerst einen Schreib- Befehl zum Geräte hinschicken, damit 
ich die benötigten Daten lesen kann.

C#: mein bisheriger Lese- Befehl
private void button32_Click(object sender, EventArgs e)
{
string str = "fe fe 5e e0 04 fd";
byte[] bytes = str.Split(' ').Select(s => 
Convert.ToByte(s,16)).ToArray();
Serial.Write(bytes, 0, bytes.Length);

byte[] read_buffer = new byte[100];
read_buffer.ToArray();
string s1=Serial.Read(read_buffer, 0, 50).ToString();
textBox2.Text = s1;
}  // Zuerst schreiben, dann lesen und dann in einem Textfeld ausgeben. 
In der Ausgabe bekomme ich immer "38 14"!

Kann mir vielleicht jemand helfen, wie ich die Daten lesen kann? Danke 
im Voraus

von Daniel (Gast)


Lesenswert?

Zusatz:

Könnte es sein, dass das Lesen zwar funktioniert aber die 
Formatumwandlung nicht??

Ich sitz an diesem Problem schon ein paar Tage. Irgendwie schaff ich es 
nicht! :/

von Pastor Braune (Gast)


Lesenswert?


von Daniel (Gast)


Lesenswert?

Vielen Dank für die rasche Antwort!

Hab den Code analysiert und verucht in meinen einzubauen. Jetzt ist es 
so, dass wenn ich den Button zum Lesen drücke -> das komplette Programm 
hängt sich auf und ich kann nichts mehr drücken.

c#
private void button32_Click(object sender, EventArgs e)
{
string str = "fe fe 5e e0 04 fd";
byte[] bytes = str.Split(' ').Select(s => Convert.ToByte(s, 
16)).ToArray();
Serial.Write(bytes, 0, bytes.Length);
            if (comO)
            {
                try
                {
                    byteEnd = Serial.NewLine.ToCharArray();

                    Bytenumber = Serial.BytesToRead;

                    this.Invoke(new EventHandler(DoUpdate));

                }
                catch (Exception ex)
                {
                }
            }
}

public void DoUpdate(object sender, System.EventArgs e)
{
textBox2.Text = readBuffer;
}

Weißt du vielleicht, was falsch sein könnte? oder gibt es andere 
Lösungen?

Wie ich begonnen habe, hätte ich gedacht, dass das Schreiben schwer wird 
und das Lesen leicht. Mittlerweile ist eher umgekehrt!

von Bastian W. (jackfrost)


Lesenswert?

Hi,

Hast du mit Breakpoints schon geschaut wo das Programm stoppt ?

Spar dir doch den String und das umwandeln und leg gleich ein Bytearray 
an.

Ich hab für die Kommunikation mit einem Coriolismassenflussmessers über 
RS232 mal das geschrieben (Senden und Empfangen läuft hier in nem 
eigenen Thread) :
1
byte[] MasseByte = { 21, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 221 };
2
this.port.Write(MasseByte, 0, 12);
3
/* ... */
4
while (this.port.BytesToRead < 12)  // Da die Antwort nicht sofort kommt hab ich hier gewartet
5
                    {
6
                        Status[0] = "Prüfe Bytes";
7
                        Status[1] = DateTime.Now;
8
                        myForm.Invoke(updateUIState, Status);
9
                        Thread.Sleep(20); 
10
                        if (!Running)
11
                            break;
12
                    }
13
/* ... */
14
15
this.port.Read(buffer, 0, 12);

Gruß JackFrost

von Daniel (Gast)


Lesenswert?

Pastor Braune schrieb:
> ganz nach unten scrollen ;-)
> https://code.msdn.microsoft.com/SerialPort-Sample-in-VBNET-fb040fb2

Danke für den Post. Wenn ich ganz runter scrolle, dann finde ich die 
Read- Funktion. Dennoch muss ich sagen, dass ich aus dem Code nicht 
schlau geworden bin. Die Funktionen SerialPort1_DataReceived und 
DoUpdate hab ich in meinen Code eingebaut (in meinen vorigen Post ist 
der Code dazu). Wenn ich es teste, dann hängt sich das Programm auf. 
Weißt du vielleicht eine Lösung?


Bastian W. schrieb:
> Hi,
>
> Hast du mit Breakpoints schon geschaut wo das Programm stoppt ?
>
> Spar dir doch den String und das umwandeln und leg gleich ein Bytearray
> an.
>
> Ich hab für die Kommunikation mit einem Coriolismassenflussmessers über
> RS232 mal das geschrieben (Senden und Empfangen läuft hier in nem
> eigenen Thread) :
>
> byte[] MasseByte = { 21, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 221 };
> this.port.Write(MasseByte, 0, 12);
> /* ... */
> while (this.port.BytesToRead < 12)  // Da die Antwort nicht sofort kommt
> hab ich hier gewartet
>                     {
>                         Status[0] = "Prüfe Bytes";
>                         Status[1] = DateTime.Now;
>                         myForm.Invoke(updateUIState, Status);
>                         Thread.Sleep(20);
>                         if (!Running)
>                             break;
>                     }
> /* ... */
>
> this.port.Read(buffer, 0, 12);
>
> Gruß JackFrost

Danke für die schnellen Anworten. Ich definiere den String und führe die 
Umwandlung deswegen durch, damit ich persönlich einen besseren Überlick 
über den Code habe. Weiteres ist so, dass ich deinen angehängten Code 
nicht ganz verstehe. Was definieren diese Zahlen?
> byte[] MasseByte = { 21, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 221 };

Ich denke nämlich, dass ich zwar etwas lese, aber es ist das falsche 
Format. Was würdest du Vorschlagen?

Die Breakpoint- Test werde ich heute Abend durchführen und wieder 
berichte, was ich erfahren habe.

von Pastor Braune (Gast)


Lesenswert?

Ich würde erstmal den Beispielcode ausprobieren und wenn es funktioniert 
den dann erweitern/anpassen.
Ich kann dir auch nur empfehlen dir die ganzen Artikel durchzulesen und 
auch den links zu folgen.

von Pastor Braune (Gast)


Lesenswert?


von EcmSpy (Gast)


Lesenswert?


von Daniel (Gast)


Lesenswert?

EcmSpy schrieb:
> C# - mit welcher Runtime?

Ich programmiere mit Microsoft Visual Studio 2015 Enterprise (somit also 
.NET Common Language Runtime)

von EcmSpy (Gast)


Lesenswert?

Dieses Konstrukt, wenn ich es auch hässlich finde, funktioniert mit Mono 
und .Net:
1
        for (i = 0; i < _bytesExpected; i++)
2
        {
3
          try                 
4
          {
5
            _dataBuffer[i] = _serialDevice.ReadByte();
6
            _bytesReceived ++;
7
          }
8
          catch (TimeoutException exp)
9
          {
10
            // clear flag
11
            _rxActive = false;
12
            _bytesReceived = 0;
13
            throw new System.TimeoutException("Connection timed out");
14
          }
15
          catch (Exception exp)
16
          {
17
            // clear flag
18
            _rxActive = false;
19
            _bytesReceived = 0;
20
            throw new Exception("Failed to read response");
21
          }  
22
        }
23
      }

von Geert H. (geerth)


Lesenswert?

Pastor Braune schrieb:
> http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm

Zitat:
If you are a beginner, it may easily take you days or weeks to go 
through and understand this totorial, but don't step to a new chapter 
before you understand the previous one! Take it easy, step by step. The 
user interface (UI) of .Net is entierly event driven and serial port 
uses multithreading. Unless you understand how this works, you will 
never be a good .Net programmer and will never be able to make reliable 
programs. No matter what .Net programming you need to do, you will need 
most of the knowledge in this totorial so forget your serial port 
problems for a while (the reason why you came here) and get the 
necessary background knowledge first. Then your serial port application 
will be a piece of cake to program. SerialPort is really not that 
difficult. For example, this is all you need to read an ASCII string and 
append it to the text in the Received textbox. The difficult part is to 
understand what you are doing!

von Bastian W. (jackfrost)


Lesenswert?

Daniel schrieb:
> Weiteres ist so, dass ich deinen angehängten Code
> nicht ganz verstehe. Was definieren diese Zahlen?

Diese Bytes müssen an den Sensor gesendet werden, so das ich als Antwort 
die geflossene Masse erhalte. Das ist quasi wie dein String direkt als 
Bytearray.

Da ich alle ~0,25s Daten empfangen habe und somit auch senden musste 
habe ich das Senden und Empfangen in einen eigenen Thread gepackt so das 
die GUI nicht durch das Warten blockiert wird. Ich weiss nicht ob es 
auch ohne gegangen währe.

Deine Daten würden ja wie folgt lauten :
1
byte[] bytes = {0xfe, 0xfe, 0x5e, 0xe0, 0x04, 0xfd};
2
3
this.Serial.Write(bytes, 0, 6); //Daten an die offne Schnittstelle Serial senden
4
/* ... */
5
while (this.Serial.BytesToRead < 12)  // Da die Antwort nicht sofort kommt hab ich hier gewartet bis die 12 Bytes in meinem Fall empfangen wurden.
6
                    {
7
                        Status[0] = "Prüfe Bytes";  // Debugging für mich
8
                        Status[1] = DateTime.Now; // Debugging für mich
9
                        myForm.Invoke(updateUIState, Status); // Debugging für mich
10
                        Thread.Sleep(20); //Wartezeit für eine erneute Prüfung
11
                        if (!Running)  // Stoppbedingung falls vom GUI Thread senden und Empfangen gestoppt werden soll
12
                            break;
13
                    }
14
/* ... */
15
16
this.Serial.Read(buffer, 0, 12);  // Einlesen der 12 ersten Bytes aus dem Empfangspuffer  von port. Buffer ist ein Bytearray

Anschließend hab ich die Daten an den GUI-Thread übergeben und da dann 
verarbeitet.

Gruß JackFrost

von Martin L. (martin_l)


Lesenswert?

Hallo Daniel,

auch wenn schon ein paar Antworten da sind, hier noch ein paar Punkte / 
Fragen die dir beim Schreiben deiner Empfangssoftware helfen sollen.

1) das Auslesen startest du, indem du auf Button32 drückst. Du sendest 
dann den Auslesebefehl. Somit kannst du doch den die Empfangsroutine 
vollig unabhängig von dieser Buttonroutine schreiben.
Scheinbar ist sie auch in dieser Routine und das finde ich 
kontraproduktiv.
Den scheinbar empfängst du ja etwas (38 14), aber das ist wohl nicht 
alles, oder?

2) hast du ein Datenblatt von dem Sensor? Darin wird mit Sicherheit 
stehen, wie der Sensor antwortet und dann kannst du deine Leseroutine 
genau darauf abstimmen und wenn sie die alle Daten empfangen hat, dann 
löst sie ein Event aus, und aktualisiert dann die Textbox.

3) da du ja deine Programmierkenntnisse erweitern möchtest schau dir mal 
die Grundzüge der OOP an und mache dir mal grundlegende Gedanken über 
die einzelnen Funktionen deines Terminalprogramms. Und danach versuchst 
du die einzelnen Funktionen zu programmieren und in eine Software zu 
integrieren.

Ich habe irgendwann auch angefangen meine PC-Software selber zu 
schreiben und alles sofort versucht in Software zu hacken. Aber 
irgendwann kommt der Punkt wo es nicht funktioniert oder man 
Fremdsoftware nicht versteht, weil man die Grundlagen nicht kennt / 
verstanden hat.

Und nicht aufgeben, irgendwann kommt die Erkenntnis

Leider habe ich aufgrund eines Jobwechsels zu wenig Zeit zum Spielen 
(Hardwarebasteln und SW dafür programmieren) aber genau das muss es 
sein. Ein Spiel auf das man Lust hat :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.