From a9f201b0619bb901f9a79b38109d905d364b1aa4 Mon Sep 17 00:00:00 2001 From: Leon Krieg Date: Sun, 15 Sep 2024 22:12:23 +0200 Subject: [PATCH] Poll ADC mode bit until conversion has finished --- src/bus/i2c.c | 44 ++++++++++++++++++++++++++++++++++---------- src/main.c | 17 ++++++----------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/bus/i2c.c b/src/bus/i2c.c index 94b7cad..789e131 100644 --- a/src/bus/i2c.c +++ b/src/bus/i2c.c @@ -21,6 +21,7 @@ // TODO: Error handling and recovery besides watchdog timer. // TODO: Add more documentation from the atmel data sheet. +// TODO: ADS1115 continuous mode instead of single-shot? // TODO: Implement TWI_vect ISR? This may not actually be // much better than the blocking approach. @@ -31,6 +32,7 @@ static void I2C_AHT20_Trigger(void); static int I2C_ADS1115_WriteRegister(byte reg, word data); static word I2C_ADS1115_ReadRegister(byte reg); +static bool I2C_ADS1115_IsReady(void); int I2C_Init(void) { @@ -464,10 +466,21 @@ static word I2C_ADS1115_ReadRegister(byte reg) return data[0] << 8 | data[1]; } +static bool I2C_ADS1115_IsReady(void) +{ + word reg; + + Sleep(20); + + reg = I2C_ADS1115_ReadRegister(0x01); + + return reg & BIT(15); +} + word I2C_ADS1115_Read(int channel) { word config; - word rate, gain, mux, os; + word os, mode, rate, gain, mux; // Operational status or single-shot conversion // start: This bit determines the operational @@ -482,7 +495,15 @@ word I2C_ADS1115_Read(int channel) // 0 : Device is performing a conversion // 1 : Device is not performing a conversion - os = 0x8000; // Start single | 10000000 00000000 + os = 0x8000; // Start single | 10000000 00000000 + + // Device operating mode: This bit controls the + // operating mode. + + // 0 : Continuous-conversion mode + // 1 : Single-shot mode or power-down state + + mode = 0x0100; // Single-shot | 00000001 00000000 // Data rate: These bits control the data rate setting. @@ -495,7 +516,7 @@ word I2C_ADS1115_Read(int channel) // 110 | 475 SPS // 111 | 860 SPS - rate = 0x0080; // 128 SPS | 00000000 10000000 + rate = 0x0080; // 128 SPS | 00000000 10000000 // Programmable gain amplifier configuration: These // bits set the FSR of the programmable gain amplifier. @@ -509,7 +530,7 @@ word I2C_ADS1115_Read(int channel) // 110 | ±0.256 V // 111 | ±0.256 V - gain = 0x0000; // 6.144 V | 00000100 00000000 + gain = 0x0000; // 6.144 V | 00000100 00000000 // Input multiplexer configuration: These bits // configure the input multiplexer. @@ -525,18 +546,21 @@ word I2C_ADS1115_Read(int channel) mux = 0; if (channel == ADS01) - mux = 0x4000; // | 01000000 00000000 + mux = 0x4000; // | 01000000 00000000 else if (channel == ADS02) - mux = 0x5000; // | 01010000 00000000 + mux = 0x5000; // | 01010000 00000000 else if (channel == ADS03) - mux = 0x6000; // | 01100000 00000000 + mux = 0x6000; // | 01100000 00000000 else if (channel == ADS04) - mux = 0x7000; // | 01110000 00000000 + mux = 0x7000; // | 01110000 00000000 - // Single-shot conversion, active low, continous mode - config = os | rate | gain | mux; + // Single-shot conversion, active low + config = os | mode | rate | gain | mux; I2C_ADS1115_WriteRegister(0x01, config); + // Wait until conversion finished + while (!I2C_ADS1115_IsReady()); + return I2C_ADS1115_ReadRegister(0x00); } diff --git a/src/main.c b/src/main.c index df250b1..78a87a5 100644 --- a/src/main.c +++ b/src/main.c @@ -60,7 +60,7 @@ static int Init(void) PWM_Init(); MOS_Enable(MOS03); // Lights - // MOS_Enable(MOS01); // Peltier + MOS_Enable(MOS01); // Peltier // MOS_Disable(MOS02); // Heating // Only FAN01 and FAN02 are receiving the correct @@ -73,7 +73,7 @@ static int Init(void) // complicated so it might be worth it to switch to // something like an ATmega328PB. - PWM_SetValue(FAN01, 50); // Fan Peltier Hot side + PWM_SetValue(FAN01, 20); // Fan Peltier Hot side PWM_SetValue(FAN02, 50); // Fan Peltier Cold Side // PWM_SetValue(FAN03, 20); // Fan Heating @@ -99,7 +99,7 @@ static void Update(void) float temp[3], rh[3]; float adct[3]; - // Info("Reading sensor values..."); + Info("Reading sensor values..."); I2C_SetChannel(AHT01); I2C_AHT20_Read(&temp[0], &rh[0]); @@ -110,18 +110,13 @@ static void Update(void) I2C_SetChannel(AHT03); I2C_AHT20_Read(&temp[2], &rh[2]); - 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("ADCT1=%.2fC, ADCT2=%.2fC", adct[0], adct[1]); - Info("ADCT3=%.2fC", adct[2]); + Info("TEMP1=%.2fC, RH1=%.2f%% ADCT1=%.2fC", temp[0], rh[0], adct[0]); + Info("TEMP2=%.2fC, RH2=%.2f%% ADCT2=%.2fC", temp[1], rh[1], adct[1]); + Info("TEMP3=%.2fC, RH3=%.2f%% ADCT3=%.2fC", temp[2], rh[2], adct[2]); // TODO: Implement state machine