Forum: Mikrocontroller und Digitale Elektronik Binäres Signal mit Störungen abtasten


von Logic zero (Gast)


Angehängte Dateien:

Lesenswert?

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

von stock (Gast)


Lesenswert?

da der glitch extrem kurz ist, hat er eine hohe frequenz, und sollte 
somit filterbar sein. mach das mal einen tiefpass hin.

von Logic zero (Gast)


Lesenswert?

stock schrieb:
> da der glitch extrem kurz ist, hat er eine hohe frequenz, und sollte
> somit filterbar sein. mach das mal einen tiefpass hin.

Wäre eine Möglichkeit, dazu müsste ich das ganze natürlich wieder 
umbauen. Habe gehofft das komplett digital lösen zu können.

von Michael (Gast)


Lesenswert?

Logic zero schrieb:
> Habe gehofft das komplett digital lösen zu können.

Dann nimm doch einen digitalen Tiefpaß. Du mußt erstmal schnell genung 
abtasten, filterst das Signal und gibst dann einen Datenstrom mit 
reduzierter Abtastrate an deine Auswertung weiter. Irgendeine 
Bandbegrenzung wird dein Eingangssignal doch haben. Mit deiner ersten 
Abtastung musst du mehr als einen Faktor zwei über der höchsten 
Signalfrequenz liegen, um Aliasing-Effekte zu vermeiden.

von stock (Gast)


Lesenswert?

eine frage der Abtastrate des ADC, bei 6 samples per bit kann man einen 
Tiefpass rechnen lassen. das sollte hinkommen, wenn man einen Mega8 mit 
10kSample laufen laesst..

von Logic zero (Gast)


Lesenswert?

Digitaler Tiefpass wäre tatsächlich eine gute Idee. Ich werd mal 
versuchen sowas einzubauen.

stock schrieb:
> eine frage der Abtastrate des ADC, bei 6 samples per bit kann man einen
> Tiefpass rechnen lassen. das sollte hinkommen, wenn man einen Mega8 mit
> 10kSample laufen laesst..

Das Signal ist bereits digital, einlesen tue ich das mit einem einfachen 
Pin.

von Peter D. (peda)


Lesenswert?

Logic zero schrieb:
> Eine Störung ist maximal 200us lang.

Dann würde ich eine 4-fach Abtastung mit 60µs Timerinterrupt machen 
(siehe Entprellung).

von Matthias L. (Gast)


Lesenswert?

>Dann würde ich eine 4-fach Abtastung mit 60µs Timerinterrupt machen

Wenn ich auf deinem Oszibild eine Timescale von 2ms/div sehe, denke ich 
auch, das es am besten und einfachsten ist, das Ganze ähnlich Tasten 
oder RC5-Einlesen per Timerinterupt zu lösen. Somit kannst DU schön LO 
und HI Zeiten einstellen. Und das funktioniert auch riochtig sauber...

von Logic zero (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe jetzt mal in Richtung digitaler Tiefpass gesucht. Weil ich aber 
keine großen Berechnungen anstellen wollte (hab nur ein paar Takte 
Rechenzeit) hab ich einfach die letzten 16 Samples in einem Ringbuffer 
gespeichert, danach mittels Mehrheitsentscheidung entschieden was für 
ein Bit es den jetzt ist. Das klappte erstaunlich gut (Siehe Anhang).

Danach konnte ich einfach die Bitlängen zählen und so entscheiden 
wieviele Bits es sind. Der Vollständigkeit halber hab ich auch noch die 
Dekodierroutine angehängt.

Damit klappt die Erkennung der Karte sogar noch in 14cm Entfernung :-)

Grüße von
Logic Zero

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.