rtos

Tuesday, October 11, 2022

How to use Zephyr ADC with NRF9160DK?

Technical Terms:

1. What is meant by 8-channel ADC?

        8 Channel ADC in Microcontroller means 

    • 8 pins of microcontrollers can be used to receive that many analog signals which can in turn be digitized.
    • However and usually there is one ADC in the microcontroller. NRF9160 ADC
    • The inputs at the pin are selected and connected to ADC via. Analog Multiplexer (part of microcontroller or ADC) one at a time
    • ADC delivers the digital code of the analog signal at the channel or pin number, which is connected to its input at a given instance.
Analog-to-digital converters (ADCs) need a reference voltage (VREF) input in order to operate properly. ADCs convert analog inputs that can vary from zero volts up to a maximum voltage level which is called the reference voltage.
    When we use the internal reference 0.6V as the ADC reference voltage, we cannot pass a voltage of more than 0.6V to ADC pins directly. If we do so the ADC output will be undesired(sometimes it will show 1024 in if it's 10 bit and sometimes it may be reduced to lower just like variable overflow). To increase/decrease the input range above the reference voltage Gain is used.  

Gain is nothing but performing multiplication or division with the actual input voltage before passing it to the ADC converter. Check this image of ADC

You can see the Gain block present between the Input voltage and the ADC circuit. We can configure this Gain to which number to be multiplied or to be divided from the Input voltage in order to provide proper value to the ADC that matches the Reference voltage. 

Example: 

Assume we chose the Internal reference voltage which is 0.6 Volt.  According to theory, we cannot pass voltage above 0.6V to ADC Channels. Let's say you want to read the AA battery voltage which is 3.6 Max Voltage (for simplicity without a voltage divider). You need to use Gain in order to make ADC work in the range of up to 3.6V. You can select 1/6 gain. By doing so it will divide the incoming voltage by 6 and pass it to ADC. 

Assume you passed an input voltage is 3.6V to ADC Pin, and you selected gain as 1/6. then the Gain part in the circuit divides the 3.6V by 0.6V. output it 0.6V. Which is exactly not greater than the internal reference voltage. 

 Zephyr ADC Supports the below gain configurations.


/** @brief ADC channel gain factors. */
enum adc_gain {
ADC_GAIN_1_6, /**< x 1/6. */
ADC_GAIN_1_5, /**< x 1/5. */
ADC_GAIN_1_4, /**< x 1/4. */
ADC_GAIN_1_3, /**< x 1/3. */
ADC_GAIN_1_2, /**< x 1/2. */
ADC_GAIN_2_3, /**< x 2/3. */
ADC_GAIN_1, /**< x 1. */
ADC_GAIN_2, /**< x 2. */
ADC_GAIN_3, /**< x 3. */
ADC_GAIN_4, /**< x 4. */
ADC_GAIN_6, /**< x 6. */
ADC_GAIN_8, /**< x 8. */
ADC_GAIN_12, /**< x 12. */
ADC_GAIN_16, /**< x 16. */
ADC_GAIN_24, /**< x 24. */
ADC_GAIN_32, /**< x 32. */
ADC_GAIN_64, /**< x 64. */
ADC_GAIN_128, /**< x 128. */
};



If you select 1/6 as Gain then 
Input range = (0.6 V)/(1/6) = 3.6 V
You can pass up to 3.6V and the gain will divide by 1.6 and pass it to ADC


If you select 2 as Gain then 
Input range = (0.6 V)/(2) = 0.3 V

Convert the raw value to Volts

  •     Remember the Gain value Input range? We are going to use that now. 
Actual_Voltage = input_raw_value * (input_volt_range / resolution)
input_raw_value: Value read from adc_read(adc_dev, &sequence);function
input_volt_range: maximum input voltage range ex: if the gain is 1/6 then the max value is 0.6/(1/6) = 3.6.  here 0.6 is an internal reference voltage and 1/6 is the gain.
resolution10-bit ADC max value. 

Find the code in the Git repo

 https://github.com/manudevappa/zephyr_adc_sample

No comments:

Post a Comment

Guide to use ProtocolBuffers (nanopb) in IoT Devices.

 What is Protocol Buffer?      I hope the reader is familiar with JSON format. It's a widely used data format for communicating between...