Periodic Voltage Sampling
ADC voltage sampling is triggered every 100ms via timer interrutp:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM1)
{
read_adc_voltage();
}
}
ADC configuration is omitted here, the sampling function witth averaging filtering is implemented as follows:
uint32_t adc_samples[10];
int init_counter = 0;
float current_voltage;
float max_voltage;
float min_voltage;
float prev_voltage;
uint8_t voltage_trend;
void read_adc_voltage()
{
HAL_ADC_Start_DMA(&hadc2, (uint32_t *)adc_samples, 10);
uint32_t raw_sum = 0;
for(int i = 0; i < 10; i++)
{
raw_sum += adc_samples[i];
}
float avg_raw = raw_sum / 10.0f;
current_voltage = 3.3f * avg_raw / 4096.0f;
// Initialize min/max values, run twice to avoid zero error from first sample
if(init_counter < 2)
{
max_voltage = current_voltage;
min_voltage = current_voltage;
prev_voltage = current_voltage;
init_counter++;
voltage_trend = 1; // 1 = rising by default
}
}
Update maximum and minimum voltage records:
void update_voltage_extremes()
{
if (current_voltage > max_voltage) max_voltage = current_voltage;
if (current_voltage < min_voltage) min_voltage = current_voltage;
}
Update voltage change trend:
// Trend codes: 1 = rising, 2 = falling
void update_voltage_trend()
{
if((uint8_t)current_voltage > (uint8_t)prev_voltage)
{
voltage_trend = 1;
}
else if((uint8_t)current_voltage < (uint8_t)prev_voltage)
{
voltage_trend = 2;
}
prev_voltage = current_voltage;
}
Main loop execusion flow:
while (1)
{
update_voltage_extremes();
update_voltage_trend();
update_lcd_display();
adjust_pwm_from_temp();
}
LCD Display Implementation
char lcd_buffer[32];
void update_lcd_display()
{
memset(lcd_buffer, 0, sizeof(lcd_buffer));
sprintf(lcd_buffer,