From db876151d61298b092524050743c92a4b5ffdedd Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Fri, 20 Sep 2024 01:07:31 +0200 Subject: [PATCH] Implement alternate voltage divider equation --- src/bus/i2c.c | 2 +- src/common/math.c | 62 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/bus/i2c.c b/src/bus/i2c.c index e5764ee..9e76913 100644 --- a/src/bus/i2c.c +++ b/src/bus/i2c.c @@ -525,7 +525,7 @@ word I2C_ADS1115_ReadRaw(int channel) // 110 | ±0.256 V // 111 | ±0.256 V - gain = 0x0000; // 6.144 V | 00000100 00000000 + gain = 0x0000; // 6.144 V | 00000000 00000000 // Input multiplexer configuration: These bits // configure the input multiplexer. diff --git a/src/common/math.c b/src/common/math.c index e6a2a07..6d3073d 100644 --- a/src/common/math.c +++ b/src/common/math.c @@ -2,41 +2,62 @@ #include +// https://www.sciencedirect.com/science/article/abs/pii/S0263224111002594 // https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation // https://onlinelibrary.wiley.com/doi/abs/10.1002/andp.18280890511 // https://onlinelibrary.wiley.com/doi/abs/10.1002/andp.18441370202 // https://bmcnoldy.earth.miami.edu/Humidity.html -// TODO: Is resistance function semantically correct? -// TODO: Check results for humidity conversion functions. - // Thermistor general constants -#define R1 10000.0f // Resistor ohm value -#define VRES 0xFFFF // 16-bit ADC resolution +#define VIN 5.0f // Source voltage (VCC) +#define GAIN 6.144f // PGA gain setting 0x00 +#define AMAX 0x7FFF // 16-bit ADC resolution +#define R1 10000 // 10k Ohm resistor // Thermistor coeficients -#define SC1 1.009249522e-3f -#define SC2 2.378405444e-4f -#define SC3 2.019202697e-7f +#define SC1 1.009249522e-3f +#define SC2 2.378405444e-4f +#define SC3 2.019202697e-7f -// Humidity conversion constants -#define TH1 100.0f -#define TH2 243.04f -#define TH3 17.625f +// Conversion constants +#define TH1 100.0f +#define TH2 243.04f +#define TH3 17.625f float Resistance(int adc_raw) { - float r2; + float av, r2; - // TODO: Improve readability. - // TODO: Make sure output is correct. + // [GND] - [10K R] - [ADC IN] - [THERMISTOR] - [VCC] - // [GND] - [10K RESISTOR] - [ADC INPUT] - [THERMISTOR] - [VCC] + // The ADC measurement is taken between a 10k Ohm + // resistor and the thermistor. This is also called + // a voltage divider circuit which has the following + // equation: - // return ((VRES - adc_raw) * R1) / adc_raw; - r2 = (float) adc_raw / 264.8f * 0.05f; + // Vout = Vin * (R2 / R1 + R2) - return R1 / (5.0f / r2 - 1.0f); + // We can solve for resistance R2 by rearranging and + // simplifying the equation: + + // R2 = R1 / (Vin / Vout - 1) + + // If the ADC reference voltage and voltage divider + // source voltage (Vin) are the same, then the + // following is true: + + // Vin / Vout = AMAX / AV + + // This means the ratio of voltage divider input + // voltage to output voltage is the same as the ratio + // of the ADC full range value (AMAX) to the value + // returned by the ADC (AV). For a 16 bit ADC like + // the ADS1115 the AMAX is 0x7FFF. + + av = adc_raw * (GAIN / VIN); + r2 = R1 / (AMAX / av - 1.0f); + + return r2; } float SteinhartHart(float res) @@ -45,6 +66,9 @@ float SteinhartHart(float res) // Convert resistance to temperature + // When the temperature increases, NTC thermistor + // resistance will decrease: + // 25C = 10000 Ohms // 100C = 6744 Ohms