STM32 ADC readings almost constant regardless of input voltage (Zephyr adc_dt sample) #106440
|
Hi everyone, I'm currently starting with Zephyr and running into issues with ADC readings that I can't explain. Setup Here is the overlay I'm using: Problem description No matter what voltage I apply to PA0 (ADC1_IN0), the readings barely change. I tested three conditions: PA0 connected to GND
Observation There is a difference between the three cases, but it's extremely small: GND ≈ 108134400 mV So the variation is only ~3,000 mV in the reported value, which clearly does not reflect the actual input range (0V → 3.3V). Also, the absolute values themselves seem completely off (very large raw values and unrealistic millivolt conversion). Additional notes Any help or pointers would be greatly appreciated. Thanks! |
Replies: 6 comments 3 replies
|
I found the cause and wanted to share in case it helps others. to made my measurements look correct on nucleo_f446re . Why this happens (my current understanding)For this setup, the ADC sample appears to be 16-bit wide, but the sample stores it in a 32-bit variable (buf) and then uses that value directly for single-ended channels. Current statusUsing uint16_t buf gives expected behavior (clear and realistic difference between GND / floating / 3.3V), but this may only be a workaround in the sample path and not the full root cause. SuggestionIt may help to make the sample safer by default (16-bit buffer, or masking/sign-extension based on resolution) to avoid confusion on targets where drivers write 16-bit samples. |
|
Hello, &adc3 { |
|
@DaviVolcan, @adtvtk, |
|
Hello, Maybe we should do the same for adc_dt ? |
|
Hi everyone, I’ve made some progress on this issue and wanted to share additional findings. At the moment, I already have a workaround working on the NUCLEO-F446RE. However, when testing on a different (Chinese) board using an STM32H743IIT6, I’m seeing a very similar problem — it looks like the ADC is not capturing the correct input range. Observed behavior
This makes it seem like the ADC is saturating or not using the expected resolution range. Prescaler investigationAfter reading issue #76493 and learning about the ADC prescaler, I tried increasing it (current value is 4), expecting it might help. However, every time I attempt to change the prescaler to a higher value, the build fails. I suspect there may be some limitation in the ADC driver, but I haven’t investigated that deeply yet. From what I saw in STM32CubeMX, the prescaler should be configurable up to 128. Clock configuration doubtsTo better understand the clock setup, I checked STM32CubeMX to visualize the clock tree, since I suspect this might be a clock misconfiguration on my side. While reading this application note: I noticed in Table 12 that for the STM32H743IIT6 (LQFP-176 with 3 ADCs), the maximum ADC clock for 16-bit resolution is 7 MHz (though I’m not completely sure I interpreted that correctly — I’ll revisit the document). Open questionsHow can I ensure the ADC is using PLL3 as its clock source in Zephyr? Hardware detailsExternal crystal: 25 MHz Device tree (WIP)stm32h743_coreboard.dts: stm32h743_coreboard.overlay: @gautierg-st — since you seem quite familiar with this area, any insights would be greatly appreciated. (UPDATE: I totally misunderstood table 12) |
|
Hi everyone, I finally figured out why it wasn’t working on the H7. An incorrect measurement initially led me down the wrong path — I thought I was measuring VREF at 3.3V, but I was actually measuring ANALOG_VDD, which is correctly at 3.3V. Both VREF and ANALOG_VDD share very similar circuitry, but ANALOG_VDD is connected to the 3.3V regulator, while VREF is routed to a header pin on the board. It turned out that VREF was actually disconnected and floating. Once I properly connected that pin to 3.3V, the measurements matched the expected values. A pretty stupid mistake, but it cost me quite some time to track down. I plan to document this properly when I upstream the board support. I'm currently waiting for the official documentation/schematics from the Chinese manufacturer, but communication with them has been a bit difficult, which slowed things down. I will still test the ADC clock configuration more thoroughly, but for now it seems to be working. Thanks, @gautierg-st ! Thanks a lot to everyone who helped! Regarding the issue pointed out by @basilegrunersmile , I’m not sure I’ll be able to look into it right away since I have exams this week at university. I’d also like to better understand Zephyr’s contribution guidelines before working on it. |
Hi everyone,
I finally figured out why it wasn’t working on the H7.
An incorrect measurement initially led me down the wrong path — I thought I was measuring VREF at 3.3V, but I was actually measuring ANALOG_VDD, which is correctly at 3.3V. Both VREF and ANALOG_VDD share very similar circuitry, but ANALOG_VDD is connected to the 3.3V regulator, while VREF is routed to a header pin on the board.
It turned out that VREF was actually disconnected and floating. Once I properly connected that pin to 3.3V, the measurements matched the expected values.
A pretty stupid mistake, but it cost me quite some time to track down. I plan to document this properly when I upstream the board support.
I'm cu…