Arduino_core_stm32: ADC reference voltage and accuracy

Created on 13 Sep 2019  路  25Comments  路  Source: stm32duino/Arduino_Core_STM32

Hi, I've noticed that there is a difference between the ADC output for these board files when using a STM32F103C8T6 blue pill module, and when using board files available here: http://dan.drown.org/stm32duino/package_STM32duino_index.json

I decided to look into this a bit further. I created a voltage resistor divider with two 100K resistors and measured the ACD output on PA1. The Vcc is 3.25v and the voltage divider is 1.62v. That's about 49.8% of Vcc. Next with the provided link board files (dan.drown.org) (using the Arduino IDE 1.8.9) I got an ADC value of 2050 of 4096 which is about 50%. But, using the board files available here (v1.6.1), I only get an ADC output of 1670 of 4096 which is about 40%.

This I believe shows that the ADC is off by about 10% using these board files.
Perhaps there is an issue with how the voltage reference is created?
Please let me know if you need any more information from me.
Thanks,
Alex

Answered Question

All 25 comments

100K voltage divider is a very weak current source. you'd need a very long sampling time in that case. use lower resistor values.

if only the different board files can explain your observation, they probably set different ADC sampling times and frequencies.

Thank you! Trying to figure out how to increase the sampling time now.

Hi @acbaruth
I've made the test and got same result btw both core using potentiometer.
I gues @crackwitz is right.

On 1.6.1 the ADC sampling time is set to ADC_SAMPLETIME_13CYCLES_5 on the next release this will be ADC_SAMPLETIME_8CYCLES_5.
You can change it by redefining ADC_SAMPLINGTIME:
https://github.com/stm32duino/Arduino_Core_STM32/blob/9bbac221af356ba9ab2852ccc3226ce86e49c631/cores/arduino/stm32/analog.cpp#L57

Thank you for the feedback @fpistm
I've tried modifying these values in build_opt.h with:
-DADC_SAMPLINGTIME=ADC_SAMPLETIME_8CYCLES_5
I've tried many different values, and have changed a few other parameters, but have seen no change in the ADC output yet. I've also tried editing analog.cpp without any luck as well.
I should add that when I changed to 10K resistors the ADC value seemed correct. However I'm trying to read a 100K thermistor so changing the sample time seems to be the only option.

I guess you set analog red resolution to 12 bits using:
analogReadResolution(12);

@fpistm, Yes, this is correct.

100K thermistor

The usual circuit for that has a 4.7K pull up resistor, the thermistor and in parallel a 10碌F ELKO to GND.
With that impedance is usually not a problem.

@AnHardt Interesting, I'll have to look into that. But speaking of usual, the simple divider circuit has always worked in the past for me with The Atmega328P, as well as the stm32f103c when using Dan Drown's core. It's odd @fpistm wasn't able to get the same result as I do with the Dan Drown core. Perhaps I'll wait for the next release to see if my attempted modifications of SAMPLETIME are the problem.

SAMPLETIME is not the problem, I've tested with default 1.6.1 and get the same result than roger's core.

Hi @acbaruth
Could you try the last release 1.7.0?
Even If I doubt this change anything on your side.

Hello @fpistm,
I've updated to 1.7.0 (as well as the Arduino IDE 1.8.10) and tried again.The 100K divider is still about 10% different from 10K divider.
Thanks for checking back back.

Could you provide the sketch you used? Is it analogReadSerial ?

It was pretty similar to analogReadSerial, I tried that sketch and got the same result.

Hi @acbaruth
I had some time to dig into this.
I setup a voltage resistor divider with two 100K resistors and get the same result.
Increasing sampletime to ADC_SAMPLETIME_239CYCLES_5 solve your issue.
Roger's core use per default a higher sample time that's why you see this difference.
Anyway as @crackwitz said 100K is a huge value for 3.3V ref.

HI @fpistm,
I've added -DADC_SAMPLETIME=ADC_SAMPLETIME_239CYCLES_5 to build_opt.h which is in the sketch directory. Looks like it's compiling with that file. https://pastebin.com/UM41Hqee But I'm not seeing any change in ADC output.

-Dname=value is for command line invocation
in a header file, you say #define name value

@crackwitz this is ok. This is the correct syntax for build_opt.h:
https://github.com/stm32duino/wiki/wiki/Customize-build-options-using-build_opt.h
@acbaruth when you told it is in the sketch folder, you sais in the source sketch folder or in the build folder?
Please, ensure the build_opt.h in the build folder contains the definition. I will check on my side if this is ok using it, I've tested modifying in analog.cpp.
And ensure it is well used as described in the warning:
https://github.com/stm32duino/wiki/wiki/Customize-build-options-using-build_opt.h#warning

Hello @fpistm,
I've added the build_opt.h initially to the sketch folder, along side the .ino file. I also found the file in the build directory here: C:\Users\Datz\AppData\Local\Temp\arduino_build_802581\sketch\build_opt.h looks like it was copied over. I've turned on verbose logging, but cannot find either message from that warning. I'll look into modifying analog.cpp.

OK that is the normal behaviour.

@acbaruth

I've added -DADC_SAMPLETIME=ADC_SAMPLETIME_239CYCLES_5 to build_opt.h

This is not the correct definition name, this is the correct one: :wink:
-DADC_SAMPLINGTIME=ADC_SAMPLETIME_239CYCLES_5

Wow, that works! Thank you.

PS. I've been looking at different values of SAMPLINGTIME in analog.cpp, but the code seems not to want to compile with certain values. Is the default value ADC_SAMPLETIME_13CYCLES_5? I was trying to look for the lowest value possible to still get accurate readings.

The code in analog.cpp is for definig the value for each series, this is not all possible value for STM32F1.
Here are the values:
https://github.com/stm32duino/Arduino_Core_STM32/blob/964576b1295606dcabeb7fd537cc444d44de1350/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h#L315-L322

Wonderful, thank you.

Is it OK now to close?

Assume it is OK.

Was this page helpful?
0 / 5 - 0 ratings