2021-12-01 08:07 AM
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.
Here is literally what the application says on how the capacitance is measured + How to configure your peripherals:
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.
2021-12-01 09:50 AM
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?
2021-12-01 10:14 AM
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:
Here is what the application note says:
Eitherway, when I do feed TIM3 and TIM4 with the internal clock fo 170MHz I simply don't go past while(AvrgICReadValue == 0);.
2021-12-02 09:52 AM
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 ...