This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

[mbed] What exactly does the return value of AnalogIn::read_u16() means?

According to this post, and this GitHub source file, in the nRF51 chip's mbed implementation:

  • The ADC reference voltage is 1/3 power supply
  • read_u16() seems to return NRF_ADC->RESULT
  • NRF_ADC->RESULT maximum possible value would be 0x3FF, when ADC input equals to ADC reference voltage.

From an experiment I just ran, I observed the following

  • At ADC input of ~897mV, read_u16() returns ~0x011a, or 282 decimal.
  • At ADC input of ~520mV, read_u16() returns ~0x00b9, or 185 decimal.
  • Leaving the ADC input pin floating, read_u16() returns ~0x00af, or 175 decimal.

Using linear approximation with the first two data points, at read_u16() value of 0x03FF, the ADC input should be >4V.

If using only one of those data points with the assumption that at 0V input, read_u16() returns 0, then 0x03FF still means a voltage >3V.

These numbers certainly cannot be 1/3 power supply! What could be going on here? Am I misunderstanding something?


Just in case this fact is the reason to the problem: To conduct my experiment, I use a (1M - 220k) voltage divider to supply 1/6 of VDD or 5V to the analog input.


On another note, according to mbed's Analog In reference and the AnalogIn.h header file, read_u16() returns "input voltage, represented as an unsigned short in the range [0x0, 0xFFFF]". This description sucks. But at the same time it doesn't seem to be what nRF51's implementation of the function is returning. Is there any comment on this?

Parents
  • Hello.

    From analogin_init in the github document you linked:

    (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
    (ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) |
    

    This prescales both the input and reference by 1/3. The reference is VDD (3v). I find this to match your numbers.

    The maximum value is 0x3FF because the nRF51 ADC support maximum 10 bit resolution.

    Update 1:

    Let me give you an example.

    • You have 3v VDD, this is scaled to 1V.
    • The input voltage is 500 mV = 0.5 V. This is scaled to about 167 mV.
    • The adc will give you (0.167/1) * 1023 = ~170.

    With your numbers:

    • We have about 3V VDD. We apply the scaling in the equation (*0.33)
    • 897 mV input gives (897 * 0.33/3000 * 0.33) *1023 = ~305. Your result of 282 is given because VDD is not exactly 3v, but a bit higher.
    • 520 mV input gives (520 * 0.33/3000 * 0.33) *1023 = ~177. Here your result is slightly higher. This can either be explained by a lower VDD (unlikely), or uncertainty in the measurement of the 520 mV. It can also be other factors in the external circuit, which might be worth investigating.
    • Wee see that the scaling of 1/3 can be removed from the equation. This means that the result you get from the adc is the input, divided by VDD, multiplied by 1023.

    -Anders

  • @anders-strand: Thanks for the update. It does seem like I have some misunderstanding of how the ADC value is calculated. I will review the nRF51 reference manual to get a better understanding of this and check back with you. Regarding more detailed data, unfortunately weekend has started where I am now, so I won't be able to get to that until Monday. Perhaps I will update with more data on Monday then.

Reply
  • @anders-strand: Thanks for the update. It does seem like I have some misunderstanding of how the ADC value is calculated. I will review the nRF51 reference manual to get a better understanding of this and check back with you. Regarding more detailed data, unfortunately weekend has started where I am now, so I won't be able to get to that until Monday. Perhaps I will update with more data on Monday then.

Children
No Data
Related