hallo, Ich versuche gerade der Effektivwert im Bezug auf Mittelwert zu berechnen, komme leider nicht weiter, programm laüft auch nicht Ich habe den folgenden Formal benutzt Effektivwert= (1/N-1)[sum of squares-(sum^2)/N] Das ist gerade mein Programm #define sqrt void main() { int16 value[100],mittel,min,max,Effwert; unsigned int16 sum,sumQ; int i ; setup_adc_ports(AN0_TO_AN1|VSS_VDD); setup_adc(ADC_CLOCK_DIV_4|ADC_TAD_MUL_16); setup_spi(SPI_SS_DISABLED); setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); while(1) { if(input(pin_b1)==1) { for (i=0;i<1;i++) { set_adc_channel(1); for (i=0;i<100;i++) { value[i]=read_adc(); delay_us(500); } sum=0; for(i=0;i<100;i++) { sum=sum+value[i]; sumQ=sumQ+value[i]^2; } mittel=sum/100; sumQ=0; for(i=0;i<100;i++) { if (i=1) Effwert=0; else Effwert=sqrt (sumQ-(sum^2/i))/(i-1); } min=value[0]; max=value[0]; for(i=0;i<100;i++) { if (value[i]>max) max=value[i]; if (value[i]<min) min=value[i]; } } for(i=0;i<100;i++) printf("%Li\n", value[i]); printf("mittelwert %li\n", mittel); printf("min %Li\n", min); printf("max %Li\n", max); printf("Summe %Lu\n", sum); printf("summeQuadrat %Lu\n",sumQ); printf("Effektivwert %Li\n",Effwert); } } }
>Ich versuche gerade der Effektivwert im Bezug auf Mittelwert zu >berechnen, komme leider nicht weiter, programm laüft auch nicht Was heißt "läuft nicht"? - Compiliert nicht? Welche Fehlermeldung? - Falsche Ergebnisse? Welche? - Absturz? Welche Architektur? Verpass deinem Code bei der Gelegenheit noch ein paar Kommentarzeilen - das ist im Moment unnötig schwer zu lesen!
Eine Frage: Was, um Himmels willen, hast du dir dabei gedacht? > > #define sqrt > Du weist schon, dass du damit deine Wurzel Operation effektiv auf eine 'Tu nichts' Operation umdefiniert hast? Wenn dein Compiler wegen der sqrt Funktion gemault hat dann ist die Lösung dafür math.h zu inkludieren und nicht den Funktionsaufruf auszuhebeln.
Der Code kompiliert mit Sicherheit nicht. Und wenn doch, dann ist immer noch einiges falsch, wie z.B. #define sqrt ohne was dahinter. ^2 hat in C auch eine andere Bedeutung. Dann noch das Thema Überlauf usw.
Compilieren tut er schon .nun keine Ergebnisse #define sqrt void main() { int16 value[100],mittel,min,max,Effwert; unsigned int16 sum,sumQ; int i ; setup_adc_ports(AN0_TO_AN1|VSS_VDD); setup_adc(ADC_CLOCK_DIV_4|ADC_TAD_MUL_16); setup_spi(SPI_SS_DISABLED); setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); while(1) { if(input(pin_b1)==1) // vom Kanal 1 einlesen { for (i=0;i<1;i++) { set_adc_channel(1); for (i=0;i<100;i++) { value[i]=read_adc(); //Werte einlesen delay_us(500); } sum=0; for(i=0;i<100;i++) { sum=sum+value[i]; // Summe bilden sumQ=sumQ+value[i]^2; //Summe Quadrat bilden } mittel=sum/100; sumQ=0; for(i=0;i<100;i++) { if (i=1) Effwert=0; else Effwert=sqrt (sumQ-(sum^2/i))/(i-1); // Effektivwert oder Standard Abweichung bilden } min=value[0]; max=value[0]; for(i=0;i<100;i++) { if (value[i]>max) //Min und Max suchen max=value[i]; if (value[i]<min) min=value[i]; } } for(i=0;i<100;i++) printf("%Li\n", value[i]); printf("mittelwert %li\n", mittel); printf("min %Li\n", min); printf("max %Li\n", max); printf("Summe %Lu\n", sum); printf("summeQuadrat %Lu\n",sumQ); printf("Effektivwert %Li\n",Effwert); } } }
med wrote:
> Compilieren tut er schon
So wie du ihn gepostet hast: Nein
int16 ist kein Standard Datentyp, damit das klappt muss irgendein
Include vorausgehen, der int16 definiert. Die includes hast du aber
nicht gezeigt.
Aber abgesehen davon: Ob ein Code compiliert oder nicht, sagt nichts
darüber aus, ob die Logik stimmt. Der Compiler überprüft, ob dein
Code die Sprachregeln erfüllt. Für die Logik ist immer noch
der Programmierer zuständig.
"Ich esse den Lastwagen mit einem Fernrohr."
ist auch ein gültiger deutscher Satz, dadurch dass er die Grammatik-
regeln erfüllt. Sinn macht er trotzdem nicht.
med wrote: > #include math.h #include <math.h> und der #define sqrt muss natürlich raus. > er erkennt die sqrt () einfach nicht Vielleicht hat dein Compiler keine sqrt() Funktion in der math.h eingetragen? Bei µC Systemen kommt das schon mal vor. Häng doch mal dein komplettes File hier an. PS: Wie weiter oben schon gesagt wurde: ^ ist nicht die Potenz Funktion. ^ macht etwas völlig anderes (bitweises XOR). Wenn du ein Qudrat haben willst, dann ist die einfachste Variante einfach x*x zu rechnen.
> for(i=0;i<100;i++) > { if (i=1) Ich glaube nicht, dass du hier eine Zuweisung haben willst. Du willst mit Sicherheit einen Vergleich { if (i == 1 ) und so wie die Logik in diesem Programmteil läuft, möchtest du auch nicht auf 1 vergleichen, sondern auf 0 { if (i == 0 ) Ich rate dir, dir einen PC Compiler zuzulegen. Damit kannst du Funktionalitäten erst mal auf dem PC testen, ehe du sie in dein µC Programm einbaust. Der Vorteil: Auf einem PC hast du einen wesentlich besseren Debugger mit dem du deinem Programm, während es läuft, auf die Finger schauen kannst und nachvollziehen kannst, was den so im Programm passiert.
med wrote:
> Ich bin auch nicht sicher ob er der Effektivwert so berechnen kann.
Das glaube ich allerdings auch nicht.
Vor allen Dingen frage ich mich, warum du den Effektivwert 100 mal
(mit jeweils einem anderen i) berechnest. Der Effektivwert hängt
doch nicht vom i ab. Du hast 100 Messwerte und von diesen 100
Messwerten berechnest du einmal den Effektivwert.
Ich probiere es gerade auf meinem Pic 18F2620 und benutze dafür ein CCS compiler. Normalerweise muss er die 100 werte ausgeben , dann Mittelwert, summe ,min ,max, summequadrat und effektivwert
med wrote:
> Das ist einfach zu vermeiden wenn i=1
Gewöhn dir schleunigst an, einen Unterschied zwischen Zuweisung
und Vergleich zu machen.
Eine Zuweisung schreibt sich in C mit einem '='.
Ein Vergleich auf Gleichheit schreibt sich in C mit 2 '=', also als '=='
if( i = 1 )
ist nicht dasselbe wie
if( i == 1 )
OK, das hab ich verbockt. In der Division steht dann i - 1
und damit da nicht durch 0 dividiert wird, machst du für
i gleich 1 eine Sonderbehandlung.
Ändert aber nichts an der Tatsache, dass deine Berechnung eigentlich
nicht für alle i von 0 bis 99 gemacht werden muss. Das N in deiner
urspünglichen Formel ist die Anzahl der Messwerte, und die ist bei
dir 100. Die ist immer 100, egal welchen Wert i gerade hat.
Und damit braucht diese Berechnung auch nicht in der for-Schleife
gemacht werden, sondern sie muss nur ein einziges mal gemacht
werden!
Was ist eigentlich aus der schönen Einrückung geworden, die ich dir in einem anderen Post gezeigt habe. Damals hast du selbst gesagt, dass das um einiges übersichtlicher ist. Und jetzt kommst du wieder mit demselben Scheiss! Glaub es endlich: Mit deiner unsystematischen Einrückerei schiesst du dir selbst ins Bein, weil du nicht mehr erkennen kannst, welche Programmteile unter der Kontrolle welcher Schleife stehen! Und damit platzierst du Berechnungen (auf gut Glück) an Programmstellen, wo sie nicht hingehören.
Ich habe das Programm natürlich probiert , das Problem lag es daran später dass er mir nur 99 werte ausgibst und manchmal auch 98 werte
könnte mir villeicht jemand helfen, komme ich nicht weiter!! SummeQuarat stimmt nicht Effektivwert stimmmt auch nicht #define NR_VALUES 100 #include <math.h> int16 value[NR_VALUES]; int16 mittel,min, max,Effwert ; unsigned int16 sum, sumQ; void SetupHardware() { setup_adc_ports(AN0_TO_AN1|VSS_VDD); setup_adc(ADC_CLOCK_DIV_4|ADC_TAD_MUL_16); setup_spi(SPI_SS_DISABLED); setup_wdt(WDT_OFF); setup_timer_0(RTCC_INTERNAL); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); } void ReadValues() { int16 i; set_adc_channel( 1 ); for( i = 0; i < NR_VALUES; i++ ) { value[i] = read_adc(); delay_us( 500 ); } } void BerechneMittel() { int16 i; sum = 0; for( i = 0; i < NR_VALUES; i++ ) sum = sum + value[i]; mittel = sum / NR_VALUES; } void BerechneEffektiv() { int16 i; sumQ=0; for(i=0;i<NR_VAlUES;i++) sumQ=sumQ+(value[i]*value[i]); Effwert=sqrt(sumQ-((sum*sum)/NR_VALUES))/(NR_VALUES-1); } void BerechneMinMax() { int16 i; min = value[0]; max = value[0]; for( i = 0; i < NR_VALUES; i++ ) { if( value[i] > max ) max = value[i]; if( value[i] < min ) min = value[i]; } } void PrintErgebnisse() { int16 i; for( i = 0; i < NR_VALUES; i++ ) printf("%Li\n", value[i]); printf( "mittelwert %li\n", mittel ); printf( "min %Li\n", min ); printf( "max %Li\n", max ); printf( "Summe %Lu\n", sum ); printf( "SummeQuadrat %Lu\n",sumQ); printf( "Effektivwert %Lu\n",Effwert); } void main() { int i; SetupHardware(); while( 1 ) { if( input( pin_b1 ) == 1 ) { ReadValues(); BerechneMittel(); BerechneEffektiv(); BerechneMinMax(); PrintErgebnisse(); } } } Ausgabe lautet: 550 550 549 550 548 546 546 546 547 546 546 546 547 545 546 543 546 542 543 543 542 541 541 540 539 539 538 538 538 537 537 536 536 535 535 535 535 534 533 533 530 531 531 530 530 530 529 528 528 527 527 527 526 526 526 525 524 523 524 523 522 521 521 520 520 519 519 519 519 518 515 515 514 516 515 515 514 509 512 512 510 509 508 508 507 506 507 506 505 505 504 504 504 504 503 503 503 503 502 mittelwert 526 min 502 max 550 Summe 52679 SummeQuadrat 55369 Effektivwert 2
Dein 1. Messwert ist beispielsweise 550 In der Effektivwert Funktion berechnest du 550*550 Das ergibt 302500. Bei einem 16 Bit unsigned int ist aber bei 65535 Schluss. Du musst die Berechnung auf int32 hochziehen.
1 | unsigned int16 sum |
2 | unsigned int32 sumQ; |
3 | |
4 | ....
|
5 | |
6 | void BerechneEffektiv() |
7 | {
|
8 | int16 i; |
9 | |
10 | sumQ = 0; |
11 | for(i = 0; i < NR_VAlUES; i++ ) |
12 | sumQ = sumQ + ( ((unsigned int32)value[i]) * value[i] ); |
13 | |
14 | Effwert = sqrt( sumQ - (( ((unsigned int32)sum)*sum)/NR_VALUES))/(NR_VALUES-1); |
15 | }
|
PS: Übrigens hast du bei deiner normalen Summe grosses Glück, dass sich das vom Wertebereich her noch ausgeht. Wenn deine Zahlen einmal ein klein wenig höher sind, dann passiert dir in sum genau das Gleiche. ADC Werte können bis 1024 hoch gehen. Du hast 100 Werte, das heist die höchste Summe die möglich ist, lautet 100 * 1024 = 102400. Und auch das liegt über dem was ein unsigned int16 zu speichern vermag (65535)
Wie sieht es aus wenn ich float benutze, ich habe es schon mal ausprobiert da kommt aber immer ein negatives wert raus
sumQ = sumQ + ( ((unsigned int32)value[i]) * value[i] ); Effwert = sqrt( sumQ - (( ((unsigned int32)sum)*sum)/NR_VALUES))/(NR_VALUES-1); kann ich unsigned int32 oben mit dem variablen deklarieren? Effektivwert ist leider auch gleich geblieben(1)
med wrote: > kann ich unsigned int32 oben mit dem variablen deklarieren? > sumQ = sumQ + ( ((unsigned int32)value[i]) * value[i] ); | das hier --------------+ ist ein cast. Er wandelt den value[i] auf 32 Bits hoch, damit die Multiplikation nicht als 16 Bit Multiplikation sondern als 32 Bit Multiplikation ausgeführt wird. Und sumQ solltest do sowieso als unsigned int32 definieren, so wie ich das in der Codekorrektur gemacht habe. > > Effwert = sqrt( sumQ - (( ((unsigned > int32)sum)*sum)/NR_VALUES))/(NR_VALUES-1); Hier ist es das Einfachste und auch das Vernünftigste, wenn du sum ebenfalls als unsigned int32 definierst. Dann brauchst du hier keine castings und kannst ganz normal schreiben Effwert = sqrt( sumQ - ( (sum*sum)/NR_VALUES))/(NR_VALUES-1); Dadurch dass sum dann ein unsigned int32 ist, wird diese Multiplikation sowieso immer als 32-Bit Multiplikation ausgeführt. unsigned int32 sum, sumQ;
Mein Problem liegt jetzt an der Effektivwert , welche variable typ werde ich am besten benutzen um ein vernünftiges ergebnis zu haben
int16 ist doch ok. PS: Hast du drann gedacht, dass die Formatangaben in deinen printf für die unsigned int32 angepasst werden müssen?
kleiner Tip: es heißt den oder dem Effektivwert. >>Ich versuche gerade den Effektivwert im Bezug auf... >>0Mein Problem liegt jetzt an dem Effektivwert... Warum benutzt du nicht den Debugger oder Simulator, da kannste Schritt für Schritt sehen was dein Programm macht.
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.