Fertirrega_v6 Without Blocking Samples

This commit is contained in:
2026-07-29 10:02:21 +01:00
parent e65f787c34
commit f1cf74ceaf
88 changed files with 13881 additions and 11752 deletions
+328 -5
View File
@@ -11,6 +11,15 @@
#include "ad5934_driver.h"
volatile AD5934_State_t ad5934_state = AD5934_IDLE;
volatile uint32_t g_ms_counter = 0; /* Incrementado a cada 1ms no Timer */
uint8_t current_mux_channel = AD5934_ID_RTD;
uint8_t current_hw_mux_connection = ADG715_Channel_Map[AD5934_CH_RTD_LOW_GAIN]; // PT100 Connection
uint8_t sweep_count = 0; /* Conta quantos sweeps foram feitos no canal atual (0 a 7) */
int16_t temperature_dut_samples[2][AD5934_TEMP_AVERAGES]={{0},{0}};
int16_t temperature_ref_samples[2][AD5934_TEMP_AVERAGES]={{0},{0}};
float temperature_display[AD5934_TEMP_AVERAGES] = {0};
@@ -19,6 +28,11 @@ float temperature_display[AD5934_TEMP_AVERAGES] = {0};
int16_t ec_dut_samples[2][AD5934_EC_AVERAGES]={{0},{0}};
float ec_display[AD5934_EC_AVERAGES] = {0};
AD5934_filter_t g_rtd_filter = {0};
AD5934_filter_t g_ec_filter = {0};
AD5934_filter_t g_ref_filter = {0};
uint8_t is_new_channel = 1;
/******************************************************************************
* @brief Set an AD5934 internal register value.
*
@@ -151,7 +165,7 @@ void AD5934_Init(void)
AD5934_SetRegisterValue(AD5934_NR_INCR_REG_LB, AD5934_STEP_FREQ_0, 2);
// Set 128 Settling Time
AD5934_SetRegisterValue(AD5934_NR_SETTLE_REG_LB, AD5934_SETTLING_TIME_0S01, 2);
AD5934_SetRegisterValue(AD5934_NR_SETTLE_REG_LB, AD5934_SETTLING_TIME_64, 2);
}
@@ -177,18 +191,50 @@ void AD5934_RestartSweep(void)
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
AD5934_Wait_For_Data_Valid();
//AD5934_Wait_For_Data_Valid();
// 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_X1)), 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);
// Place AD5934 in standby (instead of power down)
//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);
}
/******************************************************************************
* @brief Repeat Sweep at the AD5934 with the same sweep parameters.
*
* @param None.
*
* @return none.
******************************************************************************/
void AD5934_Repeat_Sweep(void)
{
// Repeat AD5934 Sweep
AD5934_SetRegisterValue(AD5934_CONTROL_REG_HB, (AD5934_CONTROL_FUNCTION(AD5934_REPEAT_FREQ) | AD5934_CONTROL_RANGE(AD5934_400mVpp_RANGE) | AD5934_PGA_GAIN(AD5934_PGA_GAIN_X1)), 1);
}
/******************************************************************************
* @brief Stop the AD5934 to sweep.
*
* @param None.
*
* @return None.
******************************************************************************/
void AD5934_StopSweep(void)
{
// 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_X1)), 1);
// Place AD5934 in standby (instead of power down to save startup time)
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);
}
/******************************************************************************
* @brief Start the AD5934 frequency sweep parameters.
*
* @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: none
*
* @return Real(int16) and Imaginary(int16) numbers into a int32.
******************************************************************************/
@@ -386,7 +432,6 @@ float AD5934_GetImpedance(float temperature_dut)
ec_dut_samples[1][i] = ec_dut_samples[1][i-1];
}
// Deconstruct 32-bit sample into Real and Imaginary components
ec_dut_samples[0][0] = (float)(int16_t)(sample_dut & 0xFFFF);
ec_dut_samples[1][0] = (float)(int16_t)((sample_dut >> 16) & 0xFFFF);
@@ -424,6 +469,30 @@ float AD5934_GetImpedance(float temperature_dut)
}
/******************************************************************************
* @brief Get Real and Imaginary values and calculate Magnitude.
*
* @param: none
*
* @return Magnitude (float).
******************************************************************************/
float AD5934_GetMagnitude(void)
{
// Get Real Data register
int16_t real_value = ((AD5934_GetRegisterValue(AD5934_REAL_REG_LB,2)));
// Get Imaginary Data register
int16_t imag_value = ((AD5934_GetRegisterValue(AD5934_IMG_REG_LB,2)));
// Calculate Magnitude using float function sqrtf
float magnitude = sqrtf(((float)real_value * (float)real_value) + ((float)imag_value * (float)imag_value));
// Return magnitude value
return (magnitude);
}
/**
* @brief Monitora o status com TIMEOUT para evitar travamento do sistema.
@@ -585,6 +654,260 @@ float AD5934_Calibrate(float dry_probe_real, float dry_probe_imag, float standar
return calibration_factor;
}
void AD5934_Process_System(void)
{
static uint32_t state_timer = 0;
uint8_t status = 0;
switch (ad5934_state)
{
case AD5934_IDLE:
ADG715_Update(current_mux_channel); // Starts changing the mux channel
is_new_channel = 1; // Forces first channel
state_timer = g_ms_counter;
ad5934_state = AD5934_WAIT_MUX;
break;
case AD5934_WAIT_MUX:
if ((g_ms_counter - state_timer) >= AD5934_SYNC_MUX_SETTLING) // Wait until AD715 Mux switch stability
{
sweep_count = 0;
ad5934_state = AD5934_START_CONVERSION;
}
break;
case AD5934_START_CONVERSION:
state_timer = g_ms_counter; // Starts to count the Burst period for the sweeps
/* DECISÃO DE COMANDO: Novo canal vs Leituras sucessivas */
if (is_new_channel) // Decision: Channel Switched or Next Sample in the Burst ?
{
AD5934_RestartSweep(); // Clean some AD5934 internal registers to Re-Start Sweep
is_new_channel = 0; // Resets the flag to read the next Sample Burst
}
else
{
AD5934_Repeat_Sweep(); // Get Sample and just repeat reading
}
ad5934_state = AD5934_WAIT_CONVERSION; // Next State
break;
case AD5934_WAIT_CONVERSION:
status = (uint8_t)AD5934_GetRegisterValue(AD5934_STATUS_REG, 1); // Check if the current converion is ready in the AD5934
if ((status & AD5934_STATUS_DATA_VALID) != 0)
{
ad5934_state = AD5934_READ_DATA;
}
break;
case AD5934_READ_DATA:
{
float magnitude = AD5934_GetMagnitude();
switch (current_mux_channel)
{
case AD5934_ID_RTD:
AD5934_RTD_NewSample(magnitude);
break;
case AD5934_ID_EC:
AD5934_EC_NewSample(magnitude);
break;
case AD5934_ID_REF:
AD5934_Reference_NewSample(magnitude);
break;
}
sweep_count++;
if (sweep_count >= AD5934_BURST_SIZE) // Check if number of samples for the burst is complete
{
ad5934_state = AD5934_SWITCH_MUX; // Next Re-Start Sweep
}
else
{
ad5934_state = AD5934_WAIT_NEXT_SWEEP; // Next Repeat Sweep
}
}
break;
case AD5934_WAIT_NEXT_SWEEP:
if ((g_ms_counter - state_timer) >= AD5934_TIME_PER_SWEEP)
{
ad5934_state = AD5934_START_CONVERSION;
}
break;
case AD5934_SWITCH_MUX:
AD5934_StopSweep(); // Put AD5934 in Standby
current_mux_channel = (uint8_t)((current_mux_channel + 1) % 3); // Pointer to the next channel (Circular Buffer 0 to 2)
switch (current_mux_channel)
{
case AD5934_ID_RTD:
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
current_hw_mux_connection = AD5934_CH_RTD_LOW_GAIN; //PT100
else
current_hw_mux_connection = AD5934_CH_RTD_MID_GAIN; //PT1000
break;
case AD5934_ID_EC:
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == GPIO_PIN_SET) // Hardware Setup: Gain Selection (PA6)
current_hw_mux_connection = AD5934_CH_EC_HIGH_GAIN;
else
current_hw_mux_connection = AD5934_CH_EC_MID_GAIN;
break;
case AD5934_ID_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
current_hw_mux_connection = AD5934_CH_REF100R_LOW_GAIN; // 100 Ohms Reference Resistor
else
current_hw_mux_connection = AD5934_CH_REF1K_MID_GAIN; // 1K Reference Resistor
break;
}
ADG715_Update(current_hw_mux_connection); // Change the analog mux
is_new_channel = 1; // Channel Switched
state_timer = g_ms_counter; // Reload timer to wait for stability
ad5934_state = AD5934_WAIT_MUX; // Next State
break;
}
}
/**
* Simple insertion sort - BURST_SIZE is small, so the cost is negligible
* and it avoids depending on qsort/heap allocation.
**/
void AD5934_Sort_Array(float *v, uint8_t n)
{
for (uint8_t i = 1; i < n; i++)
{
float key = v[i];
int8_t j = (int8_t)i - 1;
while (j >= 0 && v[j] > key)
{
v[j + 1] = v[j];
j--;
}
v[j + 1] = key;
}
}
/**
* Trimmed mean: sorts the buffer IN PLACE (the caller's burst buffer is
* about to be reset right after this call anyway, so preserving its
* original order is not needed), discards TRIM_COUNT values from each
* end, and averages the remainder. Sorting in place avoids a temporary
* array and removes the need for memcpy()/string.h entirely.
**/
float AD5934_Trimmed_Mean(float *buffer, uint8_t n, uint8_t trim)
{
AD5934_Sort_Array(buffer, n);
uint8_t start = trim;
uint8_t end = n - trim; /* exclusive */
if (end <= start) /* guard against a misconfigured trim value */
{
start = 0;
end = n;
}
float sum = 0.0f;
uint8_t count = 0;
for (uint8_t i = start; i < end; i++)
{
sum += buffer[i];
count++;
}
return sum / (float)count;
}
/*
* Simple average of the history buffer (stage-2 sliding window)
*/
float AD5934_History_Average(const float *hist, uint8_t n)
{
float sum = 0.0f;
for (uint8_t i = 0; i < n; i++)
sum += hist[i];
return sum / (float)n;
}
/*
* Common processing core: applied identically to all 3 channels.
* Receives the current raw reading and the channel's state (global
* arrays/struct).
**/
void AD5934_Process_Sample(AD5934_filter_t *ch, float raw)
{
/* --- Stage 1: accumulate into the current burst --- */
ch->burst[ch->burst_index] = raw;
ch->burst_index++;
if (ch->burst_index < AD5934_BURST_SIZE)
return; /* still collecting the burst, nothing else to do */
/* Burst complete: compute the trimmed mean */
float burst_result = AD5934_Trimmed_Mean(ch->burst, AD5934_BURST_SIZE, AD5934_TRIM_COUNT);
ch->burst_index = 0; /* reset for the next burst */
/* --- Stage 2a: rolling history / sliding window --- */
ch->history[ch->history_index] = burst_result;
ch->history_index = (uint8_t)((ch->history_index + 1) % AD5934_HISTORY_SIZE);
if (ch->history_count < AD5934_HISTORY_SIZE)
ch->history_count++;
float window_average = AD5934_History_Average(ch->history, ch->history_count);
/* --- Stage 2b: first-order IIR low-pass filter on the burst result --- */
if (!ch->iir_initialized)
{
ch->iir_state = burst_result;
ch->iir_initialized = 1;
}
else
{
ch->iir_state = AD5934_IIR_ALPHA * burst_result + (1.0f - AD5934_IIR_ALPHA) * ch->iir_state;
}
/* Final output: combines the IIR state (fast response to real drift)
* with the window average (more stable, slower response). Adjust
* the weighting per channel if needed. */
ch->filtered_value = 0.5f * ch->iir_state + 0.5f * window_average;
ch->value_valid = 1;
}
/* ---------------------------------------------------------------------- */
/* PUBLIC FUNCTIONS - ONE PER CHANNEL */
/* ---------------------------------------------------------------------- */
/* Call this every time a sweep completes with the mux on the RTD
* (PT100/PT1000) channel */
void AD5934_RTD_NewSample(float raw)
{
AD5934_Process_Sample(&g_rtd_filter, raw);
}
/* Call this every time a sweep completes with the mux on the EC
* (conductivity probe) channel */
void AD5934_EC_NewSample(float raw)
{
AD5934_Process_Sample(&g_ec_filter, raw);
}
/* Call this every time a sweep completes with the mux on the on-board
* precision reference resistor channel */
void AD5934_Reference_NewSample(float raw)
{
AD5934_Process_Sample(&g_ref_filter, raw);
}
/*****************************************************************************
* ADG715
*****************************************************************************
+213 -6
View File
@@ -9,9 +9,14 @@
#include "ads1015_driver.h"
ADS1015_I2C i2c;
ADS1015_I2C i2c_ads1015;
float ph_dut_samples[ADS1015_PH_AVERAGES]={0};
ADS1015_filter_t g_ph_filter = {0};
volatile ADS1015_State_t ads1015_state = ADS1015_IDLE;
// Write the register
static void writeRegister(ADS1015_I2C *i2c, uint8_t reg, uint16_t value) {
uint8_t pData[3] = { reg, (uint8_t) (value >> 8), (uint8_t) (value & 0xFF) };
@@ -36,13 +41,14 @@ static void ADSbegin(ADS1015_I2C *i2c) {
// Declare an ADS1015 structure
void ADS1015(ADS1015_I2C *i2c, I2C_HandleTypeDef *hi2c, uint8_t i2cAddress) {
i2c->hi2c = hi2c;
i2c->m_i2cAddress = i2cAddress << 1; // It's Important to shift the address << 1
i2c->m_i2cAddress = i2cAddress; // << 1; // It's Important to shift the address << 1
i2c->m_conversionDelay = ADS1015_CONVERSIONDELAY;
i2c->m_bitShift = 4;
i2c->m_gain = GAIN_TWOTHIRDS; /* +/- 6.144V range (limited to VDD +0.3V max!) */
i2c->m_gain = GAIN_SIXTEEN; /* +/- 6.144V range (limited to VDD +0.3V max!) */
//ADSbegin(i2c); //Ready is not used
}
/*
* // The ADC input range (or gain) can be changed via the following
// functions, but be careful never to exceed VDD +0.3V max, or to
@@ -126,7 +132,7 @@ int16_t ADSreadADC_Differential_0_1(ADS1015_I2C *i2c) {
ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
ADS1015_REG_CONFIG_DR_128SPS | // 128 samples per second (default)
ADS1015_REG_CONFIG_DR_250SPS | // 128 samples per second (default)
ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)
// Set PGA/voltage range
@@ -271,6 +277,207 @@ int16_t ADSgetLastConversionResults(ADS1015_I2C *i2c) {
}
}
void ADS1015_Process_System(void)
{
static uint32_t state_timer = 0;
static uint32_t sample_count = 0;
uint16_t config_reg = 0;
switch (ads1015_state)
{
case ADS1015_IDLE:
sample_count = 0;
ads1015_state = ADS1015_START_CONVERSION;
break;
case ADS1015_START_CONVERSION:
state_timer = g_ms_counter;
/* Escreve no Config Register (P[1:0]=01b) com OS=1 para
* iniciar a conversão single-shot. O bit OS só tem efeito
* quando o dispositivo está em power-down (seção 7.4.2.1) */
// Write config register to the ADC
writeRegister(&i2c_ads1015, ADS1015_REG_POINTER_CONFIG, ADS1015_CONFIG_START_SINGLE);
ads1015_state = ADS1015_WAIT_CONVERSION;
break;
case ADS1015_WAIT_CONVERSION:
/* Poll do bit OS no Config Register (P[1:0]=01b):
* Ao LER o bit OS:
* 0b = dispositivo ainda convertendo
* 1b = conversão concluída, dado pronto no Conversion Register
* (Tabela 8-4, descrição do bit OS)
*/
config_reg = readRegister(&i2c_ads1015, ADS1015_REG_POINTER_CONFIG);
if (((config_reg & ADS1015_REG_CONFIG_OS_SINGLE) != 0) && (g_ms_counter - state_timer)>ADS1015_TIME_PER_SAMPLE)
{
ads1015_state = ADS1015_READ_DATA;
}
// (opcional) tratar timeout comparando g_ms_counter - state_timer
// Datasheet: conversão single-cycle, tempo = 1/DR (ex: 1600SPS ≈ 625µs)
break;
case ADS1015_READ_DATA:
{
/* Muda o Address Pointer para o Conversion Register (P[1:0]=00b)
* e lê os 16 bits. Dado é 12 bits em complemento de 2,
* left-justified em D[15:4]; D[3:0] sempre lê 0h (Tabela 8-3) */
int16_t raw = (int16_t)readRegister(&i2c_ads1015, ADS1015_REG_POINTER_CONVERT);
raw >>= 4; // remove os 4 bits reservados (D[3:0]), resultado = 12 bits signed
float value = (float)(4096 - raw); // ((float)raw * ADS1015_ADC_VREF) / ADS1015_ADC_MAX; // usa FSR configurado no PGA
ADS1015_pH_NewSample(value);
sample_count++;
if (sample_count >= ADS1015_BURST_SIZE)
{
ads1015_state = ADS1015_IDLE;
}
else
{
state_timer = g_ms_counter;
ads1015_state = ADS1015_WAIT_NEXT_SAMPLE;
}
}
break;
case ADS1015_WAIT_NEXT_SAMPLE:
if ((g_ms_counter - state_timer) >= ADS1015_TIME_PER_SAMPLE)
{
ads1015_state = ADS1015_START_CONVERSION;
}
break;
}
}
/**
* Simple insertion sort - BURST_SIZE is small, so the cost is negligible
* and it avoids depending on qsort/heap allocation.
**/
void ADS1015_Sort_Array(float *v, uint8_t n)
{
for (uint8_t i = 1; i < n; i++)
{
float key = v[i];
int8_t j = (int8_t)i - 1;
while (j >= 0 && v[j] > key)
{
v[j + 1] = v[j];
j--;
}
v[j + 1] = key;
}
}
/**
* Trimmed mean: sorts the buffer IN PLACE (the caller's burst buffer is
* about to be reset right after this call anyway, so preserving its
* original order is not needed), discards TRIM_COUNT values from each
* end, and averages the remainder. Sorting in place avoids a temporary
* array and removes the need for memcpy()/string.h entirely.
**/
float ADS1015_Trimmed_Mean(float *buffer, uint8_t n, uint8_t trim)
{
ADS1015_Sort_Array(buffer, n);
uint8_t start = trim;
uint8_t end = n - trim; /* exclusive */
if (end <= start) /* guard against a misconfigured trim value */
{
start = 0;
end = n;
}
float sum = 0.0f;
uint8_t count = 0;
for (uint8_t i = start; i < end; i++)
{
sum += buffer[i];
count++;
}
return sum / (float)count;
}
/*
* Simple average of the history buffer (stage-2 sliding window)
*/
float ADS1015_History_Average(const float *hist, uint8_t n)
{
float sum = 0.0f;
for (uint8_t i = 0; i < n; i++)
sum += hist[i];
return sum / (float)n;
}
/*
* Common processing core: applied identically to all 3 channels.
* Receives the current raw reading and the channel's state (global
* arrays/struct).
**/
void ADS1015_Process_Sample(ADS1015_filter_t *ch, float raw)
{
/* --- Stage 1: accumulate into the current burst --- */
ch->burst[ch->burst_index] = raw;
ch->burst_index++;
if (ch->burst_index < ADS1015_BURST_SIZE)
return; /* still collecting the burst, nothing else to do */
/* Burst complete: compute the trimmed mean */
float burst_result = ADS1015_Trimmed_Mean(ch->burst, ADS1015_BURST_SIZE, ADS1015_TRIM_COUNT);
ch->burst_index = 0; /* reset for the next burst */
/* --- Stage 2a: rolling history / sliding window --- */
ch->history[ch->history_index] = burst_result;
ch->history_index = (uint8_t)((ch->history_index + 1) % ADS1015_HISTORY_SIZE);
if (ch->history_count < ADS1015_HISTORY_SIZE)
ch->history_count++;
float window_average = ADS1015_History_Average(ch->history, ch->history_count);
/* --- Stage 2b: first-order IIR low-pass filter on the burst result --- */
if (!ch->iir_initialized)
{
ch->iir_state = burst_result;
ch->iir_initialized = 1;
}
else
{
ch->iir_state = ADS1015_IIR_ALPHA * burst_result + (1.0f - ADS1015_IIR_ALPHA) * ch->iir_state;
}
/* Final output: combines the IIR state (fast response to real drift)
* with the window average (more stable, slower response). Adjust
* the weighting per channel if needed. */
ch->filtered_value = 0.5f * ch->iir_state + 0.5f * window_average;
ch->value_valid = 1;
}
/* ---------------------------------------------------------------------- */
/* PUBLIC FUNCTIONS - ONE PER CHANNEL */
/* ---------------------------------------------------------------------- */
void ADS1015_pH_NewSample(float raw)
{
ADS1015_Process_Sample(&g_ph_filter, raw);
}
float ADSCalculate_ph_mV(void) // pH in mV
{
float ph_dut_sum;
@@ -279,7 +486,7 @@ float ADSCalculate_ph_mV(void) // pH in mV
for (i = (ADS1015_PH_AVERAGES-1); i > 0; i--)
ph_dut_samples[i] = ph_dut_samples[i-1];
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)
ph_dut_samples[0] = (((float)(ADSreadADC_Differential_0_1(&i2c_ads1015)) * 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++)
ph_dut_sum += ph_dut_samples[i];
@@ -333,7 +540,7 @@ float ADSCalculate_ph_Uncompensated(void)
* Note: The subtraction of 2048 assumes a differential configuration
* where the midpoint is at the mid-scale of the ADS1015.
*/
float v_measured = ((float)(2048 - ADSreadADC_Differential_0_1(&i2c)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX;
float v_measured = ((float)(ADSreadADC_Differential_0_1(&i2c_ads1015)) * ADS1015_ADC_VREF) / ADS1015_ADC_MAX;
/*
* 2. Calculate the original Slope (measured during calibration).
+68 -12
View File
@@ -20,6 +20,7 @@
#include "main.h"
#include "adc.h"
#include "i2c.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
@@ -57,6 +58,8 @@
/* USER CODE BEGIN PV */
uint8_t rx_buffer[256]; /*!< Buffer for received data */
uint8_t tx_data[] = "Hello RS-485 Broadcast!"; /*!< Data to send */
@@ -158,14 +161,21 @@ int main(void)
MX_I2C1_Init();
MX_I2C2_Init();
MX_USART1_UART_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
Flash_Load_Page(&flash_data);
HAL_TIM_Base_Start_IT(&htim3);
//TempSensor_Init(&hadc1);
/*
HAL_TIM_Base_Start(&htim3);
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)AD_RES, 2); // Internal Temperature conversion
*/
@@ -176,8 +186,12 @@ int main(void)
rs485_init();
ADS1015(&i2c, &hi2c1, ADS_ADDR_GND);
ADSsetGain(&i2c, GAIN_FOUR);
ADS1015(&i2c_ads1015, &hi2c1, ADS1015_ADDR_GND);
//ADSsetGain(&i2c_ads1015, GAIN_FOUR);
ADG715_ResetChannels();
// Start CE and RTD Measurement
@@ -189,7 +203,7 @@ int main(void)
/* Infinite loop */
/* 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
@@ -265,14 +279,15 @@ int main(void)
}
*/
while (1)
{
AD5934_Process_System();
ADS1015_Process_System();
current_millis = HAL_GetTick();
current_millis = g_ms_counter;
// Piscar LED verde em PB5 a cada 0,5 segundos
@@ -289,8 +304,19 @@ int main(void)
uint8_t led_data[2] = {0x01, current_green_state}; // Command 0x01 for green LED
}
/*
status1 = rs485_send_broadcast(ph_t, strlen((char*)ph_t));
ph_compensated = ADSCalculate_ph_mV() ;
FloatToString(tempString, ph_compensated);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_ph, strlen((char*)newline_ph));
*/
}
// Piscar LED vermelho em PB4 a cada 1 segundo
@@ -308,26 +334,44 @@ int main(void)
}
if (g_rtd_filter.value_valid)
{
float rtd_final = g_rtd_filter.filtered_value;
status1 = rs485_send_broadcast(tm_t, strlen((char*)tm_t));
temperature_RTD = AD5934_GetTemperature(refResistance);
FloatToString(tempString, temperature_RTD);
//temperature_RTD = AD5934_GetTemperature(refResistance);
FloatToString(tempString, rtd_final);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_temp, strlen((char*)newline_temp));
}
if (g_ec_filter.value_valid)
{
float ec_final = g_ec_filter.filtered_value;
status1 = rs485_send_broadcast(ad_t, strlen((char*)ad_t));
admittance_EC = AD5934_GetImpedance(temperature_RTD);
FloatToString(tempString, admittance_EC);
//admittance_EC = AD5934_GetImpedance(temperature_RTD);
FloatToString(tempString, ec_final);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_admi, strlen((char*)newline_admi));
}
if (g_ref_filter.value_valid)
{
//float reference_final = g_ref_filter.filtered_value;
status1 = rs485_send_broadcast(ph_t, strlen((char*)ph_t));
ph_compensated = 10*ADSCalculate_ph_mV();//ADSCalculate_ph_Compensated(temperature_RTD);
ph_compensated = g_ph_filter.filtered_value;
FloatToString(tempString, ph_compensated);
status0 = rs485_send_broadcast(tempString, (strlen((char*)tempString)-1));
status1 = rs485_send_broadcast(newline_ph, strlen((char*)newline_ph));
status1 = rs485_send_broadcast(newline, strlen((char*)newline));
}
}
@@ -524,6 +568,18 @@ void intToStr(int N, char *str) {
}
}
/* TIM3 Timer Interrupt */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM3)
{
g_ms_counter++; /* Relógio global do sistema */
}
}
/*
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
+15
View File
@@ -55,6 +55,7 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim3;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
@@ -198,6 +199,20 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
+10 -3
View File
@@ -41,9 +41,9 @@ void MX_TIM3_Init(void)
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 3;
htim3.Init.Prescaler = 2;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 59999;
htim3.Init.Period = 999;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
@@ -55,7 +55,7 @@ void MX_TIM3_Init(void)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
@@ -77,6 +77,10 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM3_MspInit 0 */
/* TIM3 clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();
/* TIM3 interrupt Init */
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspInit 1 */
/* USER CODE END TIM3_MspInit 1 */
@@ -93,6 +97,9 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
/* USER CODE END TIM3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM3_CLK_DISABLE();
/* TIM3 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspDeInit 1 */
/* USER CODE END TIM3_MspDeInit 1 */