Guten Morgen! Habe folgende Aufgabenstellung: Es soll erkannt werden ob 2 Frequenzen im Bereich von 125-140kHz (ja eh klar - Powerline) anwesend sind und je nachdem ein Portpin high oder low sein. Nebenbei ist noch ein wenig UART Kommunikation zu erledigen (19200bps, ca. alle 100ms) und je nachdem was dort gekommen ist ein PWM Signal verändert werden. Mit einem ARM7@60Mhz komme ich wenn ich wenn ich 2 IIR Filter 1.Ordnung berechne gerade mal auf max. 25kHz Samplerate bzw. "Berechnungsrate". Selbst wenn ich dort noch Codeoptimierungen machen könnte auf die nötige Samplerate komme ich mit diesem Prozessor wohl nicht - für was hat der dann eigentlich einen ADC der 400kS/s schafft?) Ich hab zwar schon recht erfolgreiche Versuche mit "Bandpassunterabtastung" gemacht wo ich die Anwesenheit der Frequenzen recht gut festgestellt habe, jedoch brauche ich dann wohl einen recht guten Bandpass am Eingang. Das würde aber wahrscheinlich auf Spulen hinauslaufen und die benötigen Platz den ich nicht habe. Für mehr als einen nicht allzuaufwändigen Tiefpass wird kaum Platz sein (Platine max 2x3cm). Nun meine Frage: Was brauche ich an Rechenpower um eben mit ca. 350-400kHz Abzutasten und 2 IIR Filter 2.Ordnung zu berechnen? Schaft ein dsPIC das? Ehrlich gesagt war ich von der Langsamkeit des ARMs schon sehr überrascht. "richtige" DSP scheiden wohl aus da das Programmierequipment dafür wohl richtig Geld kostet (mehr als Bastlerbudget gibts leider nicht). Außerdem sollen die Bauteile pro Platine nicht mehr als 5-7€ kosten (dsPIC ist recht günstig und vorallem beschaffbar). Gibts bessere Methoden als IIR um die Anwesenheit einer bestimmten Frequenz festzustellen? Analogtechnik ist nicht grundsätzlich verboten, da ich aber ohnehin etwas uC Artiges benötige wärs ideal wenn dieser dies erledigen könnte. Danke im Voraus Oli
Was soll denn ein IIR 2.Ordnung ? Wenn die Frequenzen ja bekannt sind ist es viel einfacher. Das Signal gleichzeitig mit Sin & Cos der gesuchten Frequenz multiplizieren und integrieren. Die Frequenzunschaerfe bekommt man mit der weniger als unendlichen Laenge
>>Mit einem ARM7@60Mhz komme ich wenn ich wenn ich 2 IIR Filter 1.Ordnung >>berechne gerade mal auf max. 25kHz Samplerate bzw. "Berechnungsrate". Die IIRs in integer implementieren, auf Overflows achten! Es schadet ja auch nicht, wenn Du die beiden Frequenzen unterabtastest, die spiegeln sich dann runter, z.B. 100kHz mit 90ks/s abgetastet sieht aus wie 80kHz. Die kannst Du dann prima erkennen. Cheers Detlef
> Es schadet ja auch nicht, wenn Du die beiden Frequenzen unterabtastest, > die spiegeln sich dann runter, z.B. 100kHz mit 90ks/s abgetastet sieht > aus wie 80kHz. Die kannst Du dann prima erkennen. Ähm, ne, 100kHz mit 90kHs/s abgetastet sieht aus wie 10kHz: 100kHz gespiegelt um 90khz ist 80kHz, 80kHz gespiegelt an Nyquist 45kHz zeigt 10khz. Cheers Detlef
@Detlef_a: ja genau sowas ähnliches mach ich gerade. Ich Taste mit z.B. 12,5kHz ab und sehe jetzt den Bereich von 125-130kHz als 0-5kHz. Nur muß da ein recht steiler Bandpass vor den ADC damit keine Aliases von anderen Frequenzen reinkommen. Den will ich eigentlich irgendwie vermeiden. Mehr als ein Tiefpass 3-4.Ordnung sollte es nicht werden (Platzprobleme). Bin jetzt auf den Goertzel-Algorithmus gestossen der für meine Anwendung ggenau das richtige sein soll. Mal sehen ob ich überhaupt verstehe um was es da geht. MfG Oli
Der Goertzel ? War nicht die Frage nach der Anwesenheit von Frequenzen ? Deswegen muss man die ja noch nicht bestimmen. Eine komplex multiplikation mit einem oder zwei sinussen ist viel einfacher.
Hallo Zacc Der Ansatz klingt interessant (und recht einfach und schnell) Bin leider recht neu in dem Thema deswegen nochmal nachgefragt: Versteh ich das richtig: Sinus- und Cosinuswerte (von welcher Frequenz? Signalfrequenz? )in Tabelle und Eingangswerte damit multiplizieren (jeden Wert mit jeden oder wie?), dann die Ergebnisse aufaddieren und wenn Ergebniss Grenze übersteigt ist die Frequenz "da"? Hat das ganze eine offiziellen Namen? Trotzdem mal danke für alle Antworten MfG Oli
Einen komplizierten Bandpaß/Tiefpaß würde ich nicht dazu aufbauen. Dann lieber nochmal auf die digitale Seite kucken: ARM7 braucht doch 3 Takte oder so für ne Multiplikation, also 20e6 Multiplikationen @60MHz. Für zwei IIRs brauchst Du 10Multiplikationen, also 4e6 bei 400ks/s samplerate. Damit ist der ARM doch 5mal schneller als Du brauchst! @Zacc: Für den Sinus brauchst Du tabellierte Werte. Falls Du die sin/cos on the fly erzeugst ist das dergleiche hack wie nen IIR. Cheers Detlef
Das mag schon sein das der so schnell ist aber ich hab in meiner Sample/Berechnung ISR einen Portpin gesetzt den ich mit dem Oszi beobachte um zu schauen wie lang er in der ISR ist und irgendwie braucht mein IIR 1.Ordnung mit dem Sampling (braucht angeblich 11 Takte) und ein wenig Speicher umladen so lang das sich max. 30kHz (entspricht kSmpls/S) ausgehen. Wie gesagt ich hab noch nix optimiert (Compiler gcc-C). Werd mal den Assembler anschmeißen. Seltsam ist - selbst wenn ich in der ISR einfach nur einen Wert aus einer Tabelle auf den DAC schreibe und dann einmal index++ mache dauert das so lang das max. 100kHz Interruptrate gehen. Ich glaub ich mach was falsch. (Die ISR wird übrigends vom Timer getriggert) MfG Oli
Guten Morgen Hab gestern noch etwas mit dem ARM herumexperimentiert. 1.) Mal rein in einer Endlosschleife Portpins getoggelt. Ergebniss: C Code mit gcc kompiliert: 2,4MHz Toggelrate, Assembler: etwas über 8 Mhz Toggelrate. Da ist sicher noch was drinn wo dann auch diverse Signalverarbeitung am ARM möglich ist. 2.) Wenn ich jetzt rechne: 60Mhz, 400kSmpls/s -> 150 Takte Rechenzeit pro Sample 27Takte braucht er mind. bis er in der ISR ist, 143!!! Takte (hab mich gestern verlesen) braucht der ADC bis er fertig ist (da ergeben sich dann so ziemlich genau die angegebenen 400kSmpls/s bei 60Mhz Systemtakt) Man kann während diesen 143 Takten zwar was anderes machen aber irgendwann brauch ich den Wert um zu rechnen. Wenn das dann auch noch 100Takte braucht bin ich sowieso jenseits von gut und böse. Mal sehen ob es geht den ADC direkt vom Timer zu triggern und die ISR dann vom "ADC fertig Interrupt". Da sollte sich das dann mit ASM Programmierung mal grade so ausgehen. Das Problem ist dann nur das für die Hauptschleife dann genau garkeine Zeit mehr überbleibt 3.) Deswegen ja meine Frage ob der dsPIC da nicht vielleicht die bessere Wahl wäre (richtigen TI oder Analog DSP kann ich mir vermutlich nicht leisten). ARM7 hat den Vorteil das ich da Board und Programmierequipment schon habe. Aber wenn mir jetzt jemand sagt das das mit dsPIC locker von der Hand geht (oder der gar noch unterfordert ist) dann würd ich mir sogar die Mühe machen auf diesen umzustellen. MfG Oli P.S.: Juhu Freitag - noch wenige Stunden und dann ab ins Wochenende
Wenn dein ARM DMA hat könntest du längere Blöcke vom ADC einlesen und danach verarbeiten, das spart den Interrupt-Overhead. Aber muss die Verarbeitung überhaupt kontinuierlich sein? Reicht es nicht "ab und zu mal" einen Block zu speichern und in diesem die Detektion durchzuführen? Dann würde das auch ein AVR schaffen (falls der ADC mitkommt).
Mein Ansatz mit Sinus und cosinus zu multiplizieren ist der Ansatz den man fuer Fourierkoeffizienten im Allgemeinen nimmt. Die Sin/ Cos We\rte nimmt man natuerlich aus einer Tabelle.
Primitiv-Vorschlag. Auf einen analogen Tiefpass (Spannungsteiler) Signal draufgeben. Die Spannung muss sich dann über die Frequenz am ADC-Eingang einstellen. Nur noch ADC auslesen und Fenster kontrollieren. Mit einer hohen ADC-Auflösung wird das Ergebnis recht scharf. Sebastian
Hallo @andreas: DMA hat er leider nur für USB (LPC2148). Ich hätte bisjetzt nicht entdeckt das der auch für was anderes zu gebrauchen ist. Das mit dem "ab und zu" verarbeiten klingt aber interessant. Ich möchte halt gern mind. 4800bps über dieses "Powerline" System (nur hat die Line über die es geht kaum Power :-) ) schaufeln. Dh. wenn ich mind. doppelt so schnell berechnen kann sollts eigentlich passen. Werd am Abend Versuche machen. Wenn wirklich mit AVR oder MSP430 machbar dann wär das natürlich ein Traum, nur dürften die ADCs zu langsam sein. @Sebastian: Das mit dem analogen FM Demodulator funktioniert aber wahrscheinlich nur wenn der Betrag der Eingagsspannung bekannt ist bzw. mit einer automatischen Verstärkungsregelung (siehe Radio). Außerdem will ich auf Analogtechnik so weit wie möglich verzichten, für viel mehr als die CPU ist eigentlich nicht Platz MfG Oli
>27Takte braucht er mind. bis er in der ISR ist, >143!!! Takte (hab mich gestern verlesen) braucht der ADC bis er fertig >ist (da ergeben sich dann so ziemlich genau die angegebenen 400kSmpls/s >bei 60Mhz Systemtakt) >Man kann während diesen 143 Takten zwar was anderes machen aber >irgendwann brauch ich den Wert um zu rechnen. Wenn das dann auch noch >100Takte braucht bin ich sowieso jenseits von gut und böse. was haelst du davon:
1 | volatile int oldval; |
2 | |
3 | isr(){ |
4 | start_adc(): |
5 | calculate_iir(oldval); |
6 | wait_for_adc(); |
7 | oldval = adcval; |
8 | }
|
dann hast du keine probleme mit den mind. 143 takten ;)
Hallo n!x Ja so ähnlich passiert das jetzt auch. Der ADC ist jetzt so eingestellt das er ca. 200Takte für ein Sample braucht. Immer wenn er fertig ist triggert er die ISR und sampled gleich weiter. Also von der Verarbeitungsgeeschwindigkeit ist das jetzt durchaus OK. Hab etwas mit Assembler optimiert. Das was der gcc produziert ist sowieso irgendwie recht müllig wenns schnell sein muß: z.B. verwendet er kaum einmal andere Register als r2 und r3. Und er fügt "sinnlose" Registerkopierbefehle ein nur damit z.B. immer r2 (oder halt r3) Zielregister ist. Und so Sachen wie banked Register (bei FIQ) kennt scheint er auch nicht zu kennen. MfG Oli
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.