Forum: Analoge Elektronik und Schaltungstechnik einfache Ton-Signalauswertung


von Martin H. (martin_h43)


Lesenswert?

Guten Abend zusammen

ich bin seit einigen Jahren "stiller" Mitleser von vielen Beiträgen aus 
diesem Forum. Vorab vielen Dank für die grosszüge Weitergabe eues 
Know-how. Man findet in diesem Forum zu (fast) jedem Problem einen 
Lösungsansatz!

Leider habe ich nun ein analoges Problem, bei dem ich nicht mehr weiter 
komme:

Um einen Vorgang, den wir aufgezeichnet haben, nachvollziehen zu können, 
haben wir auf einer Tonspur jeweils einen 1kHz Impuls aufgezeichnet.
Nun möchte ich mit einem AVR diesen Impuls auswerten und 
weiterverarbeiten.

Wie bringe ich nun diesen Impuls aus einem Kopfhörerausgang in den 
ATMEGA8?

Direktes Anhängen an einen digitalen Eingang und nur den positiven 
Anteil des Signals messen funktioniert nicht.


Vielen Dank für die Unterstützung beim analogen Teil, den ich überhaupt 
nicht verstehe...


Viele Grüsse
Martin

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Musst du den 1kHz Ton aus anderen Geräuschen herausfiltern oder ist er 
alleiniger Inhalt der Tonspur?

Wenn es nur darum geht, aus dem 1kHz Ton ein digitales 0/1 Signal zu 
machen, könntest du den NE567 Tondekoder Baustein einsetzen. Bei 
genügend freier Rechenleistung kannst du auch den AD Wandler des Mega8 
(warum nehmen die Leute den immer noch?) nehmen und per z.B. Görtzel 
Algorithmus die 1kHz extrahieren.

: Bearbeitet durch User
von wartemal (Gast)


Lesenswert?

Verstaerke das 1kHz Signal so, dass eine Rechteckfrequenz daraus wird
und messe die Dauer einer Periode….

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?


von Bernd K. (prof7bit)


Lesenswert?

Tiefpass (1kHz) -> samplen mit dem ADC (4 kS/s) -> Bandpass -> 
Gleichrichten -> Tiefpass.

Sollte ein Atmega im Halbschlaf nebenher machen können.

von Martin H. (martin_h43)


Lesenswert?

Vielen Dank für die raschen Vorschläge

Auf der Tonspur läuft sonst nichts.
der AVR kann sich voll auf das Auslesen konzentrieren.
Ich muss schlussendlich nur die Länge des Impulses messen, nicht die 
Frequenz selber.
Wie soll ich das bei 1kHz Filtern, damit ich am ADC vernünftig messen 
kann?

Herzlichen Dank

Viele Grüsse
Martin

von Martin H. (martin_h43)


Lesenswert?

Auf der Tonspur läuft sonst nichts.
Der AVR kann sich voll auf das Auslesen konzentrieren.
Ich muss schlussendlich nur die Länge des 1kHz Testton-Impulses messen, 
nicht die Frequenz selber.
Der ATMEGA 8 ist auf dem myAVR Board schon verbaut und genügt für sehr 
viele Anwendungen...

In der Zwischenzeit tendiere ich dazu, den positive Signalanteil auf 5V 
zu verstärken und mit einem RC-Glied zu glätten, so dass ich einen 
digitalen Eingang nutzen kann.

Ich habe ein LM1458 für die Verstärkung angedacht. Ist das der richtige 
OP für diese Anwendung?
Wie lege ich das RC-Glied aus, so dass da was sinnvoll geglättet 
rauskommt?

: Bearbeitet durch User
von wartemal (Gast)


Lesenswert?

Du willst sicher ein R2R als MC User.

von Mike (Gast)


Lesenswert?

Bernd K. schrieb:
> Tiefpass (1kHz)

Warum willst du das interessierende Signal um 3dB abschwächen, bevor du 
es abtastest?

von Martin H. (martin_h43)


Lesenswert?

R2R meint Rail to Rail, nehme ich an. Habe gerade gesehen das der LM1458 
nicht wirklich passt...
Wäre ein TS912 eine passende Alternative?

Wie legt man das RC-Glied richtig aus, so dass bei 5V eine schöne 
Wellenlandschaft entsteht, aber die Zeit für den Spannungsanstieg beim 
Eintreffend des Signals und einen raschen Spannungsabfall am Schluss des 
Testimpules möglich ist?

von Bernd K. (prof7bit)


Lesenswert?

Mike schrieb:
>> Tiefpass (1kHz)
>
> Warum willst du das interessierende Signal um 3dB abschwächen, bevor du
> es abtastest?

Ja, hast recht. Also etwas höher mit der Grenzfrequenz, aber nicht allzu 
hoch, bei 2kHz muss wirklich Schluss sein.

von Martin H. (martin_h43)


Lesenswert?

Mike schrieb:
> Bernd K. schrieb:
>> Tiefpass (1kHz)
>
> Warum willst du das interessierende Signal um 3dB abschwächen, bevor du
> es abtastest?

Damit ich für den uP ein "digitales" Signal erhalte.
Was ist die Alternativ? Ab an den ADC, nur messe ich dann sehr viel 0V, 
da der negative Teil des Sinus fehlt. Ich denke, das wird 
Programmiertechnisch sehr viel komplizierter. Oder liege ich da falsch?

von Jobst Q. (joquis)


Lesenswert?

Probiers mal mit einem NE567. Das ist ein preiswertes IC, das genau für 
solche Zwecke gedacht ist.

von Bernd K. (prof7bit)


Lesenswert?

Jobst Quis schrieb:
> Probiers mal mit einem NE567.

Er will doch eh einen ATMega nehmen, der hat alles drin um einen NE567 
(und noch viel mehr) komplett in Software zu implementieren, warum dann 
also ein zusätzliches Bauteil auf die Platine und dafür dann 95% des 
Atmega ungenutzt brachliegen lassen?

von Martin H. (martin_h43)


Lesenswert?

Bernd K. schrieb:
> Jobst Quis schrieb:
>> Probiers mal mit einem NE567.

Vielen Dank für den Tipp.
Ich bin gerade am Datenblatt...



>
> Er will doch eh einen ATMega nehmen, der hat alles drin um einen NE567
> (und noch viel mehr) komplett in Software zu implementieren, warum dann
> also ein zusätzliches Bauteil auf die Platine und dafür dann 95% des
> Atmega ungenutzt brachliegen lassen?


Weil er kein Mathematiker ist, vielleicht?

von wartemal (Gast)


Lesenswert?

Mangelndes Vorstellungsvermögen?
Natürlich sollte der MC das nebenher machen.

von Stromverdichter (Gast)


Lesenswert?

Du hast doch ein einfaches Signal. Das würde ich klassisch mit einem 
Hochpass filtern und dann per Diode einen kleinen Kondensator laden, der 
den µC-Pin 2-3 Amplituden lange durchschalten kann. Dann damit auf einen 
Schmitt-trigger Eingang. Damit bist du den ganzen unsicheren 
Programmieraufwand los. Du musst halt nur die 2 kleinen Kondensatoren 
und die 2 passenden Widerstands-Werte bestimmen.

von m.n. (Gast)


Lesenswert?

Martin H. schrieb:
> Wie legt man das RC-Glied richtig aus, so dass bei 5V eine schöne
> Wellenlandschaft entsteht, aber die Zeit für den Spannungsanstieg beim
> Eintreffend des Signals und einen raschen Spannungsabfall am Schluss des
> Testimpules möglich ist?

Du brauchst keine 5 V Signale und auch keinen OPV.
Der ATmega hat einen Analog-Komparator, der ab wenigen Millivolt ein 
Signal auswerten kann.
Einfach wiederholt einen Interrupt auslösen lassen und die Zeit für alle 
Impulse messen. Dafür braucht man einen Timer, der immer wieder 
zurückgesetzt (nachgeladen wird). Kommt kein Impuls mehr, läuft der 
Timer über und man kann die Gesamtzeit bewerten.
Geschickterweise stellt man den Timer so ein, daß er nach ca. 1,5 ms 
überläuft.

von Mike (Gast)


Lesenswert?

Bernd K. schrieb:
> Mike schrieb:
>>> Tiefpass (1kHz)
>>
>> Warum willst du das interessierende Signal um 3dB abschwächen, bevor du
>> es abtastest?
>
> Ja, hast recht. Also etwas höher mit der Grenzfrequenz, aber nicht allzu
> hoch, bei 2kHz muss wirklich Schluss sein.

Das ist sportlich. Ein Filter, dass innerhalb eines Faktor 2 bei der 
Frequenz vollstängig (wieviel dB auch immer das sind) vom 
Durchlassbereich in den Sperrbereich geht.

von Bernd K. (prof7bit)


Lesenswert?

Mike schrieb:

> Das ist sportlich.

Es ist ja zum Glück nix anderes mehr drauf auf der Tonspur, außer leisem 
Hintergrundrauschen. Wahrscheinlich bräuchte er gar keinen 
Aliasing-Filter und es würde trotzdem noch wunderbar funktionieren. Es 
spricht aber auch nix dagegen statt mit 4kHz halt eben mit 8 oder 
meinetwegen noch mehr abzutasten, da kommt der Atmega noch lange nicht 
ins Schwitzen.

von MaWin (Gast)


Lesenswert?

Bernd K. schrieb:
> Er will doch eh einen ATMega nehmen, der hat alles drin um einen NE567
> (und noch viel mehr) komplett in Software zu implementieren, warum dann
> also ein zusätzliches Bauteil

Eben nicht, genau umgekehrt.

Der ATmega braucht einen vorgeschalteten OpAmp als Verstärker und einen 
Bandpass um Aliasimgartefakte mit der Samplefrequenz zu unterdrücken.

Der NE567 braucht das alles nicht und liefert bereits ein Signal so lang 
der 1kHz Impuls auf dem Band ist.

von Bernd K. (prof7bit)


Lesenswert?

MaWin schrieb:
> Der ATmega braucht einen vorgeschalteten OpAmp als Verstärker und einen
> Bandpass um Aliasimgartefakte mit der Samplefrequenz zu unterdrücken.

Er kommt vom Kopfhörerausgang, da braucht er nix mehr zu verstärken, das 
reicht so. Auch über Aliasing muss er sich keine Gedanken machen wenn er 
nur 1kHz auf ner ansonsten leeren Tonspur erkennen will.

Ich hab mit nem Atmega ohne Aliasing-Filter 1kHz PSK31 dekodiert (mit 
4kHz(!) abgetastet), zusätzliches weißes(!) Rauschen so weit aufgedreht 
daß vom Signal mit dem Ohr nichts mehr zu hören war, das ganze dann auf 
den Lautsprecher, dann ins Mikrofon, breitbandig verstärkt, rein in den 
ADC (ohne Aliasing-Filter!) und konnte es fehlerfrei dekodieren. 
Wohlgemerkt es war mit dem Ohr kaum noch wahrzunehmen. Wenn sowas 
funktioniert dann kann man erst recht das wesentlich simplere 1kHz 
vorhanden/abwesend auf ner ansonsten leeren Tonspur mit 50dB 
Rauschabstand oder was das Aufzeichnungsgerät so hat erkennen ohne 
irgendwelche Verrenkungen anzustellen, denk ich mal.

Also vom Kopfhörerausgang direkt rein in den ADC (Kondensator und zwei 
Widerstände), 4kHz samplen, Filtern, erkennen und fertig.

von Dirk J. (dirk-cebu)


Lesenswert?

Martin H. schrieb:

> Nun möchte ich mit einem AVR diesen Impuls auswerten und
> weiterverarbeiten.
Wenn man jetzt noch wüsste, wozu der weiterverarbeitet werden soll, 
könnte man sich sogar den AVR sparen.
Zum Beispiel Steuerung eines Projektors: Das Kopfhörersignal (eventuell 
vorverstärken) gleichrichten und damit einen Transistor ansteuern, der 
ein Relais anzieht. Fertig!

von Simpel (Gast)


Lesenswert?

Am Eingang den Pullup einschalten, einen C gegen Masse und eine Diode 
davor. Das Ganze AC-mässig ankoppeln. Fertig. Dann hast du nen 
Low-Pegel, solange das Signal anliegt.

von Martin H. (martin_h43)


Lesenswert?

m.n. schrieb:
> Martin H. schrieb:
>> Wie legt man das RC-Glied richtig aus, so dass bei 5V eine schöne
>> Wellenlandschaft entsteht, aber die Zeit für den Spannungsanstieg beim
>> Eintreffend des Signals und einen raschen Spannungsabfall am Schluss des
>> Testimpules möglich ist?
>
> Du brauchst keine 5 V Signale und auch keinen OPV.
> Der ATmega hat einen Analog-Komparator, der ab wenigen Millivolt ein
> Signal auswerten kann.
> Einfach wiederholt einen Interrupt auslösen lassen und die Zeit für alle
> Impulse messen. Dafür braucht man einen Timer, der immer wieder
> zurückgesetzt (nachgeladen wird). Kommt kein Impuls mehr, läuft der
> Timer über und man kann die Gesamtzeit bewerten.
> Geschickterweise stellt man den Timer so ein, daß er nach ca. 1,5 ms
> überläuft.


Vielen Dank für die verschiedenen Ideenansätze.
Um die Robustheit bezüglich des Eingangspegels zu verbessern, werde ich 
das Eingangssignal mit einem TS912 um den Faktor 5-10 verstärken.
Dieses Signal werde ich über den Komparator mit steigender Flanke/Timer 
so auswerten, wie das m.n. vorgeschlagen hat.
Danke für euren Hirnschmalz;-))

Viele Grüsse
Martin

: Bearbeitet durch User
von michael_ (Gast)


Lesenswert?

Dirk J. schrieb:
> Zum Beispiel Steuerung eines Projektors: Das Kopfhörersignal (eventuell
> vorverstärken) gleichrichten und damit einen Transistor ansteuern, der
> ein Relais anzieht. Fertig!

Das war auch mein Gedanke.
Aber der TE will ja nicht sagen wozu es ist.
Ich habe da mal meinen H. Jakubaschk Elektronikbastelbuch für Foto- und 
Filmamateure hervorgeholt.
Dort ist zur Theorie alles gesagt.

von batman (Gast)


Lesenswert?

Bernd K. schrieb:
> Er kommt vom Kopfhörerausgang, da braucht er nix mehr zu verstärken, das
> reicht so. Auch über Aliasing muss er sich keine Gedanken machen wenn er
> nur 1kHz auf ner ansonsten leeren Tonspur erkennen will.
>
> Ich hab mit nem Atmega ohne Aliasing-Filter 1kHz PSK31 dekodiert (mit
> 4kHz(!) abgetastet), zusätzliches weißes(!) Rauschen so weit aufgedreht
> daß vom Signal mit dem Ohr nichts mehr zu hören war, das ganze dann auf
> den Lautsprecher, dann ins Mikrofon, breitbandig verstärkt, rein in den
> ADC (ohne Aliasing-Filter!) und konnte es fehlerfrei dekodieren.

Auf starkes weißes Rauschen muß der Dekoder ja auch ansprechen, weil es 
auch die 1kHz enthält.

von Bernd K. (prof7bit)


Lesenswert?

batman schrieb:

> Auf starkes weißes Rauschen muß der Dekoder ja auch ansprechen, weil es
> auch die 1kHz enthält.

Mit ner PLL kann man das einigermaßen vermeiden, es geht halt nur ein 
bisschen Zeit verloren bis man den Zustand "eingerastet" zweifelsfrei 
erkennt.

von Bernd K. (prof7bit)


Lesenswert?

Hier ist eine 1kHz PLL auf dem ATmega.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
#define TIMER_PERIOD        4000
6
#define PLL_GAIN            100
7
#define SAMPLE_PERIODS      4
8
#define DETECT_SMOOTH       4
9
#define DETECT_THRESHOLD    1000
10
11
#define BUFFER_SIZE         SAMPLE_PERIODS * 4
12
13
#define SET_SAMPLE()        GPIOR0 |=  0x01
14
#define CLR_SAMPLE()        GPIOR0 &= ~0x01
15
#define IS_SAMPLE()        (GPIOR0 &   0x01)
16
17
uint16_t sample_buffer[BUFFER_SIZE] = {0};
18
uint8_t sample_ptr = 0;
19
int16_t I = 0;
20
int16_t Q = 0;
21
22
void uart_send8(int8_t val) {
23
    loop_until_bit_is_set(UCSR0A, UDRE0);
24
    UDR0 = val;
25
}
26
27
void uart_send16(int16_t val) {
28
    uart_send8(val);
29
    uart_send8(val >> 8);
30
}
31
32
int main() {
33
    // GPIO
34
    DDRB = (1 << PB5);                      // yellow LED
35
36
    // UART
37
    UBRR0  = 3;                             // 468000 Baud (this works on Arduino-UNO!)
38
    UCSR0A = (1 << U2X0);                   // double-speed
39
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
40
    UCSR0C = (1 << USBS0) | (1 << UCSZ01) | (1 << UCSZ00);
41
42
    // timer
43
    // mode 4 (CTC -> OCR1A), 4kHz (das wird unsere Abtastrate sein)
44
    TCCR1B = (1 << WGM12) | (1 << CS10);
45
    TIMSK1 = (1 << OCIE1A);
46
    OCR1A = TIMER_PERIOD;
47
48
    // ADC
49
    // Wandlung manuell anstossen, Interrupt bei beendeter Wandlung
50
    ADCSRA  = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (0 << ADPS0);
51
    ADMUX   = (0 << REFS1) | (1 << REFS0);
52
    DIDR0   = (1 << ADC0D);
53
54
    sei();
55
56
    int32_t detected_sum = 0;
57
58
    while (1) {
59
        if (IS_SAMPLE()) {
60
            CLR_SAMPLE();
61
62
            // PLL (tan-lock-loop)
63
            // (Ja, das ist eigentlich kein richtiger arctan
64
            // aber es kommt ihm nahe genug für unsere
65
            // Zwecke und braucht nur eine Division und
66
            // eine Multiplikation. Wers nicht glaubt:
67
            // einfach mal die Funktion plotten von 0 bis 2pi.
68
            int16_t scale = (abs(I) + abs(Q));
69
            int32_t phase_error;
70
            if (I > 0) {
71
                phase_error = -Q;
72
                phase_error *= PLL_GAIN;
73
                phase_error /= scale;
74
                phase_error += PLL_GAIN;
75
            } else {
76
                phase_error = Q;
77
                phase_error *= PLL_GAIN;
78
                phase_error /= scale;
79
                phase_error -= PLL_GAIN;
80
            }
81
            OCR1A = TIMER_PERIOD - phase_error;
82
            //uart_send16(phase_error);
83
84
85
            detected_sum += (Q - (detected_sum >> DETECT_SMOOTH));
86
            int16_t detected = detected_sum >> DETECT_SMOOTH;
87
88
            //uart_send16(detected);
89
90
            if (detected > DETECT_THRESHOLD) {
91
                PORTB |= (1 << 5);
92
            }
93
            if (detected < DETECT_THRESHOLD / 2) {
94
                PORTB &= ~(1 << 5);
95
            }
96
        }
97
    }
98
}
99
100
ISR(ADC_vect) {
101
    // quadrature sampling and also
102
    // some filtering in one go.
103
    uint16_t new_sample = ADC;
104
    uint16_t old_sample = sample_buffer[sample_ptr];
105
    sample_buffer[sample_ptr] = new_sample;
106
    uint8_t phase = sample_ptr & 3;
107
    switch (phase) {
108
    case 0:
109
        I -= old_sample;
110
        I += new_sample;
111
        break;
112
    case 1:
113
        Q -= old_sample;
114
        Q += new_sample;
115
        break;
116
    case 2:
117
        I += old_sample;
118
        I -= new_sample;
119
        break;
120
    case 3:
121
        Q += old_sample;
122
        Q -= new_sample;
123
        SET_SAMPLE();
124
        break;
125
    }
126
    if (++sample_ptr == BUFFER_SIZE) {
127
        sample_ptr = 0;
128
    }
129
}
130
131
ISR(TIMER1_COMPA_vect) {
132
    ADCSRA |= (1 << ADSC);
133
}

von batman (Gast)


Lesenswert?

Danke, werd ich mir interessehalber noch mal angucken. Hatte das aber 
schon mal mit (analoger) PLL gelöst und dort habe ich genau das 
beschriebene Verhalten, Ansprechen auf laute Geräusche, was ja 
eigentlich auch zu erwarten ist. Der NE567 spricht nach ca. 10(?) Wellen 
der passenden Periodendauer an.
Ist im Prinzip nicht schlimm, weil es so seinen Zweck erfüllt, aber 
wahrscheinlich auch nicht mehr als ein schlichter Filter.

von Carsten R. (kaffeetante)


Lesenswert?

Das Ganze erscheit mir in dieser Form etwas sinnfrei. Da steckt doch 
eine weitere Absicht dahinter.

Wenn das Signal bekannt ist, was gibt es da noch auszuwerten? Ich frage 
das, weil davon abhängt ob ein Lösungsvorschlag geeignet ist für die 
eigentliche Aufgabe.

Willst Du irgedetwas mit dem 1 kHz-Signal synchronisieren oder ist es 
ein Ton sondern eine PWM mit 1 kHz bei dem du den Dutycycle abfragen 
willst, oder....

von Bernd K. (prof7bit)


Lesenswert?

batman schrieb:
> Danke, werd ich mir interessehalber noch mal angucken. Hatte das aber
> schon mal mit (analoger) PLL gelöst und dort habe ich genau das
> beschriebene Verhalten, Ansprechen auf laute Geräusche, was ja
> eigentlich auch zu erwarten ist.

Du kannst mit dem Wert DETECT_THRESHOLD spielen und mit DETECT_SMOOTH 
(vorsicht: DETECT_SMOOTH geht mit 2^x also ab 9 oder so wirds zu arg). 
Mit hohem DETECT_SMOOTH und feinfühlig eingestelltem DETECT_THRESHOLD 
kann man den Ton noch aus extremstem Rauschen heraus erkennen. Wenn 
wenig Rauschen da ist kann DETECT_SMOOTH bei 4 oder sogar kleiner 
bleiben.

Mit den uart-Funktionen und nem Plotter wie meinem DebugTerminal kannst 
Du im laufenden Betrieb die relevanten Variablen beobachten, dann ist es 
einfacher zu justieren.

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.