← index #6572PR #5033
Related · high · value 1.149
QUERY · ISSUE

NRF52840: ADC is 8 bits, how to set to 12 bits?

openby JPFrancoiaopened 2020-10-25updated 2024-09-13
enhancementport-nrf

Hi,

I have been playing with the latest version of micropython on the nrf52840 USB dongle. The temperature over bluetooth example works perfectly for me (as a proof that micropython is properly flashed on the board).

I wanted to try and read some values from the ADC pins. I wired the pin 0.29 to a potentiometer, and initialized an ADC object:

from machine import ADC
adc = ADC(5)
adc.value()

However, I could only get values between 0 and 255 (0 when the potentiometer was turned to the minimum, 255 when turned to the maximum). This obviously means the ADC has an 8-bits resolution

The specs of the board tell us we can use 8, 10, 12 and even 14 bits of resolution (with oversampling): https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.0.pdf

I wasn't able to find a method in the ADC class to set the resolution of the ADC. Is it possible in the current state of micropython for the nrf boards?

CANDIDATE · PULL REQUEST

Implement consistent machine.ADC with read_u16() method

closedby dpgeorgeopened 2019-08-21updated 2021-02-02

This PR implements the beginnings of a revised machine.ADC class which is intended to make the ADC class more standardised across ports. See #3943 and #4213 for background discussion.

The PR here implements the following (simple) API for stm32, esp8266, esp32 and nrf ports:

from machine import ADC

adc = ADC(source) # source can be a pin or channel (eg int)
adc.read_u16() # take a reading, returning a value between 0 and 65535 inclusive

On stm32 the source can be any pin that has ADC support, or a constant ADC.CORE_VREF, ADC.CORE_VBAT, ADC.CORE_TEMP for internal channels. It will pick the correct ADC peripheral that supports that source (eg ADC1, ADC2 or ADC3). Other ports support taking a pin and/or a channel number.

The method read_u16() is named to emphasise the units, that it's an unsigned 16-bit number, and is the raw ADC reading scaled to 16 bits.

The aim of this PR is to make basic ADC functionality available in a consistent way across ports. Other things (eg setting resolution, sample time, selecting ADC peripheral block) can be added later, but at least construction and reading (implemented by this PR) are necessary features and the approach taken here is hopefully obvious and not controversial (up to perhaps the name read_u16). In other words, it should be possible to decide on the API presented here regardless of how additional features (mentioned above) might be implemented and exposed to the user.

Comments/discussion are very welcome.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied