Split thermistor functions into separate logical units and add TODO
This commit is contained in:
@@ -14,11 +14,6 @@
|
|||||||
#define TW_MR_SLA_NACK 0x48 // SLA+R transmitted, NACK received
|
#define TW_MR_SLA_NACK 0x48 // SLA+R transmitted, NACK received
|
||||||
#define TW_MR_DATA_ACK 0x50 // Data received, ACK returned
|
#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: Error handling and recovery besides watchdog timer.
|
||||||
// TODO: Add more documentation from the atmel data sheet.
|
// TODO: Add more documentation from the atmel data sheet.
|
||||||
// TODO: ADS1115 continuous mode instead of single-shot?
|
// TODO: ADS1115 continuous mode instead of single-shot?
|
||||||
@@ -477,7 +472,7 @@ static bool I2C_ADS1115_IsReady(void)
|
|||||||
return reg & BIT(15);
|
return reg & BIT(15);
|
||||||
}
|
}
|
||||||
|
|
||||||
word I2C_ADS1115_Read(int channel)
|
word I2C_ADS1115_ReadRaw(int channel)
|
||||||
{
|
{
|
||||||
word config;
|
word config;
|
||||||
word os, mode, rate, gain, mux;
|
word os, mode, rate, gain, mux;
|
||||||
@@ -563,21 +558,3 @@ word I2C_ADS1115_Read(int channel)
|
|||||||
|
|
||||||
return I2C_ADS1115_ReadRegister(0x00);
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ int I2C_AHT20_Init(void);
|
|||||||
int I2C_AHT20_Read(float *temp, float *rhum);
|
int I2C_AHT20_Read(float *temp, float *rhum);
|
||||||
|
|
||||||
// ADS1115 analog to digital converter
|
// ADS1115 analog to digital converter
|
||||||
word I2C_ADS1115_Read(int channel);
|
word I2C_ADS1115_ReadRaw(int channel);
|
||||||
float I2C_ADS1115_ReadThermistor(int channel);
|
|
||||||
|
|
||||||
#endif // MAD_CORE_BUS_I2C_H
|
#endif // MAD_CORE_BUS_I2C_H
|
||||||
|
|||||||
@@ -2,29 +2,67 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// https://bmcnoldy.earth.miami.edu/Humidity.html
|
// 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.18280890511
|
||||||
// https://onlinelibrary.wiley.com/doi/abs/10.1002/andp.18441370202
|
// https://onlinelibrary.wiley.com/doi/abs/10.1002/andp.18441370202
|
||||||
|
// https://bmcnoldy.earth.miami.edu/Humidity.html
|
||||||
|
|
||||||
// TODO: Make sure all results for conversion functions are correct.
|
// TODO: Is resistance function semantically correct?
|
||||||
|
// TODO: Check results for humidity conversion functions.
|
||||||
|
|
||||||
// Conversion constants
|
// Thermistor coeficients
|
||||||
static const float C1 = 100.0f;
|
static const float SC1 = 1.009249522e-3f;
|
||||||
static const float C2 = 243.04f;
|
static const float SC2 = 2.378405444e-4f;
|
||||||
static const float C3 = 17.625f;
|
static const float SC3 = 2.019202697e-7f;
|
||||||
|
static const float R1 = 10000.0f;
|
||||||
|
|
||||||
|
// Humidity conversion constants
|
||||||
|
static const float TH1 = 100.0f;
|
||||||
|
static const float TH2 = 243.04f;
|
||||||
|
static const float TH3 = 17.625f;
|
||||||
|
|
||||||
|
float Resistance(int adc_raw)
|
||||||
|
{
|
||||||
|
float r2;
|
||||||
|
|
||||||
|
// TODO: Improve readability.
|
||||||
|
// TODO: Make sure output is correct.
|
||||||
|
|
||||||
|
// [GND] - [10K RESISTOR] - [ADC INPUT] - [THERMISTOR] - [VCC]
|
||||||
|
|
||||||
|
r2 = (float) adc_raw / 264.8f * 0.05f;
|
||||||
|
|
||||||
|
// XXX: Ohms Law solved for resistance?
|
||||||
|
// R = V / I
|
||||||
|
return R1 / (5.0f / r2 - 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resistance to temperature
|
||||||
|
float SteinhartHart(float res)
|
||||||
|
{
|
||||||
|
float logr, t;
|
||||||
|
|
||||||
|
// 25C = 10000 Ohms
|
||||||
|
// 100C = 6744 Ohms
|
||||||
|
|
||||||
|
logr = log(res);
|
||||||
|
t = 1.0f / (SC1 + SC2 * logr + SC3 * pow(logr, 3));
|
||||||
|
|
||||||
|
return t - 273.15f; // Kelvin to celsius
|
||||||
|
}
|
||||||
|
|
||||||
// Dewpoint TD
|
// Dewpoint TD
|
||||||
float Dewp(float t, float rh)
|
float Dewp(float t, float rh)
|
||||||
{
|
{
|
||||||
float a, b;
|
float a, b;
|
||||||
|
|
||||||
a = log(rh / C1);
|
|
||||||
b = C3 * t / (C2 + t);
|
|
||||||
|
|
||||||
// 243.04*(LN(RH/100)+((17.625*T)/(243.04+T)))/
|
// 243.04*(LN(RH/100)+((17.625*T)/(243.04+T)))/
|
||||||
// (17.625-LN(RH/100)-((17.625*T)/(243.04+T)))
|
// (17.625-LN(RH/100)-((17.625*T)/(243.04+T)))
|
||||||
|
|
||||||
return C2 * (a + b) / (C3 - a - b);
|
a = log(rh / TH1);
|
||||||
|
b = TH3 * t / (TH2 + t);
|
||||||
|
|
||||||
|
return TH2 * (a + b) / (TH3 - a - b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temperature T
|
// Temperature T
|
||||||
@@ -32,13 +70,13 @@ float Temp(float td, float rh)
|
|||||||
{
|
{
|
||||||
float a, b;
|
float a, b;
|
||||||
|
|
||||||
a = log(rh / C1);
|
|
||||||
b = C3 * td / (C2 + td);
|
|
||||||
|
|
||||||
// 243.04*(((17.625*TD)/(243.04+TD))-LN(RH/100))/
|
// 243.04*(((17.625*TD)/(243.04+TD))-LN(RH/100))/
|
||||||
// (17.625+LN(RH/100)-((17.625*TD)/(243.04+TD)))
|
// (17.625+LN(RH/100)-((17.625*TD)/(243.04+TD)))
|
||||||
|
|
||||||
return C2 * (b - a) / (C3 + a - b);
|
a = log(rh / TH1);
|
||||||
|
b = TH3 * td / (TH2 + td);
|
||||||
|
|
||||||
|
return TH2 * (b - a) / (TH3 + a - b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relative Humidity RH
|
// Relative Humidity RH
|
||||||
@@ -46,11 +84,11 @@ float Rhum(float t, float td)
|
|||||||
{
|
{
|
||||||
float a, b;
|
float a, b;
|
||||||
|
|
||||||
a = C3 * td / (C2 + td);
|
|
||||||
b = C3 * t / (C2 + t);
|
|
||||||
|
|
||||||
// 100*(EXP((17.625*TD)/(243.04+TD))/
|
// 100*(EXP((17.625*TD)/(243.04+TD))/
|
||||||
// EXP((17.625*T)/(243.04+T)))
|
// EXP((17.625*T)/(243.04+T)))
|
||||||
|
|
||||||
return C1 * (exp(a) / exp(b));
|
a = TH3 * td / (TH2 + td);
|
||||||
|
b = TH3 * t / (TH2 + t);
|
||||||
|
|
||||||
|
return TH1 * (exp(a) / exp(b));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#ifndef MAD_CORE_COMMON_MATH_H
|
#ifndef MAD_CORE_COMMON_MATH_H
|
||||||
#define MAD_CORE_COMMON_MATH_H
|
#define MAD_CORE_COMMON_MATH_H
|
||||||
|
|
||||||
|
float Resistance(int adc_raw);
|
||||||
|
float SteinhartHart(float res);
|
||||||
|
|
||||||
float Dewp(float t, float rh);
|
float Dewp(float t, float rh);
|
||||||
float Temp(float td, float rh);
|
float Temp(float td, float rh);
|
||||||
float Rhum(float t, float td);
|
float Rhum(float t, float td);
|
||||||
|
|||||||
21
src/main.c
21
src/main.c
@@ -110,8 +110,8 @@ static int Init(void)
|
|||||||
|
|
||||||
static void Update(void)
|
static void Update(void)
|
||||||
{
|
{
|
||||||
float t[3], rh[3];
|
float t[6], rh[3];
|
||||||
float adct[3];
|
word raw;
|
||||||
|
|
||||||
Info("Reading sensor values...");
|
Info("Reading sensor values...");
|
||||||
|
|
||||||
@@ -124,13 +124,18 @@ static void Update(void)
|
|||||||
I2C_SetChannel(AHT03);
|
I2C_SetChannel(AHT03);
|
||||||
I2C_AHT20_Read(&t[2], &rh[2]);
|
I2C_AHT20_Read(&t[2], &rh[2]);
|
||||||
|
|
||||||
adct[0] = I2C_ADS1115_ReadThermistor(ADS01);
|
raw = I2C_ADS1115_ReadRaw(ADS01);
|
||||||
adct[1] = I2C_ADS1115_ReadThermistor(ADS02);
|
t[3] = SteinhartHart(Resistance(raw));
|
||||||
adct[2] = I2C_ADS1115_ReadThermistor(ADS03);
|
|
||||||
|
|
||||||
Info("T1=%.2fC, RH1=%.2f%%, ADCT1=%.2fC", t[0], rh[0], adct[0]);
|
raw = I2C_ADS1115_ReadRaw(ADS02);
|
||||||
Info("T2=%.2fC, RH2=%.2f%%, ADCT2=%.2fC", t[1], rh[1], adct[1]);
|
t[4] = SteinhartHart(Resistance(raw));
|
||||||
Info("T3=%.2fC, RH3=%.2f%%, ADCT3=%.2fC", t[2], rh[2], adct[2]);
|
|
||||||
|
raw = I2C_ADS1115_ReadRaw(ADS03);
|
||||||
|
t[5] = SteinhartHart(Resistance(raw));
|
||||||
|
|
||||||
|
Info("T1=%.2fC, RH1=%.2f%%, NT1=%.2fC", t[0], rh[0], t[3]);
|
||||||
|
Info("T2=%.2fC, RH2=%.2f%%, NT2=%.2fC", t[1], rh[1], t[4]);
|
||||||
|
Info("T3=%.2fC, RH3=%.2f%%, NT3=%.2fC", t[2], rh[2], t[5]);
|
||||||
|
|
||||||
// TODO: Implement state machine
|
// TODO: Implement state machine
|
||||||
// TODO: Handle serial commands
|
// TODO: Handle serial commands
|
||||||
|
|||||||
Reference in New Issue
Block a user