PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme bei Kommunikation mit Visual Basic.net und Attiny



the_Ghost666
12.12.2007, 17:56
Moin zusammen.

Ich habe folgende Aufgabenstellung:
Es soll ein Attiny gesteuert werden, der einen Gerätetest durchführt und Daten sammelt. Diese sollen dann via RS232 an einen Rechner übertragen werden.
Momentan erfolgt die RS232 Routine im Attiny mittels Software, bei 15Mhz, 19200Baud und Polling. Die Steuerung erfolgt mit Asciizeichen.
Der PC pingt zuerst "P" im Sekundentakt, bis der Controller das P zurückgibt. Dieser pollt nach dem Reset seine Rx Leitung, bis er ein P erkennt und antwortet mit 2ndem P. Damit erkennt der PC, dass ein Gerät vorhanden ist.
Bis hierhin klappt alles.
Danach sendet der PC ein "O" um die Einstellungen zu setzen, der µC antwortet mit "S?" woraufhin der PC einen Parameter sendet. Danach passiert das noch 2x bis die Konfiguration abgeschlossen ist. Also immer Frage vom µC "S?", "T?", "N?". Der Rechner antwortet mit dem Datenbyte.
Es ist nun so geregelt, das der Rechner auf die Frage wartet, der µC auf das Datenbyte. Hierbei scheint es nun zu passieren, dass der PC oder Controller den Einsatz verpasst, und beide warten auf den anderen (Deadlock).
Die Abfrage, ob der Controller geantwortet hat, erfolgt folgendermaßen:

Do Until Me.SerialPort1.ReadChar()="S?"
Loop

Eigentlich müssten doch alle Zeichen im Buffer des Ports liegen, oder? Dennoch bekommt der PC die Sendung fast immer nicht mit. Ich denke das Problem liegt in der PC Schleife, hat jemand eine Ahnung oder Lösung?
Ich arbeite dabei in einem separaten Thread, damit die zweite Schnittstelle einen anderen Tester bedienen kann.

Steinigtmich
12.12.2007, 18:39
Moin.

Ich bin jetzt alles andere als ein Experte für VB.net, aber...


Moin zusammen.
Do Until Me.SerialPort1.ReadChar()="S?"
Loop

Was macht ReadChar? Liest das nicht genau 1 Zeichen ein? Weil dann kanns ja garnicht so funzen.

Desweiteren, der Takt der seriellen Kommunikation könnte einen zu hohe Fehler haben. Den Taktfehler konnte ich jetzt bei 15 MHz nicht auf die Schnelle nachschlagen, aber bei dieser Baudrate gibt mir mein Datenblatt vom Atmega32 folgende Infos: 14.7456 MHz: Fehler 0%, 16 Mhz: 0.2%
Das könnte u.U. schon zu hoch sein, PC-Schnittstellen sind da teilweise recht empfindlich.

the_Ghost666
12.12.2007, 18:46
Ich mache das Timing in Software ohne interrupts, bei 52,08µs /bit komm ich auf 52,1µs, das ist alles genau eingestellt, die einfach übertragung gelingt auch (mit dem PC, Terminalprogramm).
ReadChar liest ein Zeichen Synchron aus dem Stream (laut MS Hilfe, was synchron heißt bleibt kryptisch). Ich habe es schon nur mit einem Zeichen probiert, selbes Problem. Es kann passieren, dass der Rechner die Anfrage verschluckt, weil diese zu schnell hinter dem "O" gesendet wird.
Wir haben schon probiert ein Hardwarehandshake einzubauen, dies ist auch nicht problemlos, deswegen tippe ich als Fehlerquelle auf meine Abfrage.

Steinigtmich
12.12.2007, 19:04
Na dann ist doch klar, warums nicht läuft.

Do Until Me.SerialPort1.ReadChar()="S?"

Hier wird dann 1 Zeichen aus dem Empfangspuffer ausgelesen, und mit 2 Zeichen verglichen. Die Bedingung kann ja niemals true werden.

Überprüfe lieber ob ein S empfangen wird, und überprüfe danach auf das ?


Edit:

Ich will sagen, lass den Empfangspuffer in einer Schleife Zeichen für Zeichen abarbeiten. Falls z.B. ein S kommt, wird als nächstes (hoffentlich) ein ? kommen.

the_Ghost666
12.12.2007, 22:21
Sorry, hab den halben satz vergessen: ich hab es auch mit einem Zeichen versucht, mit dem gleichen Fehler. Ich nutze Docklight um mir den Verkehr anzuschauen.
Ich habe auch andere Befehle probiert, zb ReadLine, mti einem "?" als endofline. Und nun hat es dennoch das Problem, dass meist kein S gelesen wird, sondern die Funktion "" zurückliefert, scheinbar als ob er gerade zu beschäftigt ist um den puffer zu bearbeten so oder so...irgend ein dummes timingproblem

Willa
13.12.2007, 00:10
Hi! Also ich lese Zeichen so aus:

if serialport1.BytesToRead > 0 then
Do
textbox1.AppendText (chr(SerialPort1.Readbyte))
textbox1.ScrollToCaret
If SerialPort1.BytesToRead = 0 Then
Exit Do
End If
Loop
end if

Vielleicht hilft das ja?
Viele Grüße,
William

marvin42x
13.12.2007, 14:20
Es gibt bei VB2005 eine Eigenart mit Strings umzugehen die mich einige Suche gekostet hat.
Wenn ich die Zeilen richtig verstehe:

Do Until Me.SerialPort1.ReadChar()="S?"
Loop

ist „S?“ wegen der Ausrufungszeichen ein String. und den vergleichst du mit dem Empfangsergebnis.
Ich hoffe mal das ReadChar() auch mehr als einen Char liefert weil die Sache sonst sowieso nie passt.
Jetzt zu der Eigenart:
Das kann man am besten im Debug Modus sehen.
Setze einen Breakpoint auf die Zeile.
lass das Programm anlaufen.
wenn es am Breakpoint hält schau dir den Inhalt von ReadChar an.
Achte darauf ob bei dem angezeigten String vorne UND hinten das Ausführunszeichen ist.
wenn es hinten nicht ist musst du ein unsichtbares Zeichen mit einem kleinen Befehl abschneiden und dann funktioniert der Stringvergleich auch wieder .
Falls das so ist kann ich Dir die Lösung Posten.

Netter Gruß

the_Ghost666
13.12.2007, 19:35
moin,
ich hab dieses problem gelöst, ich habe beim auslösen des Data_Received events, das ausgelöst wird, wenn 2 byte vorhanden sind, den Puffer mit ReadExisting komplett ausgelesen und in einen String geschrieben.
Statt nun Do Until mit ReadChar auszuführen, mache ich Do Until Data_Buffer ="S?"
dies klappt an sich.

Nun hat sich aber ein zweites Problem gezeigt.
Ich kommuniziere die Steuerbefehle, und das Gerät macht was es soll. Nun müssen die gesammelten Daten ausgelesen werden. Dafür setze ich den Schwellwert für das Event von 2 auf 298 (296Datenbytes + E! als Ende). Direkt nach dem senden quitiert der PC die Sendung mit "O" und der Controller fragt den Beginn eines neuen Scandurchlaufs "F?"
Vorher hab ich natürlich den Schwellwert wieder auf 2 Byte gesetzt.
Der PC wartet hierauf. Allerdings passiert es ab und zu, oder fast sofort wenn ich den Rechner durch Verschieben von Fenstern beschäftigte, dass der Controller zwar F? sendet, aber der Empfangspuffer leer bleibt. Da der µC das nur einmal tut, warten nun beide aufeinander (Deadlock).
Hat jemand eine Ahnung warum soetwas passieren kann (eigentlich doch hardwaregepuffert) und wie man das Problem löst?