Hallo :)
Ich baue grade ein RFID-Lesegerät sowie RFID-Tag in Kreditkartengröße
zwecks Türsteuerung. Das System hat mittlerweile eine Reichweite von
11cm, wenn ich weiter weg gehe wird das Signal stärker gestört. Um jetzt
die maximale Reichweite rauszukitzeln will ich mit geeigneten
Algorithmen das Signal doch noch erkennen können.
Im Anhang seht ihr einmal das Signal was das Lesegerät ausgibt wenn die
Karte normal weit weg ist, und einmal wie das Signal aussieht wenn die
Störung zu stark wird.
Das Signal selber ist so kodiert dass nach 3 gleichen Bits ein
invertiertes Bit eingefügt wird. Somit wird die maximale Lauflänge
begrenzt damit der Empfänger das Signal leichter auswerten kann. Ein Bit
ist jeweils 700us +- 100us lang. Eine Störung ist maximal 200us lang.
Sie tritt gehäuft zwischen 2 HIGH-Bits auf (da hier der Tag das nächste
Bit laden muss kann er nicht kontinuierlich HIGH senden, diese Stelle
ist für Störungen sehr anfällig), kann jedoch auch selten an anderen
Stellen auftreten. Ab und zu kommt es auch zu einem HIGH-Glitch (also
eine 1 für ein paar us die eigentlich eine 0 sein sollte).
Zwischen 2 Frames sind mindestens 4 Bitzeiten LOW, sodass man sich auf
den Anfang synchronisieren kann. Ein Frame ist durch die Kodierung
zwischen 16 und 23 Bit lang, am Anfang befindet sich zusätzlich immer
eine 1010-Präambel.
Der Mikrochip, ein ATTiny13 sampled das Signal alle 50us. Er soll das
Signal abtasten, rekonstruieren, eventuelle glitches entfernen und das
Signal dekodieren. Danach wird das Signal per UART rausgeschickt.
Mein Problem ist jetzt das rekonstruieren und entfernen der glitches.
Würde kein glitch auftreten sähe meine Routine wie folgt aus:
1 | uint8_t packet = 0; // haben wir grade ein paket?
|
2 | uint8_t error = 0; // Fehler aufgetreten?
|
3 | uint8_t last = 0; // letztes Bit
|
4 | uint8_t count = 0; // wieviele Samples das Bit unverändert ist
|
5 | uint32_t data = 0; // Ergebnis
|
6 |
|
7 | ISR(TIM0_COMPA_vect) // 50us
|
8 | {
|
9 | uint8_t bit = PINB & (1 << PB0); // setted
|
10 | if (bit == last)
|
11 | {
|
12 | if (packet) // nur mitzählen wenn wirklich daten gesendet werden
|
13 | {
|
14 | if (count <= 50)
|
15 | ++count;
|
16 | else if (!bit) // 4 Bitzeiten LOW
|
17 | {
|
18 | if (!error) // nur fehlerfreie Daten weiterleiten
|
19 | {
|
20 | // ende markieren
|
21 | data <<= 1;
|
22 | data |= 1;
|
23 | EvalData(data);
|
24 | }
|
25 | packet = 0;
|
26 | error = 0;
|
27 | }
|
28 | }
|
29 | }
|
30 | else
|
31 | {
|
32 | if (packet)
|
33 | {
|
34 | if (10 <= count && count <= 18) // ein Bit
|
35 | {
|
36 | data <<= 1;
|
37 | if (bit)
|
38 | data |= 0b1;
|
39 | }
|
40 | else if (24 <= count && count <= 32) // zwei Bit
|
41 | {
|
42 | data <<= 2;
|
43 | if (bit)
|
44 | data |= 0b11;
|
45 | }
|
46 | else if (38 <= count && count <= 46) // drei Bit
|
47 | {
|
48 | data <<= 3;
|
49 | if (bit)
|
50 | data |= 0b111;
|
51 | }
|
52 | else // Fehler, Paket verwerfen
|
53 | error = 1;
|
54 | }
|
55 | else if (bit) // neues Paket?
|
56 | {
|
57 | packet = 1; // mitzählen
|
58 | count = 1; // ein Sample bereits empfangen
|
59 | data = 1; // Bit als Markierung
|
60 | }
|
61 | last = bit;
|
62 | }
|
63 | }
|
Leider geht das nicht wenn das Signal gestört ist. Meine erste Idee war,
sich den alten Bitcount ebenfalls zu merken und wenn der neue kleiner
als 4 (200us) ist, einfach den alten weiter zu nutzen als ob der glitch
nicht aufgetreten ist. Nur weiß ich dann nicht wann ich die Bits
eintragen soll, weil eine erkannte Flanke ja eine "falsche" Flanke sein
kann.
Das einlesen eines digitalen Signales ist bestimmt ein Standardproblem
in der Elektronik, schließlich braucht man das fast überall. Gibt es
dazu Standardlösungen oder Erklärende Artikel? Gesucht habe ich schon
aber ich finde nur Seiten die sich mit dem samplen von Analogsignalen
beschäftigen.
Freundliche Grüße von
Logic zero