在 LCD 上显示浮点数

Display floating point numbers on an LCD

如何获取变量伏特以在 LCD 上显示浮点数?

LCD只显示小数点后有很多E结尾的浮点数。我只需要2位小数,那我怎么显示呢?

int main (void){

    adcinit();

    lcd_init();//initializes LCD
    lcd_clear();//clear screen
    lcd_home();


    uint16_t value;
    float volts;
    while(1){
        ADCSRA |= (1<<ADSC);//start ADC conversion
        delay_ms(54);//delay 54 millisecond
        value = ADCW;//assign ADC conversion to value
        volts=(value*5)/1023;
        lcd_goto_xy(0,0);// coordinates of the cursor on LCD Display
        lcd_printf("ADC Value: %d ",value);//display on LCD
        lcd_goto_xy(0,1);// coordinates of the cursor on LCD Display
        lcd_printf("Volts: %f ",volts);//display on LCD
    }
}

试试这个:

编辑:我刚刚编辑了电压显示,因为值是整数。但是原理是一样的。

int main (void){

    adcinit();

    lcd_init();//initializes LCD
    lcd_clear();//clear screen
    lcd_home();


    uint16_t value;
    float volts;
    while(1){
        ADCSRA |= (1<<ADSC);//start ADC conversion
        delay_ms(54);//delay 54 millisecond
        value = ADCW;//assign ADC conversion to value
        volts=(float)(value*5)/1023;
        lcd_goto_xy(0,0);// coordinates of the cursor on LCD Display
        lcd_printf("ADC Value: %d ",value);//display on LCD
        lcd_goto_xy(0,1);// coordinates of the cursor on LCD Display
        lcd_printf("Volts: %.2f ",volts);//display on LCD
    }
}

如果函数 lcd_printf() 与 Arduino 的函数 sprintf() 基于相同的库,格式说明符 '%f' 即使用作 '%.2f'.

第一步:在提出备选方案之前,有必要从模数转换器读取的数值中得到一个计算良好的浮点值。

If the ADC is a 10-bits, the range should be 1024 (instead of 1023).

value = ADCW;//assign ADC conversion to value
volts=((float)value*5.0f)/(1024.0f); 

Step2.1: 显示 2 位小数固定浮点值的第一个快速解决方案是将其转换为 2 个整数。

lcd_printf("Volts: %d.%02d ",(int)volts, (int)(volts*100)%100));//display on LCD

而不是

lcd_printf("Volts: %.2f ",volts);//display on LCD

步骤 2.2: 显示 2 位小数固定浮点值的更 'official' 解决方案是使用 dtostrf() 函数,如 "Arduino sprintf float not formatting".

char str_volts[15]; // to store the float-to-string converted value
lcd_printf("Volts: %s ",dtostrf(volts, 4, 2, str_volts));//display on LCD
// 4 = minimum number of char ('X.XX'), 2 = number of decimals

而不是

lcd_printf("Volts: %.2f ",volts);//display on LCD

我在原文 post 的最后一句中回答问题 - 而不是标题。但这是您项目的正确答案。

你说 "I only need 2 decimal places" - 所以这应该告诉你不需要浮点数学。物理学家和工程师需要浮点数来表示非常、非常小或非常、非常大的数量,但您需要 "fixed point" - 这意味着进行整数数学运算并正确选择您的单位。定点更快、更准确并减少了编译二进制文件的大小,因为不需要浮点代码。

最简单的解决方案是使用整数并显示毫伏,就像您刚刚使用的 delay() 函数采用毫秒整数而不是秒的小数作为参数一样。

#define VREF 5000
uint32_t mvolts;
.
.
mvolts=(value*VREF)>>10; // No floats here...
lcd_printf("milliVolts: %d",mvolts); // ...and no casts

如果您必须显示伏特,那么这样做就可以了:

lcd_printf("Volts: %d.%02d ",mvolts/1000, (mvolts%1000)/10);

请注意,顺便说一句,mvolts 是一个 32 位整数,因为您现在将 10 位数字乘以 5000,而这不适合 16 位。这是必需的,因为您需要在进行缩放时保持值的准确性。我认为这不是标题 off-topic,因为我认为您确实想要显示 正确的 值,否则显示那两位小数没有意义。

除非你小心,否则编译器会计算出 5000/1024 的值 - 4.8828125 - 然后进行整数运算,这会去掉小数部分并最终将你的 ADC 结果乘以 4。为了保证正确的行为,乘以 5000 然后除 - 2 个单独的操作。由于1024是2**10,右移十位等于除以1024

最后 - 不要假设从 ADC 读取 1023 实际上意味着 5.000 伏特到 4 位有效数字;通过调整 #define VREF 来校准经过测试的电压表以获得正确的结果。