mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik wurzel berechnen


Autor: tobias hofer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich habe folgendens problem:
(quadratischer wert von adc berechnen)

float temp;

temp = sqrt(ADC_BUF*ADC_BUF);
sprintf(Display_Buffer,"Input : %5d mV",(int)temp);


Vom analog wandler bekomme ich einen unsigned int wert in ADC_BUF. 
Diesen Wert multipliziere ich mit sich selbst, und ziehe dan die wurzel 
und möchte ihn als
int wert (verliere sicher genauigkeit) in display_buffer schreiben.


nur bekomme ich z.b. wenn ADC_BUF = 1000 als ausgabe immer 130. Wie kann 
ich
das richtig lösen ohne das ich sprintf mit float machen muss.

vieleich hat jemand eine andere idee. ich bin leider nicht so bewannt in 
zahlenformaten.

gruss tobias

Autor: tobias hofer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun habe ich das erste Problem gelöst. Ich musste
ADC_BUS zu einem float casten.

Nun wird die wurzel richtig berechnet die ausgabe am display hat aber 
immer noch ein vorzeichen.
z.b.

ADC_BUS = -2048 -> ausgabe nach multiplikation und sqrt() -2048.
wie kann ich das ändern?

gruss tobias

Autor: Bertrik Sikken (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
You get 130 because the product ADC_BUF*ADC_BUF is somehow limited to a 
16-bit number: (1000*1000) modulo 65536 = 16960 and sqrt(16960) = 130.
What is the native bit width of you microcontroller?
Do you know the size of an 'int' and of a 'long int'?

Maybe you can fix it by doing something like
temp = sqrt((<32-bit type>)ADC_BUF * (<32-bit type>)ADC_BUF);

I don't why you first square a value and then take the square root. 
Isn't it simpler to do just
temp = (float)ADC_BUF;
?

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

und wozu das Ganze? Du hast einen unsigned-Wert, quadrierst ihn und 
ziehst wieder die Wurzel. Das Ergebnis ist dann wieder der ursprüngliche 
unsigned-Wert. Du kannst dir die Operation also sparen.

Matthias

Autor: tobias hofer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Das oben ist nur ein Beispiel damit ich in meinem Programm den fehler 
einfacher finden kann. In der richtigen anwendung kommt der quadrierte 
Wert aus einem IIR Filter. Aus dem Endergebniss muss ich dann die Wurzel 
ziehen.

Das Programm berechnet den RMS wert vom analog eingang.

Der ADC_BUF wert ist typ int. Der analog wandler hat 12bit auflösung und 
das zahlen format habe ich auf signed int eingestellt (-1 -2047 0 0 1 
2048)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.