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
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.
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
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
>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
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.
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.
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
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.
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