c# serielle Kommunikation & Richtungsumschaltung

Gast #3655526
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
}
Angehängte Dateien:
Gast #3655532
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.
Gast #3655566
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.
Gast #3655573
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.
#3655622
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
Gast #3655649
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...
Persönliche Seite #3655696
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren