Effektivwert berechnen

#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);



   }
  }
 }
#862330
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!
#862332
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 #862336
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);



   }
  }
 }
#862340
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.
#862346
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.
#862352
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.
#862357
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.
#862366
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!
#862371
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 #862542
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
#862563
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 #862619
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)
#862648
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 #862700
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren