How to convert uint32_t to double or float and print?

12.2k Views Asked by At

I'm using an analog to digital converter to read a voltage value from 0 to 3.3V. The ADC gives an output from 0x00 to 0x0FFF (0 to 4095). I want to print the voltage reading with two decimal places. I have read a number of answers but nothing I've tried has worked. Here's my code:

uint32_t pui32ADC0Value[1]; // ADC0 data value
double D0v;                 // Decimal value

// Read value from ADC
ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

// Convert to decimal
D0v = (double)pui32ADC0Value[0] / 4095 * 3.3;

// Print to console
UART0printf("\n\r> D0 = %.2d V", D0v);

The output I get is: D0 = ERROR2d V

pui32ADC0Value prints without any problems and gives the expected values, so I know that it is working.

What does this error mean?

NOTE: UART0printf is a pre-defined UART function on the TIVA TM4C microcontroller I am using.

UPDATE: I wrongly assumed UART0printf is identical to printf, as I have used it before with %u, %s, and %x. However for numbers it only supports %c, %i, and %u. I am re-working my code and will update if I don't get anywhere.

UPDATE 2: Could I do something like this? I know it will round incorrectly...

uint32_t pui32ADC0Value[1]; // ADC0 data value
uint32_t D0v[2];                 // Decimal value

// Read value from ADC
ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

// Convert to decimal
for ( int i = 0; i <= 2; i++){
    D0v[i] = (pui32ADC0Value[0]/10^i) / 4096 * 3.3;
}

// Display the AIN0 (PE0) digital value on the console.
UART0printf("\n\r> D0 = %d.%d%d V", D0v[0],D0v[1],D0v[2]);
2

There are 2 best solutions below

6
nnn On BEST ANSWER

If this function works printf like:

UART0printf("\n\r> D0 = %.2f V\n", D0v);

Also your code may work a little faster if you use:

D0v = (double)pui32ADC0Value[0] * (3.3 / 4095);

The compiler will precompute 3.3 / 4095 and will do a single floating point multiply operation. Otherwise it's possible that the division is done first (which usually takes much more CPU cycles than a multiply) and then the multiply * 3.3 will be done.

Also since you seems to need only 2 digit precision, you could use float (single precision) instead of double. It may execute faster (but it's possible to be even slower), this depends on the platform.

Update for UPDATE2 in the question:

Try this:

uint32_t pui32ADC0Value[1]; // ADC0 data value
uint32_t D0v;               // Decimal value

// Read value from ADC
ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

// Convert to millivolts
D0v = pui32ADC0Value[0] * (3300.0 / 4095);

// Display the AIN0 (PE0) digital value on the console.
UART0printf("\n\r> D0 = %d mV", D0v); // If it's OK for you to display in mV
UART0printf("\n\r> D0 = %d.%03d V", D0v / 1000, D0v % 1000); // Print in V
0
Lightness Races in Orbit On

There is no such printf format string as

%.2d

The formatter %d means integer, so there are no decimal-precision options for it. The %. is being parsed as an error (as it does not exist), and the 2d is making it verbatim into your output.

The formatter for floating-point values is %f, so:

%.2f

However, all this is based on the assumption that UART0printf, which you do not identify in your question whatsoever, is identical to printf.