zu große Daten

Gast #2585514
Lesenswert?

Mit meinem Programm möchte ich AD/Wandeln und anschließend den 
Mittelwert und die Standardabweichung bilden.

Jedoch funktioniert das aus irgendeinem Grund nicht. Beim builden zeigt 
mein AVR Studio 4 keine Fehlermeldung, jedoch schreibt das Programm im 
Build Fenster:
Data:        264 bytes (103.1% Full)

Wie kann das bei so einem kleinem Programm sein? Wo liegt der Fehler.

Ich verwende einen attiny45.

Hier mein bescheidenes Programm:

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>

int main(void)
{

unsigned ergebnis, ergebnisalt, i;


    ADMUX = 0x96;
    ADCSRA = 0x87;
    ADCSRB = 0x00;
    DIDR0 = 0x3F;

    DDRB = 0x07;

    ergebnis = 0;
    ergebnisalt = 0;


    PORTB |= 0x02;


    int data [10];

    for (i = 0; i < 10; i++)

    {
      ADCSRA |= 0x40;

      while (ADCSRA & 0x40);

      data [i] = ADCW;

    }


    double xm;
    int sum = 0;

    for (i=0; i<10; i++)

    {
      sum += data[i];
    }


    xm =  (double) sum / 10;

    double stabw = 0;
    double qsum = 0;

    for  (i=0; i<10; i++)

    {
      qsum += pow(data [i] - xm,2);
    }


    stabw = sqrt(1.0/9*qsum);

    if (stabw > 3) PORTB |= 0x01;

    ergebnis = xm;
}

Kann mir jemand bei meinem Problem helfen?
Gast #2585532
Lesenswert?

Mark schrieb:
> stabw = sqrt(1.0/9*qsum);
>     if (stabw > 3) PORTB |= 0x01;

das ist zum beispiel sehr ungünstig für den kleinen µC. Das kann man 
sehr viel einfacher machen, in dem man schon mal die Wurzel entfernt

> stabw = 1.0/9*qsum;
>     if (stabw > 9) PORTB |= 0x01;

das ganze kann man noch weiter treiben in dem man jetzt noch die 
multiplikation wegnimmt.
#2585533
Lesenswert?

> qsum += pow(data [i] - xm,2);

das ist jetzt aber nicht dein Ernst, oder?
Für ein simples Quadrat die pow() Funktion einzusetzen.

Hast du eine Ahnung davon, was die alles treiben muss um x hoch 0.78 
berechnen zu können? Und denselben Aufwand muss sie auch bei dir 
treiben, selbst wenn dein Exponent 2 ist.
Persönliche Seite #2585541
Lesenswert?

Stefan Ernst schrieb:
> Mark schrieb:
>> Data:        264 bytes (103.1% Full)
>>
>> Wie kann das bei so einem kleinem Programm sein? Wo liegt der Fehler.
>
> libm.a nicht mit gelinkt.

...was dann u.a. zu http://gcc.gnu.org/PR29524 führt.

Mit der AVR-Libc ist selbst auf keinen Tinys float einsetzbar, falls man 
es richtig angeht: 4000 Stellen von Pi mit ATtiny2313.

Wenn man allerdings blindlinks alles ins Programm reinzieht was geht ... 
dann nicht.
Gast #2586406
Lesenswert?

Danke für die Tipps mit der Wurzel und dem Quadrat, ich bin ein 
absoluter Anfänger und weiß darüber noch wenig. Jedoch löst dies mein 
eigentliches Problem nicht, nämlich warum der Datenspeicher so voll ist.
Ich habe versucht das double wegzulassen doch auch dann funktioniert es 
nicht.

Was soll
"libm.a nicht mit gelinkt."
bedeuten?
Gast #2586443
Lesenswert?

Habe das obige Programm durchlaufen lassen.

Make meldet:

Program: 1508
Data   : 0

Auszug aus dem MAP-File:

Memory Configuration

Name             Origin             Length             Attributes
text             0x00000000         0x00002000         xr
data             0x00800060         0x0000ffa0         rw !x
eeprom           0x00810000         0x00010000         rw !x
fuse             0x00820000         0x00000400         rw !x
lock             0x00830000         0x00000400         rw !x
signature        0x00840000         0x00000400         rw !x
default        0x00000000         0xffffffff
Gast #2586466
Lesenswert?

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>


int main(void)
{

unsigned ergebnis, ergebnisalt, i;


    ADMUX = 0x96;
    ADCSRA = 0x87;
    ADCSRB = 0x00;
    DIDR0 = 0x3F;

    DDRB = 0x07;

    ergebnis = 0;
    ergebnisalt = 0;


    PORTB |= 0x02;


    int data [10];


    for  (i=0; i<10; i++)

    {
      ADCSRA |= 0x40;

      while (ADCSRA & 0x40);

      data [i] = ADCW;
    }


    int xm;
    int sum = 0;



    for  (i=0; i<10; i++)

    {

      sum += data[i];
    }



    xm =  sum / 10;

    int stabw = 0;
    int qsum = 0;

    for  (i=0; i<10; i++)

    {
      qsum += ((data [i] - xm)*(data [i] - xm));
    }


    stabw = (1.0/9*qsum);


    if (stabw > 9) PORTB |= 0x01;



    ergebnis = xm;
}
Gast #2586538
Lesenswert?

Da ist immer noch ein float drin, und du hast libm.a nicht dazu gelinkt.

>Program:    2428 bytes (59.3% Full)
>(.text + .data + .bootloader)

>Data:        264 bytes (103.1% Full)
>(.data + .bss + .noinit)


mit libm.a ergibt das

>Program:     972 bytes (23.7% Full)
>(.text + .data + .bootloader)

>Data:          0 bytes (0.0% Full)
>(.data + .bss + .noinit)

Oliver
Gast #2586688
Lesenswert?

> stabw = (1.0/9*qsum);
>  if (stabw > 9) PORTB |= 0x01;
diese Rechnung braucht den ganzen platz. Kürze sie weg.

if (qsum > 27) PORTB |= 0x01;

(keine ahnung ob das jetzt stimmt, bitte selber nachrechnen)

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