cancel
Showing results for 
Search instead for 
Did you mean: 

Problem reading analog values from 3 different potentiometers on STM32 Nucleo-F446RE

AP.10
Associate II

I have been trying to use three pots as dials for a guitar effects pedal project. Their purpose is to simply read the voltage from 0 - 3.3V and with some scaling (to turn the raw readings into 0-100 values) in the code to store these 3 values inside an array of length 3 and also display them in my LCD. I have tried to use one pot per ADC (3 onboard) as well as different channels on the same ADC.

The weird thing is that it works as intended for the first 2 pots but if I add the 3rd one with the same ADC configurations it simply won't read. The value stays oscillating as if the pin was free or grounded.

I am using pins PA0, PA1, and PA2 for ADC1, ADC2, and ADC3 respectively. I am using 3.3V as the input for the pots. Please let me know if anything occurs to you or have had a similar issue in the past!

Here is my current code main and ADC init configs (all 3 are the same)

------------------------------------------------------------------------------------------------------------------

int main(void)

{

 /* USER CODE BEGIN 1 */

 /* 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_ADC1_Init();

 MX_ADC2_Init();

 MX_ADC3_Init();

 /* USER CODE BEGIN 2 */

 lcd16x2_init_4bits(URS_GPIO_Port, URS_Pin, UE_Pin, UD4_GPIO_Port, UD4_Pin, UD5_Pin, UD6_Pin, UD7_Pin);

 lcd16x2_setCursor(0, 0);

 lcd16x2_cursorShow(0);

 HAL_Delay(500);

 HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);

 HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);

 lcd16x2_clear();

 lcd16x2_printf("   ADEPT");

 HAL_Delay(1500);

 lcd16x2_clear();

 lcd16x2_setCursor(1, 0);

 lcd16x2_printf("  FX System");

 HAL_Delay(1500);

 HAL_ADC_Start(&hadc1);

 HAL_ADC_Start(&hadc2);

 HAL_ADC_Start(&hadc3);

 /* USER CODE END 2 */

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

 // Poll ADC1 for PotA

 HAL_ADC_PollForConversion(&hadc1, 1000);

 // Store value reading for PotA

 potValues[0] = HAL_ADC_GetValue(&hadc1);

 // scale value between 0 and 99

 scaledValuePA = potValues[0] * 0.0247821;

 if(scaledValuePA > 99) {

 scaledValuePA = 99;

 }

 HAL_ADC_PollForConversion(&hadc2, 1000);

 potValues[1] = HAL_ADC_GetValue(&hadc2);

 scaledValuePB = potValues[1] * 0.0247821;

 if(scaledValuePB > 99) {

 scaledValuePB = 99;

 }

 HAL_ADC_PollForConversion(&hadc3, 1000);

 potValues[2] = HAL_ADC_GetValue(&hadc3);

 scaledValuePC = potValues[2] * 0.0247821;

 if(scaledValuePC > 99) {

 scaledValuePC = 99;

 }

 //Display Effect 1 Screen

 lcd16x2_1stLine();

 lcd16x2_printf(" Distortion");

 lcd16x2_2ndLine();

 //lcd16x2_printf(" A:00 B:00 C:00 ");

 //lcd16x2_printf("Value1 = %.1f", 123.45))

 lcd16x2_printf(" A:");

 lcd16x2_printf("%d", scaledValuePA);

 lcd16x2_printf(" B:");

 lcd16x2_printf("%d", scaledValuePB);

 lcd16x2_printf(" C:");

 lcd16x2_printf("%d", scaledValuePC);

 //lcd16x2_printf("%d", scaledValuePC);

 //updateLCD();

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

 }

 /* USER CODE END 3 */

}

-------------------------------------------------------------------------------

static void MX_ADC1_Init(void)

{

 /* USER CODE BEGIN ADC1_Init 0 */

 /* USER CODE END ADC1_Init 0 */

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC1_Init 1 */

 /* USER CODE END ADC1_Init 1 */

 /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

 */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.ScanConvMode = DISABLE;

 hadc1.Init.ContinuousConvMode = ENABLE;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.NbrOfConversion = 1;

 hadc1.Init.DMAContinuousRequests = DISABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

 */

 sConfig.Channel = ADC_CHANNEL_0;

 sConfig.Rank = 1;

 sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN ADC1_Init 2 */

 /* USER CODE END ADC1_Init 2 */

}

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> But for now, would you recommend for me to use three separate ADCs as I am attempting now? or is it a better approach to use one ADC with 3 different channels?

Either approach will work. A single ADC converting 3 channels and transferring them directly to memory with ADC will be harder to set up, but easier to use once it's set up.

> STM32 Nucleo-F446RE

In this case, the most likely explanation is that SB63 isn't closed, so D1 isn't connected to PA2.

0693W00000FDBgsQAH.png 

0693W00000FDBgxQAH.png

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6

Read out and check/compare/post content of the ADCs registers and content of relevant GPIO registers.

JW

TDK
Guru

> The weird thing is that it works as intended for the first 2 pots but if I add the 3rd one with the same ADC configurations it simply won't read. The value stays oscillating as if the pin was free or grounded.

Can you describe this more objectively? If you try to convert 3 pins as in the code you posted, what values are you getting out? Is only the third value "incorrect" or are all of them not as expected?

If you feel a post has answered your question, please click "Accept as Solution".
AP.10
Associate II

ADC1 and ADC2 readings are correct (0 - 4095 raw values as I turn the pot from start to end position). Only the third value which is the ADC3 reading is incorrect (the raw value is within range but stays the same regardless of the pot turning) I made sure that the ADC3 setting is in continuous reading mode. I will post more details once I plug everything back in. But for now, would you recommend for me to use three separate ADCs as I am attempting now? or is it a better approach to use one ADC with 3 different channels?

TDK
Guru

> But for now, would you recommend for me to use three separate ADCs as I am attempting now? or is it a better approach to use one ADC with 3 different channels?

Either approach will work. A single ADC converting 3 channels and transferring them directly to memory with ADC will be harder to set up, but easier to use once it's set up.

> STM32 Nucleo-F446RE

In this case, the most likely explanation is that SB63 isn't closed, so D1 isn't connected to PA2.

0693W00000FDBgsQAH.png 

0693W00000FDBgxQAH.png

If you feel a post has answered your question, please click "Accept as Solution".
AP.10
Associate II

So it seems that there is no way to use use the ADC3 through D0 or D1 without making hardware changes, correct? Also, I am using the nucleo board to prototype before transferring code to our custom PCB. In the case of the stm32 chip on the PCB, I am thinking this would not be an issue since it looks like this setup is specific to the nucleo board?

Also I should mention I got it to work using pin PC3 on the Nucleo board, which confirms that pins PA2 and PA3 do not seem to be connected to D1 and D0 as you mentioned. So thanks for clarifying that!