How to fix mbed AnalogIn.read_voltage() returning nan or 0.000 (PlatformIO)

Problem:

You are trying to read an ADC voltage in mbed / PlatformIO like this:

AnalogIn myADC(PA_5); 
// Read and print voltage, then return
float v = myADC.read_voltage();
printf("%f\n", v);

but this only prints nan or 0.000.

Solution:

mbed doesn’t know the reference voltage for your platform. The easiest method is to provide the referene voltage in the constructor of AnalogIn:

AnalogIn myADC(PA_5, 3.3);

This specifies a reference voltage of 3.3V. While this applies to most applications in their default configuration, note that the reference voltage might be different depending on the configuration of your microcontroller.

In my experience, it’s almost always better to experimentally verify the reference voltage instead of trying to theorize about it if it’s not immediately obvious.

Full example:

#include <mbed.h>

BufferedSerial pc(USBTX, USBRX, 115200); // tx, rx

AnalogIn   myADC(PA_5, 3.3);

FileHandle *mbed::mbed_override_console(int fd) {
    return &pc;
}

int main() {
  while(1) {
    float v = myADC.read_voltage();
    printf("%f\n", v);
    ThisThread::sleep_for(100ms);
  }
}
{
    "target_overrides": {
      "*": {
        "target.printf_lib": "std"
      }
    }
}