Forum: Mikrocontroller und Digitale Elektronik Checksumme RFM12


von P. F. (pfuhsy)


Lesenswert?

Hallo zusammen,

ich hab mal eine Verständnisfrage zur Übertragung einer Checksumme mit 
RFM12.

Ich sende foldendes an meinen Empfänger:
1
RFM_send(0xAA); //Präamble
2
RFM_send(0xAA); //Präamble
3
RFM_send(0xAA); //Präamble
4
5
RFM_send(0x2D); //Synchronisation
6
RFM_send(0xD4); //Synchronisation
7
8
RFM_send(0x80); //Datenbyte 1
9
RFM_send(0x80); //Datenbyte 2
10
11
//RFM_send(0x100) //Checksumme = Datenbyte 1 + Datenbyte 2;
12
13
RFM_send(0xAA); //Suffix
14
RFM_send(0xAA); //Sufiix
15
RFM_send(0xAA); //Suffix

Mein Empänger ist so eingestellt, dass der 2 Datenbytes (8 Bit-Länge) 
empfängt. Wenn ich jetzt eine Checksumme mitsenden will, muss ich doch 
die Summe je nach Länge aufsplitten oder sehe ich das falsch ? Die Summe 
von Datenbyte 1 und 2 würde doch in ein weiteres Datenbyte von 8 Bit 
nicht reinpassen. Mal angenommen ich hätte 8 Datenbyte zum versenden, 
könnte die Checksumme doch so groß sein, dass ich diese achteln müsste. 
Da könnte ich Daten oder direkt doppelt senden. Wo ist da der Sinn ?

Gruss

von Peter II (Gast)


Lesenswert?

Peter F. schrieb:
> Wo ist da der Sinn ?

eine checksumme ist keine einfache summe.

Die checksumme ist immer gleich lang.

http://de.wikipedia.org/wiki/Pr%C3%BCfsumme

von Phantomix X. (phantomix)


Lesenswert?

Darum nimmt man als "Checksumme" auch meistens keine einfache Addition 
(auch wenn der Name das suggeriert). Schau dir mal den XOR-Operator an 
(in C ein Accent-Circumflex ^ ).
Und wenn du es "richtig" machen willst, nimmst du CRC8 oder CRC16.

Edith: Man kann natürlich auch eine Addition machen, das Ergebnis dann 
MODULO 256 nehmen (bzw. die oberen Bits wegschmeißen) um auf 8 Bit zu 
kommen. So ähnlich funktioniert das bei Intel-Hex

: Bearbeitet durch User
von Bastler (Gast)


Lesenswert?

>Edit: Man kann natürlich auch eine Addition machen, das Ergebnis dann
>MODULO 256 nehmen (bzw. die oberen Bits wegschmeißen) um auf 8 Bit zu
>kommen. So ähnlich funktioniert das bei Intel-Hex

Oder bei Profibus...


Ich mach dass bei meinem eigenen Protokoll auch so.
Was soll daran unsicherer sein als per XOR?
Wichtig ist dass es eine Checksumme gibt.

von P. F. (pfuhsy)


Lesenswert?

Peter II schrieb:
> Peter F. schrieb:
>> Wo ist da der Sinn ?
>
> eine checksumme ist keine einfache summe.
>
> Die checksumme ist immer gleich lang.
>
> http://de.wikipedia.org/wiki/Pr%C3%BCfsumme

Das ging ja fix. Ich hatte mir mal ein Beispiel-Programm besorgt, 
welches Daten über RFM12 versendete. Wenn ich mich recht entsinne sah 
das ganze etwa so aus:
1
...
2
RFM_send(0x30); //Datenbyte 1
3
chksum += 0x30;
4
RFM_send(0x31); //Datenbyte 2
5
chsum += 0x31;
6
...

Dann war ja schon die Vorlage nicht in dem Sinne was die Checksumme 
eigentlich macht.

Gut und danke. Ich werde mal was dazu lesen.

von Peter II (Gast)


Lesenswert?

vermutlich ist dann chksum  aber nur als Byte deklariert, damit wird sie 
auch nicht größer als ein Byte.

von P. F. (pfuhsy)


Lesenswert?

Gibt es denn eine Header mit CRC8 für AVR oder muss ich den Kram selbst 
schreiben ? Auf den ersten Blick finde ich nichts mit Google.

von Peter II (Gast)


Lesenswert?

Peter F. schrieb:
> Gibt es denn eine Header mit CRC8 für AVR oder muss ich den Kram selbst
> schreiben ? Auf den ersten Blick finde ich nichts mit Google.

dann suche einfach nicht bei google, sondern einfach mal in den 
header-Dateien von deiner toolchain.

von P. F. (pfuhsy)


Lesenswert?

Peter II schrieb:
> Peter F. schrieb:
>> Gibt es denn eine Header mit CRC8 für AVR oder muss ich den Kram selbst
>> schreiben ? Auf den ersten Blick finde ich nichts mit Google.
>
> dann suche einfach nicht bei google, sondern einfach mal in den
> header-Dateien von deiner toolchain.

Auch ne Möglichkeit, danke für den Tip.

von Christian K. (the_kirsch)


Lesenswert?

Ich hatte auch mal sowas gemacht.

Hatte da ein kleines Protokoll gebastelt, es beinhaltete:
Ziel-Adresse, Quell-Adresse, Daten-Länge, Daten, CRC16-Checksum.


Der Empfänger hat zuerst geprüft ob er überhaupt angesprochen wird, und 
wenn nicht hat er abgebrochen (und wieder auf das Synchronisationsmuster 
gewartet)



Bezüglich des Suffix in deiner Sende-Routine.
Nach dem letzte echte Byte das gesendet werden soll, müssen noch zwei 
Dummy Bytes an dem RFM12 übergeben werden, bevor der Sender 
ausgeschaltet wird. Das liegt daran, das der RFM12 einen 16-Bit 
Sendepuffer hat.

Wenn man das nicht macht, und den Sender zu früh ausschaltet, fehlen die 
letzten zwei Bytes.

: Bearbeitet durch User
von P. F. (pfuhsy)


Lesenswert?

Christian K. schrieb:
> Ziel-Adresse, Quell-Adresse, Daten-Länge, Daten, CRC16-Checksum.

So ähnlich hab ich da auch vor.

Christian K. schrieb:
> Bezüglich des Suffix in deiner Sende-Routine.
> Nach dem letzte echte Byte das gesendet werden soll, müssen noch zwei
> Dummy Bytes an dem RFM12 übergeben werden, bevor der Sender
> ausgeschaltet wird. Das liegt daran, das der RFM12 einen 16-Bit
> Sendepuffer hat.

Wenn ich doch 3x "RFM_send(0xAA);" sende, wäre das doch sogar einmal 
zuviel.

Christian K. schrieb:
> Wenn man das nicht macht, und den Sender zu früh ausschaltet, fehlen die
> letzten zwei Bytes.

Ich vermute mal das dann in den Statusregister ein Fehler gemeldet wird, 
aber sonst nicht passiert oder ?

von Christian K. (the_kirsch)


Lesenswert?

Peter F. schrieb:
>> Wenn man das nicht macht, und den Sender zu früh ausschaltet, fehlen die
>> letzten zwei Bytes.
>
> Ich vermute mal das dann in den Statusregister ein Fehler gemeldet wird,
> aber sonst nicht passiert oder ?

Wenn man den Sender ausschaltet während noch Bytes im Puffer sind, gibt 
es kein Fehlerbit im Statusregister. Die letzten Bits werden einfach 
nicht gesendet.

Die RFM_send()-Funktion wartet am Anfang auf das RGIT-Bit im 
Statusregister.

RGIT: TX register is ready to receive the next byte (Can be cleared by 
Transmitter Register Write Command)


Welche Lib Verwendest du?

Gibt es eine Funktion mit der man das RGIT-Bit abfragen kann?

Dann kannst du den Code Folgendermaßen anpassen:

RFM_send(0xAA);
RFM_send(0xAA);
RFM_RGIT_ready();
RFM_txoff();

Wenn es keine gesonderte Funktion dafür gibt, ist 3-maliges RFM_send() 
ein Workaround.

: Bearbeitet durch User
von P. F. (pfuhsy)


Lesenswert?

Christian K. schrieb:
> Die RFM_send()-Funktion wartet am Anfang auf das RGIT-Bit im
> Statusregister.

Da müsste ich in meine Sende-Funktion nochmal gucken ob das bedacht ist.

Christian K. schrieb:
> Welche Lib Verwendest du?
> Gibt es eine Funktion mit der man das RGIT-Bit abfragen kann?

Ich hatte mir zu Anfang eine Biblothek aus einen Beispielprojekt 
kopiert. Mittlerweile hab ich die Header aber nach meinen bedürfnissen 
und zum besseren Verständnis geändert. Die Funktion sagt mir auf den 
ersten Blick aber nichts.

Den Sinn von der Präamble hab ich verstanden (damit sich der RFm12 
erstmal "einschwingt"). Aber warum den überhaupt der Suffix ? Die Daten 
sind zu dem Zeitpunkt doch schon gesendet ? Wenn ich dass noch richtig 
im Kopf habe, hab ich das mal ohne Suffix probiert, ging aber nicht.

von Christian K. (the_kirsch)


Lesenswert?

Das "Sulfix" wird nie gesendet. Es dient nur dafür den Sendepuffer zu 
füllen, damit der Sender nicht zu früh abgeschaltet wird.

Alternativ könnte man auf Dummy-Bytes verzichten, wenn man stattdessen 
auf das RGUR-Bit wartet und dann erst den Sender ausschalten.

Aber das RGIT/FFIT ist einfache abzufragen, da es das erste Bit im 
Statusregister ist, und sofort am MISO-Pin Anliegt wenn SS auf Low geht.


RGUR: TX register under run, register over write (Cleared after Status 
Read Command)

von P. F. (pfuhsy)


Lesenswert?

Christian K. schrieb:
> Das "Sulfix" wird nie gesendet. Es dient nur dafür den Sendepuffer zu
> füllen, damit der Sender nicht zu früh abgeschaltet wird.

Aha, so wird mir einiges klar. Danke für die Infos.

von Rainer B. (katastrophenheinz)


Lesenswert?

Ganz andere Frage: Schon mal über Einsatz von RFM69 statt RFM12 
nachgedacht ?
Der kann glaube ich CRC in Hardware.

von P. F. (pfuhsy)


Lesenswert?

Ne. Ich arbeite jetzt schon seit über einem Jahr mit dem Modul, da werde 
ich jetzt nicht die Hardware ändern.

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.