Effektivwert berechnen

OP #862326
Lesenswert?
• ▲
▼
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);



   }
  }
 }
Lesenswert?
• ▲
▼
>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!
Lesenswert?
• ▲
▼
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.
Gast
Lesenswert?
• ▲
▼
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);



   }
  }
 }
Lesenswert?
• ▲
▼
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.
Lesenswert?
• ▲
▼
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.
Lesenswert?
• ▲
▼
>                     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.
Lesenswert?
• ▲
▼
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.
Lesenswert?
• ▲
▼
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!
Lesenswert?
• ▲
▼
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.
Gast
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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)
Gast
Lesenswert?
• ▲
▼
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)
Lesenswert?
• ▲
▼
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;
Gast
Lesenswert?
• ▲
▼
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.