Strings empfangen klappt nicht

Deine Datenpakete können unterschiedlich lang sein, und es gibt kein "fertig-Symbol"? Du mußt also auf das "A" des nächsten Paketes warten?
Ich würde das in etwa so angehen:
-je eine Variable für "Anzeiger" und "Wert", die grad empfangen werden (Word)
-eine Statusvariable, was aktuell empfangen wird (2bit)
-UART mit IRQ
in der ISR
-ist das empfangene Byte "A", setze Status auf 0 Anzeiger und Wert enthalten korrekte, zu verarbeitende Daten
-ist es "/", setze Satus auf 1, Anzeiger und Wert enthalten korrekte, zu verarbeitende Daten, die verarbeitet/kopiert werden müssen. beide Vars auf 0 setzen.
-ist es ein "\" setze Status auf 2
-jedes andere Zeichen: ziehe 48 ab (=Zahl als byte), wenn status=1, multipliziere Anzeiger mit 10, und addiere das neue byte; bei Status=2 dasselbe mit Wert
Bei genauerer Betrachtung kann man das A dann auch ignorieren (wenn A, dann Reti), und mit einem Bit als Status auskommen.
 
So, nun sitz ich wieder am PC...

Mit einem einfachen Programm habe ich mal geschaut, ob überhaupt / und \ ankommen. Diese wurden einfach gezählt und das Ergebnis auf LCD ausgegeben. Da das Verhältnis zueinander passt, gehe ich von einer korrekten Übertragung aus. Zur Sicherheit habe ich schon vorher die Baudrate auf 2400 runter gesetzt.

So sieht mein derzeitiges Programm aus:
Code:
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 2400

$hwstack = 100
$swstack = 100
$framesize = 100

Config Portd = Output
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.1
Config Lcd = 16 * 2
Cls

' Die LEDs dienen nur zur Kontrolle
Led1 Alias Portb.0
   Config Led1 = Output
Led2 Alias Portb.1
   Config Led2 = Output
Led3 Alias Portb.2
   Config Led3 = Output
Led4 Alias Portb.3
   Config Led4 = Output
Led5 Alias Portb.4
   Config Led5 = Output

Dim A As Byte
Dim Neu As Byte
Dim Erwarten As Byte
Dim S As String * 5
Dim Instrument As String * 10
Dim Wert As String * 10

On Urxc Onrxd
Enable Urxc
Enable Interrupts

Do
   Select Case Neu
   Case 1:
         S = Chr(a)
      Select Case S
         Case "/" :
           Erwarten = 1                                     ' es wird ein Instrument erwartet
           Toggle Led1
         Case "\" :
           Erwarten = 2                                     ' es wird ein Wert erwartet
           Toggle Led2
      End Select
      If Erwarten = 1 And A <> 92 Then                      'es wird ein Instrument erwartet und das Zeichen ist kein \ -> also eine Zahl!
         Instrument = Instrument + S
         Neu = 0                                            'Merker Neu zurücksetzen: Zeichen wurde ausgewertet
         Toggle Led3
      End If
      If Erwarten = 2 And A <> 47 Then                      'es wird ein Wert erwartet und das Zeichen ist kein / -> also eine Zahl!
         Wert = Wert + S
         Neu = 0                                            'Merker Neu zurücksetzen: Zeichen wurde ausgewertet
         Toggle Led4
      End If
      If Erwarten = 2 And A = 47 Then                       'Wert erwartet? Ja! Dieser endet mit einem / -> anzeigen!
         Toggle Led5
         Cls
         Lcd Instrument
         Locate 2 , 1
         Lcd Wert
         Instrument = ""
         Wert = ""
         Erwarten = 0
      End If
   End Select
Loop

End

Onrxd:
   A = Inkey()
   Neu = 1                                                  'Merker Neu setzen: Zeichen wurde noch nicht ausgewertet
Return

Ich hoffe, es ist einigermaßen verständlich.

So sieht zB ein Datensatz des Flugsimulators aus: A/40\2919.78/30\325.42/

Im Betrieb arbeiten die LEDs 1-4, nur Nr. 5 bleibt unverändert. Diese arbeitet, wenn es zur Anzeige kommt. Dazu muss vorher ein Wert empfangen worden sein (erwarten = 2) und dann ein /.

Für die Auswertung gehe davon aus, dass die Zeichen "sauber" sind, d.h. sich nirgendwo ein Fremdzeichen einschmuggelt.

Kann man den Datenstrom irgendwie parallel auf dem PC anzeigen lassen?


Edit:
Ich habe gerade mal mit AVR Term einen Datensatz wie oben an Com1 geschickt - auch da wird nix angezeigt! Da könnte also ein ganz, ganz doofer Denkfehler drin sein..?!
 
Ich habe nun das Programm mit ein paar LCD-Befehlen erweitert, so dass ich die Werte sehen kann, wenn ich per AVR Term was schicke...
Und was ist?? Murks!

Ich schicke ein A/40\2919.78/ hin, lasse mir, wenn ich den Instrumenten-String erweitere, den String Instrumente ausgeben und ein /29 kommt raus...
 
Hi,

bist du dir sicher das diese ganze Kette auch aus der RS232 des PCs rauskommt und auf die Leitung geht ?
Backslash sind zB für den PC Steuerzeichen die Verzeichnisse/Dateinamen trennen. Doppelpunkte werden zB für Laufwerke gebraucht. Bist du dir wirklich sicher das die Zeichen auch auf den Weg zum Controller gehen ? Pack doch mal nen zweiten PC/Laptop mit einem Terminalprogramm das auch alle Zeichen anzeigt gegen den anderen PC (statt des Controllers) und sieh dir an was auf die Leitung geht. Nicht das da irgendetwas kaputtinterpretiert wird.

Gruß
Dino
 
Hi,

bist du dir sicher das diese ganze Kette auch aus der RS232 des PCs rauskommt und auf die Leitung geht ?

Ne, habe ich doch mehrfach geschrieben. Den Verdacht habe ich auch. Mit einem zweiten PC wird etwas schwer, mal schauen, ob ich mir das heute Abend noch antue...

Kann ich denn den RS232 parallel mitlesen?
 
Hallo zusammen!

Also ich habe jetzt mal dein Beispiel genommen und sende via PRINT diesen String:
A/40\2919.78/30\325.42/
vom AVR aus zum PC.

Per HTerm empfange ich die Daten und das Ergebnis ist wie erwartet:
(Anzeige in ASCII, HEX und decimal)
Ditron_RS232_Flugsimulator.gif


Dann habe ich mal diesen "Sonderzeichenstring" erstellt:
:/\*'#<>|°^&%$§
und ihn ebenfalls von AVR zum PC gesendet.

Das Ergebnis seht ihr hier:
(Anzeige in ASCII, HEX und decimal)
Ditron_RS232_Sonderzeichentest.gif
Bis auf ° und § wird alles erkannt.


Wenn also das Übermitteln deines "Flugsimulatorstrings" fehlerfrei vom AVR zum PC über RS232 funktioniert.... warum soll es dann nicht auch anders herum funktionieren? :hmmmm:

Irgendwas stimmt da mit deiner LCD-Ausgabe nicht!
Wenn der Zeichensatz im LCD unter 2Ahex nicht ein * hat, dann zeigt das LCD natürlich auch Murks an.... und trotzdem sind die Daten richtig eingegangen!
Du musst dir also schon die einzelnen Decimal- oder Hexwerte vom ASCII-Code auf dem LCD anzeigen lassen und nicht das Zeichen selbst! ;)


Grüße,
Cassio
 
Hmm... ich weiß zwar (noch) nicht, was das 2Ahex ist, aber das finde ich auch noch heraus.

Gegen deine Theorie spricht leider, dass ich in dem Programm zur Kontrolle auch Leuchtdioden eingebaut habe. Und die LED Nr. 5, die in Bereich "Anzeigen" angesprochen wird, reagiert gar nicht. Also stimmt da irgendwas anderes nicht :(
 
Hmm... ich weiß zwar (noch) nicht, was das 2Ahex ist, aber das finde ich auch noch heraus.

Hallo Ditron!

Die 2Ahex habe ich auch etwas "blöd" zusammen geschrieben. ;)

2Ahex = 2A hexadecimal, oder auch 2Ah, oder auch &H2A.......... oder eben 042 decimal bzw. * als ASCII-Zeichen. :D

Das war natürlich nur ein Beispiel und bezog sich nicht direkt auf dein Beispiel!

Dein Programm mit der LED5 muss ich mir gleich noch mal ansehen!

Grüße,
Cassio
 
Hallo Ditron!

LED5 hin oder her....

Du prüfst doch hier schon:
Code:
S = Chr(a)

Select Case S
         Case "/" :
           Erwarten = 1                                     ' es wird ein Instrument erwartet
           Toggle Led1
         Case "\" :
           Erwarten = 2                                     ' es wird ein Wert erwartet
           Toggle Led2
      End Select

ob das \ (092) oder / (047) gesendet wird.... was dir dann LED1 und LED2 ja schon anzeigen!
Was suchst du eigentlich? :hmmmm:



Du könntest natürlich auch dirket nach dem ASCII-Wert suchen:
Code:
Select Case A
         Case 92 :
           Erwarten = 1                                     ' es wird ein Instrument erwartet
           Toggle Led1
         Case 47 :
           Erwarten = 2                                     ' es wird ein Wert erwartet
           Toggle Led2
      End Select


Ist doch viel einfacher...... und du musst nicht erst über die Sringumwandlung gehen. ;)


Grüße,
Cassio
 
Ne, habe ich doch mehrfach geschrieben.
Ups ... dann hab ichs wohl mehrfach überlesen weil ich den Thread nur überflogen hab. War in der Länge schon recht gut angewachsen.

Kann ich denn den RS232 parallel mitlesen?
Das geht. Man kann die Datenleitung die man mitlesen möchte auf ne andere Serielle auf RxD legen und sehen was da abgeht. Das habe ich früher wie es noch keine Ethernet-LANs gab gerne gemacht um Fehler zu finden. Statistische Multiplexer haben damals die Datenströme der Datenleitungen auf die Seriellen Terminals und Drucker verteilt.

Gruß
Dino
 
Gar nicht so einfach zu erklären... bei nem Glas Bier mit Zettel und Stift wäre das einfacher ;)

Also, der Flugsimulator gibt Daten der Anzeiger raus. Diese werden umgesetzt und auf Com1 geschickt. Die Daten sehen so aus: A/40\2919.78/30\325.42/ Was was bedeuten könnte, habe ich weiter oben geschrieben. Um die Daten weiter zu verarbeiten, benötige ich aus diesesen Daten folgendes:

/40 --> Nr. des Instruments, hier Höhenanzeiger
2919.78 --> Wert, hier zB die Höhe 2919.78m
/30 --> hier Kursanzeiger
325.42 --> aktueller Kurs

Diese vier Werte brauche ich einzeln. Dabei wollte folgendermaßen vorgehen:
Das A ignoriere ich, brauche ich nicht (später könnte man das Nutzen um ein Reset der Variablen durchzuführen)
Es kommt eine Zeichenkette, sobald / kommt, ist der folgende String der Datensatz für das Instruments (erwarten = 1). Weiter auslesen... nächster Datensatz wird die Nr. des Instruments werden, bis ein \ kommt. Also bis dahin das ausgelesene Zeichen zum Instrumenten-String adieren.
Irgendwann kommt ein \ und somit wird erwarten=2. Also wieder solange die ankommenden Daten zum Wert adieren, bis erwarten=2 ist und ein / kommt.
Also habe ich nun in Instrument einen String für das Instrument (zB Höhenanzeiger) und in Wert einen String für den Wert (zB Flughöhe)
Wenn also erwarten=2 und es kommt ein /, dann die Daten anzeigen (später weiter verarbeiten), Variablen löschen und von vorne gehts los.

Ich werde also die Instrumenten-Nr. und den Wert nacheinander aus dem String herauslesen. So ist mein Plan...

Und nun versuche ich mal, die seriellen Daten von einem zum anderen Rechner zu schicken... *seufz*
 
Hallo Ditron!

Schau dir doch meinen Snapshot vom HTerm noch mal genau an!

Guckst du--> Ditron_RS232_Flugsimulator.gif


JEDES Zeichen kommt doch einzeln über die serielle Schnittstelle!
Wenn du nun ein Array deklarierst (von mir aus 32 Byte), dann kannst du doch hinterher mit jedem Byte machen was du möchtest!
Bedenke bitte, dass jeder "Zahlen-Wert" (für dein Gehirn z.B. 123.45) letztlich nur aus einer Aneinanderreihung von EINZELNEN Bytes besteht!
Für den AVR existiert kein Zahlen-Wert 123.45 (also ein Single) sondern nur: 49 50 51 46 52 53 !

Scheinbar müssen wir das bis zum Stammtisch-Treffen am 04.02.12 vertagen.
Vielleicht wird es ja tatsächlich nach einem Glas Bier deutlicher. :D

Grüße,
Cassio
 
Ich beobachte nun gerade die Daten auf einem zweiten PC - alles perfekt! Die Daten kommen ohne Fehler an.

Momentan möchte ich die Daten einfach nur aufn Display darstellen, dass umwandeln des Wert-Strings in eine Zahl kommt später (mit val() ).

Den Fehler kann ich nun also etwas einschränken, oder?
Daten werden richtig gesendet, nur der Empfang klappt nicht. Also wird da irgendwo ein Fehler auf der Seite des uC liegen. Wenn ich die Beobachtungen auf dem LCD so bewerte, scheint es, als ob Daten verloren gehen. Ich habe es auch schon ohne Interrupt versucht - nö, funzt nicht.

Ich nutze einen Atmega32 mit einem 16Mhz-Quarz (der 14.7..MHz ist noch im Zulauf...).

Fliegt von euch keiner den IL-2 Sturmovik-Flugsimulator?? ;)
 
Ich nutze einen Atmega32 mit einem 16Mhz-Quarz
damit hab ich bis 115kBaud keine Probleme. Also muß irgendwas anderes nicht passen.

Ach ja ... Bier gibts da nicht. Ist ne Jugendfreizeitstätte ;) Dafür aber Kaffee, Tee, Wasser, Limo, ... Müssen wir also notfalls nebenan verlängern ;) Bei den Autofahrern wird das mit Bier aber sowieso etwas schlecht gehen ;)

Gruß
Dino
 
Heute Abend werde ich mal einen anderen Rechner nutzen.

Kurzer Hintergrund:
Das Spiel stellt die Daten als UDP-Server im Netzwerk zur Verfügung. Ein User aus dem Flugsimulator-Forum hat ein Programm geschrieben, dass diese Daten abfragt und an die Com-Schnittstelle schickt.

Ich kann übrigens selber einstellen, welche von welchen Instrumenten ich die ich vom Flugsimulator haben möchte. Entsprechend ist der gesendete String kürzer oder länger. Ebenso kann ich einstellen, was das allerletzte Zeichen in einem String sein soll: zB A/40\2919.78/30\325.42/ oder A/40\2919.78/30\325.42@ oder A/40\2919.78/30\325.42X . Damit die Werte immer zwischen \ und / sind, habe als letztes Zeichen ein / gewählt.

So, nun kommts:
Wenn ich nur ein Instrument abfrage, dann klappt es mit folgendem Aufbau: A/40\2919.78@
Falls das alles nix wird mit meiner obigen Abfrage, werde ich an den User herantreten und fragen, ob er dir Strings entsprechend verarbeiten kann: statt A/40\2919.78/30\325.42/ ein A/40\2919.78@ /30\325.42@ schicken. Aber eigentlich müsste das der uC so verarbeiten können.

Sind vielleicht die Strings A/40\2919.78/30\325.42/ zu lang für einen sauberen Com-Empfang?
 
Quark, das sind doch grad mal 25 Byte...
mach mal folgendes:
-UART verwenden mit IRQ
-String definieren (als leeren String)
-in der UART-ISR:
--Wenn empfangenes Zeichen="A", dann String auf LCD ausgeben und String=""
--empfangenes Zeichen an String anhängen

Zu den möglichen Werten der "Instrumente": Anfangs waren das ganze Zahlen, jetzt hast Du 2 Nachkommastellen. Sind die fix? (könnte man dann vielleicht einfach ... äh ... centieinheiten draus machen?)

edit: Die LCD-Ausgabe selbst muß im Hauptprogramm erfolgen, in der ISR also den Puffer-String in einen Ausgabe-String kopieren

edit2: wenn Ihr das selbst PC-seitig implementiert habt, warum macht Ihr dann nicht gleich Nägel mit Köpfen, und orientiert Euch am NMEA-Protokoll?
Insbesondere das CR LF nach jedem Datensatz erleichtert Dir den Empfang mit BASCOM, da gibts doch mMn 'n Input-Befehl...
 
Ok, das werde ich heute Abend machen!

Die Werte können mit und ohne Kommastellen sein, je nachdem, was für Werte es sind.

Ich hänge mal Readme der Device Link an.

Anhang anzeigen DeviceLink.txt


Zum edit2:
Das NMEA-Protokoll sagt mir leider nichts.
Aber die Sache mit dem Input-Befehl wäre noch ein Ansatz: auf dem uC auf einen Input warten, der PC gibt den kompletten String "ein", d.h. mit CR/LF am Ende. Und dann, nach dem Input den String zerlegen. Ist auf jeden Fall einen Versuch wert.
 
Zum NMEA-Protokoll:
Da müsste der Datenstring ja im PC zerlegt werden. Das wäre eine zusätzliche Arbeit, die wieder Fehler beinhalten könnte. Ich muss dazu sagen, dass das Programm, das die Daten vom UDP auf Com schickt, mir jemand anders für mich geschrieben hat. Ich möchte da seine Hilfsbereitschaft nicht überstrapazieren ;)
 
OK, das sollte auch so gehen. Ich dachte, dieses Protokoll wäre von Euch/dem User... egal
Dein "letztes Zeichen" ist natürlich das "/". Das A ignorierst Du. Das "/" signalisiert Dir, daß der Wert-String valide ist, und zum letzen Instrument-String paßt (und daß jetzt ein neuer Instrument-String kommen kann). Das "\" signalisiert Dir, daß jetzt ein Wert-String kommt, und der Instrument-String valide ist.
Soweit waren wir ja schon. Jetzt wäre entscheidend, was eigentlich Dein Ziel ist. Wenn das nur einfach auf ein LCD ausgegeben werden soll (insbes. ohne weitere Formatierung), kannst Du's bei den ASCII-Bytes lassen, da genau diese auch an's LCD weitergegeben werden müssen. Willst Du mit den "Zahlen" irgendwie rechnen, mußt Du sie entsprechend umwandeln.
Desweiteren ist die Frage, wie Du mit den "Instrumenten" umgehen willst. Das sind ja diskrete Werte. Sollen die so ausgegeben werden? Oder überhaupt nicht? Oder stattdessen je irgendein bestimmter Text?
Welche / wieviele dieser diskreten Instrumente soll der µC unterstützen?

Mein Vorschlag @ #56 sollte den letzten Datensatz aufs LCD bringen (also vom "A" bis zum "letzten Zeichen") - wenn das geht, kannst Du Dich um das zerpflücken kümmern.
 
Du hast recht, ich hätte euch vorher noch etwas mehr Input geben sollen.

Mein weites Ziel ist die Darstellung auf "echten" Instrumenten. Der Flugsimulator IL-2 ist thematisch im Zeitraum 1930 - 1945 angesiedelt, also noch nix mit Displays und so. Ich möcht mir ein kleines Cockpit bauen, auf dem zumindest die wichtigsten Instrumente angezeit werden. Wenn ich zB den Geschwindigkeitsanzeiger nehme, soll das ein Servo sein, der die Nadel bewegt. Dafür brauche ich dann die Zahl. Versuche dahingehend waren schon vielversprechend. Hauptproblem ist momentan für mich das Zerlegen des Datensatzes.

Diesen werde ich, wie von dir vorgeschlagen, mir heute Abend mal anzeigen lassen.



An dieser Stelle möchte ich mich bei allen bedanken, die mir hier mit Geduld weiter geholfen haben! Es zeigt sich für mich wieder: nicht die Anzahl der User macht ein Forum wertvoll, sondern das Wissen und die Hilfsbereitschaft! :)


PS: Momentan siehts so aus:Cockpit_1.jpg
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)