Hallo zusammen, Am Ausgang eines Rohdatenfunkmoduls (AT86RF211) lese ich einen Datenstrom ein und werte den aus. Hier ist ständiges Grundrauschen in Form von "1" und "0" mit wechselnden Impuls/Pausenzeiten vorhanden und darin eingebettet dann ein Telegramm welches ich auswerten will. siehe Bild "Telegramm". Bevor das eigentliche Telegramm kommt, gibts eine Art Trigger oder Präambel. Wenn diese kommt, möchte ich das Telegramm aufzeichnen und auswerten. Momentan startet die Aufzeichnung, wenn eine Pause von 5ms vor dem Trigger ist. Jetzt habe ich aber auch Sender, die Telegramme ohne diese 5ms Pause vorweg losschicken, also ist es besser, direkt auf eine Bitfolge zu triggern... siehe Bild "Trigger im Telegramm", da sind auch die Bitzeiten markiert. Wie kann ich soetwas "genau" rausfinden? Zielsystem ist ein PIC18F2685 und der Dateneingang ist RB0. Mein jetziges Prinzip ist: - Bei Flanke - an RB0 wird TMR0 im 16 Bit Mode gestartet - Wenn Zeit >5ms, dann aufzeichnen, sonst verwerfen Die Aufzeichnung und Auswertung läuft bereits, aber nicht bei dieser Art von Telegramm. Ich möchte nun genau dann triggern, wenn das angehangene Triggerbitmuster erkannt wird. Wie kann ich das angehen? MfG CL
Was du da als "Datenmüll" bezeichnest, dient dazu, dass sich die PLL des Empfängers mit dem Sender synchronisieren kann. Wenn das geschehen ist, liegen weitere Flanken der Datenbits genau auf den dort vorgegeben, und die PLL braucht nur noch ganz wenig nachzujustieren um synchron zu bleiben. Dadurch kann man das erste Datenbit des Sync sicher erkennen und vom Rauschen unterscheiden.
Hp M. schrieb: > Was du da als "Datenmüll" bezeichnest, dient dazu, dass sich die PLL des > Empfängers mit dem Sender synchronisieren kann. > > Wenn das geschehen ist, liegen weitere Flanken der Datenbits genau auf > den dort vorgegeben, und die PLL braucht nur noch ganz wenig > nachzujustieren um synchron zu bleiben. > > Dadurch kann man das erste Datenbit des Sync sicher erkennen und vom > Rauschen unterscheiden. Ja, ist bekannt, trifft hier aber nicht direkt zu. Ich habe mal ein Bild angehangen, wie der Empfang bei anderen Sendern in diesem System aussieht. Da siehst Du links noch ein bisl Müll, dann kommt die Pause (worauf ich dann triggere) und dann kommt die Präambel. Man sieht auch, wie das Telegramm im "Grundrauschen" eingebettet ist. Auch wenn nichts sendet, ist der Müll da. Mal mehr mal weniger. Hast jemand weitere Ideen wie ich die Bitfolge exakt bemerken kann? CL
Vielleicht suchst du erst mal (in den Datenblättern zu deinem Funksensormodulen) nach der Definition und Erklärung für Leerlauf-Signal Ankündigungs-Signal Daten-Signal Warum sollen wir das für dich tun, ohne die Dinger zu kennen?
Jacko schrieb: > Leerlauf-Signal Ankündigungs-Signal Daten-Signal > > Warum sollen wir das für dich tun, ohne die Dinger zu kennen? Cool bleiben! Hier soll niemand was für mich tun, sondern nur Tipps geben, den Rest mache ich natürlich selbst. => Leerlauf-Signal Ankündigungs-Signal Daten-Signal ...gibt es hier nicht, der RF Chip arbeitet im "Pipe" - Mode, das heisst er reicht durch was kommt, steht auch so im Datenblatt. Es ist auch nichts getaktet oder syncronisiert mit einem zus. Clock o.ä. Es geht hier ja nur darum, wie ich am besten die o.g. Bitfolge aus dem Datenstrom erkennen kann. CL
C. L. schrieb: > Die Aufzeichnung und Auswertung läuft bereits ... Und wie wird das gemacht? Da könnte eine Vorlage drin stecken. C. L. schrieb: > Mein jetziges Prinzip ist: > - Bei Flanke - an RB0 wird TMR0 im 16 Bit Mode gestartet > - Wenn Zeit >5ms, dann aufzeichnen, sonst verwerfen Es wird wohl darauf hinauslaufen, dass man die 10 Zeiten des sync Frame einzeln auf passende Länge auswertet und bei jedem "gut" eine Statemachine weiterzählt. Wenn die es bis zur 10 geschafft hat fängt das Nutzsignal an. Ob man das mit polling oder Timer realisiert hängt davon ab, ob der µC noch was anderes nebenher zu machen hat.
C. L. schrieb: > => Leerlauf-Signal Ankündigungs-Signal Daten-Signal > ...gibt es hier nicht, der RF Chip arbeitet im "Pipe" - Mode, das heisst > er reicht durch was kommt, steht auch so im Datenblatt. Aber für das Modul, das am Sender sitzt und dort die Daten generiert, müsste so etwas doch spezifiziert sein? Ist denn wenigstens die Zeitdauer für 1 Bit bekannt? Nach deinen Screenshots sind es etwa 120µs. Wenn das immer für alle Sender gleich ist, ist die Erkennung der Präamble einfach: Du misst für jede High-Low-Phase die Zeit und fütterst damit eine Zustandsmaschine. Dabei musst du beachten, dass die erste Low-Phase, die nominell 2 Bitzeiten lang ist, durch eine vorangehende Pause verlängert werden kann. Ist die Zeitdauer für 1 Bit nicht von vorab bekannt, kannst du diese bestimmen, indem du beim Start des Systems die H/L-Zeiten des Signals erst einmal für ein paar Millisekunden (bzw. so lange, bis mindestens ein Datenpaket inkl. Präambel durch ist) auswertest. Edit: Ok, Dieter war schneller :)
:
Bearbeitet durch Moderator
Dieter W. schrieb: > Ob man das mit polling oder Timer realisiert hängt davon ab, ob der µC > noch was anderes nebenher zu machen hat. Ich bin momentan auch auf dem Trip, das so wie Du gesagt hast auszuwerten. Der µC macht die Puls/Pausenmessung via Interrupt und hat nur in der Main die Aufbereitung und Auswertung und das aussenden des Telegramms ans HTerm. Da wäre noch satt Platz, Speicher sowie zeitlich auch. Yalu X. schrieb: > Aber für das Modul, das am Sender sitzt und dort die Daten generiert, > müsste so etwas doch spezifiziert sein? Das ist ein Problem. Über die Funkstrecke ist nichts bekannt, alles quasi nur Reverse Engineering. Auch nur aus Hobbygründen. Ich habe mal ein Bild angehangen in dem der Empfangsmode des RF dargestellt ist. Das CLK zur Empfangssyncronisation ist leider nicht vorhanden, weil im Register abgestellt. Auf diesen Teil der SW habe ich keinen Zugriff. Yalu X. schrieb: > Ist denn wenigstens die Zeitdauer für 1 Bit bekannt? Nach deinen > Screenshots sind es etwa 120µs. Wenn das immer für alle Sender gleich > ist, ist die Erkennung der Präamble einfach: Du misst für jede > High-Low-Phase die Zeit und fütterst damit eine Zustandsmaschine. > Dabei musst du beachten, dass die erste Low-Phase, die nominell 2 > Bitzeiten lang ist, durch eine vorangehende Pause verlängert werden > kann. Bitzeit passt so. Das mit der Statemachine ist genau der Punkt! Wie? Ich würde es jetzt geschachtelt angehen: If Pausenzeit ca. 120us dann prüfe nächste Pulszeit. If Puls ca. 120us dann prüfe Pause von 480us if... if.. if. wenn das alles erfolgreich durchgelaufen ist, dann aufzeichen. Würdet Ihr das on the Fly ausmessen, dann aufzeichnen oder erst abspeichern und dann analysieren ob das Bitmusster vorkommt? Ich finde meinen Ansatz sehr umständlich gelöst - wie mach Ihr das prinzipiell? CL
Dieter W. schrieb: > Es wird wohl darauf hinauslaufen, dass man die 10 Zeiten des sync Frame > einzeln auf passende Länge auswertet und bei jedem "gut" eine > Statemachine weiterzählt. Man kann aber doch das Signal permanent Decodieren und die Bits in ein Schieberegister schieben. Dann muss nur (bei jedem Bit) ein Vergleich auf das richtige Startpattern erfolgen. Wenn's passt, hat man den Trigger.
:
Bearbeitet durch User
Das sieht nach einem Manchester kodiereten Signal aus. Schaue Mal nach 64Bit manchester, da gibt es am Anfang 4 Sync-Bits + 1 Parity was als Folge 5 Einset am Anfang des Bitstromes hat.
C. L. schrieb: > If Pausenzeit ca. 120us dann prüfe nächste Pulszeit. > If Puls ca. 120us dann prüfe Pause von 480us > if... > if.. > if. Das würde ich eher mit einem Array lösen. Nehmen wir mal an, dass die zu erwartenden Zeiten Puls1, Pause1, Puls2, Pause2, Puls3, Pause4 usw. lauten. Dann kannst Du schreiben:
1 | # define MAX_BITS 4 // 4 Puls/Pause-Zeiten
|
2 | int puls[MAX_BITS] = { 120, 240, 120, 180 }; |
3 | int pause[MAX_BITS] = { 240, 100, 180, 220 }; |
4 | ...
|
5 | idx = 0; |
6 | |
7 | while (idx < MAX_BITS) |
8 | {
|
9 | t = puls_messen (); |
10 | |
11 | if (t < puls[idx] - TOLERANZWERT || t > puls[idx] + TOLERANZWERT) |
12 | {
|
13 | idx = 0; |
14 | pause_messen (); // nachfolgende Pause lesen, Zeit ignorieren |
15 | continue; // wieder von vorn anfangen |
16 | }
|
17 | |
18 | t = pause_messen (); |
19 | |
20 | if (t < pause[idx] - TOLERANZWERT || t > pause[idx] + TOLERANZWERT) |
21 | {
|
22 | idx = 0; |
23 | continue; // wieder von vorn anfangen |
24 | }
|
25 | |
26 | idx++; |
27 | }
|
28 | |
29 | // Muster erkannt!
|
Man kann das auch als Zustandsmaschine werten. idx ist hier Dein Zustandswert. Wenn er MAX_BITS erreicht hat, bist Du fertig. Wenn man während der ganzen Messung auch noch etwas anderes machen will, empfiehlt sich der Gang über eine Timer-ISR, welche das Signal mit geeigneter Abtastrate pollt und dann idx zu gegebener Zeit hochzählt. So ähnlich arbeitet übrigens (stark vereinfacht) IRMP. Nur kann es dabei bis zu 40 verschiedene Protokolle gleichzeitig erkennen.
C. L. schrieb: > Bevor das eigentliche Telegramm kommt, gibts eine Art Trigger oder > Präambel. > Wenn diese kommt, möchte ich das Telegramm aufzeichnen und auswerten. Das ist kein programmtechnisches, sondern ein mathematisches Problem. "Muster" findet man mit (Auto-)korrelation. Sicherlich gibts dafür im WWW auch passende Programmschnipsel.
Thomas E. schrieb: > ein Vergleich > auf das richtige Startpattern erfolgen. Wenn's passt, hat man den > Trigger. Gute Idee, d.h. ein "on the Fly" - Vergleich zu einem festen Muster... Mache ich mir Gedanken zu. ♪Geist schrieb: > 64Bit manchester, da gibt es am Anfang 4 Sync-Bits + 1 Parity was als > Folge 5 Einset ... ist eine neue Info, schaue ich mir an. Frank M. schrieb: Diese Routine werde ich angehen. idx ist der Zustandswert, das ist quasi die Anzahl der Durchläufe bzw. wo der Automat gerade steht? Weiß gar nicht, ob 'continue' mein compiler versteht, habe ich noch nicht verwendet. Harald W. schrieb: > (Auto-)korrelation. Supi, werde ich nach suchen.... Danke für die Ansätze, ich werde weiter berichten... CL
C. L. schrieb: > Diese Routine werde ich angehen. Gut. > idx ist der Zustandswert, das ist quasi die Anzahl der Durchläufe bzw. > wo der Automat gerade steht? Ja, es ist sozusagen die bisher zurückgelegte Weglänge bis zum Ziel - im Beispiel ist sie 4. Die Variable idx durchläuft dann die Schritte 0, 1, 2, 3 und ist bei 4 im Ziel. > Weiß gar nicht, ob 'continue' mein compiler versteht, habe ich noch > nicht verwendet. Kann jeder C-Compiler, das ist Standard. Damit springst Du an den Anfang der while-Schleife. Achja: Vor Betreten der while-Schleife solltest Du auf die beginnende Flanke des Pulses warten. Die beiden Mess-Funktionen warten dann auf die jeweils endende Flanke. So, wie das oben dargestellt wurde, kann der µC währenddessen keine anderen Aufgaben wahrnehmen. Wenn das für Dich so okay ist, mach es so. Sonst muss man andere Geschütze auffahren und die Messungen in eine Timer-ISR verlagern. Dann wird es auch zu einem "echten" Zustandsautomaten. Aber das kann man nicht eben in 5 bis 10 Zeilen erledigen.
Frank M. schrieb: > Sonst muss man andere Geschütze auffahren und die Messungen in eine > Timer-ISR verlagern. Dann wird es auch zu einem "echten" > Zustandsautomaten. Aber das kann man nicht eben in 5 bis 10 Zeilen > erledigen. Soweit alles klar. Die eigentliche Messung läuft bereits mit TMR0 ISR, wird allerdings erst gestartet bzw. das Interrupt enable freigegeben, wenn die Aufzeichnung beginnen soll. Ich muss mal sehen, wie ich das entweder auf Messung im Dauerbetrieb umstelle und dann Deine Routine verwende oder ob ich das in dem Programm schon so einbinden kann. Das ganze lebt nur für die Telegrammerfassung, der uC braucht nichts nebenbei zu machen. Denke, das wird klappen. Thx erstmal soweit. CL
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.