www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik c code vereinfachen


Autor: sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich versuch grad einen feuchtigkeitssensor zu programmieren der eine 
impedanz hat. Ich hab grad eine anweisung geschrieben aber die ist 
leider zu groß, also code size limit überschritten.

Weis jemand wie man das vereinfachen kann:???

    if (erg_luft <= 0x84)             //     80   6,85k
    {     h=80;
    }
    else if (erg_luft <= 0x106)     // 77,5
    {     h=77.5;
    }
    else if (erg_luft <= 0x128)     // 75  10,5k
    {     h=75;
    }
    else if (erg_luft <= 0x168)     // 72,5
    {     h=72.5;
    }
    else if (erg_luft <= 0x207)     // 70  17k
    {      h=70;
    }
    else if (erg_luft <= 0x256)     // 67,5
    {      h=67.5;
    }
    else if (erg_luft <= 0x305)    // 65    25k
    {     h=65;
    }


Vielen Dank

mfg

Sepp

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also eine Tabelle abklappern wird sich nicht rentieren.

Du könntest statt floats uint8_t zuweisen, die den doppelten Wert 
aufweisen: Offensichtlich ist die Genauigkeit, die h aufweist, nicht
größer wie 0.5%. Somit weist Du erst mal einem uint8_t den Wert 135 
(=67.5*2) zu. Hinterher kommt die Hälfte in den float.

Und das evtl. mit ner Tabelle kombinieren.

Autor: R. Freitag (rfr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was heisst" code size limit überschritten."  genau?

Würde eine case-Anweisung helfen?

Gruss

Robert

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Prinzip so:

inline float Doit(uint16_t erg_luft)
{
    const uint16_t Tab[] = { 0x84,0x106,0x128,0x168,0x207,0 };
    uint8_t Result = 160;
    uint16_t *p;
    for (p=Tab; *p; p++,Result -= 5)
        if (erg_luft <= *p)
            return ((float)Result)*0.5;
    return 0.0;
}

Autor: sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit case hab ichs schon versucht das funtk aber nur mit constanten 
faktoren im case und das bringt mir nichts

@eddy

also die tabelle sieht sehr intressant aus, da ich aber c nicht so 
vertieft gelernt hab hört sich da ein wenig kompliziert an?

was macht der befehl uint8_t Result = 160; ?
wieso gibts uint16_t und uint8:t?

vielen dank

mfg

Autor: sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (erg_luft <= 0x84)             //     80   6,85k
    {     h=80;
    }

durch den bereich bekomm ich im h die prozent der luftfeuchtigkeit
also h=80, das kann ich dan ausgeben

aber in der tabelle wo würd das dann stehen?
also jetzt ist wenns kleiner <=84h ist, dann steht im h=80;

mfg

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nur so eine Frage: worauf programmierst du, dass du derart wenig 
Speicher hast ... oder überschreitet das Gesamtprojekt den vorhanden 
Speicher ...

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>h=77.5;

Die paar if's sind bestimmt nicht das Problem, die brauchen doch nur ein 
paar Byte Programmspeicher. Aber wenn du im weiteren mit den float-Werte 
rechnest, kommen da ganz schnell ein paar kB für die floating point libs 
hinzu.

Lass die floats ganz weg, und nimm dafür geeignet skalierte Integer. 
Oder FixPoint-Arithemtik. Dann klappt es auch auf einem Tiny.

Oliver

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aaaalso:

Die Anweisung

uint8_t Result = 160;

setzt ein einzelnes Byte auf den Wert 160, welcher später als 80.0 
zurück gegeben wird. Mit jedem Schleifendurchlauf wird der Wert um 5 
reduziert, was 2.5% Luftfeuchtigkeit entspricht. Somit braucht man die 
Werte für die Luftfeuchtigkeit gar nicht erst mit in die Tabelle packen. 
Ist es richtig, dass die Tabelle eigentlich noch viel länger ist? Dann 
rentiert sich der Aufwand umso eher.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso:

uint8_t ist auf den allerallermeisten CPUs nix anderes wie ein unsigned 
char. Damit ist halt besser ausgedrückt, was konkret benötigt wird.

Mit uint16_t sagt der Programmier dem C-Compiler, dass er definitiv 
einen unsigned int mit 16 Bit haben möchte. Das läuft meistens auf einen 
unsigned short int hinaus.

Autor: B e r n d W. (smiley46)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo  sepp

Bist Du Dir sicher, daß in den Bedingungen das 0x stehen muß? Die grüne 
Kurve besteht aus Dezimalzahlen und die blaue aus Hexwerten. Die 
Dezimale macht irgendwie mehr Sinn.

Ich mach mal mit diesen Werten weiter.
84, 106, 128, 168, 207, 256, 305

Wie es scheint, ist jeder zweite Wert linear interpoliert. Man könnte 
über eine Funktion direkt das richtige Ergebnis erhalten, ohne Tabelle. 
Dann hätte das Ergebnis 1% Auflösung (rel.Hum).

Als Polynom 2.er Ordnung, (Fehler 0,5%):
h = ((long)160*x*x/1000 - (long)1286*x/10 + 89380) / 1000;

Als Gerade (Fehler 1,3%):
h = (long)-63*x/1000 + 84

Mfg. Bernd

Autor: rechnen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oft ist es gut, die werte mal zu zeichnen.

Der zusammenhang scheint linear zu sein, daher ist die
berechnung einfach:

h = -0.024 * erg_luft + 82,6

Diese Berechnung mit Festkomma oder (besser) longint
optimieren und fertig.

Autor: B e r n d W. (smiley46)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Gerade kann man noch weiter vereinfachen:

Aus
h = (long)-64*erg_luft/1024 + 84
wird
h = 84 - (erg_luft>>4);

Vier mal nach rechts schieben entspricht einer Division durch 16, 
genauso wie 64/1024.

Gruß, Bernd

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.