Hallo, ich habe Schwierigkeiten einen Atmega128 zu programmieren. Ich bin ganz neu in dem Gebiet und bin im Moment total durcheinander. Ich muss zwei Mikrofonsignale (die zwei Ohren des Menschen repräsentieren) mit dem ADC aufnehmen und eine Kreuzkorrelation der beiden durchführen. Ich habe das ganze mit Matlab simuliert und es funktioniert. Ich muss das folgende Programm auf dem Microcontroller schreiben: int main (void) { // (2) float adcval_1[300]; //Signal von dem ersten Mikrofon float adcval_2[300]; // Signal von dem zweiten Mikrofon for ( i=251; i<301;i++){ //zero padding der zwei Signale adcval_1[i]=0; adcval_2[i]=0; } float sum=0; float sum_0 =0; float sum_1=0; int counter =0; for (int i=0; i<36;i++){ // Kreuzkorrelation der Signale for(int n=0; n<250;n++){ sum_1= adcval_1[n+1]*adcval_2[n+18]; sum=sum+sum_1; } sum_1=0; if(sum_0<sum){ // nach Maximum suchen sum_0=sum; counter=i; } sum=0; } counter=counter-18; / Wegdifferenz der beiden Signale float delay=counter/31250; float dist=343*delay; float sinalpha= dist/0.2; float alpha = asin(sinalpha); // Richtung(Winkel) des Tons Wobei der ADC muss so eingestellt werden,dass er abwechselnd Werte der zwei Mikrofone aufnimmt und in den Arrays adcval_1 und adcval_2 speichert. Es kann sein dass,das ganze sehr einfach ist,aber ich habe ganz wenig Ahnung und weiss nicht wie ich anfangen soll.
:
Verschoben durch Admin
Weiß nicht, ob ich es richtig verstanden habe. Aber du kannst doch das eine Mikrofon an einen ADC-Kanal anschließen, das andere Mikrofon an dem anderen Kanal. Nachdem du den ersten Wert von einem Kanal hast, schaltest du den auf den anderen Kanal und holst den Wert ab und dann wieder auf den ersten Kanal und so weiter bis du alle deine Werte hast. Aber wenn du noch keine Ahnung hast wie das geht, versuch erst die Werte von einem Kanal zu holen und seh sie dir an, ob die einigermaßen stimmen, dann kannst du mit der Kanalumschlatung weitermachen. Es ist nicht so schwer, lies dir im Datenblatt den Paragraf zu ADC durch.
Hallo Ana, das was Du da eingefügt hast kann doch nicht das ganze Programm sein. Häng mal alles an, was Du schon geschrieben hast. (Ich hoffe doch Du hast das selbst geschrieben) Axel
Hallo, danke für die schnelle Antwort. Das Programm abe ich selbst geschrieben,deswegen bin ich nicht sicer ob es stimmt. Ic habe Problemme mit dem ADC einstellen und abwechselnd die Werte holen. Ich weiss nicht wie ich mir Werte ausgeben lassen kann,damit ich schauen kann ob es was sinvolles rauskommt. Noch dazu ich weiss nicht was ich mit "float"Werte und negative Werte genau machen muss. Und noch dazu,soweit ich verstanden habe der Atmega128 arbeitet mit 4MHz,ich möchte die Frequenz des ADCs möglichst runterstellen. Geht es nur mit den prescaler Bits,oder gibt es eine andere Möglichkeit auch? Hier ist mein komplettes Programm: #include <avr/io.h> // (1) #include <stdint.h> #include <math.h> int main (void) { // (2) float adcval_1[300]; float adcval_2[300]; uint8_t ind_1=0; uint8_t ind_2=0; for (uint8_t i=2; i<503;i++){ if(i%2==0){ ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR); ADCSRA =(1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); ADCSRA |= (1<<ADSC); while (ADCSRA & (1<<ADSC) ){ ; } adcval_2[ind_2] = ADCH*0.0025- 1.28; // Kanal 0, im adcval_2 speichern ind_2++; } else{ ADMUX =(1<<MUX2) | (1<<REFS1) | (1<<REFS0) | (1<<ADLAR); ADCSRA =(1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); ADCSRA |= (1<<ADSC); while (ADCSRA & (1<<ADSC) ){ // Kanal 4, im adcval_1 speichern ; } adcval_1[ind_1] =ADCH*0.0025-1.28; ind_1++; } } for (uint8_t i=251; i<301;i++){ // Zero padding adcval_1[i]=0; adcval_2[i]=0; } float sum=0; float sum_0 =0; float sum_1=0; int8_t counter =0; for (uint8_t i=0; i<36;i++){ // Kreuzkorrelation for(uint8_t n=0; n<250;n++){ sum_1= adcval_1[n+1]*adcval_2[n+18]; sum=sum+sum_1; } sum_1=0; if(sum_0<sum){ sum_0=sum; counter=i; } sum=0; } counter=counter-18; float delay=counter/31250; // Delay zwischen die beiden Signale,(fs=31250) float dist=343*delay; //Wegdifferenz der beiden Signale float sinalpha= dist/0.2; // Richtung des Tons als sinus der Winkel float alpha = asin(sinalpha); // Winkel bestimmen while(1){ } return 0; }
Ana Kamenova schrieb: > Hallo, > > danke für die schnelle Antwort. Das Programm abe ich selbst > geschrieben,deswegen bin ich nicht sicer ob es stimmt. Ic habe Problemme > mit dem ADC einstellen und abwechselnd die Werte holen. Fang damit an, das AVR-GCC-Tutorial zu studieren. Da gibt es auch einen Abschnitt über den ADC > Ich weiss nicht > wie ich mir Werte ausgeben lassen kann,damit ich schauen kann ob es was > sinvolles rauskommt. Dann musst du dir dafür was einfallen lasse. UART, LCD da gibt es schon ein paar Möglichkeiten. > Noch dazu ich weiss nicht was ich mit "float"Werte > und negative Werte genau machen muss. Die meisten float willst du da ganz sicher nicht haben. Fang damit an, zumindest die Messwerte einfach nur als ganze Zahlen zu sehen. Negative Werte kannst du gar nicht haben. Mit dem ADC kannst du nur positive Spannungen messen. zur Not muss man eben das Signal in der Spannungslage verschieben. > Und noch dazu,soweit ich > verstanden habe der Atmega128 arbeitet mit 4MHz,ich möchte die Frequenz > des ADCs möglichst runterstellen. Der geht sowieso so schnell oder so langsam wie du ihn programmierst. In einem Programm etwas langsamer zu machen ist kein Problem. Die Umkehrung ist schwieriger :-)
Karl heinz Buchegger schrieb: > Die meisten float willst du da ganz sicher nicht haben. Fang damit an, > zumindest die Messwerte einfach nur als ganze Zahlen zu sehen. > > Negative Werte kannst du gar nicht haben. Mit dem ADC kannst du nur > positive Spannungen messen. zur Not muss man eben das Signal in der > Spannungslage verschieben. Ja das habe ich schon gemacht,ich messe nur positive Werte.Später für die Kreuzkorrelation benötige ich die "echten" Werte. Kann ich die einfach umrechnen und weiter arbeiten?
zieh einfach einen Offset von dern Werten ab, und schon sind sie wieder teils negativ
Erkläre doch mal was diese Kreuzkorrelation machen soll. Als Formel ohne Programm
Düsendieb schrieb: > Erkläre doch mal was diese Kreuzkorrelation machen soll. Als Formel ohne > Programm Und wenn du das hast, dann geh noch mal dein Programm durch und sieh nach ob du alle Elemente deiner Erklärung wiederfindest. UNd wenn du dann dein Programm nicht einfach so hinrotzt, sondern sauber einrückst, dann siehst du auch wo du hier Mist gebaut hast bzw. in Matlab nicht richtig getestet hast.
Weitere Fragen: wann fängt das Programm an zu arbeiten, was geschieht mit dem Ergebnis? Der ADC wird bestimmt kein so schönes Sinussignal wie in der Simulation aufnehmen. Was geschieht mit einzelnen Peaks? Welche Frequenz hat das zu messende Signal? Recht der Array um eine komplette Schwingung aufzunehmen?
Die Kreuzkorrelation multipliziert die Werte der Zwei Signale x u.s,(wobei x ist um n verschoben) und bildet die Summe der Multiplikationen. Das wird für 0<n<maxn Verschiebungen durchgeführt. Das Ziel ist ein Max(Ks) aller Summen zu finden. Ks(x;n) =∑ x(t + n ) *s(t) Meine Frage ist,nachdem ich den Offset abziehe und meine echte Spannungswerte bekomme,kann ich einfach weiter multiplizieren und addieren?
Ana Kamenova schrieb: > Die Kreuzkorrelation multipliziert die Werte der Zwei Signale x > u.s,(wobei x ist um n verschoben) Das mit dem verschieben .... das findet sich aber in deinem Code nicht wieder. > und bildet die Summe der > Multiplikationen. Das wird für 0<n<maxn Verschiebungen durchgeführt. Da der erste Punkt sich schon nicht wiederfindet, findet sich auch der Teil bei dir im Programm nicht wieder. -> Nochmal zurück ins Matlab und mit anderen Werten probieren. > Meine Frage ist,nachdem ich den Offset abziehe und meine echte > Spannungswerte bekomme,kann ich einfach weiter multiplizieren und > addieren? Im Prinzip: ja. Nur musst du darauf achten, dass dir die Berechnungen nicht übergehen. Die naive Vorstellung, dass float jede beliebige Zahl in unbegrenzter Genauigkeit aufnehmen kann, ist leider .... reichlich naiv.
Düsendieb schrieb: > Weitere Fragen: > > wann fängt das Programm an zu arbeiten, was geschieht mit dem Ergebnis? > > Der ADC wird bestimmt kein so schönes Sinussignal wie in der Simulation > aufnehmen. Was geschieht mit einzelnen Peaks? > > Welche Frequenz hat das zu messende Signal? Recht der Array um eine > komplette Schwingung aufzunehmen? Das Programm soll anfangen sobald ein Ton die Mikrofone trifft. Das ganze muss ein künstlicher Kopf sein,der sich in der Richtung der Schalls dreht. Die Mikrofone stecken in den Ohren. Im Matlab habe ich mit keinem Sinus getestet,sondern mit signale aus den selben Mikrofone. Im Matlab wurde der Winkel richtig bestimmt. Mein Ergebnis(Winkel) soll dann weiter einem Schrittmotor übergeben,der den Kopf dreht. Meine Aufgabe zuerst ist mit dem Microcontroller den Winkel zu bestimmen. Meine Wunschfrequenz wäre 16KHz,wenn ich die so niedrig stellen kann. Die Array Größen aus meinem Programm sind nur ein Beispiel,ich werde mit viel mehr Werten rechnen müssen.
ich muss zugeben, trotz befragung von Wikipedia habe ich noch nicht so richtig verstanden, worum es dabei geht. Mit den Analogeingängen füllst Du zwei Arrays mit Integerwerten zwischen 0 und 1024. Nehmen wir mal an, das Sinal ist sogar sinusförmig. Was soll dann geschehen?
Ana Kamenova schrieb: > Das Programm soll anfangen sobald ein Ton die Mikrofone trifft. Das > ganze muss ein künstlicher Kopf sein,der sich in der Richtung der > Schalls dreht. Die Mikrofone stecken in den Ohren. Im Matlab habe ich > mit keinem Sinus getestet,sondern mit signale aus den selben Mikrofone. > Im Matlab wurde der Winkel richtig bestimmt. Dann machs nochmal mit anderen Messwerten. Du wirst sehen, dass dein Programm wieder zum selben Winkel kommt. Im Moment machst du keine Kreuzkorrelation sondern dein Programm bestimmt einen Wert, den du vorher schon wusstest. Du hast dein Programm solange getrimmt, bis du den bereits bekannten Wert herausbekommen hast.
Düsendieb schrieb: > ich muss zugeben, trotz befragung von Wikipedia habe ich noch nicht so > richtig verstanden, worum es dabei geht. Es geht darum, in einer Messreihe eine bekannte Messreihe möglichst gut wiederzufinden. Auf Deutsch: Du verschiebst dein bekanntes Signal solange über dem gemessenen Signal nach links oder rechts, bist du die beste Übereinstimmung hast. GPS arbeitet zb so. Der GPS Empfänger weiß wie das Signal im Prinzip aussehen müsste und fahndet dann im empfangenen Signal danach. Ohne Kreuzkorrelation würde das Signal im Rauschen untergehen. Ich finde hier ist das ganz gut und knapp beschrieben http://tu-freiberg.de/fakult4/imfd/lehre/fluid/MT/Kreuzkorrelation.pdf
Karl heinz Buchegger schrieb im Beitrag: > Im Moment machst du keine Kreuzkorrelation sondern dein Programm > bestimmt einen Wert, den du vorher schon wusstest. Du hast dein Programm > solange getrimmt, bis du den bereits bekannten Wert herausbekommen hast. Entschuldigung es gibt ein Tippfehler dabei,so habe ich es gemeint: for (uint8_t i=0; i<36;i++){ // Kreuzkorrelation for(uint8_t n=0; n<250;n++){ sum_1= adcval_1[n+i]*adcval_2[n+18]; // i ist die Verschiebung sum=sum+sum_1; } sum_1=0; if(sum_0<sum){ sum_0=sum; counter=i; } sum=0; }
Ana Kamenova schrieb: > Entschuldigung es gibt ein Tippfehler dabei So sieht das schon besser aus. Jetzt wirfst du noch deinen ganzen ADC Kram raus und verwendest die Funktionen aus dem AVR-GCC-Tutorial.
Düsendieb schrieb: > Mit den Analogeingängen füllst Du zwei Arrays mit Integerwerten zwischen > 0 und 1024. Ich möchte die zwei Arrays mit den Werten: adcval_1[ind_1] =ADCH*0.0025-1.28 füllen, 0.0025= Uref/1024, 1.28 ist Uref/2(Offset)
Ana Kamenova schrieb: > Düsendieb schrieb: > >> Mit den Analogeingängen füllst Du zwei Arrays mit Integerwerten zwischen >> 0 und 1024. > > Ich möchte die zwei Arrays mit den Werten: > > adcval_1[ind_1] =ADCH*0.0025-1.28 > > füllen, 0.0025= Uref/1024, 1.28 ist Uref/2(Offset) Preisfrage: Was ist der Unterschied zwischen 2.65 Euro und 265 Cent Antwort: So gesehen kar keiner. Man kann mit beiden Beträgen dasselbe einkaufen. Als Geldmenge sind sie gleich. Aber das eine ist eine Zahl mit einem Dezimalpunkt und das andere nicht. Rechnen mit Floating Point ist auf deinem Mega128 über den Daumen gepeilt rund 30 bis 50 mal langsamer als rechnen mit ganzen Zahlen. Ob deine Zahlen jetzt von -1.0 bis +1.0 oder von -512 bis +512 laufen, kommt sich aufs gleiche raus. Du musst nur berücksichten, dass zweiteres einfach nur das 512-fache des ersteren ist.
Karl heinz Buchegger schrieb : > Jetzt wirfst du noch deinen ganzen ADC Kram raus und verwendest die > Funktionen aus dem AVR-GCC-Tutorial. Ja genau,das ist eigentlich mein Problem,die Einstellung des ADCs war mir nicht klar
Karl heinz Buchegger schrieb im Beitrag: > Rechnen mit Floating Point ist auf deinem Mega128 über den Daumen > gepeilt rund 30 bis 50 mal langsamer als rechnen mit ganzen Zahlen. Würde es dann gehen,den Offset umrechnen(ganze Zahl) und weiter arbeiten?
Ana Kamenova schrieb: > Karl heinz Buchegger schrieb im Beitrag: > >> Rechnen mit Floating Point ist auf deinem Mega128 über den Daumen >> gepeilt rund 30 bis 50 mal langsamer als rechnen mit ganzen Zahlen. > > Würde es dann gehen,den Offset umrechnen(ganze Zahl) und weiter > arbeiten? LOL Ob du zu 2.68 Euro noch 0.5 Euro Offset dazuzählst, oder ob du zu 268 Cent noch 50 Cent dazuzählst, kommt sich aufs gleiche raus.
Karl heinz Buchegger schrieb: > Ob du zu 2.68 Euro noch 0.5 Euro Offset dazuzählst, oder ob du zu 268 > Cent noch 50 Cent dazuzählst, kommt sich aufs gleiche raus. Ok danke :-)))))) d.h ich muss einfach die Werte richtig messen(ADC einstellen).
Ana Kamenova schrieb: > Karl heinz Buchegger schrieb: > >> Ob du zu 2.68 Euro noch 0.5 Euro Offset dazuzählst, oder ob du zu 268 >> Cent noch 50 Cent dazuzählst, kommt sich aufs gleiche raus. > > > Ok danke :-)))))) > > d.h ich muss einfach die Werte richtig messen(ADC einstellen). Genau Also: Aus dem Tut die fertigen Routinen holen, noch die Einstellung der Referenzspannung anpassen und mal ausprobieren, wie gut dein Signal gesampelt wird. Zunächst mal mit nur 1 Mikrofon, dann mit 2. Nicht alles auf einmal in Betrieb nehmen. Alles Schritt für Schritt. 16Khz müssten mit dem ADC noch drinnen sein. Geh mit der Abtastfrequenz so hoch, wie es gerade noch zulässig ist. (Dir ist auch klar, dass 16kHz Abtastfrequenz eine vorhergehende Filterung des Signals auf unter 8kHz Bandbreite bedingt?)
Karl heinz Buchegger schrieb: > (Dir ist auch klar, dass 16kHz Abtastfrequenz eine vorhergehende > Filterung des Signals auf unter 8kHz Bandbreite bedingt?) Es geht um Sprachsignale und ich gehe davon aus,dass die unter 8kHz liegen
Karl heinz Buchegger schrieb: > 16Khz müssten mit dem ADC noch drinnen sein. Geh mit der Abtastfrequenz > so hoch, wie es gerade noch zulässig ist. Was ich noch sagen wollte: Zwischen dem Aufnehmen der Sampels kann man zur Not immer noch ein wenig warten, wenn der ADC wirklich zu schnell sein sollte. Aber ich denke spätestens wenn der ADC beide Mikrofone wechselweise sampeln soll, wird das nicht mehr wirklich notwendig sein.
Ich möchte die Abtastfrequenz niedrig halten,weil ich so wenig wie möglich Werte sampeln möchte. Ich mache mir Gedanken ob der Microcontroller genug RAM für das Ganze hat.
Kleine Anmerkung:
1 | for (uint8_t i=251; i<301;i++){ // Zero padding |
2 | adcval_1[i]=0; |
3 | adcval_2[i]=0; |
4 | }
|
mit
1 | float adcval_1[300]; |
2 | float adcval_2[300]; |
ergibt eine Überschreitung der Arraygrenzen. In adcval_* existiert kein Index mit dem Wert 300.
Ana Kamenova schrieb: > Ich möchte die Abtastfrequenz niedrig halten,weil ich so wenig wie > möglich Werte sampeln möchte. Mach lieber die Aufnahmezeit kleiner und die Abtastrate hoch, sonst ist das Signal hoffnungslos eckig. Außerdem liegt ja sonst nichts großes im Speicher Axel
Als ich schlage folgende Struktur vor: Hauptschleife Schleife bis ein Analogeingang ein Signal größer irgendwas misst Schleife zur Aufnahme von x Werten Auswertung der Messreihen Bildung des Sollwert für den Schrittmotor Schleife bis der Schrittmotor sein Ziel erreicht hat Ende Hauptschleife Alles wird nur in Integerwerten gerechnet, da die ADC sowieso nur Werte von 0 bis 1024 liefert. Axel
Wenn ich z. B int8_t adcval_1[500]; definieren möchte,kommt die folgende Warnung: large integer implicitly truncated to unsigned type und der Microcontroller tut nichts,ist die Arraygröße zu groß? mit eine Größe von z.B 100 kommt die Meldung nicht.
Ana Kamenova schrieb: > Wenn ich z. B > > int8_t adcval_1[500]; definieren möchte,kommt die folgende Warnung: > > > large integer implicitly truncated to unsigned type Für welche Zeile kommt diese Meldung? Für die zitierte doch eher nicht, oder täusche ich mich? Schau mal nach, welche Zeile das betrifft und zeige sie inklusive der daran beteiligten Variablentypen.
Hc Zimmerer schrieb:
> Für welche Zeile kommt diese Meldung? Für die zitierte doch eher nicht,
ja die Zeile war es nicht,aber ich darf aber nicht mehr als 290 für die
Arrays nehmen,daher habe ich zu wenig Werte und bekomme nichts
sinvolles als Ergebnis.
Gut. Es ist nicht besonders sinnvoll, eine Fehlermeldung zu zitieren, ohne dass die davon betroffene Zeile dem Leser bekannt ist. Wenn Du nicht mehr als 290 Werte in ein Array bringst und sonst falsch gerechnet wird (so verstehe ich Deine Aussage): Hast Du die Arrays mit [300] vereinbart und nur 290 davon verwendet, oder steht in der Vereinbarung [290]? Und welche Speicherauslastung wird bei Beendigung des Kompiliervorgangs angezeigt? Wie viel bss, wie viel data?
als ich hab mal schnell in einem Programm für einen Mega 168 folgendes eingegeben: unsigned char adcval_1[1500]; unsigned char adcval_2[1500]; und in der Hauptschleife: while(1){ adcval_1[1234]=27; adcval_2[1499]=123; . . . . Da hat der Compiler nirgens gemeckert Axel
auch gegen: unsigned int adcval_1[1500]; unsigned int adcval_2[1500]; // ********Initialisierung******************************************** initial(); // Initialisierung Ports, Timer lcd_init(); // LCD Initialisierung // ******************************************************************* while(1){ adcval_1[1234]=27000; adcval_2[1499]=1234; hat er nichts zu sagen außer: Build succeeded with 0 Warnings...
Da muss das Problem wohl wo anders liegen. auch: unsigned int zeiger=0; unsigned int adcval_1[1500]; unsigned int adcval_2[1500]; // ********Initialisierung******************************************** initial(); // Initialisierung Ports, Timer lcd_init(); // LCD Initialisierung Start_Clock(); // ******************************************************************* while(1){ zeiger=1234; adcval_1[zeiger]=27000; adcval_2[zeiger+23]=1234; ist OK
> Hc Zimmerer schrieb: >> Für welche Zeile kommt diese Meldung? Für die zitierte doch eher nicht, Den FEhler habe ich gefunden und korrigiert. Nun,wenn ich z.B 7500 eingebe kommt das folgende: Program: 326 bytes (0.2% Full) (.text + .data + .bootloader) Data: 0 bytes (0.0% Full) (.data + .bss + .noinit) Build succeeded with 0 Warnings... trotzdem tut der Microcontroller nichts(ich habe den LEDs so programmiert,das bei sinvolles Ergebnis 2 läuchten und wenn nicht sollen 3 läuchten.) In dem Fall ist alles dunkel. Erst unter 290 passiert was
Hi >als ich hab mal schnell in einem Programm für einen Mega 168 folgendes >eingegeben: >unsigned char adcval_1[1500]; >unsigned char adcval_2[1500]; Klingt bei 1k Ram interessant. MfG Spess
Ups. Danke für den Hinweis. Immerhin hat der Mega128 – 4K Bytes Internal SRAM
Wenn Du mit 7500 die Größe Deiner Arrays meinst: dass das nicht funktionieren kann, kannst Du Dir selbst ausrechnen. Jede Float belegt schließlich 4 Bytes. Somit bräuchtest Du 30 kBytes. Der ATmega128 hat 4 kBytes SRAM. Erstaunlich ist nur die .data + .bss - Ausgabe. Möglicherweise zeigt die Mist, weil Du weit jenseits von Gut und Böse liegst. Natürlich meinte ich die Speicherbelegung bei 290 oder 300 Arraygröße. Auch die Frage nach der Vereinbarung ist noch offen. (@Axel Düsendieb: Ich habe nach wie vor keine Ahnung, was Du beweisen willst. Ich finde einfach nichts, was irgendwie bemerkenswert wäre, an Deinen Codeschnipseln. Außer dass Du die Speicherbelegung ebenfalls zu den vernachlässigbaren Informationen zu zählen scheinst (trotz großer Arrays) und prompt weit daneben liegst.)
Natürlich 7500 war nur als Beispiel,diese Größe brauche ich ncht,aber ich brauche schon was größeres als 290
Noch was:
1 | float delay=counter/31250; // Delay zwischen die beiden Signale,(fs=31250) |
counter ist eine int, 31250 sowieso. Beide Operanden also int, demnach wird eine Integer-Division durchgeführt. Somit kann delay nur die Werte 1.0, 0, und -1.0 annehmen.
Hallo, könnt ihr mir bitte sagen ob die ADC-Einstellungen stimmen und wie kann ich feststellen mit welcher Frequenz der Microcontroller arbeitet? #include <avr/io.h> // (1) #include <stdint.h> #include <math.h> /* ADC initialisieren */ void ADC_Init(void) { uint16_t result; ADMUX = (1<<REFS0) | (1<<REFS1); // interne Referenzspannung nutzen ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler ADCSRA |= (1<<ADEN); // ADC aktivieren ADCSRA |= (1<<ADSC); // eine ADC-Wandlung while (ADCSRA & (1<<ADSC) ); result = ADCW; } int16_t ADC_Read( uint8_t channel ) { ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); ADCSRA |= (1<<ADSC); while (ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten ; return ADCW; // ADC auslesen und zurückgeben } int main (void) { // (2) int16_t adcval_1[1000]; int16_t adcval_2[1000]; ADC_Init(); for (uint16_t i=0; i<1000;i++){ adcval_1[i]= ADC_Read(0)-430; // 430 ist der Offset adcval_2[i]= ADC_Read(6)-430; }
Ana Kamenova schrieb: > ADMUX = (1<<REFS0) | (1<<REFS1); // interne Referenzspannung nutzen = Internal 2.56V Voltage Reference with external capacitor at AREF pin. Daher sollte das Analogsignal nicht größer sein > ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler = ADPS2 ADPS1 ADPS0 = Division Factor 128 Kann man nichts falsch machen, aber die Wandelung ist evtl zu langsam. Willst schließlich schnell abtasten. CKSEL3..0 0001 ==> Nominal Frequency (MHz) 1,0Mhz Note: 1. The device is shipped with this option selected. Wenn der Controller frisch aus der Presse kam, dann sollte er 1Mhz Taktfrequenz haben. Ansonsten die Fuses kontrollieren. Zur Kontrolle kann man auch den Timer 1 programmieren und eine LED blinken lassen. Axel
Danke :-), ich habe dafür gesorgt,dass das Signal kleiner als 2.56V bleibt. Und die Abtastrate möchte ich auch niedrig halten. Für mich ist wchtig, dass der Teil: int main (void) { int16_t adcval_1[1000]; int16_t adcval_2[1000]; ADC_Init(); for (uint16_t i=0; i<1000;i++){ adcval_1[i]= ADC_Read(0)-430; // 430 ist der Offset adcval_2[i]= ADC_Read(6)-430; } richtig ist. Es sind zwei Mikrofonsignale,die ich abwechselnd mit zwei Kanäelen des ADCs aufnehmen möchte.
Ana Kamenova schrieb: > Abtastrate möchte ich auch niedrig halten. Für mich ist wchtig, dass der > Teil: ... > richtig ist. Grundsätzlich spricht da jetzt erst mal nichts dagegen. Genaueres kann man erst sagen, wenn du dir eine Möglichkeit schaffst, dir die Warte anzusehen. In deinem Fall wäre natürlich eine UART ideal, da es mit deinen Wertemengen auf einem LCD schon recht eng ist. Damit kann man sich dann auch einmal grafisch aufbereiten, was der ADC da eigentlich gesampelt hat. Man könnte einen Minimaltest machen: Wenn mit dem ADC etwas nicht stimmt, dann sind meistens alle Werte gleich, entweder 0 oder 1024.
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.