2016-11-21 34 views
0

浮動小数点数をLCDに表示するにはどのように変数、voltsを取得しますか?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 
    } 
} 
+0

何を表示していますか? – immibis

+2

ここには 'volts =(value * 5)/ 1023'という問題があります。これらはすべて整数であるため、計算結果は整数になります。これはおそらくあなたが望むものではありません。 'volts =(value * 5f)/ 1023f'を試してみてください。 – msandiford

+0

ミリボルトを表示することを検討してください: '符号なしボルト=(値* 5000L + 1024/2/*この値をラウンド* /)/ 1024;に加算し、FP演算を避けてください。 – chux

答えて

0

機能lcd_printf()は、Arduinoのための機能sprintf()よりも、同じライブラリに基づいている場合、書式指定子'%f'がよく'%.2f'として使用する場合でも、管理されていません。

ステップ1:代替ソリューションを提案する前に、アナログ - デジタル変換器から読み取った数値から適切に計算されたフロート値を取得する必要があります。

ADCは10ビットの場合、範囲は(代わり1023)であるべきです。

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

Step2.1: 2-小数固定float値を表示するための第一及び迅速な解決策は2つの整数でそれを変換することです。代わり

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

ステップ2.2の

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

2-小数固定float値を表示するために、より「公式」溶液は"Arduino sprintf float not formatting"に提案されているようにdtostrf()関数を使用することです。

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 
0

これを試してみてください:

編集:値がintだったので、私はちょうど、電圧の表示、編集。しかし、プリンシペは同じでしょう。

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 
    } 
} 
+1

キャスティングが間違っているか、少なくともこのコードを読んでいる人にとっては明らかではないようです。典型的な値はボルト=(値* 5.0)/ 1023です。 (1023についてはここでは論じません) –

+0

キャストは部門の左側に適用されるので、読者が不必要に混乱しても正しいと思われます。 –

1

私は、オリジナルのポストの最後の文で質問に答えるよ - ない見出しを。しかし、これはあなたのプロジェクトにとって正しい答えです。

あなたは「私は小数点以下2桁しか必要ありません」と言っているので、浮動小数点数学の必要はないと言えます。物理学者やエンジニアは、非常に小さい、非常に大量の浮動小数点数を表現する浮動小数点数を必要としますが、整数定理を実行してユニットを正しく選択することを意味する「固定小数点」が必要です。固定小数点は、浮動小数点コードの必要がないため、コンパイルされたバイナリのサイズが小さく、迅速かつ正確になります。

最も単純な解決策は、使用したdelay()関数が秒数ではなく整数ミリ秒の引数をとるのと同じ方法で、整数と表示のミリボルトを使用することです。

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

あなたがボルトを表示しなければならない場合、これはトリックを行います。あなたは今、10ビット数を乗算しているのでミリボルトは、32ビットの整数であること、によって、

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

お知らせそれは16ビットに収まらないでしょう。スケーリングの実行中に値の精度を維持する必要があるため、これが必要です。 正しいの値を表示したいと思っている、または小数点以下2桁の表示に意味がないと考えているので、これは話題に向かっているとは思わない。

慎重でない限り、コンパイラは5000/1024 - 4.8828125の値を計算し、小数部を切り捨て、ADC結果に4を掛ける整数演算を行います。正しいことを保証するには5000を掛けた後、2つの別々の演算を除算します。 1024が2 ** 10で、10ビット右にシフトすることは1024で割ることと同じです。

最後に、ADCからの1023の読み取りが実際に5.000ボルトから4桁の有効数字を意味すると仮定しないでください。適切な結果を得るために、#define VREFを微調整して、試験済みの電圧計に対して較正してください。

+0

私の答えを編集したばかりなので、浮動小数点数が必要だと思うあなたの理由はスケーリングファクタを表すことかもしれません。それはそうですか?chuxとmsandifordはどちらも同じ問題について上記でコメントしています - 私はちょうど起こっていることをもっと長く説明しています。 –

+0

もしあなたがボルトのセントだけを必要とするならば、 'lcd_printf()'が 'mvolts%1000/10'のように正しい結果を得るために10で呼び出すなら、最後の式を分割しなければなりません。 –

+0

Luis: mVで考える。 –

関連する問題