Forum: Mikrocontroller und Digitale Elektronik Funksystem - Fehlererkennung und Fehlerkorrektur


von Flo (Gast)


Lesenswert?

Hallo


Ich bin gerade dabei für meinen Privatgebrauch Funkboards zu basteln. 
Also ein Funkmodul im 433MHz Band plus ein AVR (ATmega32) der die ganze 
Ansteuerung, Datenverarbeitung, etc übernimmt.

Die Funkerei verläuft bidirektional mit 2 Funkmodulen. Es werden Strings 
unterschiedlicher Länge gesendet.

Das ganze funktioniert auf dem Steckbrett reibungslos.

Nun will ich eine Fehlerbehandlung einbauen für den Fall wenn es nicht 
mehr so reibungslos funktioniert.

Leider kenne ich mich mit Fehlerbehandlung nicht so gut aus und bin auf 
der Suche nach effektiven Methoden zur Fehlererkennung und 
Fehlerkorrektur für mein Problem. Im Netz finde ich so viel, dass ich 
nicht weis was ich nun verwenden soll und was zeitgemäß und effektiv 
ist.

Bisher habe ich das seeeehr trivial gelöst (fast schon steinzeitmäßig).
Ich habe eine Startbyteabfrage (alle Datenpakete müssen mit dem selben 
Byte beginnen), Prüfsummen (Quersummenberechnung) und ein Byte das die 
Länge des zu übertragenden Strings angibt.
Schön wäre es noch zu erkennen ob Datenpakete einfach im Nirvana 
gelandet sind. So eine Art Paket-Zähler auf beiden Seiten...

Anregungen sind erwünscht :-)

von Chris D. (m8nix)


Lesenswert?

Du könntest versuchen, wenn es die Datenrate erlaubt, mit einem Echo
zu arbeiten. Sprich die empfangenen Daten werden vom Slave 1 zu 1 zum 
Master zurückgesendet. Wenn das Empfangene dann identisch mit den 
Ursprungsdaten ist könnte der Master dem Slave ein aknolege senden.
Bei einer fehlerhaften Übertragung würde ein noaknolede gesendet werden, 
was den Slave dazu veranlasst die Daten zu verwerfen.

Gruss Chris

von Flo (Gast)


Lesenswert?

Danke für deine Antwort :-)

An soetwas ähnliches dachte ich auch schon, nur dein Stickwort 
Acknowledge bringt mich noch auf etwas anderes. Das ganze Datenwort 
zurückzusenden ist nicht möglich. Ein Datenwort kann maximal aus 50 
Datenbytes + Startbyte + Längenbyte + Prüfsummenbytes bestehen. Das sind 
dann ca. 60 Bytes. Die jedesmal zurückzusenden wäre bei hohem 
Datenaufkommen nicht drin.
Aber stattdessen könnte der Receiver ja wie beim I2C-Bus nur ein kurzes 
ACK senden, irgendein spefifiziertes Byte. Der Transmitter wartet 
einfach eine definierte Zeit lang. Kommt ein ACK zurück wird das nächste 
Byte gesendet, kommt nix zurück wird das Byte nochmal gesendet.

Einzigsten Manko ist, dass die "Signallaufzeit" zwischen Senden und 
Empfang gerne mal einige viele Millisekunden dauern kann und sich für 
die Zeit nichts tut. Aber das muss ich wohl in Kauf nehmen wenn ich 
soetwas implementieren will.

von Peter R. (gelb)


Lesenswert?

@ Flo (Gast) :
Fehlerkorrektur war mir für meine Projekte zu aufwändig. Echo der 
kompletten Daten ist zu viel Funkverkehr. Ein simpler XOR-CRC brachte 
kein gutes Ergebnis bei einem kleinen Spaziergang mit dem Sender weg vom 
Empfänger.

Aber ein guter CRC (2 Byte zusätzlich zum Übertragungspaket, etwa 70 
Byte Paketlänge) genügt, um Übertragungsfehler sicher zu erkennen. Wenn 
der Empfang fehlschlägt, gibt es eben kein ACK vom Empfänger. Der Sender 
macht dann timeout und probiert es nochmal oder gibt erstmal auf. Also 
im Prinzip wie dein Lösungsansatz.

Meine Links zum Thema CRC:

Beitrag "CRC-16 Prüfsumme (serielle Übertragung)"

http://www.zorc.breitbandkatze.de/crc.html

Das Polynom $8408 sowie der Startwert $ffff der ISO 15693 in Verbindung 
mit dem Code von Peter Dannegger funktioniert bei mir nachvollziehbar 
und einwandfrei. Wird der übertragene CRC-Wert mit eingerechnet, 
entsteht bei korrekter Übertragung immer $f0b8.

Grüße, Peter

von Skippy (Gast)


Lesenswert?

Ich habe auch mal ein Protokoll für sowas ähnliches wie ein Funksystem 
entwerfen dürfen (für Läsergetriebene Übertragung rund 2 km) allerdings 
hatte ich da auch erheblich Freie Hand

Checksumme hab ich einfach mit Paritätsbit gearbeit wobei da natürlich 
moderne Verfahren sicher die bessere Wahl sind(z.b. das von gelb 
genannte).

die ersten beiden bytes gaben die Paketart an
# und nummer (z.b. #9) war für die Adressierung verschiedener geräte
## entsprach dem ACK
ER stand für Fehlermeldung hat das gerät festgestellt das irgend ein 
Fehler aufgetreten ist konnte es jederzeit sein gegenüber informieren

damit hatte ich dann die wichtigsten sachen implementiert
festgelegt war z.b. das das gerät 10nachrichten/Pakete + Overhead senden 
konnte bevor ein ACK notwendig war. damit konnte man dann auch Pakete 
zählen durch des ER konnte aber auch schon verher bekannt gegeben werden 
das was nicht stimmt um zu verhindern das z.b. noch 9pakete kommen 
obwohl schon was nicht stimmt

vielleicht gibt dir das den notwendigen tip ;-) ansonsten halt uns auf 
jedenfall auf dem laufenden

von Chris D. (m8nix)


Lesenswert?

Mein Vorschlag noch zum ACK

> Kommt ein ACK zurück wird das nächste
> Byte gesendet, kommt nix zurück wird das Byte nochmal gesendet.
> Einzigsten Manko ist, dass die "Signallaufzeit" zwischen Senden und
> Empfang gerne mal einige viele Millisekunden dauern kann und sich für
> die Zeit nichts tut.


Es muss ja nicht zwanghaft ein ACK folgen... Auch wenn die 
Sende/Empfangsreichweite o.K. ist, können auch andere Störeinflüsse den 
Datenverkehr stören. Dann kannst du immmer noch ein NOAK senden um zu 
verhindern das der Master warten muss. Auch wenn der's nicht mitbekommt 
/ mitbekommen kann. (Kleiner Zeitgewinn falls letzteres nicht zutrifft.)

Der Vorteil am Echoverfahren ist eben das du keine CRC's berechnen 
musst, ein einfacher Vergleich, ohne Rechenoperationen, reicht und du 
bist zu 100% sicher das die Daten stimmen, was man bei CRC nicht 
vollständig behaupten kann. Ich weiss nicht wie's bei den ATmegas 
aussieht, aber bei den 8051'er musste man immer warten bis das 
USART-Flag einem erlaubte ein neues Byte zu senden.... diese Zeit könnte 
z.B. schon mit einem Vergleich eines zurückgesendeten Bytes genutzt 
werden. Ein Echo kannst du in bidirektionalen Systemen sofort nach dem 
eintreffen des ersten Byts zurücksenden. Wenn du, wie in deiner Idee, 
nach jedem Byte auf ein ACK warten musst ergibt sich daraus eine horende 
gesamte Wartezeit die in keinem Verhältnis zum Echotimeout steht.

Hier noch ein kleinens Rechenbeispiel:
60 bytes = 480 bits per second... bei 9600 bps Übertragungsrate sind das 
50ms .... mit Echo 100ms "tehoretisch" ... Nehmen wir ruhig das 
zweifache an ... also 200ms für senden empfangen, puffern, zurücksenden, 
vergleichen.
Bist du sicher das du mit einem Timeout von 200ms hinkommst auf das 
warten eines ausbleibenden ACK? Echo hört sich immer schlimm an.. ist 
aber einfach auszuwerten und zudem 100% sicher.

Sicher aber auch nur wenn das ACK bzw. NOAK gut kodiert, mehr als ein 
Byte lang und zudem in der Bitfolge unverwechselbar ist. Aber das gilt 
für alle Arten von Acknowledge-Übertragungen.

von Manuel (Gast)


Lesenswert?

Ich habe in meinem Funk-Alarm System eine Übertragung realisiert, die 
mittels Sender- und Empfänger-ID mehrere  Nodes und Master ermöglicht. 
Fehler werden über den Retry-Counter, der CRC checksum, einem time-out 
und ACK/NOACK identifiziert. Läuft seit einigen Monaten ohne Probleme. 
Da Sender und Empfänger einstelbar sind, geht auch eine Kommunikation 
zwischen zwei Nodes ohne die Alarmzentrale. Das Übertragungfomat ist 
IMMER gleich, nur die Anzahl Datenbytes ist unterschiedlich. Also Sender 
schickt Message - Empfänger wertet aus und sendet im gleichen Format das 
ACK bzw NOACK im command Byte zurück.

Format
-------------
receiverID + senderID + command + retries + length + data[0] .... 
data[length-1] + CRC

Address IDs
-----------
Nodes   = 0x01 to 0x3F
Masters = 0x80 to 0x8F

Commands
--------
00 = Ping
01 = Status
02 =
03 =
04 =
05 =
06 =
07 =
08 =
09 =
10 =
.
.
.
55 = ACK of transmission
AA = NACK of transmission = resend package

von Flo (Gast)


Lesenswert?

@ Chris D.

Ich glaube du hast mich nfalsch verstanden oder ich habe es falsch 
ausgedrückt.
Ich will NICHT nach jedem einzelnen Byte ein ACK/NCK senden. Das wäre ja 
Schwachsinn...
Vielmehr will ich das so machen:
- Transmitter sendet, Receiver empfängt Daten. Sind Daten valide (also 
Startbyte OK, Länge OK, Checksumme OK) gibt er ein ACK zurück. Das 
können 2 Bytes sein.

- Transmitter sendet, Receiver empfängt Daten. Daten sind aber nicht 
valide, irgendein Fehler. Receiver gibt NCK (NOT ACK) zurück, 
Transmitter sendet Daten erneut.

- Transmitter sendet, Receiver empfängt nichts. Transmitter rennt nach 
wenigen Millisekunden ins Timeout und weis, dass sich ein erneutes 
Senden nicht lohnt weil der Receiver eh nix empfangen wird.


So muss man nur nach eden DatenPACKET ein ACK/NCK senden. Also auf das 
Extrembeispiel von oben hin kommen auf die 60 Bytes nur 2 Bytes 
ACK/NCK-Check. Das verringert die Sache schon enorm.
Natürlich könnte man jedes empfangene Byte sofort wieder zurücksenden 
und auf Gültigkeit gegenprüfen. Aber das verdoppelt grundsätzlich immer 
das Transfervolumen und damit die Transferzeit. Sollte eines der Module 
außerdem mal etwas länger brauchen als das andere laufen sie Gefahr, 
dass sie zur gleichen Zeit senden oder empfangen und damit nichts mehr 
geht.

Über so ein Funksystem mit mehreren Tranceivern bin ich momentan auch am 
überlegen...wäre auch cool ;-)

von Flo (Gast)


Lesenswert?

Oh sehe gerade, dass ich wirklich Byte geschrieben habe...
Sorry, ich meinte wirklich Datenpacket ;-)

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.