Arduino:printf / fprintf打印问号而不是浮点数

我有一个Arduino草图的以下代码:

#include  LiquidCrystal lcd(12, 11, 5, 4, 3, 2); static FILE lcdout = {0} ; static int lcd_putchar(char ch, FILE* stream) { lcd.write(ch) ; return (0) ; } void setup() { lcd.begin(16, 2); fdev_setup_stream (&lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE); } void loop() { stdout = &lcdout; printf("%.2f Volts", 2.0); } 

问题出现在代码的最后一行。 这应该打印出“2.00伏特”,而是打印“?伏特”(问号而不是实际的浮点值)。 如果我尝试格式化整数,这很有用。

所以基本上,如果我用以下内容替换printf行,它将正常工作:

 printf("%d Volts", 2); //prints correctly "2 Volts" 

知道问题是什么?

用于AVR的GNU工具链(包含在Arduino IDE中)默认使用C标准库的“缩小”版本,其中,例如,浮点支持减少/从格式化I / O函数中删除(只是为了使printf()能够适应芯片的几千字节长的存储空间。)

如果您希望这个工作,您必须使用-Wl,-u,vfprintf -lprintf_flt链接器标志-Wl,-u,vfprintf -lprintf_flt链接包含printf()的正常版本的另一个库。

avr-libc 文档 :

如果需要包括浮点转换在内的完整function,则应使用以下选项:

-Wl,-u,vfprintf -lprintf_flt -l

请注意,如果您的MCU没有任何浮点支持,则应尽量避免浮点运算。 浮点运算将在软件中完成,效率非常低,需要大量的闪存。

我做了这个:

 unsigned char buffer[32]; void setup() { serial.begin(); } void loop() { if(serial.available()) { int size = serial.read(buffer); if (size!=0) { //serial.write((const uint8_t*)buffer, size); int bright = atoi((char *) buffer); //int final = ((unsigned int)buffer[0]); //int final = bright -'0'; serial.write(bright); serial.write('\n'); } } serial.poll(); } 

当我通过usb发送0-255的值时,我得到一个ascii字符。 我应该找到一种方法将ascii char转换为int。

例如我输入65并打印A

我有一些旧的代码可能会有所帮助,如果你想完全避免printf,只需要在小数之前和之后使用给定的位数打印。 此代码在C中编译,并且在Arduino IDE中也可以正常工作。 它几乎肯定可以用更少的C ++行完成。 pow10可以通过编程方式完成,但CI版本中不支持以下function:

 #include  /* Because lcd and serial don't support printf, and its very costly, and all we need is simple formating with a certain number of digits and precision, this ftoa is enough. If digits is negative, it will pad left. */ #define BUF_LEN 20 char buf[BUF_LEN]; //need a buffer to hold formatted strings to send to LCD int ftoa(char * str, float f, char digits, char precision) { char i=0,k,l=0; long a,c; long pow10[10] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000}; unsigned char b; char decimal='.'; if(digits>=10) {return 0;}; // check for negative float if(f<0.0) { str[i++]='-'; f*=-1; (0=0) { c = pow10[k]; c = a/c; if(c>0) { break; } k--; } // number of digits in whole number are k+1 if (010) { //overflow decimal = 'e'; } /* extracting most significant digit ie right most digit , and concatenating to string obtained as quotient by dividing number by 10^k where k = (number of digit -1) */ for(l=abs(k);l>=0;l--){ c = pow10[l]; b = a/c; str[i++]=(l&&!b?' ':b+48); //digit or pad a%=c; } if (precision) {str[i++] = decimal;}; /* extracting decimal digits till precision */ if (0>precision) {k=0; precision=abs(precision);} for(l=0;l 

你可以玩它并看到它在这里运行: http : //ideone.com/AtYxPQ