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
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
Verstaerke das 1kHz Signal so, dass eine Rechteckfrequenz daraus wird und messe die Dauer einer Periode….
Hier noch ein wenig Literatur: http://www.myplace.nu/avr/gtuner/ http://people.ece.cornell.edu/land/courses/ece4760/FinalProjects/s2005/ejt22/index.htm
Tiefpass (1kHz) -> samplen mit dem ADC (4 kS/s) -> Bandpass -> Gleichrichten -> Tiefpass. Sollte ein Atmega im Halbschlaf nebenher machen können.
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
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
Bernd K. schrieb: > Tiefpass (1kHz) Warum willst du das interessierende Signal um 3dB abschwächen, bevor du es abtastest?
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?
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.
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?
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?
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?
Mangelndes Vorstellungsvermögen? Natürlich sollte der MC das nebenher machen.
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.
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.
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.
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.
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.
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.
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!
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.
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
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.
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.
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.
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 | }
|
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.
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....
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.