From 6c88a493bae27019e657a5df0d8e02d326c96fce Mon Sep 17 00:00:00 2001 From: Paul Goeser Date: Sat, 9 Apr 2011 01:02:45 +0200 Subject: [PATCH] filter tested, fixed, curve working, found an analog hardware bug --- TODO | 12 +++++++--- firmware/slavechip/Makefile | 4 ++++ firmware/slavechip/filter.c | 45 +++++++++++++++++++++++++++++-------- firmware/slavechip/main.c | 4 ++-- 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index dc1673d..214ee0b 100644 --- a/TODO +++ b/TODO @@ -3,15 +3,14 @@ Was will ich jetzt tun? Mess-software: -[B] besseres protokoll, mit funktionen mit returnwerten -[C] ringbuffer für debug-printf --[A] clean muxer mit offset implem --[A] Kennlinien-code verwenden -[A-] "Event-driver" für die korrekte Messabfolge --[C] Rauschen bewerten +-[C] Rauschen besser bewerten Mess-hardware: -[A2] Weitere Kanäle löten -[A1] Blockkondensatoren bewerten -[A] Pt1000-Messbrücke bauen +-[A] Lösung für das offset-zeuch finden, EMV-Filter impedanz durchrechnen Hardware: -[B] Gehäuse @@ -23,6 +22,13 @@ generelle Software: -[C3] besserer Softtimer mit statistik +Zum offsetfilterzeuch: +Der FET hat einen zu großen On-Widerstand (oder interagiert irgendwie böse mit dem Filter) um mit anliegender Thermospannung gut zu nullen. +Ich habe in einem Test bei Raumtemperatur -4.5°C offset gemessen, bei +40°C über Raumtemperatur allerdings nurnoch -0.5°C offset. Mit einem 470ohm-widerstand in Reihe zum Sensor ist das Offset bie +40°C wieder bei etwa -4.3°C, die Temperaturmessung unterscheidet sich um weniger als 0.3°C. +Das Offsetkompensator-konzept sollte überdacht werden. +Der INA leistet nicht genug. Zu warm geworden? (alternativ: statischer offset?) + + TODO für ersten funktionierenden Stand: Hardware: diff --git a/firmware/slavechip/Makefile b/firmware/slavechip/Makefile index 8d11541..264de00 100644 --- a/firmware/slavechip/Makefile +++ b/firmware/slavechip/Makefile @@ -2,6 +2,10 @@ include ../Makefile.inc DEFINES += -DF_CPU=8000000 +CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm # add float to snprintf +CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax + + COMPILE = avr-gcc $(CFLAGS) $(DEFINES) OBJECTS = main.o mcp_adc.o i2c_simple.o softtimer.o spi_proto.o spi.o spi_pointers.o muxer.o debug.o filter.o diff --git a/firmware/slavechip/filter.c b/firmware/slavechip/filter.c index a2658be..5f19a3b 100644 --- a/firmware/slavechip/filter.c +++ b/firmware/slavechip/filter.c @@ -25,7 +25,7 @@ uint8_t filter_average_done(uint8_t channel, uint8_t samples){ float filter_average_temp_result(uint8_t channel){ float out = avg_cumul[channel]; - out /= avg_count[channel]; + out = out / (float)avg_count[channel]; return out; } @@ -50,10 +50,10 @@ uint16_t filter_float_to_decimal8(float f){ //uint16_t calc_temp(int16_t val, uint8_t channel) { // float mV = ((float) avg_temp(val, channel))/1000000; -float filter_voltage_to_temp(float mV){ - float temp = 0; - if(mV < 0) { - /* t in mV +float filter_temp_to_voltage(float temp){ + float mV = 0; + if(temp < 0) { + /* t in temp E = sum(i=0 to n) c_i t^i. ; n=10 */ const static float coef[] = { @@ -70,11 +70,11 @@ float filter_voltage_to_temp(float mV){ -0.163226974860E-22 }; for(int i=0; i<11; i++) { - temp += coef[i] * pow(mV, i); + mV += coef[i] * pow(temp, i); } } else { /* - t in mV + t in temp E = sum(i=0 to n) c_i t^i + a0 exp(a1 (t - a2)^2). ; n = 9 */ const static float coef[] = { @@ -91,12 +91,39 @@ float filter_voltage_to_temp(float mV){ }; const static float a[] = {0.118597600000E+00, -0.118343200000E-03, 0.126968600000E+03}; for(int i=0; i<10; i++) { - temp += coef[i]*pow(mV, i); + mV += coef[i]*pow(temp, i); } // ich glaube das summenzeichen erstreckt sich nicht auf das exp - temp += a[0] * pow(exp(a[1]*(mV - a[2])), 2); + mV += a[0] * pow(exp(a[1]*(temp - a[2])), 2); } + return mV; +} + + + + + +float filter_voltage_to_temp(float mV){ + //TODO: evtl kennlinien für <0°C und >500°C + + // Kennlinen aus http://srdata.nist.gov/its90/download/type_k.tab + float temp=0; + const static float coef[] = { + 0.000000E+00, + 2.508355E+01, + 7.860106E-02, + -2.503131E-01, + 8.315270E-02, + -1.228034E-02, + 9.804036E-04, + -4.413030E-05, + 1.057734E-06, + -1.052755E-08, + }; + for(int i=0; i<10; i++) { + temp += coef[i] * pow(mV, i); + } return temp; } diff --git a/firmware/slavechip/main.c b/firmware/slavechip/main.c index edccbcc..25b40d9 100644 --- a/firmware/slavechip/main.c +++ b/firmware/slavechip/main.c @@ -65,13 +65,13 @@ int __attribute__((noreturn)) main(void) { // total gain is 100 (50 from INA, 2 from ADC) // full signed range on ADC is +-2.048V // with 16bit, 1LSB is worth 0.0625mV - // with the gain added in that's 0.000625 + // with the gain added in that's 0.000625mV filter_average_input(active_sensor, f); if(filter_average_done(active_sensor,16)){ float noise = filter_average_noise(active_sensor); float temp = filter_average_result(active_sensor); - dbgLog("temp: %3.3f°C (lastval %i), noise: %3.5f",temp, data, noise); + dbgLog("temp: %3.3f°C (lastval %i), noise: %e\n",temp, data, noise); } } }