2019-09-27 11:37 AM
I'm facing a problem trying to format floating point numbers in STM32CubeIDE. The uC is STM32F103. I've checked the "use newlib-nano to print floating numbers" in the project settings.
To narrow things down, I used the following code snippet to reproduce the error:
char strP[100];
uint16_t cx = 0;
cx = snprintf(strP, 100, "%6.2f, %6.2f, %6.2f, %6.2f", 0.0115697104, -0.0796313286, -0.0220388453, -0.111881733);
The error doesn't appear on every iteration of the example code. It works most of the time, actually. When it fails, it prints:
26815634999686289245754584189029181710324847797922429453525901675501503951146118153956426275383940846635237101275691881352391832390627762028461487571337216.00, 0.00, -0.00, 0.00"
Or:
0.00 2.00 0.00 2.00
Things I tried to fix the problem:
I'm sending some floating point numbers to the uart to plot inclinometer data on a PC. This issue is annoying me for some days. Any help would be appreciated. Thanks!
2019-09-30 06:48 AM
I think I'd be range checking my numbers and outputting an alerting message for that. You can also scale and print as integers as a secondary confirmation. Signs point to looking in the wrong place.
2019-09-30 06:48 AM
@Community member - Here's a reference that clarifies the variadic promotion and %lf business:
https://stackoverflow.com/questions/4264127/correct-format-specifier-for-double-in-printf/4264154
Hope that helps!
Best Regards, Dave
2019-09-30 07:43 AM
@Dave Nadler Increased heap from 0x200 (default) to 0x400 and also increased stack size from 0x400 (default) to 0x600. The problems seems fixed. Should I take this as the definitive solution?
2019-09-30 08:17 AM
@rrnicolay - Yes, but: Any decent embedded application incorporates checking of heap and stack use to ensure this kind of thing doesn't happen... FreeRTOS provides excellent stack-check facilities; heap is a little harder. You need to be sure you aren't going to run out of stack or heap.
Hope that helps,
Best Regards, Dave
2019-09-30 10:20 AM
I'm probably gonna switch for FreeRTOS in a close future. I'm already aware of the benefits. Thank you @Dave Nadler and @Community member !
2019-10-01 08:12 AM
Unfortunately, the problem is still there. Code:
char strP[100] = { '\0' };
uint16_t cx = 0;
cx = snprintf(strP, 100, "%5.2f, %5.2f, %5.2f", accScaled[0], accScaled[1], accScaled[2]);
if(accScaled[2] < 0.5) {
cx = 3; // Breakpoint in this line never gets triggered
}
if (cx > 0 && cx < 40) {
debug_printf("%s\r\n", strP);
}
void vprint(const char *fmt, va_list argp) {
char string[300] = { '\0' };
uint8_t sz = 0;
if (vsprintf(string, fmt, argp) > 0) {
sz = strlen(string);
HAL_UART_Transmit(uartHandler, (uint8_t*) string, sz, 0xffff);
}
}
/* custom printf() function */
void debug_printf(const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
vprint(fmt, argp);
va_end(argp);
}
In the attached file, the green line should never be "0".
i'm using 0x500 for heap and 0x700 for stack.
2019-10-01 11:48 AM
char strP[30] = { '\0' };
int16_t cx = 0;
cx = snprintf(strP, 30, "%5.2f", (float) 1.00);
float back2Float = atof(strP);
if (cx > 0 && cx < 30) {
if (back2Float != 1.00)
debug_printf("%s, %5.2f, %d\r\n", strP, back2Float, cx);
The strP is (sometimes) converted to " 0.00" in snprintf.
2019-10-01 11:58 AM
Have you established what your stack utilization actually is?
Perhaps use strstr() to trigger on the "0.00" pattern so you can break point on the first instance of failure. And chase the flow back from there.
2019-10-01 01:06 PM
2020-01-08 10:33 PM
Hi Nicolay
I have the same problem ( -0.00/ -2.00/ 0.00) but I m increase the heap and stack but the problem continue, same using keil, but when I m using visualGDB work fine, how fix your problem??