cancel
Showing results for 
Search instead for 
Did you mean: 

Humidity measurement (But actually capacitance) using STM32G4 - Nucleo

OKhal.1
Associate

Hello,

I seek help (It could be my code or electronic setup) to achieve capacitance measuring application using STM32G4. The application is outlined in the note "AN4232" --> Section 3.5 "Humidity measurement". There is a project example of this application but sadly only for the STM32F3 firmware package --> Comparator project examples --> COMP_HYGROMETER.

I am not interested in measuring humidity, but this application relies on measuring the capacitance (My goal) from which the humidity is determined. I think (but ignorant of the exact details) I am right in saying that this application relies on the charging/discharging of a foreign/external capacitor and the combination of a single comparator + single DAC as a voltage reference for the comparator + two TIM modules, one can determine the time-constant of the external capacitor from which you can determine the capacitance itself. I configured a STM32G431KB-Nucleo board project and followed the steps outlined in the application AN4232. I can't read a useful capacitance value.

0693W00000GZgCSQA1.png0693W00000GZgDBQA1.png0693W00000GZgKWQA1.pngHere is literally what the application says on how the capacitance is measured + How to configure your peripherals:

0693W00000GZhTAQA1.png 

Below is the main code, I understand that I could have a problem setting up my peripherals which obviously can't be seen from the code below. Please let me know if you do want to have a look at a specific part of the code and what would be the best way to share it.

__IO uint16_t AvrgICReadValue = 0;
uint16_t ICReadValue = 0;
uint16_t ICCounter = 0;
uint32_t SumICReadValue = 0;
uint16_t ICError = 0;
uint32_t DisplayValue = 50;
uint32_t UpdateDisplayValue = 1;
uint32_t RHmin = 99;
uint32_t RHmax = 0;
float Capacitance;
float TriggerTime;
 
float Capacitance55RH = 180e-12; /* typical capacitance value at 55% RH */
 
float RelativeHumidity;
 
/* USER CODE END 0 */
 
 
 
/**
 
 * @brief The application entry point.
 
 * @retval int
 
 */
 
int main(void)
 
{
 
 /* USER CODE BEGIN 1 */
 
	uint16_t tmp = 0;
 
	float capacitance_temp = 0;
 
 /* USER CODE END 1 */
 
 
 
 /* MCU Configuration--------------------------------------------------------*/
 
 
 
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 
 HAL_Init();
 
 
 
 /* USER CODE BEGIN Init */
 
 
 
 /* USER CODE END Init */
 
 
 
 /* Configure the system clock */
 
 SystemClock_Config();
 
 
 
 /* USER CODE BEGIN SysInit */
 
 
 
 /* USER CODE END SysInit */
 
 
 
 /* Initialize all configured peripherals */
 
 MX_GPIO_Init();
 MX_USART2_UART_Init();
 MX_COMP4_Init();
 MX_DAC1_Init();
 MX_TIM3_Init();
 MX_TIM4_Init();
 
 /* USER CODE BEGIN 2 */
 
 
 
 while(AvrgICReadValue == 0);
 
 
 /* USER CODE END 2 */
 
 
 
 /* Infinite loop */
 
 /* USER CODE BEGIN WHILE */
 
 while (1)
 
 {
 
  /* Calculate Trigger Time Value */
 
  TriggerTime = (float) (AvrgICReadValue)/SystemCoreClock;
 
  /* Comp4 inverted input connected to DACx :
 
  * TriggerTime = RES * Capacitance * ln(VDD/(VDD - VREF))
 
  * @VREF = 2.086V (generated by DAC), ln(VDD/(VDD - VREF)) is ~ 1
 
  * ==> Capacitance = TriggerTime/RES
 
  */
 
  Capacitance = (float) TriggerTime/RES;
 
  capacitance_temp = Capacitance;
 
  /* USER CODE END WHILE */
 
 
 
  /* USER CODE BEGIN 3 */
 
 }
 
 /* USER CODE END 3 */
 
}
 
 
 
/* USER CODE BEGIN 4 */
 
/**
 
 * @brief Input Capture callback in non blocking mode
 
 * @param htim : TIM4 IC handle
 
 * @retval None
 
 */
 
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
 
{
 
	if(htim->Instance == TIM4)
 
	{
 
 /* Get the converted value */
 
 ICReadValue = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
 
 
 
 /* Increment the counter */
 
 ICCounter++;
 
 
 
 /* sum up the samples */
 
 SumICReadValue += ICReadValue;
 
 
 
 if(ICCounter > 255)
 
 {
 
 /* Compute the average value for 256 samples */
 
 AvrgICReadValue = SumICReadValue/256;
 
 ICCounter = 0;
 
 SumICReadValue = 0;
 
 }
 
	}
 
}

HAL_TIM_IC_CaptureCallback is the only callback needed for this application. Although the example code for this application has some fancy LCD setup to display the value of humidity/capacitance on an LCD, I simply put my code in debug and place a break point at the float variable "Capacitance" to inspect its value but I am not reading back anything useful, certainly not 10nF which is what I am using in my setup and expecting to measure.

Regards.

3 REPLIES 3
MM..1
Chief II

Try atach ioc and code replace with code snip

while(AvrgICReadValue == 0);
 tmp = SystemCoreClock*REFCAP;
 tmp = tmp*RES;
 ICError = (uint16_t) (AvrgICReadValue-(uint16_t)tmp);

and for my info when debug and scope pins , work your design?

For example if break on 4 line how value is tmp and ICError?

OKhal.1
Associate

Hi MM thnx bunch for your interest buddy,

Actually after a second thought, I don't need these lines, since they rely on having a "Reference Capacitor" available on the STM32F3 board to measure ICError which I don't actually have. Well The only capacitor I have attached is the 10nF so this is pointless. my new main has this removed:

while(AvrgICReadValue == 0);
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	    /* Calculate Trigger Time Value */
	    TriggerTime = (float) (AvrgICReadValue)/SystemCoreClock;
	    /* Comp4 inverted input connected to DACx :
	     * TriggerTime = RES * Capacitance * ln(VDD/(VDD - VREF))
	     * @VREF = 2.086V (generated by DAC),  ln(VDD/(VDD - VREF)) is ~ 1
	     *  ==>  Capacitance = TriggerTime/RES
	     */
	    Capacitance = (float) TriggerTime/RES;
 
	    capacitance_temp = Capacitance;

So there is one thing I don't understand here, in the application note AN4232, it says TIM3 and TIM4 are "CLOCKED" @ 72Mhz which is the internal clock of that STM32F3. but after examining their code project example "COMP_HYGROMETER" it seems as if TIM3 and TIM4 aren't using any clock source? so I am wondering here shall I feed my TIM3 and TIM4 with my internal 170MHz STM32G4 clock?

As for your question, yes I do actually go past while(AvrgICReadValue == 0); Only if I don't setup TIM3 and TIM4 with any clock at all:

0693W00000GZhJFQA1.png 

Here is what the application note says:

0693W00000GZhK8QAL.png 

Eitherway, when I do feed TIM3 and TIM4 with the internal clock fo 170MHz I simply don't go past while(AvrgICReadValue == 0);.

MM..1
Chief II

Hi i dont know this example , but in your code i dont see start PWM .

In teory if TIM3 is 16bit tim then result freq signal is 72M/65536 equal to PWM period, and duty need set to half aka 50%

but primary on source MCU example is pin and timer chanel used together, Pin connected to RC have alternative TIM3 CH3 func usw.

As i write in first message , run PWM and measure pin connected on your design to 82k rezistor. Need see here square ...