Reading Analog Data in Zephyr with a nrf52840
It turned out to be much harder to read the ADC in Zephyr than I expected. As usual the documentation is slim and the syntax was a little strange partly because of the way the nordic nrf52 devices do analog input.
What’s key to know is that there’s one ADC (run as a nrf,saadc — successive approximation ADC) and it has 8 channels, corresponding to the 8 possible analog input pins (AIN0…AIN7). To do an analog read you specify which analog channel to use (out of the 8) and that defines which physical pin is used.
I added the following to prj.conf in the project to enable the adc sections during compiles,
CONFIG_ADC=y
CONFIG_ADC_ASYNC=y
and, i enabled it on the board by adding this to myboard.dtsi:
&adc { /* ADC */
status = "okay";
};
which enables the nrf52840 peripheral named ‘adc’.
I also added an (optional) alias so that the adc name applies somewhat hardware-independently. This is at the top of myboard.dtsi:
aliases {
... (other stuff)
adcctrl = &adc;
...
};
Having the alias lets us use a couple of zephyr macros to get the device name
DT_LABEL(DT_ALIAS(adcctrl))
in the source code.
Source Code
Working C code is below