#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; }