2024-02-12 10:59 AM - edited 2024-02-12 11:12 AM
I have the following code that I call from a freertos task scheduled with a period of 100 ms.
It reads the voltage applied to a pin and return the voltage value as a float.
float pinin_pv(void) {
/* Return the pin voltage in the interval [0, PIN_VOLTAGE] */
extern ADC_HandleTypeDef hadc1;
const uint32_t ADC_RESOLUTION_BITS = 10;
const uint32_t pippo = hadc1.Init.Resolution; // Only for explanation
const float PIN_VOLTAGE = 5000.0F; // [mV]
const float ANALOG_IN_RESOLUTION =
PIN_VOLTAGE / (float)(1 << ADC_RESOLUTION_BITS); // [mV]HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
size_t analog_read = HAL_ADC_GetValue(&hadc1);
float pin_voltage;
pin_voltage = ANALOG_IN_RESOLUTION * (float)analog_read;
return pin_voltage;
}
As you see, I have hard-coded const uint32_t ADC_RESOLUTION_BITS = 10; but I would like to pull this information from hadc1.Init.Resolution; (as example, I defined a variable named pippo in the code above). However, the value of pippo is like 1000 times larger that what is supposed to be. How to fix it? Is it possible to avoid hard-coding the variable PIN_VOLTAGE as well?
Solved! Go to Solution.
2024-02-12 12:51 PM - edited 2024-02-12 12:54 PM
Look at the definition for hadc1.Init.Resolution to see the various values and do an if statement for each.
if (hadc1.Init.Resolution == ADC_RESOLUTION_6B) {
...
} else if (hadc1.Init.Resolution == ADC_RESOLUTION_8B) {
...
} ...
You can also look at how they're defined within the register to make a formula for this.
> const float PIN_VOLTAGE = 5000.0F; // [mV]
Not sure what you mean here. Why is this hard-coded to 5V anyway? Shouldn't it be 3.3V? CubeMX allows you to define a value for VREF+ (technically VDD) that you could use if you want.
#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */
2024-02-12 11:02 AM
Use this button to properly post source code:
2024-02-12 11:02 AM - edited 2024-02-12 11:05 AM
Ok! I wish to edit my post, but I cannot figure out how... :\
EDIT: Found!
2024-02-12 12:51 PM - edited 2024-02-12 12:54 PM
Look at the definition for hadc1.Init.Resolution to see the various values and do an if statement for each.
if (hadc1.Init.Resolution == ADC_RESOLUTION_6B) {
...
} else if (hadc1.Init.Resolution == ADC_RESOLUTION_8B) {
...
} ...
You can also look at how they're defined within the register to make a formula for this.
> const float PIN_VOLTAGE = 5000.0F; // [mV]
Not sure what you mean here. Why is this hard-coded to 5V anyway? Shouldn't it be 3.3V? CubeMX allows you to define a value for VREF+ (technically VDD) that you could use if you want.
#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */
2024-02-12 01:18 PM
Usch! Right, I could use a switch-case statement for the resolution. I tried to look into the definition but it’s a bit cryptic.
Regarding the voltage I have 5 volts because the range of the input signal on that pin (PC0 in my case) is 0-5V.
2024-02-12 01:54 PM
5V is definitely above the limit for ADC pins. It is limited to VREF+, which is usually VDDA, which is usually VDD.
2024-02-13 06:49 AM
Usch! I reduced it to 3.3V and the readings are actually correct now! (I compared with a multimeter and when I have 5.0V the readings were wrong). Thanks for the heads up! :)