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.
Was heisst" code size limit überschritten." genau? Würde eine case-Anweisung helfen? Gruss Robert
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; }
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
nur so eine Frage: worauf programmierst du, dass du derart wenig Speicher hast ... oder überschreitet das Gesamtprojekt den vorhanden Speicher ...
>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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.