2024-02-20 10:59 PM
Hello ALL,
ADC values when 2 channel are disturbed when used in STM32L071 board. i have tried changing the sampling time of channels still no difference the voltage at that pin is around 2.5 volt but the ADC value after conversion i am receiving is around 1100- 1200. i am not using DMA mode can anyone suggest me any other ways to rectify it?
Thank you
Solved! Go to Solution.
2024-03-01 12:48 AM
Hello @RomainR.
The problem got solved when i deactivated the ADC0 channel i.e. PA0 after taking the sample and enabled again to take the sample.
Thank you so much for your suggestions.
Regards,
Nirav Mehta.
2024-02-21 12:52 AM
Hello @Nirav
Can you give more details about your application?
Which GPIO Analog ADCs do you actually use on your hardware and which ones are converted by your firmware?
Are you using a custom board, what is the VDDA and VSSA configuration, are they wired correctly? If your STM32L073 package has VREF+/VREF- pins, same comment.
Let me know?
Best regards,
Romain,
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.
2024-02-21 02:30 AM
Hello @RomainR.
I am using channel 0 and channel 8 which are connected to GPIO PA0 and PA8 and yes we are using a custom board the VDDA is 3.3 V, yes they are wired correctly also we are using STM32L071 STM32L073.
Best Regards,
Nirav
2024-02-21 02:44 AM
@Nirav Thank you for your details
I'm ok with PA0 is ADC_IN0 channel.
But PA8 is not an ADC channel 8, and this GPIO is not associated with the ADC.
If you refer to DS10685, the Table 16 list all pin definition with ADC additional functions (right column)
It is PB0 which is ADC_IN8.
Best regards,
Romain,
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.
2024-02-21 02:47 AM
Hello @RomainR.
Sorry for the confusion i created we are using PB0 as channel 8 as you mentioned.
Regards,
Nirav
2024-02-21 03:06 AM - edited 2024-02-21 03:07 AM
Ok, if you are confident about the hardware side, let's check firmware side.
How do you use the ADC with the 2 channels PA0 ADC_IN0 and PB0 ADC_IN8.
There is no ADC sequencer on the L0 family, you must do this via firmware and query each of the regular conversions. You can refer to this discussion below for more detail:
Best regards.
Romain,
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.
2024-02-21 03:32 AM
Hello @RomainR.
void ADC_Select_CH8(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = 8;
//sConfig.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
/****************************************************************************************************/
/***************** Channel 0 for temperature ************************************************/
void ADC_Select_CH0(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 0;
//sConfig.SamplingTime = ADC_SAMPLETIME_39CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
/****************************************************************************************************/
float largest(float arr[], int n)
{
int i;
// Initialize maximum element
float max = arr[0];
// Traverse array elements from second and
// compare every element with current max
for (i = 1; i < n; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
/********************************************************************************
* Read J1772 ADC values
*/
void Read_J1772_ADC_Value(void)
{
ADC_Select_CH8();
//HAL_Delay(1);
for(int i=0;i<20;i++)
{
//HAL_Delay(1);
HAL_ADC_Start(&hadc);
HAL_Delay(5);
if(HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY) == HAL_OK)
{
HAL_Delay(5);
adc_raw_value2 = HAL_ADC_GetValue(&hadc); //for debugging purpose
adc_value[i] = (adc_raw_value2 * (3.3/4096));}
HAL_ADC_Stop(&hadc);
}
GetADCVal_J1772 = largest(adc_value, 20);
//dataMeterSystem.J1772_adc_val = (GetADCVal_J1772*12.34) - 21.05; //test at udaipur
// dataMeterSystem.J1772_adc_val = (7.350*GetADCVal_J1772) - 10.90; //Actual on circuit
//dataMeterSystem.J1772_adc_val = (7.350*GetADCVal_J1772) - 10.00; //Actual on circuit
dataMeterSystem.J1772_adc_val = (7.350*GetADCVal_J1772) - 8.00;
}
void Read_Temp_ADC_Value(void)
{
ADC_Select_CH0();
HAL_ADC_Start(&hadc);
if(HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY) == HAL_OK)
{
adc_raw_value = HAL_ADC_GetValue(&hadc); //for debugging purpose
adc_value[0] = (adc_raw_value * (3.3/4096));}
HAL_ADC_Stop(&hadc);
GetADCVal_Temp = adc_value[0] ;
//dataMeterSystem.Temperature = (GetADCVal_Temp*26.303833) + 2; //Actual on circuit * 26.303833)-1
dataMeterSystem.Temperature[0] = (GetADCVal_Temp*26.303833) - 2;
}
As you can see here we are using both channel to read different things PA0 is used for external temperature measurement and PB0 is used to measure input from NCV20072DR2G IC but the data from the IC get's distorted after some time
2024-02-21 04:35 AM
We cannot see ADC configuration in your code, and ADC Clock (must be <= 16MHz in VOS Range 1), and all common settings.
If PB0 ADC_IN8 provide some unexpected results after some time, how much ADC raw conversion value is deviated? What's about the voltage applied to PB0 input at the same time (from NCV2007DR2G OPAMP IC) ?
Try the code STM32CubeL0 example on your hardware, change the code from PA0 to PB0 and check the conversion results?
\STM32Cube_FW_L0_V1.12.2\Projects\NUCLEO-L073RZ\Examples\ADC\ADC_RegularConversion_Polling,
Check again your analog signal chain at the input of the NCV2007DR2G , and at its output.
Best regards,
Romain,
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.
2024-02-21 05:16 AM
> //sConfig.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
This line isn't doing anything.
General tips to improve ADC accuracy are here:
Connect the pins to GND, verify output is at/near 0.
Connect pins to VREF+/VDDA, verify output is at/near 4095.
2024-02-26 03:11 AM
Hello @RomainR.
Here is the ADC setting required by you
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
We first use channel 0 and than channel 8 to read the data but the ADC value is not correctly measured also when i only use single channel i am getting perfect value in both function
ADC value when using channel 0 should be around 1200 normally and for channel 0 it should be around 3800 to 4000 but it's not working that way.
Thanks
Nirav