Forum: PC Hard- und Software Hilfe beim Einlesen des Com Ports C#


von Daniel B. (yzdani)


Angehängte Dateien:

Lesenswert?

Servus,

ich scheitere gerade beim Einlesen einer COM-Schnittstelle.

Die Schnittstelle sollte richtig konfiguriert sein.
Methoden wie "port.readline" und "port.readexisting" funktioniern hier 
auch nicht zu 100%

Ich möchte mit der Software ein Bluetooth Modul steuern.
Über Terminal Software wie Tera Term und Cool Term funktioniert dies 
wunderbar, doch es ist nicht Sinn und Zweck das ganze von einem Terminal 
aus zu Steuern.
Auf den Port zu schreiben funktioniert, und der Chip gehorcht auch den 
Befehlen.
Scheitert aber beim Einlesen der sichtbaren Devices.
Die genaue Länge des Bytestreams ist unklar und ein Absatz wird auch 
keiner empfangen.

Ich habe den Auschnitt des Cods mal angehängt.

Der Chip ist ein WT32I mit der neuesten IWRAP Firmware

Freue mich auf eine Antwort!

von Borislav B. (boris_b)


Lesenswert?

So spontan würde ich sagen, dass du viel zu viel liest:
1
char[] macadress = new char[port.BytesToRead];
2
3
for (int i = 0; i < macadress.Length;i++ )
4
            {
5
                port.Read(macadress, i, port.BytesToRead);
6
                    
7
            }

Die Schleife kannst du dir sparen:
1
char[] macadress = new char[port.BytesToRead];
2
port.Read(macadress, 0, port.BytesToRead);

Und vorsicht: BytesToRead kann auch 0 sein!

von benutzer (Gast)


Lesenswert?

Ich würde eher sagen das es zu schnell geht.

Du sendest einen Datenpacket richtung Bluetooth modul und erwartest das 
das Modul innerhalb weniger Taktzüglen deines Programmes eine antwort 
erhält.

Versuche es mal üwie folgt an zugehen

- du initialisiert den serialPort im Konstruktor deines Forms
- beim Clicken auf einen Button sendest du mit der Write Methode der 
serial Port Klasse dein Datenpacket weg
- mit dem Event aus der Serial Port klasse
private void serialPort_DataReceived(object sender, 
SerialDataReceivedEventArgs e)

dort kannst du die empfangen daten dann verarbeiten

von Daniel B. (yzdani)


Lesenswert?

Boris P. schrieb:
> Und vorsicht: BytesToRead kann auch 0 sein!

Danke für deine Anwtort!

Was wäre eine bessere Alternative?

Gruss
Dani

von Pusteblumenwegmäher (Gast)


Lesenswert?

public int Read(char[] buffer, int offset, int count)

Generell solltest du beachten, dass Read nicht unbedingt 'count' Bytes 
zurückgibt, sondern maximal 'count' Bytes. Du darfst also den 
zurückgelieferten Wert nicht ignorieren.
Man kann nicht im Voraus wissen, wieviel bei einem Read gelesen wird 
(*). Wenn gar keine Daten zur Verfügung stehen, blockiert Read, bis 
mindestens 1 Byte gelesen werden kann oder bis zum Timeout; zwischen 
Timeout und 'count' Bytes ist also alles möglich. Im einfachsten Fall 
verwendest du eine Schleife, die erst verlassen wird, wenn insgesamt 
count Bytes gelesen wurden.

(*) Als ich vor kurzem ein Gerät per USB-Adapter ausgelesen habe, kam 
der kurze Datenblock manchmal in einem Stück, dann wieder in 4 Teilen an 
...

Ein paar Tipps:

http://blogs.msdn.com/b/bclteam/archive/2006/10/10/top-5-serialport-tips-_5b00_kim-hamilton_5d00_.aspx

http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport

Ich selbst würde es bei einem neuen Projekt wahrscheinlich mit dem 
BaseStream versuchen (und gegebenenfalls, bei .NET >= 4.5, mit 
ReadAsync).

BTW: Falsches Unterforum (-> PC-Programmierung)

von Daniel B. (yzdani)


Lesenswert?

Hab es jetzt mit dem DataReceived event versucht.
https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived(v=vs.110).aspx

In der Konsole funktioniert das Programm, aber auf der GUI bekomm ich 
das mit dem data received handler nicht hin...

Bitte um Hilfe!

Gruß
Dani

von Borislav B. (boris_b)


Lesenswert?

Daniel R. schrieb:
> In der Konsole funktioniert das Programm, aber auf der GUI bekomm ich
> das mit dem data received handler nicht hin...

Hö? Das macht doch gar keinen Unterschied.
Beschreib mal genauer, was nicht klappt...

von Daniel B. (yzdani)


Lesenswert?

Hab jetzt eine Multiline Textbox erstellt.
Die empfangenen Daten sollen in der Textbox dargestellt werden.
Wenn ich auf dem Board einen Taster drücke wird ein String gesendet.

wenn ich jetzt im Datareceived handler bin will ich den empfangen Text 
sofort in die Textbox schreiben (wie ein Terminal)
1
 textbox1.appendtext(myserialport.readExisting());

aber das mag er nicht...

von Borislav B. (boris_b)


Lesenswert?

Natürlich nicht :-)

Das ist ja ein Thread-übergreifender Vorgang.
=> Stichwort: "Invoke"

von Daniel B. (yzdani)


Lesenswert?

Hast du mir hier für ein Code Beispiel?
Noch nie damit gearbeitet....

von Christian D. (chris83)


Lesenswert?

private void serialPort1_DataReceived(object sender, 
System.IO.Ports.SerialDataReceivedEventArgs e)
        {

            try
            {
                if (InvokeRequired)
                {
                    Invoke(new MethodInvoker(DoSerialInput));
                }
            }
            catch
            {

            }
        }

 private void DoSerialInput()
        {
            string s = "";
            try
            {
                s = serialPort1.ReadLine();
            }
            catch
            {
                return;
            }
}


So habe ich das bei mir gelöst.
in s steht dann was Empfangen wurde und kann weiter verarbeitet werden.

von Daniel B. (yzdani)


Angehängte Dateien:

Lesenswert?

Vielen Dank!

klappt aber immer noch nicht....

Code hängt dran...

von Christian D. (chris83)


Lesenswert?

Den Port solltest du schon vorher Öffnen nicht erst dann wenn du Daten 
aus ihm lesen möchtest.

von Daniel B. (yzdani)


Angehängte Dateien:

Lesenswert?

Mach jetzt mit einem button den Port auf und mit einem anderen wieder 
zu.

geht immer noch nicht...

von Christian D. (chris83)


Lesenswert?

Weißt du auch auf welchem Com-Port was ankommt? Einmal nimmst 4 dann 
wieder 6. Bei sovielen unbekannten kann der Fehler überall liegen.

Schau doch mal mit H-Term oder einem anderen Tool ob überhaupt was beim 
Com-Port ankommt.

von Daniel B. (yzdani)


Lesenswert?

Es kommt was an (Bei Cool Term). Hab nur einen Arduino dran gehängt 
welcher mir die ganze Zeit ein string sendet, statt dem richtigen Board.

von Christian D. (chris83)


Lesenswert?

Cool Term hast du aber geschlossen wenn du das C#-Programm startest 
oder?
Auf den Com-Port kann nur ein Programm zugreifen.

von Daniel B. (yzdani)


Lesenswert?

Ja, wenn es offen wäre wär auch ein öffnen des Ports nicht möglich..

von Borislav B. (boris_b)


Lesenswert?

Bist du sicher, dass dein DataReceived Eventhandler überhaupt beim Port 
registriert ist? Davon sehe ich nämlich nichts...

=>
mySerialPort.DataReceived += serialPort1_DataReceived;

: Bearbeitet durch User
von Christian D. (chris83)


Lesenswert?

port.Open();
port.DataReceived += new 
SerialDataReceivedEventHandler(serialPort1_DataReceived);

Mist war einer schneller. Aber wollte ich auch gerade anmerken.

von Daniel B. (yzdani)


Lesenswert?

Es funktioniert!!!!...auf dem Arduino...
vomevalboard kommt immer noch nichts...

Das sollte ich Empfangen:

WRAP THOR AI (6.0.0 build 952)
Copyright (c) 2003-2014 Bluegiga Technologies Inc.
READY.

beim Terminal gehts...

von Daniel B. (yzdani)


Lesenswert?

Was auch komisch ist, der Codevorschlag für die Konsole von Microsoft 
geht...

von Daniel B. (yzdani)


Lesenswert?

Danke für die Hilfe!

Falls jemand ein ähnliches Problem haben sollte, dann checkt mal die 
Terminal settings auf DTR und RTS!

1
myserialport.DtrEnable = true;
2
myserialport.RtsEnable = true;

kann Wunder wirken!!!

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.