Skip to main content
ZKURT.1
Senior
January 27, 2022
Question

Hi. I want to measure the voltage of the battery with the ADC. Currently the voltage of the battery is 3.3 volts. I always see the result "6106" on the serial screen. What could I be doing wrong? Can you help me please?

  • January 27, 2022
  • 5 replies
  • 9581 views

code:

/* USER CODE BEGIN 2 */

 HAL_UART_Transmit(&hlpuart1, (uint8_t *)"Basladi\r\n", 9, 100);

HAL_ADC_Start(&hadc);

#define VREFINT_CAL_ADDR 0x1FF80078

#define VREFINT_CAL ((uint16_t*) VREFINT_CAL_ADDR)

#define MAX_VOLTAGE 3000.0

uint32_t VREFINTADC;

char buffer[23];

 /* USER CODE END 2 */

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

 VREFINTADC=HAL_ADC_GetValue(&hadc);

 float VDD = MAX_VOLTAGE * (*VREFINT_CAL / (float) VREFINTADC);

 sprintf(buffer, "%f", VDD);

 HAL_UART_Transmit(&hlpuart1, (uint8_t *)buffer, 5, 1000);

 HAL_UART_Transmit( &hlpuart1, (uint8_t *)"\r\n", 2, 100);

 HAL_Delay(2000);

 }

This topic has been closed for replies.

5 replies

Andrew Neil
Super User
January 27, 2022

0693W000008xsqBQAQ.pngHave you proved that your code actually works using various known input voltages; eg, supplied from a potentiometer?

You need to show the schematic of how you've connected the ADC input to the battery; it's not "behind" a voltage regulator - is it?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
ZKURT.1
ZKURT.1Author
Senior
January 27, 2022

hello, I didn't quite understand what you mean, but I connected a cable between the + part on the breadboard and the adc pin input. I'm currently running the power from the power supply. The power supply is adjustable, I can increase or decrease it. i will put battery after the code works

MM..1
Chief III
January 27, 2022

You cant start ADC and immediately get value.

 /* USER CODE BEGIN 3 */
//here add pool for value ... or wait for complete flag or how yuo config ADC
 
 VREFINTADC=HAL_ADC_GetValue(&hadc);
 

Andrew Neil
Super User
January 27, 2022

@MM..1​ "pool (sic) for value"

* poll

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Peter BENSCH
Technical Moderator
January 27, 2022

And please remember that with the STM32L010C6 a measurement is always relative to VDD because VREF is not accessible due to the pin limitation of the package.

Absolute measurements are thus only possible indirectly by performing them with two measurements:

  • one measurement of Vrefint or an external reference voltage and
  • one measurement at the ADC input.

Afterwards, both have to be put in relation to each other to get an absolute value.

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Andrew Neil
Super User
January 27, 2022

Alternatively, if VDD is directly connected to the battery, a measurement of Vrefint (which is constant) relative to VDD (which changes with battery voltage) will give you a measurement of the battery voltage ...

EDIT

If VDD is supplied via a regulator, this might (depending on the system) enable you to detect when the battery has fallen to such a level that the regulator can no longer regulate...

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
ZKURT.1
ZKURT.1Author
Senior
January 27, 2022

I watched videos about ADC, but I could not understand this subject (voltage measurement with ADC-Vref Internal). I need help. Are there any resources you can recommend?

MM..1
Chief III
January 28, 2022

Sample code

/*##-3- Start the conversion process #######################################*/
 if (HAL_ADC_Start(&AdcHandle) != HAL_OK)
 {
 /* Start Conversation Error */
 Error_Handler();
 }
 
 /*##-4- Wait for the end of conversion #####################################*/
 /* Before starting a new conversion, you need to check the current state of
 the peripheral; if it’s busy you need to wait for the end of current
 conversion before starting a new one.
 For simplicity reasons, this example is just waiting till the end of the
 conversion, but application may perform other tasks while conversion
 operation is ongoing. */
 if (HAL_ADC_PollForConversion(&AdcHandle, 10) != HAL_OK)
 {
 /* End Of Conversion flag not set on time */
 Error_Handler();
 }
 
/* Check if the continuous conversion of regular channel is finished */
 if ((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_EOC_REG) == HAL_ADC_STATE_EOC_REG)
 {
 /*##-5- Get the converted value of regular channel ########################*/
 uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
 }

for regular ADC next levels is interrupt , triggered, DMA etc.

ssipa.1
Visitor II
January 28, 2022

Try to check your code. in means of the maximum screen showing or any stored value

ZKURT.1
ZKURT.1Author
Senior
January 28, 2022
#define VREFINT_CAL_ADDR			0x1FF80078
#define VREFINT_CAL 				((uint16_t*) VREFINT_CAL_ADDR)
 HAL_ADC_Start(&hadc);
	HAL_ADC_PollForConversion(&hadc, 100);
	uint16_t VREFINTADC = HAL_ADC_GetValue(&hadc);
	HAL_ADC_Stop(&hadc);
	float VDD = 3000.0 * (*VREFINT_CAL / (float) VREFINTADC);

Hi. this is my code i am debugging it returns 0

MM..1
Chief III
January 28, 2022

start with only show VREFINTADC

or normal calculated 3300 * getedval / 4096 for 12bit ADC

or add use

HAL_ADCEx_Calibration_Start(&hadc)

float conv is last step after all works

And method for measure with Vref help is explained How to get the best ADC accuracy in STM32 microcontrollers - Application note