Fertirrega_v6 AD5934 frequency at 2.5kHz

This commit is contained in:
2026-07-24 18:03:46 +01:00
parent c215488ec2
commit e65f787c34
27 changed files with 11159 additions and 10676 deletions
+68 -12
View File
@@ -87,10 +87,14 @@ extern "C" {
// Values for frequency counts = (freq*2^27)/(1MHz/16) // Values for frequency counts = (freq*2^27)/(1MHz/16)
#define AD5934_FREQ_4K882HZ 0x009FF92F // 4.882kHz
#define AD5934_FREQ_2K5HZ 0x0051EB86 // 2.5kHz
#define AD5934_FREQ_1K953HZ 0x003FFEF3 // 1.953kHz
#define AD5934_FREQ_1K590HZ 0x003419E3 // 1.59kHz #define AD5934_FREQ_1K590HZ 0x003419E3 // 1.59kHz
#define AD5934_FREQ_0HZ 0x00000000 // 0Hz #define AD5934_FREQ_0HZ 0x00000000 // 0Hz
#define AD5934_STEP_FREQ_0 0x0000 // 0 passos #define AD5934_STEP_FREQ_0 0x0000 // 0 passos
#define AD5934_SETTLING_TIME_0S01 0x000C // 0,01s //#define AD5934_SETTLING_TIME_0S01 0x000C // 0,01s
#define AD5934_SETTLING_TIME_0S01 0x0080
/*****************************************************************************/ /*****************************************************************************/
/**************************** Command Codes **********************************/ /**************************** Command Codes **********************************/
@@ -122,7 +126,7 @@ extern "C" {
#define AD5934_CH_EC_10MS 0x21 #define AD5934_CH_EC_10MS 0x21
#define AD5934_CH_EC_5MS 0x22 #define AD5934_CH_EC_5MS 0x22
*/ */
/*
#define AD5934_CH_REF100R_LOW_GAIN 0x09 #define AD5934_CH_REF100R_LOW_GAIN 0x09
#define AD5934_CH_REF100R_MID_GAIN 0x0A #define AD5934_CH_REF100R_MID_GAIN 0x0A
#define AD5934_CH_REF100R_HIGH_GAIN 0x0C #define AD5934_CH_REF100R_HIGH_GAIN 0x0C
@@ -138,7 +142,7 @@ extern "C" {
#define AD5934_CH_EC_LOW_GAIN 0x81 #define AD5934_CH_EC_LOW_GAIN 0x81
#define AD5934_CH_EC_MID_GAIN 0x82 #define AD5934_CH_EC_MID_GAIN 0x82
#define AD5934_CH_EC_HIGH_GAIN 0x84 #define AD5934_CH_EC_HIGH_GAIN 0x84
*/
#define AD5934_LOW_GAIN_BASE 0x01 #define AD5934_LOW_GAIN_BASE 0x01
#define AD5934_MID_GAIN_BASE 0x02 #define AD5934_MID_GAIN_BASE 0x02
#define AD5934_HIGH_GAIN_BASE 0x04 #define AD5934_HIGH_GAIN_BASE 0x04
@@ -161,9 +165,11 @@ extern "C" {
#define AD5934_RTD_A 3.9083e-3f #define AD5934_RTD_A 3.9083e-3f
#define AD5934_RTD_B (-5.775e-7f) #define AD5934_RTD_B (-5.775e-7f)
#define AD5934_TEMP_AVERAGES 8 #define AD5934_TEMP_AVERAGES 16
#define AD5934_EC_AVERAGES 8 #define AD5934_EC_AVERAGES 16
#define AD5934_EC_ALPHA_PER_C 0.02f
#define AD5934_EC_TEMP_REF_C 25.0f
union Bytes2Int union Bytes2Int
{ {
@@ -183,13 +189,59 @@ union Short2Long
uint32_t number; uint32_t number;
}; };
extern int16_t temperature_dut_samples[AD5934_TEMP_AVERAGES][2]; typedef enum {
extern int16_t temperature_ref_samples[AD5934_TEMP_AVERAGES][2]; AD5934_CH_REF100R_LOW_GAIN = 0,
AD5934_CH_REF100R_MID_GAIN,
AD5934_CH_REF100R_HIGH_GAIN,
AD5934_CH_REF1K_LOW_GAIN,
AD5934_CH_REF1K_MID_GAIN,
AD5934_CH_REF1K_HIGH_GAIN,
AD5934_CH_REF10K_LOW_GAIN,
AD5934_CH_REF10K_MID_GAIN,
AD5934_CH_REF10K_HIGH_GAIN,
AD5934_CH_RTD_LOW_GAIN,
AD5934_CH_RTD_MID_GAIN,
AD5934_CH_RTD_HIGH_GAIN,
AD5934_CH_EC_LOW_GAIN,
AD5934_CH_EC_MID_GAIN,
AD5934_CH_EC_HIGH_GAIN,
AD5934_CH_MAX // Guarda automaticamente o número total de canais (15)
} AD5934_Channel_t;
static const uint8_t ADG715_Channel_Map[AD5934_CH_MAX] = {
[AD5934_CH_REF100R_LOW_GAIN] = (ADG715_SW1 | ADG715_SW4),
[AD5934_CH_REF100R_MID_GAIN] = (ADG715_SW2 | ADG715_SW4),
[AD5934_CH_REF100R_HIGH_GAIN] = (ADG715_SW3 | ADG715_SW4),
[AD5934_CH_REF1K_LOW_GAIN] = (ADG715_SW1 | ADG715_SW5),
[AD5934_CH_REF1K_MID_GAIN] = (ADG715_SW2 | ADG715_SW5),
[AD5934_CH_REF1K_HIGH_GAIN] = (ADG715_SW3 | ADG715_SW5),
[AD5934_CH_REF10K_LOW_GAIN] = (ADG715_SW1 | ADG715_SW6),
[AD5934_CH_REF10K_MID_GAIN] = (ADG715_SW2 | ADG715_SW6),
[AD5934_CH_REF10K_HIGH_GAIN] = (ADG715_SW3 | ADG715_SW6),
[AD5934_CH_RTD_LOW_GAIN] = (ADG715_SW1 | ADG715_SW7),
[AD5934_CH_RTD_MID_GAIN] = (ADG715_SW2 | ADG715_SW7),
[AD5934_CH_RTD_HIGH_GAIN] = (ADG715_SW3 | ADG715_SW7),
[AD5934_CH_EC_LOW_GAIN] = (ADG715_SW1 | ADG715_SW8),
[AD5934_CH_EC_MID_GAIN] = (ADG715_SW2 | ADG715_SW8),
[AD5934_CH_EC_HIGH_GAIN] = (ADG715_SW3 | ADG715_SW8)
};
extern int16_t temperature_dut_samples[2][AD5934_TEMP_AVERAGES];
extern int16_t temperature_ref_samples[2][AD5934_TEMP_AVERAGES];
extern float temperature_display[AD5934_TEMP_AVERAGES]; extern float temperature_display[AD5934_TEMP_AVERAGES];
extern int16_t ec_dut_samples[AD5934_EC_AVERAGES][2]; extern int16_t ec_dut_samples[2][AD5934_EC_AVERAGES];
extern int16_t ec_ref1_samples[AD5934_EC_AVERAGES][2]; extern int16_t ec_ref1_samples[2][AD5934_EC_AVERAGES];
extern int16_t ec_ref2_samples[AD5934_EC_AVERAGES][2]; extern int16_t ec_ref2_samples[2][AD5934_EC_AVERAGES];
extern float ec_display[AD5934_EC_AVERAGES]; extern float ec_display[AD5934_EC_AVERAGES];
extern float ec_temp_dut[AD5934_EC_AVERAGES]; extern float ec_temp_dut[AD5934_EC_AVERAGES];
@@ -211,7 +263,9 @@ uint32_t AD5934_Sweep(void);
void AD5934_RestartSweep(void); void AD5934_RestartSweep(void);
float AD5934_GetTemperature(void); float AD5934_Get_Ref_Resistance(void);
float AD5934_GetTemperature(float mag_ref);
float AD5934_GetImpedance(float temperature_dut); float AD5934_GetImpedance(float temperature_dut);
@@ -221,7 +275,9 @@ float AD5934_Round_Float_Precision(float value, uint8_t number_of_decimals);
float AD5934_Linear_Correction(float raw_value); float AD5934_Linear_Correction(float raw_value);
float AD5934_Get_Target_Conductivity(float temp); float AD5934_EC_Compensate_To_25C(float ec_raw_uScm, float temp_C);
float AD5934_EC_Calibrate_Temperature(float temp_C);
void ADG715_SetRegisterValue(char value); void ADG715_SetRegisterValue(char value);
+6 -4
View File
@@ -13,6 +13,7 @@
#define INC_ADS1015_DRIVER_H_ #define INC_ADS1015_DRIVER_H_
#include <stdint.h> #include <stdint.h>
#include <math.h>
#include "main.h" // Assuming HAL is included via main.h #include "main.h" // Assuming HAL is included via main.h
#include "stm32f1xx_hal.h" #include "stm32f1xx_hal.h"
#include "flash_manager.h" #include "flash_manager.h"
@@ -125,9 +126,9 @@ extern "C" {
#define ADS1015_KELVIN_OFFSET 273.15f // Constante de conversão Kelvin #define ADS1015_KELVIN_OFFSET 273.15f // Constante de conversão Kelvin
#define ADS1015_ADC_MAX 4095.0f #define ADS1015_ADC_MAX 4095.0f
#define ADS1015_ADC_VREF 3.3f #define ADS1015_ADC_VREF 1024.0f //1.024V in mV
#define PH_DELTA_CALIB 3.0f // Difference between pH 7 and pH 4 used in calibration #define PH_DELTA_CALIB 3.0f // Difference between pH 7 and pH 4 used in calibration
#define ADS1015_PH_AVERAGES 8 #define ADS1015_PH_AVERAGES 16
#define ADS1015_TEMPERATURE_ROW 0 #define ADS1015_TEMPERATURE_ROW 0
#define ADS1015_PH_4_BUFFER_ROW 1 #define ADS1015_PH_4_BUFFER_ROW 1
@@ -149,7 +150,7 @@ typedef enum {
extern float ph_averages[ADS1015_PH_AVERAGES]; extern float ph_dut_samples[ADS1015_PH_AVERAGES];
@@ -171,9 +172,10 @@ void ADSstartComparator_SingleEnded(ADS1015_I2C* i2c, uint8_t channel, int16_t
int16_t ADSgetLastConversionResults(); int16_t ADSgetLastConversionResults();
void ADSsetGain(ADS1015_I2C* i2c, adsGain_t gain); void ADSsetGain(ADS1015_I2C* i2c, adsGain_t gain);
adsGain_t ADSgetGain(ADS1015_I2C* i2c); adsGain_t ADSgetGain(ADS1015_I2C* i2c);
float ADSCalculate_ph_Volts(void); float ADSCalculate_ph_mV(void);
float ADSCalculate_ph_Compensated(float temp_dut); float ADSCalculate_ph_Compensated(float temp_dut);
float ADSCalculate_ph_Uncompensated(void); float ADSCalculate_ph_Uncompensated(void);
float ADSinterpolate_ph(float temp_dut, uint8_t row_index); float ADSinterpolate_ph(float temp_dut, uint8_t row_index);
float ADSRound_Float_Precision(float value, uint8_t number_of_decimals);
#endif /* INC_ADS1015_DRIVER_H_ */ #endif /* INC_ADS1015_DRIVER_H_ */
+7 -4
View File
@@ -27,14 +27,17 @@
typedef struct __attribute__((packed, aligned(4))) typedef struct __attribute__((packed, aligned(4)))
{ {
uint32_t magic_number; // 4 bytes (Validação) uint32_t magic_number; // 4 bytes (Validação)
float ph4_volts; // 4 bytes float ph4_mV; // 4 bytes
float ph7_volts; // 4 bytes float ph7_mV; // 4 bytes
float ph_temperature; // 4 bytes
float ph_slope_mV; // 4 bytes
float ph7_real; // 4 bytes
float ec1413_mag; // 4 bytes float ec1413_mag; // 4 bytes
float ec0_mag; // 4 bytes float ec0_mag; // 4 bytes
float temperature_value; // 4 bytes float ec_factor; // 4 bytes
uint8_t PT100_PT1000_switch; // 1 byte uint8_t PT100_PT1000_switch; // 1 byte
uint8_t EC10mS_EC5mS_switch; // 1 byte uint8_t EC10mS_EC5mS_switch; // 1 byte
uint8_t reserved[998]; // Preenchimento para completar 1024 bytes (1KB) uint8_t reserved[986]; // Preenchimento para completar 1024 bytes (1KB)
} FlashPage_t; } FlashPage_t;
extern FlashPage_t flash_data; extern FlashPage_t flash_data;
+7 -6
View File
@@ -127,12 +127,13 @@ void Error_Handler(void);
/* USER CODE BEGIN Private defines */ /* USER CODE BEGIN Private defines */
#define STATE_RUNNING_OK 0x00 #define STATE_RUNNING_OK 0x00
#define STATE_SETUP_CALIBRATION 0x01 #define STATE_NO_SETUP_CALIBRATION 0x01
#define STATE_RS485_SUPPLY_FAULT 0x02 #define STATE_PH4_DRY_EC_CALIBRATION 0x02
#define STATE_PH_SUPPLY_FAULT 0x03 #define STATE_PH7_WET_EC_CALIBRATION 0x03
#define STATE_EC_RTD_SUPPLY_FAULT 0x04 #define STATE_RS485_SUPPLY_FAULT 0x04
#define STATE_NO_SETUP_CALIBRATION 0x05 #define STATE_PH_SUPPLY_FAULT 0x05
#define STATE_HIGH_AMBIENT_TEMPERATURE 0x06 #define STATE_EC_RTD_SUPPLY_FAULT 0x06
#define STATE_HIGH_AMBIENT_TEMPERATURE 0x07
extern uint8_t main_state; extern uint8_t main_state;
/* USER CODE END Private defines */ /* USER CODE END Private defines */
+171 -156
View File
@@ -11,12 +11,12 @@
#include "ad5934_driver.h" #include "ad5934_driver.h"
int16_t temperature_dut_samples[AD5934_TEMP_AVERAGES][2]={{0},{0}}; int16_t temperature_dut_samples[2][AD5934_TEMP_AVERAGES]={{0},{0}};
int16_t temperature_ref_samples[AD5934_TEMP_AVERAGES][2]={{0},{0}}; int16_t temperature_ref_samples[2][AD5934_TEMP_AVERAGES]={{0},{0}};
float temperature_display[AD5934_TEMP_AVERAGES] = {0}; float temperature_display[AD5934_TEMP_AVERAGES] = {0};
int16_t ec_dut_samples[AD5934_EC_AVERAGES][2]={{0},{0}}; int16_t ec_dut_samples[2][AD5934_EC_AVERAGES]={{0},{0}};
float ec_display[AD5934_EC_AVERAGES] = {0}; float ec_display[AD5934_EC_AVERAGES] = {0};
/****************************************************************************** /******************************************************************************
@@ -142,7 +142,7 @@ void AD5934_Init(void)
AD5934_SetRegisterValue(AD5934_CONTROL_REG_LB, (AD5934_CONTROL_FUNCTION(AD5934_RESET)), 1); AD5934_SetRegisterValue(AD5934_CONTROL_REG_LB, (AD5934_CONTROL_FUNCTION(AD5934_RESET)), 1);
// Configure starting frequency // Configure starting frequency
AD5934_SetRegisterValue(AD5934_START_FREQ_REG_LB, AD5934_FREQ_1K590HZ, 3); AD5934_SetRegisterValue(AD5934_START_FREQ_REG_LB, AD5934_FREQ_2K5HZ, 3);
// Configure frequency increment step // Configure frequency increment step
AD5934_SetRegisterValue(AD5934_FREQ_INCR_REG_LB, AD5934_FREQ_0HZ, 3); AD5934_SetRegisterValue(AD5934_FREQ_INCR_REG_LB, AD5934_FREQ_0HZ, 3);
@@ -165,22 +165,22 @@ void AD5934_Init(void)
void AD5934_RestartSweep(void) void AD5934_RestartSweep(void)
{ {
// Place AD5934 in standby // Place AD5934 in standby
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_STANDBY) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X5)), 1); AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_STANDBY) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
// Initialize starting frequency, Start frequency sweep, standby // Initialize starting frequency, Start frequency sweep, standby
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, ((AD5934_CONTROL_FUNCTION(AD5934_INIT_START_FREQ)) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X5)), 1); AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, ((AD5934_CONTROL_FUNCTION(AD5934_INIT_START_FREQ)) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
// Disable Internal Reset State // Disable Internal Reset State
AD5934_SetRegisterValue(AD5934_CONTROL_REG_LB, AD5934_CONTROL_FUNCTION(AD5934_RESERVED), 1); AD5934_SetRegisterValue(AD5934_CONTROL_REG_LB, AD5934_CONTROL_FUNCTION(AD5934_RESERVED), 1);
// Configure Range Output, PGA gain andPlace AD5934 in sweep // Configure Range Output, PGA gain andPlace AD5934 in sweep
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_START_FREQ_SWEEP) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X5)), 1); AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_START_FREQ_SWEEP) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
// Wait for data to be valid // Wait for data to be valid
AD5934_Wait_For_Data_Valid(); AD5934_Wait_For_Data_Valid();
// Power Down // Power Down
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_POWER_DOWN) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X5)), 1); AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_POWER_DOWN) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
} }
@@ -212,54 +212,44 @@ uint32_t AD5934_Sweep(void)
/****************************************************************************** /******************************************************************************
* @brief Calculate Temperature. * @brief Get Reference Resistance on Board.
* *
* @param channel - AD5934_CH_PT100 or AD5934_CH_PT1000. * @param channel - AD5934_CH_PT100 or AD5934_CH_PT1000.
* *
* @return impedance. * @return impedance.
******************************************************************************/ ******************************************************************************/
float AD5934_GetTemperature(void) float AD5934_Get_Ref_Resistance(void)
{ {
uint8_t i, ch_dut, ch_ref; uint8_t i;
uint32_t sample; uint32_t sample;
int32_t ref_sum[2], dut_sum[2]; int32_t ref_sum[2];
float real_ref,imag_ref, real_dut, imag_dut, ratio, discriminant, mag_dut, mag_ref, ratio_mag, impedance_dut, temperature_sum, gain_factor; float real_ref,imag_ref, real_dut, mag_ref;
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET) // OFF = PT1000, ON = PT100, PA7 has internal pull-up and switch connects to GND if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET) // OFF = PT1000, ON = PT100, PA7 has internal pull-up and switch connects to GND
{ ADG715_Update(AD5934_CH_REF100R_LOW_GAIN); // Set the Reference Resistor on board in the Analog Mux
ch_ref = AD5934_CH_REF100R_LOW_GAIN;
ch_dut = AD5934_CH_RTD_LOW_GAIN; //PT100
gain_factor = 100.0f;
}
else else
{ ADG715_Update(AD5934_CH_REF1K_MID_GAIN); // Set the Reference Resistor on board in the Analog Mux
ch_ref = AD5934_CH_REF1K_MID_GAIN;
ch_dut = AD5934_CH_RTD_MID_GAIN; //PT1000
gain_factor = 1000.0f;
}
ADG715_Update(ch_ref); // Set the Reference Resistor on board in the Analog Mux
HAL_Delay(2); //Wait a little
sample = AD5934_Sweep(); // Get Reference Resistor Values from ADC sample = AD5934_Sweep(); // Get Reference Resistor Values from ADC
// Move values in the vectors // Move values in the vectors
for (i = (AD5934_TEMP_AVERAGES-1); i > 0; i--) for (i = (AD5934_TEMP_AVERAGES-1); i > 0; i--)
{ {
temperature_ref_samples[i][0] = temperature_ref_samples[i-1][0]; //real temperature_ref_samples[0][i] = temperature_ref_samples[0][i-1]; //real
temperature_ref_samples[i][1] = temperature_ref_samples[i-1][1]; //imag temperature_ref_samples[1][i] = temperature_ref_samples[1][i-1]; //imag
} }
// Read real and imaginary data // Read real and imaginary data
temperature_ref_samples[0][0] = (int16_t)(sample & 0x0000FFFF); //real temperature_ref_samples[0][0] = (int16_t)(sample & 0x0000FFFF); //real
//temperature_ref_samples[0][1] = 0xFFFF-(((sample & 0xFFFF0000)>>16)); //imag //temperature_ref_samples[1][0] = 0xFFFF-(((sample & 0xFFFF0000)>>16)); //imag
temperature_ref_samples[0][1] = (int16_t)((sample & 0xFFFF0000)>>16); //imag temperature_ref_samples[1][0] = (int16_t)((sample & 0xFFFF0000)>>16); //imag
// Sum values in the vectors // Sum values in the vectors
for (i = 0, ref_sum[0]=0, ref_sum[1]=0; i < AD5934_TEMP_AVERAGES; i++) for (i = 0, ref_sum[0]=0, ref_sum[1]=0; i < AD5934_TEMP_AVERAGES; i++)
{ {
ref_sum[0] += (int32_t)temperature_ref_samples[i][0]; //real ref_sum[0] += (int32_t)temperature_ref_samples[0][i]; //real
ref_sum[1] += (int32_t)temperature_ref_samples[i][1]; //imag ref_sum[1] += (int32_t)temperature_ref_samples[1][i]; //imag
} }
real_ref = ((float)ref_sum[0])/((float)AD5934_TEMP_AVERAGES); real_ref = ((float)ref_sum[0])/((float)AD5934_TEMP_AVERAGES);
@@ -268,27 +258,54 @@ float AD5934_GetTemperature(void)
// Calculate gain factor impedance // Calculate gain factor impedance
mag_ref = sqrtf((real_ref * real_ref) + (imag_ref * imag_ref)); mag_ref = sqrtf((real_ref * real_ref) + (imag_ref * imag_ref));
ADG715_Update(ch_dut); return mag_ref;
HAL_Delay(2); }
/******************************************************************************
* @brief Calculate Temperature.
*
* @param channel - Magnitude of the Reference Resistor.
*
* @return impedance.
******************************************************************************/
float AD5934_GetTemperature(float mag_ref)
{
uint8_t i, ch_ref;
uint32_t sample;
int32_t dut_sum[2];
float real_dut, imag_dut, ratio, discriminant, mag_dut, ratio_mag, impedance_dut, temperature_sum, gain_factor, temp_result;
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7) == GPIO_PIN_SET) // OFF = PT1000, ON = PT100, PA7 has internal pull-up and switch connects to GND
{
ch_ref = AD5934_CH_RTD_LOW_GAIN; //PT100
gain_factor = AD5934_GAIN_FACTOR_100R;
}
else
{
ch_ref = AD5934_CH_RTD_MID_GAIN; //PT1000
gain_factor = AD5934_GAIN_FACTOR_1K;
}
ADG715_Update(ch_ref);
sample = AD5934_Sweep(); // Get PT100/PT1000 Values from ADC sample = AD5934_Sweep(); // Get PT100/PT1000 Values from ADC
for (i = (AD5934_TEMP_AVERAGES-1); i > 0; i--) for (i = (AD5934_TEMP_AVERAGES-1); i > 0; i--)
{ {
temperature_dut_samples[i][0] = temperature_dut_samples[i-1][0]; //real temperature_dut_samples[0][i] = temperature_dut_samples[0][i-1]; //real
temperature_dut_samples[i][1] = temperature_dut_samples[i-1][1]; //imag temperature_dut_samples[1][i] = temperature_dut_samples[1][i-1]; //imag
} }
// Read real and imaginary data // Read real and imaginary data
temperature_dut_samples[0][0] = (int16_t)(sample & 0x0000FFFF); //real temperature_dut_samples[0][0] = (int16_t)(sample & 0x0000FFFF); //real
//temperature_dut_samples[0][1] = 0xFFFF-(((sample & 0xFFFF0000)>>16)); //imag //temperature_dut_samples[0][1] = 0xFFFF-(((sample & 0xFFFF0000)>>16)); //imag
temperature_dut_samples[0][1] = (int16_t)((sample & 0xFFFF0000)>>16); //imag temperature_dut_samples[1][0] = (int16_t)((sample & 0xFFFF0000)>>16); //imag
for (i = 0, dut_sum[0]=0, dut_sum[1]=0; i < AD5934_TEMP_AVERAGES; i++) for (i = 0, dut_sum[0]=0, dut_sum[1]=0; i < AD5934_TEMP_AVERAGES; i++)
{ {
dut_sum[0] += (int32_t)temperature_dut_samples[i][0]; //real dut_sum[0] += (int32_t)temperature_dut_samples[0][i]; //real
dut_sum[1] += (int32_t)temperature_dut_samples[i][1]; //imag dut_sum[1] += (int32_t)temperature_dut_samples[1][i]; //imag
} }
real_dut = ((float)dut_sum[0])/((float)AD5934_TEMP_AVERAGES); real_dut = ((float)dut_sum[0])/((float)AD5934_TEMP_AVERAGES);
@@ -297,8 +314,8 @@ float AD5934_GetTemperature(void)
// Calculate magnitude // Calculate magnitude
mag_dut = sqrtf((real_dut * real_dut) + (imag_dut * imag_dut)); mag_dut = sqrtf((real_dut * real_dut) + (imag_dut * imag_dut));
for (i = (AD5934_TEMP_AVERAGES-1); i > 0; i--) //for (i = (AD5934_TEMP_AVERAGES-1); i > 0; i--)
temperature_display[i] = temperature_display[i-1]; //temperature_display[i] = temperature_display[i-1];
ratio_mag = mag_ref / mag_dut; ratio_mag = mag_ref / mag_dut;
@@ -313,18 +330,23 @@ float AD5934_GetTemperature(void)
// Calculate impedance discriminant with the ratio // Calculate impedance discriminant with the ratio
discriminant = (AD5934_RTD_A*AD5934_RTD_A)-(4.0f * AD5934_RTD_B * (1.0f - ratio)); discriminant = (AD5934_RTD_A*AD5934_RTD_A)-(4.0f * AD5934_RTD_B * (1.0f - ratio));
//temp_result = (-AD5934_RTD_A + sqrtf(discriminant)/(2.0f * AD5934_RTD_B));
return (AD5934_Round_Float_Precision(((-AD5934_RTD_A + sqrtf(discriminant))/(2.0f * AD5934_RTD_B)),2));
//return (AD5934_Round_Float_Precision(temp_result,1));
// Calculate new temperature with the discriminant // Calculate new temperature with the discriminant
temperature_display[0] = (-AD5934_RTD_A + sqrtf(discriminant))/(2.0f * AD5934_RTD_B); //temperature_display[0] = (-AD5934_RTD_A + sqrtf(discriminant))/(2.0f * AD5934_RTD_B);
// Sum of all temperatures // Sum of all temperatures
for (i = 0, temperature_sum=0.0f; i < AD5934_TEMP_AVERAGES; i++) // for (i = 0, temperature_sum=0.0f; i < AD5934_TEMP_AVERAGES; i++)
temperature_sum += temperature_display[i]; // temperature_sum += temperature_display[i];
// Is the temperature stable? // Is the temperature stable?
if(temperature_display[0]>0.0f && (abs(temperature_display[0]-temperature_display[AD5934_TEMP_AVERAGES-1])/temperature_display[0])<0.1f) //if(temperature_display[0]>0.0f && (abs(temperature_display[0]-temperature_display[AD5934_TEMP_AVERAGES-1])/temperature_display[0])<0.1f)
return(AD5934_Round_Float_Precision(temperature_sum/((float)AD5934_TEMP_AVERAGES),1)); // Sum / number of averages //return(AD5934_Round_Float_Precision(temperature_sum/((float)AD5934_TEMP_AVERAGES),1)); // Sum / number of averages
else //else
return 0.0f; //instable values return always 0 //return 0.0f; //instable values return always 0
} }
@@ -348,11 +370,11 @@ float AD5934_GetImpedance(float temperature_dut)
else else
ec_gain = AD5934_CH_EC_MID_GAIN; ec_gain = AD5934_CH_EC_MID_GAIN;
if((ec_gain != flash_data.EC10mS_EC5mS_switch) && (main_state != STATE_SETUP_CALIBRATION)) if((ec_gain != flash_data.EC10mS_EC5mS_switch) && (main_state != STATE_PH4_DRY_EC_CALIBRATION || main_state != STATE_PH7_WET_EC_CALIBRATION))
return -1.0f; // Fatal error because the gain used in calibration is different return -1.0f; // Fatal error because the gain used in calibration is different
ADG715_Update(ec_gain); ADG715_Update(ec_gain);
HAL_Delay(2); //HAL_Delay(5);
/* 2. Data Acquisition */ /* 2. Data Acquisition */
sample_dut = AD5934_Sweep(); sample_dut = AD5934_Sweep();
@@ -360,19 +382,21 @@ float AD5934_GetImpedance(float temperature_dut)
// Shift buffer for moving average // Shift buffer for moving average
for (i = (AD5934_EC_AVERAGES - 1); i > 0; i--) for (i = (AD5934_EC_AVERAGES - 1); i > 0; i--)
{ {
ec_dut_samples[i][0] = ec_dut_samples[i-1][0]; ec_dut_samples[0][i] = ec_dut_samples[0][i-1];
ec_dut_samples[i][1] = ec_dut_samples[i-1][1]; ec_dut_samples[1][i] = ec_dut_samples[1][i-1];
} }
// Deconstruct 32-bit sample into Real and Imaginary components // Deconstruct 32-bit sample into Real and Imaginary components
ec_dut_samples[0][0] = (float)(int16_t)(sample_dut & 0xFFFF); ec_dut_samples[0][0] = (float)(int16_t)(sample_dut & 0xFFFF);
ec_dut_samples[0][1] = (float)(int16_t)((sample_dut >> 16) & 0xFFFF); ec_dut_samples[1][0] = (float)(int16_t)((sample_dut >> 16) & 0xFFFF);
/* 3. Compute Averages */ /* 3. Compute Averages */
for (i = 0; i < AD5934_EC_AVERAGES; i++) for (i = 0; i < AD5934_EC_AVERAGES; i++)
{ {
dut_sum[0] += (int32_t)ec_dut_samples[i][0]; dut_sum[0] += (int32_t)ec_dut_samples[0][i];
dut_sum[1] += (int32_t)ec_dut_samples[i][1]; dut_sum[1] += (int32_t)ec_dut_samples[1][i];
} }
real_avg = (float)dut_sum[0] / (float)AD5934_EC_AVERAGES; real_avg = (float)dut_sum[0] / (float)AD5934_EC_AVERAGES;
@@ -384,7 +408,7 @@ float AD5934_GetImpedance(float temperature_dut)
/* 5. Calibration Logic Implementation */ /* 5. Calibration Logic Implementation */
// Mode: CALIBRATION SETUP (User is defining the reference magnitude) // Mode: CALIBRATION SETUP (User is defining the reference magnitude)
if(main_state == STATE_SETUP_CALIBRATION) if(main_state == STATE_PH4_DRY_EC_CALIBRATION || main_state == STATE_PH7_WET_EC_CALIBRATION)
{ {
return mag_dut; return mag_dut;
} }
@@ -393,7 +417,7 @@ float AD5934_GetImpedance(float temperature_dut)
{ {
slope = (AD5934_GAIN_FACTOR_1413US/(flash_data.ec1413_mag-flash_data.ec0_mag)); slope = (AD5934_GAIN_FACTOR_1413US/(flash_data.ec1413_mag-flash_data.ec0_mag));
return(AD5934_GAIN_FACTOR_1413US + (mag_dut - flash_data.ec1413_mag) * slope); return(AD5934_GAIN_FACTOR_1413US + (AD5934_EC_Compensate_To_25C(mag_dut,temperature_dut) - flash_data.ec1413_mag) * slope);
} }
else else
return 0.0f; // Calibration error fallback return 0.0f; // Calibration error fallback
@@ -476,52 +500,97 @@ float AD5934_Linear_Correction(float raw_value)
/** /**
* @brief Internal helper to interpolate conductivity from the temperature matrix. * @brief Temperature compensation with drift equal to 2%
* @param temp The current temperature in Celsius. * @param admittance raw in uS/cm
* @return Interpolated conductivity value in uS/cm. * @param temperature_celsius Temperature in degrees Celsius
* @return admittance compensated
*/ */
float AD5934_Get_Target_Conductivity(float temp) float AD5934_EC_Compensate_To_25C(float ec_raw_uScm, float temp_C)
{ {
/* Matrix: Row 0 = Temperature (ºC), Row 1 = Conductivity (uS/cm) */
const float matrix[2][12] = {
{5, 10, 15, 18, 20, 22, 25, 30, 35, 40, 45, 50},
{893, 1018, 1149, 1225, 1278, 1329, 1413, 1552, 1691, 1843, 1988, 2145}
};
// Boundary Check: Lower float factor = 1.0f + AD5934_EC_ALPHA_PER_C * (temp_C - AD5934_EC_TEMP_REF_C);
if (temp <= matrix[0][0])
temp = 5;
// Boundary Check: Upper if (factor < 0.1f)
if (temp >= matrix[0][11]) factor = 0.1f;
temp = 50;
// Linear Interpolation logic return (ec_raw_uScm / factor);
for (int i = 0; i < 11; i++)
{
if (temp >= matrix[0][i] && temp <= matrix[0][i+1])
{
float t0 = matrix[0][i];
float t1 = matrix[0][i+1];
float c0 = matrix[1][i];
float c1 = matrix[1][i+1];
// Formula: y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0))
return c0 + (temp - t0) * ((c1 - c0) / (t1 - t0));
}
}
return (matrix[1][6]); // Mid point Fallback
} }
/**
* @brief Calibrates EC sensor reading to 25°C reference point
* @param temp_C Temperature of the liquid in Celsius
* @return Temperature-compensated Correction factor value at 25°C reference
*/
float AD5934_EC_Calibrate_Temperature(float temp_C)
{
// Calibration data points for standard solution (1413 uS/cm)
const float temps[] = {5, 10, 15, 18, 20, 22, 25, 30, 35, 40, 45, 50};
const float conductivities[] = {893, 1018, 1149, 1225, 1278, 1329, 1413, 1552, 1691, 1843, 1988, 2145};
// Find the two nearest temperature points for interpolation
int32_t temp_index = -1;
for (int i = 0; i < 12; i++)
{
if (temps[i] >= temp_C)
{
temp_index = i;
break;
}
}
// Handle boundary cases
if (temp_index == -1) {
// Temperature higher than max point (50°C)
temp_index = 10;
} else if (temp_index == 0) {
// Temperature lower than min point (5°C)
temp_index = 0;
}
// Interpolate conductivity at measured temperature
float temp1 = temps[temp_index - 1];
float temp2 = temps[temp_index];
float cond1 = conductivities[temp_index - 1];
float cond2 = conductivities[temp_index];
// Linear interpolation to get conductivity at measured temperature
float interpolated_cond = cond1 + (cond2 - cond1) * (temp_C - temp1) / (temp2 - temp1);
// Return real conductivity at the temperature
return(interpolated_cond/1413.0f);
}
/**
* @brief Calibrate AD5934 using dry probe and standard solution
*
* @param dry_probe_real Raw real value from dry probe measurement
* @param dry_probe_imag Raw imaginary value from dry probe measurement
* @param standard_real Raw real value from 1413 uS/cm standard solution
* @param standard_imag Raw imaginary value from 1413 uS/cm standard solution
* @return float Calibration factor for converting raw readings to admittance
*/
float AD5934_Calibrate(float dry_probe_real, float dry_probe_imag, float standard_real, float standard_imag)
{
// Calculate magnitude of dry probe reading
float dry_magnitude = sqrtf(dry_probe_real * dry_probe_real + dry_probe_imag * dry_probe_imag);
// Calculate magnitude of standard solution reading
float standard_magnitude = sqrtf(standard_real * standard_real + standard_imag * standard_imag);
// Calculate calibration factor based on known standard (1413 uS/cm)
// This assumes the standard provides a known conductance value
float calibration_factor = 1413.0f / standard_magnitude;
return calibration_factor;
}
/***************************************************************************** /*****************************************************************************
* ADG715 * ADG715
***************************************************************************** *****************************************************************************
* @brief Writes data into a register. * @brief Writes data into a register.
* *
* @param registerAddress - Address of the register. * @param value - Data value to write.
* @param registerValue - Data value to write.
* @param bytesNumber - Number of bytes.
* *
* @return None. * @return None.
*******************************************************************************/ *******************************************************************************/
@@ -549,78 +618,24 @@ void ADG715_ResetChannels(void)
/****************************************************************************** /******************************************************************************
* @brief Update Channels on the ADG715 and stop-start AD5934. * @brief Update Channels on the ADG715 and stop-start AD5934.
* *
* @param: channel = AD5934_CH_REF_100R, AD5934_CH_REF_1K, AD5934_CH_REF_10K, AD5934_CH_PT100, AD5934_CH_PT1000 or AD5934_CH_EC * @param: channel = AD5934_CH_REF_100R, AD5934_CH_REF_1K, AD5934_CH_REF_10K, AD5934_CH_PT100, AD5934_CH_PT1000, AD5934_CH_EC, ...
* *
* @return none. * @return none.
******************************************************************************/ ******************************************************************************/
void ADG715_Update(uint8_t channel) void ADG715_Update(AD5934_Channel_t channel)
{ {
HAL_StatusTypeDef status; // Garante que o índice recebido não ultrapassa os limites do vetor
if (channel >= AD5934_CH_MAX)
return;
// Disconnect all Analog Switches // Envia o byte combinado via I2C (Make-before-break nativo por barramento)
ADG715_ResetChannels(); ADG715_SetRegisterValue(ADG715_Channel_Map[channel]);
// Set the pair of connections // Gestão inteligente do delay de acomodação
if(channel == AD5934_CH_REF100R_LOW_GAIN) if (channel >= AD5934_CH_EC_LOW_GAIN)
{ HAL_Delay(20); // Canais de Condutividade Elétrica (CE) necessitam de maior estabilização química
ADG715_SetChannels(ADG715_SW1, ADG715_SW4); // Rf = 150R, Ch = Ref_100R else
} HAL_Delay(10); // Resistores puros e RTD estabilizam mais rapidamente
else if(channel == AD5934_CH_REF100R_MID_GAIN)
{
ADG715_SetChannels(ADG715_SW2, ADG715_SW4); // Rf = 1k5, Ch = Ref_100R
}
else if(channel == AD5934_CH_REF100R_HIGH_GAIN)
{
ADG715_SetChannels(ADG715_SW3, ADG715_SW4); // Rf = 6k2, Ch = Ref_100R
}
else if(channel == AD5934_CH_REF1K_LOW_GAIN)
{
ADG715_SetChannels(ADG715_SW1, ADG715_SW5); // Rf = 150R, Ch = Ref_1k
}
else if(channel == AD5934_CH_REF1K_MID_GAIN)
{
ADG715_SetChannels(ADG715_SW2, ADG715_SW5); // Rf = 1k5, Ch = Ref_1k
}
else if(channel == AD5934_CH_REF1K_HIGH_GAIN)
{
ADG715_SetChannels(ADG715_SW3, ADG715_SW5); // Rf = 6k2, Ch = Ref_1k
}
else if(channel == AD5934_CH_REF10K_LOW_GAIN)
{
ADG715_SetChannels(ADG715_SW1, ADG715_SW6); // Rf = 150R, Ch = Ref_10k
}
else if(channel == AD5934_CH_REF10K_MID_GAIN)
{
ADG715_SetChannels(ADG715_SW2, ADG715_SW6); // Rf = 1k5, Ch = Ref_10k
}
else if(channel == AD5934_CH_REF10K_HIGH_GAIN)
{
ADG715_SetChannels(ADG715_SW3, ADG715_SW6); // Rf = 6k2, Ch = Ref_10k
}
else if(channel == AD5934_CH_RTD_LOW_GAIN)
{
ADG715_SetChannels(ADG715_SW1, ADG715_SW7); // Rf = 150R, Ch = RTD
}
else if(channel == AD5934_CH_RTD_MID_GAIN)
{
ADG715_SetChannels(ADG715_SW2, ADG715_SW7); // Rf = 1k5, Ch = RTD
}
else if(channel == AD5934_CH_RTD_HIGH_GAIN)
{
ADG715_SetChannels(ADG715_SW3, ADG715_SW7); // Rf = 6k2, Ch = RTD
}
else if(channel == AD5934_CH_EC_LOW_GAIN)
{
ADG715_SetChannels(ADG715_SW1, ADG715_SW8); // Rf = 150R, Ch = EC
}
else if(channel == AD5934_CH_EC_MID_GAIN)
{
ADG715_SetChannels(ADG715_SW2, ADG715_SW8); // Rf = 1k5, Ch = EC
}
else if(channel == AD5934_CH_EC_HIGH_GAIN)
{
ADG715_SetChannels(ADG715_SW3, ADG715_SW8); // Rf = 6k2, Ch = EC
}
} }
+37 -39
View File
@@ -271,7 +271,7 @@ int16_t ADSgetLastConversionResults(ADS1015_I2C *i2c) {
} }
} }
float ADSCalculate_ph_Volts(void) float ADSCalculate_ph_mV(void) // pH in mV
{ {
float ph_dut_sum; float ph_dut_sum;
uint8_t i; uint8_t i;
@@ -279,14 +279,12 @@ float ADSCalculate_ph_Volts(void)
for (i = (ADS1015_PH_AVERAGES-1); i > 0; i--) for (i = (ADS1015_PH_AVERAGES-1); i > 0; i--)
ph_dut_samples[i] = ph_dut_samples[i-1]; ph_dut_samples[i] = ph_dut_samples[i-1];
ph_dut_samples[0] = (((float)(2048 - ADSreadADC_Differential_0_1(&i2c)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX); // 1. Converter leitura bruta do ADC para tensão real (Volts) ph_dut_samples[0] = (((float)(ADSreadADC_Differential_0_1(&i2c)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX); // 1. Converter leitura bruta do ADC para tensão real (mV)
for (i = 0, ph_dut_sum=0; i < ADS1015_PH_AVERAGES; i++) for (i = 0, ph_dut_sum=0; i < ADS1015_PH_AVERAGES; i++)
ph_dut_sum += ph_dut_samples[i]; ph_dut_sum += ph_dut_samples[i];
ph_dut_sum /= ADS1015_PH_AVERAGES; return (ADSRound_Float_Precision((ph_dut_sum/ADS1015_PH_AVERAGES),2));
return (ph_dut_sum);
} }
@@ -301,42 +299,23 @@ float ADSCalculate_ph_Volts(void)
* *
* @return float Valor de pH calculado (0.0 a 14.0). * @return float Valor de pH calculado (0.0 a 14.0).
*/ */
float ADSCalculate_ph_Compensated(float temp_dut) float ADSCalculate_ph_Compensated(float temp_dut)
{ {
// 1. Converter leitura bruta do ADC para tensão real (Volts)
float v_measured = ((float)(2048 - ADSreadADC_Differential_0_1(&i2c)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX;
// 2. Calcular o Slope original (medido na temperatura da calibração) float dut_mV = ADSCalculate_ph_mV();
// Delta pH é fixo em 3.0 (de pH 7 para pH 4)
float delta_v_calib = flash_data.ph7_volts - flash_data.ph4_volts; float t_cal_k = flash_data.ph_temperature + 273.15f;
float t_dut_k = temp_dut + 273.15f;
float slope_dut = flash_data.ph_slope_mV * (t_dut_k / t_cal_k);
float ph_result = (flash_data.ph7_real + ((dut_mV - flash_data.ph7_mV) / slope_dut));
return (ADSRound_Float_Precision(ph_result,2));
if (delta_v_calib == 0.0f)
{
return 0.0f; // Proteção contra erro de calibração/divisão por zero
} }
float slope_at_calib = PH_DELTA_CALIB / delta_v_calib;
// 3. Calcular o Fator de Correção Térmica (Equação de Nernst)
float temp_k_now = temp_dut + ADS1015_KELVIN_OFFSET;
float temp_k_ref = flash_data.temperature_value + ADS1015_KELVIN_OFFSET;
// Fator: (T_atual / T_referencia)
float thermal_factor = temp_k_now / temp_k_ref;
/*
* 4. Cálculo Final do pH
* O Slope ajustado para a temperatura atual é: slope_at_calib / thermal_factor
* Fórmula: pH = pH_ref + (V_medido - V_ref_7) * Slope_ajustado
*/
float ph_result = 7.0f + ((v_measured - flash_data.ph7_volts) * (slope_at_calib / thermal_factor));
// 5. Clamping (Garantir limites físicos)
if (ph_result < 0.0f) ph_result = 0.0f;
if (ph_result > 14.0f) ph_result = 14.0f;
return ph_result;
}
/** /**
* @brief Calculates the pH value without temperature compensation. * @brief Calculates the pH value without temperature compensation.
@@ -361,7 +340,7 @@ float ADSCalculate_ph_Uncompensated(void)
* PH_DELTA_CALIB is a constant representing the pH difference between * PH_DELTA_CALIB is a constant representing the pH difference between
* calibration points (e.g., |7.0 - 4.0| = 3.0). * calibration points (e.g., |7.0 - 4.0| = 3.0).
*/ */
float delta_v_calib = flash_data.ph7_volts - flash_data.ph4_volts; float delta_v_calib = flash_data.ph7_mV - flash_data.ph4_mV;
/* Safety check: Prevent division by zero if calibration data is invalid */ /* Safety check: Prevent division by zero if calibration data is invalid */
if (delta_v_calib == 0.0f) if (delta_v_calib == 0.0f)
@@ -377,7 +356,7 @@ float ADSCalculate_ph_Uncompensated(void)
* Formula: pH = pH_ref + (V_measured - V_ref_7) * Slope * Formula: pH = pH_ref + (V_measured - V_ref_7) * Slope
* Where pH_ref is 7.0. * Where pH_ref is 7.0.
*/ */
float ph_result = 7.0f + ((v_measured - flash_data.ph7_volts) * slope_at_calib); float ph_result = 7.0f + ((v_measured - flash_data.ph7_mV) * slope_at_calib);
/* 4. Clamping (Ensure physical limits of the pH scale) */ /* 4. Clamping (Ensure physical limits of the pH scale) */
if (ph_result < 0.0f) if (ph_result < 0.0f)
@@ -410,8 +389,10 @@ float ADSinterpolate_ph(float temp_target, uint8_t row_index)
uint8_t i = 0; uint8_t i = 0;
/* Boundary Check: Clamp to first or last index if out of range */ /* Boundary Check: Clamp to first or last index if out of range */
if (temp_target <= lut_matrix_buffer_ph[0][0]) return lut_matrix_buffer_ph[row_index][0]; if (temp_target <= lut_matrix_buffer_ph[0][0])
if (temp_target >= lut_matrix_buffer_ph[0][ADS1015_PH_TEMP_INTER_POINTS-1]) return lut_matrix_buffer_ph[row_index][ADS1015_PH_TEMP_INTER_POINTS-1]; return lut_matrix_buffer_ph[row_index][0];
if (temp_target >= lut_matrix_buffer_ph[0][ADS1015_PH_TEMP_INTER_POINTS-1])
return lut_matrix_buffer_ph[row_index][ADS1015_PH_TEMP_INTER_POINTS-1];
/* Find interpolation interval */ /* Find interpolation interval */
while (i < (ADS1015_PH_TEMP_INTER_POINTS-1) && lut_matrix_buffer_ph[0][i+1] < temp_target) while (i < (ADS1015_PH_TEMP_INTER_POINTS-1) && lut_matrix_buffer_ph[0][i+1] < temp_target)
@@ -428,4 +409,21 @@ float ADSinterpolate_ph(float temp_target, uint8_t row_index)
return y0 + (temp_target - x0) * ((y1 - y0) / (x1 - x0)); return y0 + (temp_target - x0) * ((y1 - y0) / (x1 - x0));
} }
/**
* @brief Reduz a precisão decimal de um float através de truncamento.
*
* @param valor O valor float original.
* @param casas_decimais Quantidade de casas que devem permanecer após a vírgula.
* @return float O valor com as casas decimais excedentes removidas.
*/
float ADSRound_Float_Precision(float value, uint8_t number_of_decimals)
{
float multiply = 1.0f;
for (uint8_t i = 0; i < number_of_decimals; i++)
multiply *= 10.0f;
return roundf(value * multiply) / multiply;
}
+67 -28
View File
@@ -67,14 +67,16 @@ uint8_t rs485_text[6];
uint8_t newline[]={'\n','\0'}; uint8_t newline[]={'\n','\0'};
uint8_t doubleSpace[]={'_','_'}; uint8_t doubleSpace[]={'_','_','\0'};
uint8_t newline_ph[]={'_','p','H','\n','\0'}; uint8_t newline_ph[]={'_','p','H','\n','\0'};
uint8_t newline_admi[]={'_','u','S','\n','\0'}; uint8_t newline_admi[]={'_','u','S','\n','\0'};
uint8_t newline_temp[]={' ','°','C','\n','\0'}; uint8_t newline_temp[]={' ','°','C','\n','\0'};
uint8_t newline_imag[]={'_','O','h','m','\n','\0'}; uint8_t newline_imag[]={'_','O','h','m','\n','\0'};
uint8_t newline_485[]={'_','a','d','\n','\0'}; uint8_t newline_485[]={'_','a','d','\n','\0'};
uint8_t minus[]={'-',' '}; uint8_t minus[]={'-',' '};
uint8_t ad_t[]={'A','d',':',' ','\0'};
uint8_t ph_t[]={'p','H',':',' ','\0'};
uint8_t tm_t[]={'T','M',':',' ','\0'};
uint8_t main_state = STATE_RUNNING_OK; uint8_t main_state = STATE_RUNNING_OK;
uint8_t rs485_address=0; uint8_t rs485_address=0;
@@ -121,7 +123,7 @@ int main(void)
uint32_t previous_millis_red = 0; uint32_t previous_millis_red = 0;
uint32_t current_millis; uint32_t current_millis;
float temperature_RTD, admittance_EC, ph_compensated; float temperature_RTD, admittance_EC, refResistance, update_value, ph7_interp, ph4_interp, ph_compensated;
@@ -173,9 +175,11 @@ int main(void)
// Initialize RS-485 driver // Initialize RS-485 driver
rs485_init(); rs485_init();
ADS1015(&i2c, &hi2c1, ADS_ADDR_GND);
ADSsetGain(&i2c, GAIN_SIXTEEN);
ADS1015(&i2c, &hi2c1, ADS_ADDR_GND);
ADSsetGain(&i2c, GAIN_FOUR);
ADG715_ResetChannels();
// Start CE and RTD Measurement // Start CE and RTD Measurement
AD5934_Init(); AD5934_Init();
@@ -186,19 +190,28 @@ int main(void)
/* Infinite loop */ /* Infinite loop */
/* USER CODE BEGIN WHILE */ /* USER CODE BEGIN WHILE */
for(i=0;i<AD5934_TEMP_AVERAGES;i++) // Loop to get stability and get averages
{
refResistance = AD5934_Get_Ref_Resistance(); // On Board Resistor
temperature_RTD = AD5934_GetTemperature(refResistance); // Liquid Temperature is stored
admittance_EC = AD5934_GetImpedance(temperature_RTD);
ph_compensated = ADSCalculate_ph_Compensated(temperature_RTD);
}
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3) == GPIO_PIN_RESET) // When PB3 (with internal pull up) in the Prog Header is set to GND if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3) == GPIO_PIN_RESET) // When PB3 (with internal pull up) in the Prog Header is set to GND
{ {
main_state = STATE_SETUP_CALIBRATION; main_state = STATE_PH4_DRY_EC_CALIBRATION;
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET); // Red LED On HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET); // Red LED On
for(i=0;i<32;i++) // Loop to get stability and get averages for(i=0;i<(2*AD5934_TEMP_AVERAGES);i++) // Loop to get stability and get averages
{ {
flash_data.ph4_volts = ADSCalculate_ph_Volts(); flash_data.ph4_mV = ADSCalculate_ph_mV();
flash_data.temperature_value = AD5934_GetTemperature(); // Air Temperature is not stored, just used to calculate impedance temperature_RTD = AD5934_GetTemperature(refResistance); // Air Temperature is not used in the function
flash_data.ec0_mag = AD5934_GetImpedance(flash_data.temperature_value); // Dry Probe flash_data.ec0_mag = AD5934_GetImpedance(temperature_RTD); // Dry Probe
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == GPIO_PIN_SET) if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == GPIO_PIN_SET)
flash_data.EC10mS_EC5mS_switch = AD5934_CH_EC_HIGH_GAIN; // 5mS/cm option flash_data.EC10mS_EC5mS_switch = AD5934_CH_EC_HIGH_GAIN; // 5mS/cm option
else else
@@ -209,29 +222,50 @@ int main(void)
flash_data.PT100_PT1000_switch = AD5934_CH_RTD_MID_GAIN; //PT1000 option flash_data.PT100_PT1000_switch = AD5934_CH_RTD_MID_GAIN; //PT1000 option
} }
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET); // Green LED On
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3) == GPIO_PIN_RESET); while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3) == GPIO_PIN_RESET);
HAL_Delay(500); HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET); // Green LED On main_state = STATE_PH7_WET_EC_CALIBRATION;
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
for(i=0;i<32;i++) // Loop to get stability and get averages HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET); // Red LED On
for(i=0;i<(2*AD5934_TEMP_AVERAGES);i++) // Loop to get stability and get averages
{ {
flash_data.temperature_value = AD5934_GetTemperature(); // Liquid Temperature is stored temperature_RTD = AD5934_GetTemperature(refResistance); // Liquid Temperature is stored
flash_data.ph7_volts = ADSCalculate_ph_Volts(); flash_data.ec_factor = AD5934_EC_Calibrate_Temperature(temperature_RTD);
flash_data.ec1413_mag = AD5934_GetImpedance(flash_data.temperature_value); // Get the impedance of the reference liquid flash_data.ph7_mV = ADSCalculate_ph_mV();
Flash_Save_Page(&flash_data); // Store Calibration parameters in Flash flash_data.ec1413_mag = AD5934_GetImpedance(temperature_RTD)*flash_data.ec_factor; // Get the magnitude of the reference liquid and compensate it to 25ºC
} }
ph7_interp = ADSinterpolate_ph(temperature_RTD,ADS1015_PH_7_BUFFER_ROW);
ph4_interp = ADSinterpolate_ph(temperature_RTD,ADS1015_PH_4_BUFFER_ROW);
flash_data.ph_temperature = temperature_RTD;
flash_data.ph_slope_mV = (flash_data.ph7_mV - flash_data.ph4_mV) / (ph7_interp - ph4_interp);
flash_data.ph7_real = ph7_interp;
Flash_Save_Page(&flash_data); // Store Calibration parameters in Flash
HAL_Delay(500); HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET); // Green LED On HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET); // Green LED On
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET); // Red LED On HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
main_state = STATE_RUNNING_OK; main_state = STATE_RUNNING_OK;
} }
while (1) while (1)
{ {
@@ -256,15 +290,6 @@ int main(void)
} }
temperature_RTD = AD5934_GetTemperature();
FloatToString(tempString, temperature_RTD);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_temp, strlen((char*)newline_temp));
admittance_EC = AD5934_GetImpedance(temperature_RTD);
FloatToString(tempString, admittance_EC);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_admi, strlen((char*)newline_admi));
} }
@@ -283,12 +308,26 @@ int main(void)
} }
status1 = rs485_send_broadcast(tm_t, strlen((char*)tm_t));
temperature_RTD = AD5934_GetTemperature(refResistance);
FloatToString(tempString, temperature_RTD);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_temp, strlen((char*)newline_temp));
ph_compensated = ADSCalculate_ph_Uncompensated(); status1 = rs485_send_broadcast(ad_t, strlen((char*)ad_t));
admittance_EC = AD5934_GetImpedance(temperature_RTD);
FloatToString(tempString, admittance_EC);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_admi, strlen((char*)newline_admi));
status1 = rs485_send_broadcast(ph_t, strlen((char*)ph_t));
ph_compensated = 10*ADSCalculate_ph_mV();//ADSCalculate_ph_Compensated(temperature_RTD);
FloatToString(tempString, ph_compensated); FloatToString(tempString, ph_compensated);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1)); status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_ph, strlen((char*)newline_ph)); status1 = rs485_send_broadcast(newline_ph, strlen((char*)newline_ph));
status1 = rs485_send_broadcast(newline, strlen((char*)newline));
} }
@@ -4,13 +4,16 @@
../Core/Src/ad5934_driver.c:137:6:AD5934_Init 1 ../Core/Src/ad5934_driver.c:137:6:AD5934_Init 1
../Core/Src/ad5934_driver.c:165:6:AD5934_RestartSweep 1 ../Core/Src/ad5934_driver.c:165:6:AD5934_RestartSweep 1
../Core/Src/ad5934_driver.c:195:10:AD5934_Sweep 1 ../Core/Src/ad5934_driver.c:195:10:AD5934_Sweep 1
../Core/Src/ad5934_driver.c:221:7:AD5934_GetTemperature 11 ../Core/Src/ad5934_driver.c:221:7:AD5934_Get_Ref_Resistance 4
../Core/Src/ad5934_driver.c:338:7:AD5934_GetImpedance 8 ../Core/Src/ad5934_driver.c:272:7:AD5934_GetTemperature 5
../Core/Src/ad5934_driver.c:407:6:AD5934_Wait_For_Data_Valid 3 ../Core/Src/ad5934_driver.c:360:7:AD5934_GetImpedance 10
../Core/Src/ad5934_driver.c:442:7:AD5934_Round_Float_Precision 2 ../Core/Src/ad5934_driver.c:431:6:AD5934_Wait_For_Data_Valid 3
../Core/Src/ad5934_driver.c:467:7:AD5934_Linear_Correction 1 ../Core/Src/ad5934_driver.c:466:7:AD5934_Round_Float_Precision 2
../Core/Src/ad5934_driver.c:483:7:AD5934_Get_Target_Conductivity 6 ../Core/Src/ad5934_driver.c:491:7:AD5934_Linear_Correction 1
../Core/Src/ad5934_driver.c:529:6:ADG715_SetRegisterValue 1 ../Core/Src/ad5934_driver.c:508:7:AD5934_EC_Compensate_To_25C 2
../Core/Src/ad5934_driver.c:539:6:ADG715_SetChannels 1 ../Core/Src/ad5934_driver.c:524:7:AD5934_EC_Calibrate_Temperature 5
../Core/Src/ad5934_driver.c:544:6:ADG715_ResetChannels 1 ../Core/Src/ad5934_driver.c:573:7:AD5934_Calibrate 1
../Core/Src/ad5934_driver.c:556:6:ADG715_Update 16 ../Core/Src/ad5934_driver.c:598:6:ADG715_SetRegisterValue 1
../Core/Src/ad5934_driver.c:608:6:ADG715_SetChannels 1
../Core/Src/ad5934_driver.c:613:6:ADG715_ResetChannels 1
../Core/Src/ad5934_driver.c:625:6:ADG715_Update 3
Binary file not shown.
+13 -10
View File
@@ -4,13 +4,16 @@
../Core/Src/ad5934_driver.c:137:6:AD5934_Init 8 static ../Core/Src/ad5934_driver.c:137:6:AD5934_Init 8 static
../Core/Src/ad5934_driver.c:165:6:AD5934_RestartSweep 8 static ../Core/Src/ad5934_driver.c:165:6:AD5934_RestartSweep 8 static
../Core/Src/ad5934_driver.c:195:10:AD5934_Sweep 16 static ../Core/Src/ad5934_driver.c:195:10:AD5934_Sweep 16 static
../Core/Src/ad5934_driver.c:221:7:AD5934_GetTemperature 88 static ../Core/Src/ad5934_driver.c:221:7:AD5934_Get_Ref_Resistance 48 static
../Core/Src/ad5934_driver.c:338:7:AD5934_GetImpedance 56 static ../Core/Src/ad5934_driver.c:272:7:AD5934_GetTemperature 72 static
../Core/Src/ad5934_driver.c:407:6:AD5934_Wait_For_Data_Valid 24 static ../Core/Src/ad5934_driver.c:360:7:AD5934_GetImpedance 56 static
../Core/Src/ad5934_driver.c:442:7:AD5934_Round_Float_Precision 24 static ../Core/Src/ad5934_driver.c:431:6:AD5934_Wait_For_Data_Valid 24 static
../Core/Src/ad5934_driver.c:467:7:AD5934_Linear_Correction 24 static ../Core/Src/ad5934_driver.c:466:7:AD5934_Round_Float_Precision 24 static
../Core/Src/ad5934_driver.c:483:7:AD5934_Get_Target_Conductivity 144 static ../Core/Src/ad5934_driver.c:491:7:AD5934_Linear_Correction 24 static
../Core/Src/ad5934_driver.c:529:6:ADG715_SetRegisterValue 32 static ../Core/Src/ad5934_driver.c:508:7:AD5934_EC_Compensate_To_25C 24 static
../Core/Src/ad5934_driver.c:539:6:ADG715_SetChannels 16 static ../Core/Src/ad5934_driver.c:524:7:AD5934_EC_Calibrate_Temperature 152 static
../Core/Src/ad5934_driver.c:544:6:ADG715_ResetChannels 8 static ../Core/Src/ad5934_driver.c:573:7:AD5934_Calibrate 48 static
../Core/Src/ad5934_driver.c:556:6:ADG715_Update 16 static ../Core/Src/ad5934_driver.c:598:6:ADG715_SetRegisterValue 32 static
../Core/Src/ad5934_driver.c:608:6:ADG715_SetChannels 16 static
../Core/Src/ad5934_driver.c:613:6:ADG715_ResetChannels 8 static
../Core/Src/ad5934_driver.c:625:6:ADG715_Update 16 static
Binary file not shown.
@@ -9,7 +9,8 @@
../Core/Src/ads1015_driver.c:167:9:ADSreadADC_Differential_2_3 3 ../Core/Src/ads1015_driver.c:167:9:ADSreadADC_Differential_2_3 3
../Core/Src/ads1015_driver.c:213:6:ADSstartComparator_SingleEnded 5 ../Core/Src/ads1015_driver.c:213:6:ADSstartComparator_SingleEnded 5
../Core/Src/ads1015_driver.c:255:9:ADSgetLastConversionResults 3 ../Core/Src/ads1015_driver.c:255:9:ADSgetLastConversionResults 3
../Core/Src/ads1015_driver.c:274:7:ADSCalculate_ph_Volts 3 ../Core/Src/ads1015_driver.c:274:7:ADSCalculate_ph_mV 3
../Core/Src/ads1015_driver.c:304:7:ADSCalculate_ph_Compensated 4 ../Core/Src/ads1015_driver.c:303:7:ADSCalculate_ph_Compensated 1
../Core/Src/ads1015_driver.c:350:7:ADSCalculate_ph_Uncompensated 4 ../Core/Src/ads1015_driver.c:329:7:ADSCalculate_ph_Uncompensated 4
../Core/Src/ads1015_driver.c:402:7:ADSinterpolate_ph 5 ../Core/Src/ads1015_driver.c:381:7:ADSinterpolate_ph 5
../Core/Src/ads1015_driver.c:419:7:ADSRound_Float_Precision 2
Binary file not shown.
@@ -9,7 +9,8 @@
../Core/Src/ads1015_driver.c:167:9:ADSreadADC_Differential_2_3 24 static ../Core/Src/ads1015_driver.c:167:9:ADSreadADC_Differential_2_3 24 static
../Core/Src/ads1015_driver.c:213:6:ADSstartComparator_SingleEnded 24 static ../Core/Src/ads1015_driver.c:213:6:ADSstartComparator_SingleEnded 24 static
../Core/Src/ads1015_driver.c:255:9:ADSgetLastConversionResults 24 static ../Core/Src/ads1015_driver.c:255:9:ADSgetLastConversionResults 24 static
../Core/Src/ads1015_driver.c:274:7:ADSCalculate_ph_Volts 16 static ../Core/Src/ads1015_driver.c:274:7:ADSCalculate_ph_mV 16 static
../Core/Src/ads1015_driver.c:304:7:ADSCalculate_ph_Compensated 56 static ../Core/Src/ads1015_driver.c:303:7:ADSCalculate_ph_Compensated 48 static
../Core/Src/ads1015_driver.c:350:7:ADSCalculate_ph_Uncompensated 24 static ../Core/Src/ads1015_driver.c:329:7:ADSCalculate_ph_Uncompensated 24 static
../Core/Src/ads1015_driver.c:402:7:ADSinterpolate_ph 192 static ../Core/Src/ads1015_driver.c:381:7:ADSinterpolate_ph 192 static
../Core/Src/ads1015_driver.c:419:7:ADSRound_Float_Precision 24 static
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5 -5
View File
@@ -1,5 +1,5 @@
../Core/Src/main.c:108:5:main 11 ../Core/Src/main.c:110:5:main 12
../Core/Src/main.c:338:6:SystemClock_Config 4 ../Core/Src/main.c:377:6:SystemClock_Config 4
../Core/Src/main.c:389:6:FloatToString 8 ../Core/Src/main.c:428:6:FloatToString 8
../Core/Src/main.c:451:6:intToStr 5 ../Core/Src/main.c:490:6:intToStr 5
../Core/Src/main.c:501:6:Error_Handler 1 ../Core/Src/main.c:540:6:Error_Handler 1
Binary file not shown.
+5 -5
View File
@@ -1,5 +1,5 @@
../Core/Src/main.c:108:5:main 72 static ../Core/Src/main.c:110:5:main 88 static
../Core/Src/main.c:338:6:SystemClock_Config 88 static ../Core/Src/main.c:377:6:SystemClock_Config 88 static
../Core/Src/main.c:389:6:FloatToString 104 static ../Core/Src/main.c:428:6:FloatToString 104 static
../Core/Src/main.c:451:6:intToStr 40 static ../Core/Src/main.c:490:6:intToStr 40 static
../Core/Src/main.c:501:6:Error_Handler 4 static,ignoring_inline_asm ../Core/Src/main.c:540:6:Error_Handler 4 static,ignoring_inline_asm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff