Moin!
Ein Atmega8535 soll zwischen mehreren RS232- Signalquellen umschalten.
Gelöst mittels HC151, klappt ganz herrlich.
Aber angenommen:
die Umschaltung auf eine neue Quelle erfolgt gerade inmitten eines
gesendeten Bytes. Der Puffer empfängt also das Ende eines Bytes, hält es
für den Anfang dessen, und beendet es mit dem Anfang des nächsten
kommenden Bytes.
Da kann ja nur Kacke bei rauskommem.
Ist die Sorge berechtigt oder wie lässt sich das soft-/hardwaremäßig
ausschließen?
Mange Tak- Stephan
Stephan R. schrieb:> Ist die Sorge berechtigt oder wie lässt sich das soft-/hardwaremäßig> ausschließen?
Das kann nicht nur passieren.
Nach dem Gesetz von Murphy muss und wird passieren...
Du wirst also deine SW so anpassen müssen, dass sie damit klarkommt.
Insbesondere ist ein einzelnes Byte nur ein Bruchstück der Wahrheit.
Denn i.A. wird ja eine ganze Zeichenkette über die RS232 gesendet, wo
jedes Byte seine eigene Bedeutung hat...
Stephan R. schrieb:> Der Puffer empfängt also das Ende eines Bytes, hält es> für den Anfang dessen, und beendet es mit dem Anfang des nächsten> kommenden Bytes.
Es gibt ne Erfindung die nennt sich Start Bit!
Daher gibt das kein Müll, nur das eine Byte ist kaputt...
Stephan R. schrieb:> Lmiller und Docean sind sich uneins..
Wir sind ja auch zwei... ;-)
Aber ich habe recht...
>>> Aber angenommen: die Umschaltung auf eine neue Quelle erfolgt>>> gerade inmitten eines gesendeten Bytes.>> Es gibt ne Erfindung die nennt sich Start Bit!>> Daher gibt das kein Müll, nur das eine Byte ist kaputt...
Nehmen wir mal das:
A=Startbit
D=Datenbits
E=Stopbit
X=Umschaltzeitpunkt
AD E
TX1 1111011110000111111111111 -- sendet 0xf0
AD E
TX2 1111111110111100001111111 -- sendet 0xf0
X
RX 1111011110111100001111111 -- empfängt 0xf7 und 0x1f
11110111 00011111 --> zwei Bytes korrekt empfangen,
aber Daten korrupt
Hi
>Was macht die UART mit kaputten Bytes? Wegschmeissen?
Das musst du organisieren.
Wie wäre es, einfach die Fehlerbits der UART auszuwerten?
MfG Spess
Entsteht denn bei dem von Lothar sehr schön dargestellten Fall (mein
Worst-case) ein Fehlerbit? Und was ist ein Fehlerbit? So etwas wie eine
checksumme?
@Lothar Miller: genau!
@Stephan R.: Wirst du entweder die Quellen synchronisieren müssen oder
mit einer Prüfsumme (CRC) die Möglichkeit der Fehlererkennung seitens
des Empfängers einführen müssen.
Einfach drauflos ballern iss nix.
Gruß
ich
Stephan R. schrieb:> Entsteht denn bei dem von Lothar sehr schön dargestellten Fall (mein> Worst-case) ein Fehlerbit?
Nein. Passt alles für 8N1...
> Und was ist ein Fehlerbit?
Der naheliegendste Fehler ist ein Framing Error, dass eigentlich ein
Stopbit erwartet, aber eine 0 erkannt wurde.
> So etwas wie eine checksumme?
Nein. Diese Fehler greifen nur auf der Bitebene des Protokolls.
Prüfsummen beziehen sich auf mehrere Bits.
Und mein Beispiel bezieht sich zudem auch "nur" darauf, dass beide
Sender bitsynchron sind. In der Realität sind sie das kaum bis niemals,
und deshalb wird es einige urige Fehlerbilder geben...
Insbesondere, wenn beide Sender Bytes ohne Pause hintereinander senden
kannst du durchaus auch viele falsche Bytes korrekt empfangen...
Kannst Du nicht, wenn Du zwischen zwei Streams hin und herschaltest,
über "0" schalten?! Also erst die Leitung trennen "kurz" warten und dann
auf die andere aufschalten?!
Handshake wird leider nix, da sie Signalquellen keins anbieten.
Synchronisieren wird auch schwierig, da die Geräte vällig autonom sind
(LWL- Interface und GPS- Empfänger).
Ich habe also keine Wahl als mitten in den Datenstrom reinzuspringen.
Framing-Error hört sich für mich am geeignetsten an.
Einziges Risiko wäre doch, dass, bis das erste falsche Stop- Bit
auftaucht (was statistisch nicht allzu lang dauern dürfte), nur Mist
ankommt, was denn weggeschmissen wird. (Oder?)
Wie lautet denn die Abfrage nach der Correctness des Bits? Und was tut
die UART von haus aus, wenn dieser Error auftritt?
Ich würde, falls es deine Anwendung erlaubt, das serielle Eingangssignal
in ein Schieberegister mit seriellem Ein- und Ausgang jagen. Am
parallelen Ausgang siehst du ob sich gerade irgendwas an der Übertragung
tut. Diese Ausgänge kannst du "verodern". Wenn auch nur ein Bit gesetzt
ist dann ist was in der "Pipe".
Das erfordert natürlich, dass über die Länge von min. einem Byte keine
Daten gesendet werden um die Pause erkennen zu können.
Das Schieberegister muss dann mit der Baudrate getaktet werden. Den Takt
könnte der Controller erzeugen.
RX 111101111011110000101111000010111100001111111 -- empfängt 0xf7 0x17, 0x17 und 0x1f
7
11110111 00010111 00010111 00011111 --> vier Bytes korrekt empfangen, aber Daten korrupt
> Kannst Du nicht, wenn Du zwischen zwei Streams hin und herschaltest,> über "0" schalten?!
Richtig wäre: über '1' umzuschalten, das ist der inaktive RS232-Pegel.
Das hilft aber auch nicht weiter:
Leider schon 50m Fädeldraht verfädelt, zu spät für Controllerwechsel.
Und für ein Schieberegister ist auch ken Platz mehr.. Ich möchte mich
auf die Stoppbitverarbeitung konzentrieren.
Stephan R. schrieb:> Leider schon 50m Fädeldraht verfädelt, zu spät für Controllerwechsel.> Und für ein Schieberegister ist auch ken Platz mehr.. Ich möchte mich> auf die Stoppbitverarbeitung konzentrieren.
Auf Bitebene ist das Alles ohne Synchronisierung nix. Schau dir Lothar's
Beispiele an, da hilft dir auch ein Stopbit nichts, wenn die Zahl der
Bits stimmt und der Empfänger vom Umschalten nichts mitbekommt.
Ein Stopbit ist eben ein Stopbit und dient nicht der Fehlererkennung,
die du hier dringend brauchst.
Führe wenigstens CRC ein, damit der Empfänger falsche Pakete verwerfen
kann.
Lothar Miller schrieb:> Insbesondere, wenn beide Sender Bytes ohne Pause hintereinander senden> kannst du durchaus auch viele falsche Bytes korrekt empfangen...
Stimmt!
Laß mal den MC irgendwelchen Text ununterbrochen senden.
Und danach starte auf dem PC ein Terminal und schließe ihn an.
20 Zeilen nur Mist sind durchaus möglich, ehe der Text lesbar wird.
Mit 2 Stopbits entschärft sich das leicht (nur 3 Zeilen Mist).
Du brauchst also unbedingt eine Synchronisation.
Z.B. der Sender macht vor einem neuen Paket ne Pause von mindestens 10
Bitzeiten.
Oder ein Byte mit nur einer Startflanke (0x00, 0x80, 0xC0, ... 0xFF).
Peter
Synchronisation schön und gut..
Liesse sich denn seitens des Empfangspuffers synchronisieren? Soll
heissen: falls die ankommenden Zeichen nicht aus 0-9 oder A-Z bestehen,
"was" machen.
Nur was? Schieboperation im Puffer? Gibts das?
Die einherströmende Datenflut (NMEA) kann ich echt schlecht
beeinflussen!
Stephan R. schrieb:> Die einherströmende Datenflut (NMEA) kann ich echt schlecht> beeinflussen!
Kann man den Geräten denn nicht sagen wann sie anfangen sollen zu
senden. Was sind das für Teile, die einfach ununterbrochen senden? Das
macht doch keinen Sinn.
Und wenn sie ununterbrochen senden, dann müssen Sie ein Protokoll
besitzen, mit dem Du den Anfang eines logisch zusammengehörigen
Datenpakets erkennen und auch prüfen kannst.
Stephan R. schrieb:> falls die ankommenden Zeichen nicht aus 0-9 oder A-Z bestehen,
Dann liesse sich langfristig was machen.
> Nur was? Schieboperation im Puffer? Gibts das?
Du kannst auf jeden Fall gleich mal alles wegwerfen, was nicht aus
diesen Zeichen besteht. Dann auf eine Pause im Datenstrom hoffen, und
wenn irgendwann keine Framing-Fehler mehr kommen und du nur noch
"sinnvolle" Zeichen empfängst, hast du es geschafft, dich wieder
aufzusynchronisieren. Bis dahin hilft nur hoffen... :-/
Stephan R. schrieb:> Die einherströmende Datenflut (NMEA) kann ich echt schlecht> beeinflussen!
Sicher, daß da keine Pausen zwischen den Paketen sind?
Ohne Pausen kann der Empfänger nicht 100%-ig synchronisieren, basta.
Man kann im RX-Interrupt nen Zeitstempel nehmen, ob nach dem Umschalten
bzw. zum vorherigen RX mindestens 20 Bitzeiten vergangen sind. Und erst
dann nimmt man das Paket entgegen.
Peter
U.R. Schmitt schrieb:> Was sind das für Teile, die einfach ununterbrochen senden? Das> macht doch keinen Sinn.
Eben z.B GPS-Empfänger, die die Frames z.B. im NMEA-Format im 1
Sekundentakt
senden.
Klar macht das Sinn.
Gun B. schrieb:> Eben z.B GPS-Empfänger, die die Frames z.B. im NMEA-Format im 1> Sekundentakt> senden.
Und die Frames sind dann auch wirklich 1s lang?
Wenn sie kürzer sind, hast Du doch ne Pause und alles ist in Butter.
Peter
Ich habe gerade mal gegoogelt NMEA ist doch ein standardisiertes
Datenformat, Zwischen 2 NMEA Sätzen ist bestimmt eine Pause die dafür
sorgt daß der UART bei Bitweiser Misssynchronisation einen Fehler wirft
und vorher anfangen zu lesen hat eh keinen Wert.
Ab dann liest Du den kompletten NMEA Datensatz ein, der hat sogar einen
(optionalen) CRC, den Du auswerten solltest falls vorhanden. Danach
schaltest Du auf den 2. Kanal und synchronisierst analog je nach
darüberliegendem Protokoll auf diese Daten.
Byte oder gar Bitweises Denken ist hier vollkommen unnötig.
@U.R. Schmitt:
nen Standard-GPS- Empfänger.
Werde mich mal in der Spec umsehen, obs nicht doch einen Befehl gibt,
die Aktualiesierungrate zu vergrößern. Irgendwas hab ich da mal
gelesen..
Bleibt offen: was tut der Atmega -werkseingestellt- mit Framingerrors?
Wird ein Flag gesetzt und das Byte dennoch ausgegeben oder wird es
gleich verworfen?
Karl heinz Buchegger schrieb:> Wenn sie im 1 Sekundentakt senden, senden sie eben nicht ununterbrochen.
War klar, dass die Antwort kommen musste. Fast richtig, ist nur Mist,
wenn du 8 Quellen hast, die nicht gegenseitig aufeinander warten und
synchron laufen, oder?
Wenn z.B. zwei GPS-Sender als Quellen dienen, der erste bei 0s anfängt,
der zweite bei 0,2s, dann sendet jeder für sich noch immer im
Sekundentakt, das Delta zwischen beiden ist aber 0,2s. Schaltet der
Multiplexer z.B zum Zeitpunkt 0,8s, dann erwischt er den zweiten Sender
und der sendet noch 0,4s seinen Krempel. Damit wäre Lothar's Fall wieder
gültig, nämlich eine Überlagerung von Bits, die im ungünstigsten Fall
eben ein korrektes Byte bauen.
Bei 8 Sendern oder Geräten, mit oder ohne Takt, wird's dann noch
kritischer. Irgendwie ist das alles keine saubere Lösung, wenn der
Multiplexer nicht auf die Quellen synchronisiert wird.
Stephan R. schrieb:> (NMEA)
Dann ist es quasi schon simpel.
Schade, dass diese Information erst nach 2 Stunden kommt... :-/
>> und der sendet noch 0,4s seinen Krempel.
Macht doch nichts....
Eine Sekunde später hast du wieder ein gültiges Datenpaket.
Gun B. schrieb:> Irgendwie ist das alles keine saubere Lösung,
Das sowieso.
Da ist jemand zu blauäugig an die Sache herangegangen.
Die sauberste Lösung wäre, ein IC mit mehreren USART in die Schaltung
mit aufzunehmen. Alles andere ist Murks. AUch wenn einem NMEA hier unter
die Arme greift:
Es gibt (normalerweise) eine physische Pause zwischen den Sätzen
Wir wissen, dass jeder Satz mit $ anfängt
Aber ohne dass einem zwischendurch ein paar Datensätze verloren gehen,
wirds nicht gehen.
Lothar Miller schrieb:>>> und der sendet noch 0,4s seinen Krempel.> Macht doch nichts....> Eine Sekunde später hast du wieder ein gültiges Datenpaket.
Stimmt, wenn es sich ausschliesslich um periodisch gesendete Datenpakete
handelt.
Aber was ist, wenn auf einem Kanal der GPS arbeitet, auf einem anderen
irgendeine nicht-zyklische Information gesendet wird, die zudem nicht
verloren gehen darf?
Vielleicht habe ich es in meiner Abwesenheit der Mittagspause überlesen,
ansonsten wäre es gut zu wissen, was auf den anderen Kanälen gesendet
wird (periodisch oder nicht, wichtige, z.B. sicherheitsrelevante Daten
oder nicht).
Karl heinz Buchegger schrieb:> Alles andere ist Murks.
Das sehe ich auch so. Ohne das verachtend zu meinen, ich würde so etwas
nicht wie oben genannt implementieren.
Gun B. schrieb:> War klar, dass die Antwort kommen musste. Fast richtig, ist nur Mist,> wenn du 8 Quellen hast, die nicht gegenseitig aufeinander warten und> synchron laufen, oder?
Das ist egal.
Du schaltest einfach um und prüfst auf die Pause. Dadurch ist das
folgende Paket gültig.
Dann schaltest Du wieder um, ...
Peter
Gun B. schrieb:> Vielleicht habe ich es in meiner Abwesenheit der Mittagspause überlesen,> ansonsten wäre es gut zu wissen, was auf den anderen Kanälen gesendet> wird (periodisch oder nicht, wichtige, z.B. sicherheitsrelevante Daten> oder nicht).
Sicher bin ich mir natürlich nicht, aber das hier
Beitrag "Re: Das A und O des UART- Puffers"
würde für mich den Schluss zu lassen, dass wir es mit 8 GPS Empfängern
zu tun haben. Was auch immer es für einen Sinn haben soll, 8 GPS
Empfänger in einer Schaltung zu haben.
Gun B. schrieb:> Aber was ist, wenn auf einem Kanal der GPS arbeitet, auf einem anderen> irgendeine nicht-zyklische Information gesendet wird, die zudem nicht> verloren gehen darf?
Dann gehört derjenige, der sowas verzapft, geteert und gefedert.
Wenn ein Paket nicht verloren gehen darf, dann muß ich das irgendwie
absichern.
Z.B. dadurch, daß dieses Paket quittiert werden muß, sonst wird es nach
einer Pause nochmal gesendet.
Peter
Karl heinz Buchegger schrieb:> Was auch immer es für einen Sinn haben soll, 8 GPS> Empfänger in einer Schaltung zu haben.
Könnte es sein, dass dann die statistische Abweichung quadratisch
kleiner wird? Nur so eine Idee, immerhin macht Elektor auch einen Stall
voll OPs auf eine Platine um das Rauschen zu reduzieren... ;-)
Peter Dannegger schrieb:> Das ist egal.> Du schaltest einfach um und prüfst auf die Pause. Dadurch ist das> folgende Paket gültig.> Dann schaltest Du wieder um, ...
Wenn du davon ausgehst, dass es sich um Quellen handelt, deren
Informationen periodisch gesendet werden, gebe ich dir recht.
Aber was ist, wenn z.B. eine Quelle eine Bytefolge asynchron sendet und
mit dem Senden beginnt, während der Multiplexer noch eine andere Quelle
aufgeschaltet hat, bevor er auf die erstgenannte schaltet? Dann ist
dieses Datenpaket auf jeden Fall beschädigt. Und wenn es sich z.B. nicht
um GPS-Pakete handelt, sondern z.B. um irgendeinen anderen Wert, der
alle 2 Minuten mal gesendet wird, dann erfolgt bis dahin kein Update,
das ist unabhängig vom zyklisch sendenden GPS oder sonstwas.
Kommt eben auf den Fall an. Bei ausschliesslich GPS-Daten hast du recht.
Stephan R. schrieb:> Nene, es ist ein GPS Empfänger mit NMEA Ausgang und ein LWL- Interface,> wo zwar wichtige aber dafür sich ständig wiederholende Daten reinkommen.
Damit wäre Peter's Ansatz möglich. Solche Infos wären von Anfang an
wichtig gewesen, Hellsehen ist noch buggy.
Peter Dannegger schrieb:> Wenn ein Paket nicht verloren gehen darf, dann muß ich das irgendwie> absichern.> Z.B. dadurch, daß dieses Paket quittiert werden muß, sonst wird es nach> einer Pause nochmal gesendet.
Eben, meine obige Aussagen. Ist nur die Frage, ob Stephan das auch
weiss.
Gun B. schrieb:> Aber was ist, wenn z.B. eine Quelle eine Bytefolge asynchron sendet und> mit dem Senden beginnt, während der Multiplexer noch eine andere Quelle> aufgeschaltet hat, bevor er auf die erstgenannte schaltet? Dann ist> dieses Datenpaket auf jeden Fall beschädigt. ...
Hallo,
so kompliziert muss man garnicht argumentieren, bei 1 UART und 8 Quellen
sind verlorene Pakete von vornherein unvermeidlich. Schliesslich kann
von gleichzeitig ankommenden Datensätzen nur einer empfangen werden. Bei
GPS ist das egal, dürfen dagegen aus einem Stream keine Daten
verlorengehen ist das Konzept unbrauchbar.
Gruss Reinhard
Reinhard Kern schrieb:> bei 1 UART und 8 Quellen> sind verlorene Pakete von vornherein unvermeidlich.
In Stephan's Fall richtig.
Allgemein nicht. Könnte man die Quellen senderseitig zentral aktivieren,
den Multiplexer der jeweils aktiven Quelle zuteilen und per Software der
Quelle erlauben, erst dann zu senden, wenn sie aktiviert wurde, geht da
gar nichts verloren, so lange die Daten nicht autonom von der Quelle wie
dem GPS-Empfänger im Sekundentakt gesendet werden.
Schon zig mal gemacht. Klappt prima und ist unkompliziert.
Gun B. schrieb:> und per Software der> Quelle erlauben, erst dann zu senden, wenn sie aktiviert wurde
Das ist klar, denn dann ist die Übertragung ja sogar auf Protokollebene
garantiert synchron.
Nur: so schön geordnet ist die Lage von Stephan leider nicht...
Lothar Miller schrieb:> Nur: so schön geordnet ist die Lage von Stephan leider nicht...
Schon klar.
Aber ich habe mich bezogen auf die Aussage:
>so kompliziert muss man garnicht argumentieren, bei 1 UART und 8 Quellen>sind verlorene Pakete von vornherein unvermeidlich.
Kann man pauschal eben nicht sagen.
Stephan R. schrieb:> O wie wahr...
Aus wie vielen Bytes bestehen die Daten über das LWL-Interface? Gibt es
einen Header, meinetwegen ein Startbyte, der den Frameanfang
kennzeichnet?
Gun B. schrieb:> Stephan R. schrieb:>> O wie wahr...>> Aus wie vielen Bytes bestehen die Daten über das LWL-Interface? Gibt es> einen Header, meinetwegen ein Startbyte, der den Frameanfang> kennzeichnet?
Das Problem ist immer dasselbe.
Steigt man asynchron in eine UART Übertragung ein, so kann man sich erst
einmal auf gar nichts verlassen. Jedes Byte das empfangen wurde, kann
fehlerhaft sein. Noch nicht mal auf den von der Hardware gemeldeten
Framing-Error kann man sich verlassen. D.h. man kann sich schon auf ihn
verlassen nur auf die Umkehrung nicht. Das Ausbleiben eines Framing
Errors bedeutet nicht, dass man jetzt sauber in den Datenstrom
eingeklinkt ist.
Das kann genausogut Zufall sein, dass gerade die richtigen Bits
übertragen werden, damit kein Framing Error entsteht.
@Stephan:
Jetzt noch mal genau die Frage, die ich oben irgendwie nicht beantwortet
sehe: Ist der schaltende Controller auch der Empfänger ODER kann er
zumindest auf seiner RxD mithören?
Stephan R. schrieb:> Der umschaltende Controller ist auch der Empfänger der Daten.
Also,
du kennst:
- den Header des GPS-Frames aus der NMEA
- der Frame endet mit <CR> <LF>
- du kennst den Sekundentakt des Moduls
- die Länge des GPS-Frames aus dem NMEA-Protokoll
- die Baudrate des Moduls
- damit kennst du auch die Zeitdauer des Frames
eine Menge bekannter Daten also
du schreibst:
- das du das Datenformat auf dem LWL-Interface selbst bestimmen kannst
- dann gibst du dem Frame mindestens einen Header, am besten auch eine
Endsequenz
- du kennst die Baudrate, damit die maximale Zeitdauer eines Frames
- du kannst auch hier vielleicht eine Pause zwischen den Frames
einfügen?!
auch eine Menge bekannter Größen also.
Eine Lösung wäre:
- Du startest mit dem GPS-Modul und wartest auf die nächste Pause.
- Dann auf den Beginn des Frames und schreibst ihn bis zum <CR> <LF>
weg.
- Dann schaltest du auf das LWL-Intf. um.
Du landest nun mit aller Wahrscheinlichkeit irgendwo in einem bereits
begonnenen Frame. Macht nix.
- Bei Implementation mit Pause wartest du auf diese, bevor du mitloggst.
- Mit Beginn des ersten Bytes nach der Pause schreibst du bis zum Ende
des Frames mit.
- Ende: entweder durch Endsequenz oder durch Anzahl der Bytes erkennen,
wenn konstant, oder Pause.
- Implementation ohne Pause setzt Header/Endsequenz voraus, auf den/die
du synchronisieren musst.
Dann wieder umschalten auf GPS-Modul, Pause abwarten und Folgebytes
wegschreiben. Könntest auch auf den GPS-Header synchonisieren, musst
dann aber die ASCIIs analysieren.
So, in diesem Fall würden sich deine Schaltzeiten nach den Frames
richten, d.h., nach den erkannten Headern und der Länge der Frames.
Sollte die Vorgabe aber eine periodische Umschaltung mit gleichen Zeiten
von Kanal zu Kanal sein, dann richtet sich die Framelänge eben nach dem
längeren Frame der beiden Quellen + Pause. Glaube, ist klar, was ich
meine.
Könntest auch die doppelte Framelänge z.B. beim LWL-Interf. einlesen und
außerhalb der Interruptroutine die Auswertung machen, in dem du nach dem
Header/Trailer suchst und die entsprechende Anzahl Bytes auswertest.
Wie auch immer, aber mit den Infos sollte es einfach sein. Anfangs
entstand der Eindruck eines Multiplexers mit mehr Einschränkungen.
Ich denke, ich verstehe.
So viele Päus-chen sind zwar nicht schön aber wat mut dat mut.
Werds morgen -wenn ich wieder einen laufenden ISP-Programmer hab- mal
testen.
Vielen Dank für die rege Beteiligung!