#include "ph.h"
ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;
uint32_t adc_reading;
float ph_readings[10] = {0};
uint8_t ph_i = 0;
void ph_init(void)
{
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
ADC_ChannelConfTypeDef sConfig;
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
HAL_ADC_Init(&hadc);
// Configure DMA
hdma_adc.Instance = DMA1_Channel1;
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc.Init.Mode = DMA_CIRCULAR;
hdma_adc.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_adc);
__HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc);
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
HAL_ADC_Start_DMA(&hadc, &adc_reading, 1);
//fill the rolling average buffer with real readings so the first reading isn't ~0
for (uint8_t i = 0; i < 10; i++)
{
ph_update();
HAL_Delay(100);
}
}
void ph_update(void)
{
uint32_t ph_raw = adc_reading;
ph_readings[ph_i] = ph_convert(ph_raw); //convert adc counts to pH
ph_i = (ph_i + 1) % 10;
}
float ph_get(void)
{
float ph = 0;
for (uint8_t i = 0; i < 10; i++)
{
ph += ph_readings[i];
}
ph = ph / 10;
return ph;
}
float ph_convert(uint32_t ph_raw)
{
float ph = (float)ph_raw;
return ph;
}