Forum: PC-Programmierung c# serielle Kommunikation & Richtungsumschaltung


von Gero (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
ich versuche gerade mittels C# einen µC und meinen Computer zu 
verbinden.
Ich habe ein funktionierendes Windows Programm und will dieses nun durch 
ein eigenes Programm ersetzen.

Generell funktioniert es so, dass der PC am µC einen Parameter anfrägt 
und der µC diese dann eben zurück sendet.

Das Problem hierbei ist, dass mein c#-Programm keine Daten empfängt.
Mit dem Oszi sehe ich aber, dass der µC auf meine Anfrage vom PC 
antwortet.

Ich habe mal ein Bild angehängt. Oben sieht man die Kommunikation mit 
der alten Originalprogramm, das funktioniert --> KEIN C#!

Unten ist mein c#-Programm welches nicht funktioniert. Es sieht für mich 
so aus, als würde bei meinem Programm die Übertragunsrichtung vom 
Com-Port nicht umgeschalten werden.

Sieht man glaub ganz schön daran, dass die Pegel der µC-Antwort zu klein 
sind, hier arbeiten wohl die beiden Treiber gegeneinander, oder!?

Ich habe mal den relevanten code angehängt und die Fehlerbehandlung 
heraus genommen damit es etwas übersichtlicher wird.
Könnt ihr erkennen woran das Problem liegt? mir ist nicht bekannt dass 
ich nach serialPort.Write die Übertragungsrichtung manuell umschalten 
muss, oder etwa doch!?

1
private void InitComPort()
2
{
3
  serialPort = new SerialPort(comStructure.PortName, comStructure.BaudRate, comStructure.Parity, comStructure.DataBits, comStructure.StopBits);
4
  serialPort.Handshake = this.comStructure.Handshake;
5
6
  serialPort.ReadTimeout = 500;
7
  serialPort.WriteTimeout = 500;
8
  serialPort.Open();
9
}
10
11
12
// Frägt eine Parameter am Gerät an und ließt Antwort nach einer Delayzeit aus.
13
private Int32 ReadData(byte[] Data)
14
{
15
  serialPort.Write(Data, 0, Data.Length); // sollten immer 5 bytes!?
16
17
  Thread.Sleep(50);      // warte bis Antwort da ist
18
  return (GetResponse());      // lese Antwort und Prüfe Daten auf konsitenz
19
}
20
21
22
23
24
25
// Liest Empfangsbuffer aus nachdem ein Parameter vom PC beim Geber angefragt wurde (wird von 'ReadData()' aufgerufen)
26
private Int32 GetResponse()
27
{
28
  Int32 Value;
29
  int AnzBytes = serialPort.BytesToRead;
30
31
  byte[] u8aCommandBuffer = new byte[AnzBytes];
32
  serialPort.Read(u8aCommandBuffer, 0, AnzBytes);
33
34
35
  if (AnzBytes != 0x0a) // FEHLER!!! - Anzahl Empfangener Byts falsch!
36
  {
37
    LogWindows("Fehler bei Anzahl empfangener Bytes");
38
    return (0);
39
  }
40
41
42
  Value = u8aCommandBuffer[6];    // Byte 0...4 - senden, 5...9 Antwort (senden wird gespiegelt!)
43
  Value <<= 8;            // Byte 5 Befehlsbyte wie senden (0x83, 0x81...)
44
  Value |= u8aCommandBuffer[7];    // Byte 9 Endbyte: immer 0x0d
45
  Value <<= 8;
46
  Value |= u8aCommandBuffer[8];
47
48
  return (Value);
49
50
  }
51
}

von Peter II (Gast)


Lesenswert?

von wo wird denn  GetResponse() aufgerufen?

>  int AnzBytes = serialPort.BytesToRead;
was kommt hier denn raus?



das du auf einmal alles 10byte bekommst, ist auch unwahrscheinlich meist 
sind die buffer kleiner. du musst also lesen bis du den Byte zusammen 
hast.

Beschreibe mal etwas genauer, wo das Programm etwas macht oder halt 
nicht macht.

von Gero (Gast)


Lesenswert?

Hi,
ich benütze einen RS485-Adapter der mittels USB an den PC angeschlossen 
wird und im Gerätemanager als "gewöhnlicher" COM3 auftaucht.

bei BytesToRead bekomme ich "0", es wird also überhaupt garnichts 
empfangen.
Die GetResponse wird oben in der ReadData() aufgerufen.

ICh befülle die Funktion ReadData, sende dort meine Anfrage und warte 
dann im Thread.Sleep 50 ms, dass reicht dann eben für das empfangen der 
Nachricht (am Oszibild sieht man ja dass die Antwort kleiner 30ms 
benötigt.

Dannach springe ich eben in die Getesponse und lese den seriellen Buffer 
aus und schaue, ich ich eine Antwort habe.

Ich bekomme dann eben keine Antwort und der Buffer ist leer.

Es kommt mir eben komisch vor weil ich ja am Oszi sehe, dass eben doch 
eine Antwort kommt, aber es arbeiten hier eben zwei Pegel gegeneinander. 
PC wie auch der µC stehen vermutlich in der Richtungssteuerung auf 
senden. Ein Lösungsansatz wäre wohl, wenn ich nach dem senden direkt die 
Richtungssteuerung auf Rx stellen könnte.

von Peter II (Gast)


Lesenswert?

Gero schrieb:
> ICh befülle die Funktion ReadData, sende dort meine Anfrage und warte
> dann im Thread.Sleep 50 ms, dass reicht dann eben für das empfangen der
> Nachricht (am Oszibild sieht man ja dass die Antwort kleiner 30ms
> benötigt.

das macht man nicht.

mache einfach ein

empfangen = 0
while( empfangen < 10 )
   empfangen += serialPort.Read(...)
)
//verarbeite daten


wenn nichts kommt, dann kommt eine timeout execption.

von Gero (Gast)


Lesenswert?

ja genau, dann laufe ich in die Timeout execption.

Ich versuche eben die Pegel in den Griff zu bekommen, selbst nach 500ms 
habe ich 0 BytesToRead :-(

von Peter II (Gast)


Lesenswert?

> serialPort.Handshake = this.comStructure.Handshake;


hat denn deine Hardware Handshake?

lass das mal weg.

von Holger L. (max5v)


Lesenswert?

Versuch es mal mit dem SerialPort.DataReceived-Ereignis.

serialPort.DataReceived += new 
SerialDataReceivedEventHandler(DataReceivedHandler);

private static void DataReceivedHandler(object sender, 
SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        string indata = sp.ReadExisting();
    }

http://msdn.microsoft.com/de-de/library/system.io.ports.serialport.datareceived(v=vs.110).aspx

von Gero (Gast)


Lesenswert?

der DataReceived bringt m.E.n. nichts, die Umschaltung muss ja 
unmittelbar nach dem senden passieren, das DataReceived kommt aber erst 
nach einem erfolgten Empfang von Daten zu tragen.

Ich probiere jetzt gerade mit dem Handshake etwas herum, vlt. finde ich 
ja die passende Einstellung...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Gero schrieb:
> ich benütze einen RS485-Adapter der mittels USB an den PC angeschlossen
> wird und im Gerätemanager als "gewöhnlicher" COM3 auftaucht.

Und was für einer ist das? Bessere RS485-USB-Adapter können die 
erforderliche Richtungsumschaltung transparent in Hardware abwickeln, so 
daß Du Dich nicht weiter darum kümmern musst.

So etwas ist beispielsweise bei Adaptern möglich, die einen FT232 
verwenden; denn der hat eine entsprechende Steuerleitung (siehe 
Datenblatt des FT232, Schaltungsbeispiel für Gebrauch mit 
RS485-Treiber).

Es ist daher sehr ratsam, genau so einen Adapter zu verwenden.

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.