From 1cc319cd38821f31449c9cb6d5e6a6e49d3def37 Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Sun, 15 Sep 2024 20:09:57 +0200 Subject: [PATCH] Calculate temperature from thermistor resistance --- src/bus/i2c.c | 27 ++++++++++++++++++++++++++- src/bus/i2c.h | 3 ++- src/main.c | 21 ++++++++++----------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/bus/i2c.c b/src/bus/i2c.c index a2119fb..94b7cad 100644 --- a/src/bus/i2c.c +++ b/src/bus/i2c.c @@ -2,7 +2,9 @@ #include "bus/i2c.h" #include +#include +// I2C status flags #define TW_START 0x08 // Start condition transmitted #define TW_REP_START 0x10 // Repeated start condition transmitted #define TW_MT_SLA_ACK 0x18 // SLA+W transmitted, ACK received @@ -12,6 +14,11 @@ #define TW_MR_SLA_NACK 0x48 // SLA+R transmitted, NACK received #define TW_MR_DATA_ACK 0x50 // Data received, ACK returned +// NTC conversion constants +#define NTC01 1.009249522e-3 +#define NTC02 2.378405444e-4 +#define NTC03 2.019202697e-7 + // TODO: Error handling and recovery besides watchdog timer. // TODO: Add more documentation from the atmel data sheet. // TODO: Implement TWI_vect ISR? This may not actually be @@ -528,7 +535,25 @@ word I2C_ADS1115_Read(int channel) // Single-shot conversion, active low, continous mode config = os | rate | gain | mux; - I2C_ADS1115_WriteRegister(0x01, config); + return I2C_ADS1115_ReadRegister(0x00); } + +float I2C_ADS1115_ReadThermistor(int channel) +{ + word raw; + float r1, t; + float logr2; + + // TODO: Improve readability + // https://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation + + raw = I2C_ADS1115_Read(channel); + + r1 = (float) raw / 264.8f * 0.05f; + logr2 = log(10000.0f / (5.0f / r1 - 1.0f)); + t = 1.0f / (NTC01 + NTC02 * logr2 + NTC03 * pow(logr2, 3)); + + return t - 273.15f; // Convert fahrenheit to celsius +} diff --git a/src/bus/i2c.h b/src/bus/i2c.h index f29c203..e6a543d 100644 --- a/src/bus/i2c.h +++ b/src/bus/i2c.h @@ -28,6 +28,7 @@ int I2C_AHT20_Init(void); int I2C_AHT20_Read(float *temp, float *rhum); // ADS1115 analog to digital converter -word I2C_ADS1115_Read(int channel); +word I2C_ADS1115_Read(int channel); +float I2C_ADS1115_ReadThermistor(int channel); #endif // MAD_CORE_BUS_I2C_H diff --git a/src/main.c b/src/main.c index 49fb84f..1b5efba 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,6 @@ #include -// TODO: Convert raw data from ADS1115 to usable values. // TODO: Implement optional CRC8 sensor measurement check. // TODO: Either implement software PWM for the FAN03 timer // (which will be quite complicated) or pick a chip with @@ -97,7 +96,7 @@ static int Init(void) static void Update(void) { float temp[3], rh[3]; - short adc[4]; + float adct[3]; Info("Reading sensor values..."); @@ -110,16 +109,16 @@ static void Update(void) I2C_SetChannel(AHT03); I2C_AHT20_Read(&temp[2], &rh[2]); - adc[0] = I2C_ADS1115_Read(ADS01); - adc[1] = I2C_ADS1115_Read(ADS02); - adc[2] = I2C_ADS1115_Read(ADS03); - adc[3] = I2C_ADS1115_Read(ADS04); + Sleep(200); // FIXME: Poll config register until BIT(15) == 1 + adct[0] = I2C_ADS1115_ReadThermistor(ADS01); + Sleep(200); // FIXME: Remove me - see above. + adct[1] = I2C_ADS1115_ReadThermistor(ADS02); + Sleep(200); // FIXME: Remove me - see above. + adct[2] = I2C_ADS1115_ReadThermistor(ADS03); - Info("TEMP0=%.2fC, RH0=%.2f%%", temp[0], rh[0]); - Info("TEMP1=%.2fC, RH1=%.2f%%", temp[1], rh[1]); - Info("TEMP2=%.2fC, RH2=%.2f%%", temp[2], rh[2]); - Info("ADC0=%04X, ADC1=%04X", adc[0], adc[1]); - Info("ADC2=%04X, ADC3=%04X", adc[2], adc[3]); + Info("TEMP0=%.2fC, TEMP1=%.2fC, TEMP2=%.2fC", temp[0], temp[1], temp[2]); + Info("ADCT0=%.2fC, ADCT1=%.2fC, ADCT2=%.2fC", adct[0], adct[1], adct[2]); + Info("RH0=%.2f%%, RH1=%.2f%%, RH2=%.2f%%", rh[0], rh[1], rh[2]); } int main(void)