Hallo!
Kämpfe schon seit längerem mit einem Projekt mit RFM69W und RFM69HW Transceivern.
Inzwischen habe ich so viele Fallstricke mit diesen Teilen hinter mir, das ich demnächst dazu geneigt wäre hier einen Lexikonartikel zu diesen RFM69 zu erstellen.
Aber hier habe ich jetzt mal eine gänzlich andere Frage:
Um Bits innerhalb einer Variable nach links oder rechts zu shiften gibt es ja recht einfache Befehle. Aber wie sieht das mit Arrays aus?
Ich sende zwischen meinen RFM69 GFSK-Pakete mit exakt 25 Bytes hin und her.
Diese werden von den RFM69 not der nötigen Pramble (3Byte hAA), zwei beit Syncword (h22 , hF7) vor dem ersten und einer CRC16 nach dem 25.sten Nutzbyte ausgestattet und übertragen.
Zusätzlich sorgt die Funktion Whitening das längere gleichwertige Bitketten den Empfänger nicht desynchronisieren.
Also kurz gesagt: Ich nutze bereits sämtliche Sicherungsfunktionen für die Übertragung, welche die RFM69 bieten.
Solch ein Datenpaket sieht bei mir z.B. so aus:
A0 13 68 8F 0F 14 1A E4 6A 08 00 60 F2 A0 1B A0 03 A6 00 5F 00 00 00 00 36
Das erste Byte setzt sich zusammen aus Kanal (MSB-Nibble) und Sensor-ID (LSB-Nibble) gefolgt von einem Timestamp:
Byte 2 das Jahr
Byte 3 Monat sowie Wochentag
Byte 4 Tag + MEZ/MESZ
Byte 5 Stunde
Byte 6-24 sind Sensordaten
Byte 25 ist eine eigene CRC8
Ursprünglich habe ich die CRC8 weniger wegen der Funkübertragung vorgesehen, sondern zur Datensicherung während den zahlreichen umkopierungen.
So wie oben das Musterpaket sehen also die Standardpakete aus welche ich beim Sender in den FIFO schiebe, und beim Empfänger aus dem FIFO ziehe.
Der empfangende RFM tut (inzwischen) was er soll: Er empfänge die GFSK-Pakete, sucht nach dem Syncword, schiebt ins FIFO.
Dann wird die CRC16 geprüft und das Paket im FIFO gesäubert: Alles vor dem Nutzdatenpaket (Dotting, Syncword) sowie die CRC16 wird abgeschnitten.
Erst dann löst der RFM69 den Interrupt "PayloadReady" aus.
Soweit funktioniert das, aber nicht wirklich zufriedenstellend:
Etwa alle 40-60 Pakete meckert mein Testprogramm über folgenden Fehler:
RFM69 erkennt die Reamble, erkennt das Syncwort, schiebt schön brav alles ins FIFO, und erkennt auch seine CRC16 als korrekt an.
Lese ich nach der Meldung "PayloadReady" das FIFO aus, meckert mein Testprogramm das meine eigene CRC8 als letztes Byte falsch sei.
Ein Blick in die Rohdaten zeigt schnell den Fehler: Flasche Paketsäuberung des RFM69:
5B E7 82 A0 13 68 8F 0F 14 1A E4 6A 08 00 60 F2 A0 1B A0 03 A6 00 5F 00 00
Am Anfang sind drei nicht abgeschnittene Müllbytes, Byte 1 ist um 4 Bytes nach hinten verschoben.
Als Konsequenz sind am Ende die drei letzten Paketbytes abgeschnitten, darunter halt auch meine CRC8.
Ich hänge gerade in der Abwägung:
In der geplanten Endanwendung ist ein Protokoll vorgesehen wo jedes korrekt empfangende Packet (CRC16 intern + CRC8 extern) mit einem Ack-Paket quittiert werden soll. Kommt beim Sender innerhalb von 100ms kein Ack, soll das Paket erneut gesendet werden.
Problem oberflächlich erledigt.
Andererseits könnte ich beim Empfänger auch einfach größere Arrays auslesen und mein Paket darin suchen.
Die Frage ist nur, was ist effizienter?
Gibt es eine einfache Möglichkeit die Bytes innerhalb eines Arrays nach links zu verschieben?
So nach art von...:
If RX(30) = CRC8(RX(5), 29) then SHIFT RX(), 5, Left
Grüße
Jürgen
Kämpfe schon seit längerem mit einem Projekt mit RFM69W und RFM69HW Transceivern.
Inzwischen habe ich so viele Fallstricke mit diesen Teilen hinter mir, das ich demnächst dazu geneigt wäre hier einen Lexikonartikel zu diesen RFM69 zu erstellen.
Aber hier habe ich jetzt mal eine gänzlich andere Frage:
Um Bits innerhalb einer Variable nach links oder rechts zu shiften gibt es ja recht einfache Befehle. Aber wie sieht das mit Arrays aus?
Ich sende zwischen meinen RFM69 GFSK-Pakete mit exakt 25 Bytes hin und her.
Diese werden von den RFM69 not der nötigen Pramble (3Byte hAA), zwei beit Syncword (h22 , hF7) vor dem ersten und einer CRC16 nach dem 25.sten Nutzbyte ausgestattet und übertragen.
Zusätzlich sorgt die Funktion Whitening das längere gleichwertige Bitketten den Empfänger nicht desynchronisieren.
Also kurz gesagt: Ich nutze bereits sämtliche Sicherungsfunktionen für die Übertragung, welche die RFM69 bieten.
Solch ein Datenpaket sieht bei mir z.B. so aus:
A0 13 68 8F 0F 14 1A E4 6A 08 00 60 F2 A0 1B A0 03 A6 00 5F 00 00 00 00 36
Das erste Byte setzt sich zusammen aus Kanal (MSB-Nibble) und Sensor-ID (LSB-Nibble) gefolgt von einem Timestamp:
Byte 2 das Jahr
Byte 3 Monat sowie Wochentag
Byte 4 Tag + MEZ/MESZ
Byte 5 Stunde
Byte 6-24 sind Sensordaten
Byte 25 ist eine eigene CRC8
Ursprünglich habe ich die CRC8 weniger wegen der Funkübertragung vorgesehen, sondern zur Datensicherung während den zahlreichen umkopierungen.
So wie oben das Musterpaket sehen also die Standardpakete aus welche ich beim Sender in den FIFO schiebe, und beim Empfänger aus dem FIFO ziehe.
Der empfangende RFM tut (inzwischen) was er soll: Er empfänge die GFSK-Pakete, sucht nach dem Syncword, schiebt ins FIFO.
Dann wird die CRC16 geprüft und das Paket im FIFO gesäubert: Alles vor dem Nutzdatenpaket (Dotting, Syncword) sowie die CRC16 wird abgeschnitten.
Erst dann löst der RFM69 den Interrupt "PayloadReady" aus.
Soweit funktioniert das, aber nicht wirklich zufriedenstellend:
Etwa alle 40-60 Pakete meckert mein Testprogramm über folgenden Fehler:
RFM69 erkennt die Reamble, erkennt das Syncwort, schiebt schön brav alles ins FIFO, und erkennt auch seine CRC16 als korrekt an.
Lese ich nach der Meldung "PayloadReady" das FIFO aus, meckert mein Testprogramm das meine eigene CRC8 als letztes Byte falsch sei.
Ein Blick in die Rohdaten zeigt schnell den Fehler: Flasche Paketsäuberung des RFM69:
5B E7 82 A0 13 68 8F 0F 14 1A E4 6A 08 00 60 F2 A0 1B A0 03 A6 00 5F 00 00
Am Anfang sind drei nicht abgeschnittene Müllbytes, Byte 1 ist um 4 Bytes nach hinten verschoben.
Als Konsequenz sind am Ende die drei letzten Paketbytes abgeschnitten, darunter halt auch meine CRC8.
Ich hänge gerade in der Abwägung:
In der geplanten Endanwendung ist ein Protokoll vorgesehen wo jedes korrekt empfangende Packet (CRC16 intern + CRC8 extern) mit einem Ack-Paket quittiert werden soll. Kommt beim Sender innerhalb von 100ms kein Ack, soll das Paket erneut gesendet werden.
Problem oberflächlich erledigt.
Andererseits könnte ich beim Empfänger auch einfach größere Arrays auslesen und mein Paket darin suchen.
Die Frage ist nur, was ist effizienter?
Gibt es eine einfache Möglichkeit die Bytes innerhalb eines Arrays nach links zu verschieben?
So nach art von...:
If RX(30) = CRC8(RX(5), 29) then SHIFT RX(), 5, Left
Grüße
Jürgen