9 years, 8 months ago.

AnalogIn::read_u16 function returns 0..4095. (NUCLEO-F103RB)

When I tried the following code on NUCLEO-F103RB, read_u16 function returned values between 0 and 4095.

  1. include "mbed.h"

AnalogIn adin(A0);

int main() { while(1) { printf("%d %f\n",adin.read_u16(),adin.read()); } while } main

However, the API document on the read_u16 function says "16-bit unsigned short representing the current input voltage, normalised to a 16-bit value." So I expected that I got values between 0 and 0xfff0(65520). Is this a bug in the API library for NUCLEO-F103RB?

In addition, the sample program provided by STMicro that shows how to use AnalogIn is as follows. (You can get this sample at https://mbed.org/teams/ST/code/Nucleo_read_analog_value/?platform=ST-Nucleo-F103RB .)

  1. include "mbed.h"

AnalogIn analog_value(A0);

DigitalOut myled(LED1);

Calculate the corresponding acquisition measure for a given value in mV

  1. define MV(x) ((0xFFF*x)/3300)

int main() { while(1) { uint16_t meas = analog_value.read_u16(); Converts and read the analog input value if (meas > MV(1000)) { If the value is greater than 1000 mV toggle the LED myled = !myled; } wait(0.2); 200 ms } }

The line

  1. define MV(x) ((0xFFF*x)/3300)

implies that the programmer who ported mbed library to Nucreo family thinks the read_u16 function returns a raw value of an A/D conversion, I guess. Is this right?

Question relating to:

Seems indeed he made a mistake, it is supposed to scale the raw value to 16-bit format.

posted by Erik - 03 Aug 2014

Thank you for your reply. I'm new to mbed. So I lacked confidence in my idea.

posted by Hiroshi Tanigawa 03 Aug 2014

Yes, it returns ADC raw sample in this case and I believe "normalization" does not happen for many other targets neither.

posted by Martin Kojtal 04 Aug 2014

1 Answer

9 years, 6 months ago.

I believe the ST32 arm chips have 12-bit resolution ADC's. So it looks like the raw reading is correct. you should get only 4096 total steps or 0 to 4095. With a reference voltage to 3.3V. So it's good that whatever is going on in the background returns the proper value. Otherwise you would get spurious readings.

Someone please comment on this. This is my current noob understanding of the STM32 arm chips from reading the datasheet documentation.

You are correct. However in order to have better portable code between targets the read_u16 function was intended to normalize it to 16-bits. Depending on how you do this, this requires either one or a few extra clock cycles, so the overhead is very low, especially compared to the floating point option (and then especially on the M0 targets, which aren't that good with floats).

In the meantime this should have been fixed, and the Nucleo targets now scale it to 16-bits I believe. (NXP ones already did, and Freescale ones had ADC set in 16-bit mode, so it was never an issue).

posted by Erik - 08 Oct 2014