You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
3.9 KiB

#include "filter.h"
#include <math.h>
#include "debug.h"
Sensordata sensordata[4];
float ambient_temp=25.;
float avg_cumul[CHANNELCOUNT];
float avg_lastval[CHANNELCOUNT];
uint8_t avg_count[CHANNELCOUNT];
float avg_noise[CHANNELCOUNT];
void process_thermocouple_value(int16_t raw_data, uint8_t channel){
// dbgLog("procthermval, val %i, chan %i",raw_data,channel);
// This function does everything that needs to be done to raw adc values
float a = raw_data;
a -= sensordata[channel].offset;
a = a*0.000625; // adc count to voltage (mV)
a = filter_voltage_to_temp(a); // voltage to temp
// TODO: first ambient->voltage, add that to a, then voltage->temp
a += ambient_temp; // compensate ambient temperature
// TODO: lowpass
uint16_t result = filter_float_to_fixpoint(a);
sensordata[channel].temperature = result;
}
void process_offset_value(int16_t raw_data, uint8_t channel){
sensordata[channel].offset = raw_data;
}
void process_ambient_value(int16_t raw_data){
// 9.625mV after amp per °C
float a = raw_data;
a = a * 0.03125; //adc to mV after amp
a = a / 9.625;
ambient_temp = a;
dbgLog("ambient: %3.3f°C (value %i)\n",a, raw_data);
}
uint16_t get_temperature(uint8_t channel){
if(channel>=4){
return 0;
}
return sensordata[channel].temperature;
}
void filter_average_input(uint8_t channel, float value) {
avg_cumul[channel] += value;
float noisetmp = avg_lastval[channel] - value;
avg_noise[channel] += noisetmp * noisetmp;
avg_count[channel] += 1;
}
uint8_t filter_average_done(uint8_t channel, uint8_t samples){
if(avg_count[channel] >= samples){
return(1);
}
return 0;
}
float filter_average_temp_result(uint8_t channel){
float out = avg_cumul[channel];
out = out / (float)avg_count[channel];
return out;
}
float filter_average_result(uint8_t channel){
float out = filter_average_temp_result(channel);
avg_lastval[channel] = out;
avg_cumul[channel] = 0;
avg_noise[channel] = 0;
avg_count[channel] = 0;
return out;
}
float filter_average_noise(uint8_t channel){
float noise = avg_noise[channel];
noise /= avg_count[channel];
return noise;
}
uint16_t filter_float_to_fixpoint(float f){
return( (uint16_t)(f * 256.) );
}
//uint16_t calc_temp(int16_t val, uint8_t channel) {
// float mV = ((float) avg_temp(val, channel))/1000000;
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[] = {
0.000000000000E+00,
0.394501280250E-01,
0.236223735980E-04,
-0.328589067840E-06,
-0.499048287770E-08,
-0.675090591730E-10,
-0.574103274280E-12,
-0.310888728940E-14,
-0.104516093650E-16,
-0.198892668780E-19,
-0.163226974860E-22
};
for(int i=0; i<11; i++) {
mV += coef[i] * pow(temp, i);
}
} else {
/*
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[] = {
-0.176004136860E-01,
0.389212049750E-01,
0.185587700320E-04,
-0.994575928740E-07,
0.318409457190E-09,
-0.560728448890E-12,
0.560750590590E-15,
-0.320207200030E-18,
0.971511471520E-22,
-0.121047212750E-25
};
const static float a[] = {0.118597600000E+00, -0.118343200000E-03, 0.126968600000E+03};
for(int i=0; i<10; i++) {
mV += coef[i]*pow(temp, i);
}
// ich glaube das summenzeichen erstreckt sich nicht auf das exp
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;
}