Forum: PC-Programmierung RING-Leitung der RS232 mit VB.NET auslesen


von Gast (Gast)


Lesenswert?

Hallo,

wie ich die Leitungen CTS, DSR und DCD auslesen kann, habe ich 
'rausbekommen, aber den RING-Indikator auszulesen, ist für mich ein Buch 
mit sieben Siegeln.
Alle Versuche mit "System.IO.Ports.SerialPinChange.Ring" sind 
gescheitert.
"SerialPinChange.Ring" ist immer 256, ob auf dem RI-Pin +12 V, -12 V 
oder 0 V anliegen. Wer kann helfen?

Vielen Dank

von *.* (Gast)


Lesenswert?

Profilic-USB-Adapter? Lade mal den neuesten Treiber, der ältere hat 
einen Bug betreffend RI.

von Gast (Gast)


Lesenswert?

Nein, kein USB-Adapter, sondern eine ganz normale serielle Schnittstelle 
on Board.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ich habe da nicht viel Ahnung, also weiterlesen auf eigene Gefahr!

Noch da? OK.

System.IO.Ports.SerialPinChange ist eine enum deren Mitglied Ring 
immer den Wert 256 hat (#1).

IMHO müsstest du auf das Event SerialPort.PinChanged (#2) reagieren 
nachdem du zuvor einen Handler dafür eingerichtet hast (#3) und dann 
vergleichen, ob das Event dem Wert System.IO.Ports.SerialPinChange.Ring 
entspricht.

#1 
http://msdn2.microsoft.com/de-de/library/system.io.ports.serialpinchange.aspx

#2 
http://msdn2.microsoft.com/de-de/library/system.io.ports.serialport.pinchanged.aspx

#3 http://www.msdner.com/dev-archive/57/10-64-577780.shtm
http://msdn2.microsoft.com/de-de/library/system.io.ports.serialport.pinchanged(VS.80).aspx

von Gast (Gast)


Lesenswert?

Hallo

erstmal vielen Dank für die Antwort.

Leider funktioniert diese Lösung nicht wie sie soll.
Beim ersten Ändern des Ring-Pins funktioniert alles noch wie es soll, 
dann aber beim nächsten Ändern des Zustandes des Ring-Pins, reagiert 
"SerialPort1_PinChanged" mehmals (zwischen 2 und 5, manchmal auch noch 
häufiger). Obwohl ich nur einmal den Zustand der Ring-Leitung geändert 
habe. Ich habe zum Testen einen Schalter zwischen DTR und Ring gesetzt 
und DTR auf High (+12 V) geschaltet. Wenn ich den Schalter betätige, 
sagt "SerialPort1_PinChanged", dass der Ring-Pin mehrmals betätigt wurde 
(die Häufigkeit scheint zufällig zu sein).
So weiß ich wieder nicht, welchen Zustand Ring-Pin hat.

Zweite Frage:

Wieso kann ich in "Private Sub SerialPort1_PinChanged" kein 
Label-Steuerelement ändern? Der Debugger bricht das Programm ab und 
sagt:

"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das 
Steuerelement LabelRing erfolgte von einem anderen Thread als dem 
Thread, für den es erstellt wurde."

Zur Zeit löse ich das Problem, indem ich innerhalb von "Private Sub 
SerialPort1_PinChanged" eine Variable ändere und diese in einem Timer 
auswerte.
Das gefällt mir aber nicht so gut.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Bei dem Schalter denke ich zunächst an ein rein machanisches, bei µCs 
bekanntes Problem: Prellen. D.h. Der Schalter gibt im Übergangszustand 
kein eindeutiges EIN/AUS sondern zappelt mehrmals hin und her und das 
gibt mehrere, zufällige RI-Events.

Prüfen könntest du das, indem du nicht RI per Schalter auslöst, sondern 
den Schalter (oder einen Draht) fix in der Verbindung DTR-RI lässt und 
dann per Software DTR einschaltest. Hier darf kein Prellen auftreten.

In der Praxis dürfte Prellen keine Rolle spielen, weil das 
angeschlossene Gerät nicht mit Schaltern arbeitet sondern mit 
Digital-ICs und die Prellen nicht. Wenn du Selbstgebautes anschliessen 
willst, könntest du auch per Hardware entprellen; per Software wird es 
mit dem Event-Mechanismus schwer wenn nicht unmöglich.

Zur zweiten Frage habe ich fast nix. Ich weiss nix von VB.NET. 
Programmiertechnisch würde ich versuchen, eine threadübergreifende 
Message/Event aus dem "Ring-Thread" an den "Label-Thread" zu schicken. 
Der Message/Eventhandler des "Label-Thread" kann dann die vom 
"Ring-Thread" angeforderte Änderung erledigen.

von Gast (Gast)


Lesenswert?

Hallo,

die Probleme gehen weiter ...

Bei den Leitungen CTS, DSR und DCD reagiert "SerialPort1_PinChanged" 
immer, egal ob die Leitung von "High" auf "Low" oder von "Low" auf 
"High" geschalten werden; wieso reagiert "SerialPort1_PinChanged" bei 
der RING-Leitung nur, wenn sie von "High" auf "Low" geschaltet wird? 
Wenn sie von "Low" auf "High" geschaltet wird, passiert nichts!

Wieso ist das so, und wie kann ich das umgehen?

Ein weiteres Problem ist folgendes:

Ich möchte die RING-Leitung als Eingang missbrauchen.
Man stelle sich vor, "SerialPort1" ist geschlossen. Nun setzt man die 
RING-Leitung von extern auf "High" und erst jetzt wird "SerialPort1" 
geöffnet. Wie kann ich nun die RING-Pegel abfragen, OHNE dass dieser 
verändert wird (also "SerialPinChange.CDChanged" funktioniert sowieso 
nicht)? Das gleiche natürlich auch mit dem "Low"-Pegel.
Mit den anderen Eingängen (CTS, DSR, DCD) geht das mit 
"SerialPort1.CtsHolding" usw., wieso gibt es kein 
"SerialPort1.RingHolding"?

Wie das ich das mit VB.Net lösen?

Grüße

Gast

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Stell dir das RIIIINNNNNGGGG wie die gute alte Telefonklingel vor. Du 
wirst alarmiert, wenn einer anklingelt und nicht ständig zusätzlich, 
wenn keiner anklingelt ;-)

> Ich möchte die RING-Leitung als Eingang missbrauchen.

Dös' is' 'n Broblem. Klar, dass es mit obiger Denkweise Probleme gibt.

> Man stelle sich vor, "SerialPort1" ist geschlossen. Nun setzt man die
> RING-Leitung von extern auf "High" und erst jetzt wird "SerialPort1"
> geöffnet.

Ohne geöffneten Port wirst du nicht an das Event rankommen. Die Frage 
ist dann also, ob man die Schnittstelle bedenkenlos öffnen kann/darf. 
D.h. ob ein Öffnen exklusiv ist oder nicht. Und ob man das unterscheiden 
will oder muss.

Ein Terminal-Programm muss es nicht unterscheiden - der User will mit 
dem COM Port arbeiten, also kann man den COM Port exklusiv aufmachen und 
ab dann Werte abfragen oder auf Events auswerten.

Ein Sniffer-Programm will NICHT exklusiv mit dem Port arbeiten. Es ist 
fraglich, ob das mit dieser Programmierschnittstelle d.h. über 
SerialPort geht.

Um 2002 hatte man noch keine SerialPort-Klasse in .NET 1.x, da wurde das 
COM Port Handling über DLL Zugriff auf die Windows API (#1) oder auf 
das ActiveX-Modul *MSComm.OCX* gemacht.

#1
http://www.microsoft.com/germany/msdn/library/net/vbnet/SerielleSchnittstelleMitVBNETAnsprechen.mspx?mfr=true
http://www.freevbcode.com/ShowCode.Asp?ID=4666
http://www.webtropy.com/articles/art9-1.asp?f=GetCommModemStatus
http://www.edaboard.com/ftopic284058.html
http://www.codeproject.com/KB/vb-interop/CommConfig.aspx

Das geht natürlich nur, wenn dein .NET Programm dann ausschliesslich 
unter Windows laufen soll.

Ab 2005 mit .NET 2.0 sollte sich diese Krux mit dem SerialPort 
Control/Klasse ändern (#2). Die Idee: plattformunabgängiger Code...

#2
http://programmers-corner.com/sourcecode/111
http://www.devx.com/dotnet/Article/31001

Leider nicht zum Guten mit der RI-Leitung: "RI (Ring Indicator). Input, 
which cannot be read with SerialPort." (#3)

Und später? Ziemlich erschreckend liest sich das: "SerialPort has been 
changed in .NET 3.5 in such a way that some of the code may not work or 
even worse - it may lock the COM ports FOREVER! In fact, there seems to 
be so many errors in SerialPort 3.5 that it may be regarded as useless!" 
(#3)

#3
http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm

Eine Alternative wäre, eine andere SerialPort Implementierung zu nehmen 
z.B. die kommerzielle http://franson.com/serialtools/ (hat Abfragen für 
RI, ist dann aber anscheinend auch nur für Windows - back to the Roots 
wir sind wieder in 2002). Die Open Source SerialPortNew (Sourceforge) 
ist anscheinend speziell für WinCE und ich habe mir nicht angeschaut, 
wie die es mit dem RING Indicator halten.

von *.* (Gast)


Lesenswert?

Die UART-Hardware selber produziert schon keinen Interrupt wenn RI l->h 
geht.

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.