2016-11-21 7 views
0

Wie bekomme ich die Variable, Volt, um Gleitkommazahlen auf einem LCD anzuzeigen?Gleitkommazahlen auf einem LCD anzeigen

Das LCD zeigt nur Gleitkommazahlen mit vielen Dezimalstellen mit E am Ende an. Ich brauche nur 2 Dezimalstellen, also wie zeige ich es an?

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

Was wird angezeigt? – immibis

+2

Es gibt hier ein Problem 'Volt = (Wert * 5)/1023'. All dies sind Ganzzahlen, so dass das Ergebnis der Berechnung eine Ganzzahl ist. Das ist wahrscheinlich nicht das, was du willst. Versuchen Sie es mit 'Volt = (Wert * 5f)/1023f'. – msandiford

+0

Oder betrachten Sie MilliVolts: 'unsigned Volt = (Wert * 5000L + 1024/2/* fügen Sie diesen Wert zu runden * /)/1024;' und vermeiden FP Mathe. – chux

Antwort

0

Wenn die Funktion lcd_printf() auf derselben Bibliothek als die Funktion sprintf() für Arduino basiert, wird der Formatbezeichner '%f' nicht gut sogar geschafft, wenn sie als '%.2f' verwendet.

Schritt 1: Bevor alternative Lösungen vorgeschlagen werden, ist es erforderlich, einen gut berechneten Gleitkommawert aus dem vom Analog-Digital-Wandler abgelesenen Zahlenwert zu erhalten.

Wenn der ADC a 10-Bit sollte der Bereich (statt 1023) sein.

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

Step2.1: Eine erste und schnelle Lösung ein 2-Dezimalzahlen fester Gleitkommawert anzuzeigen es in 2 ganzen Zahlen umzuwandeln ist.

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

Statt

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

Schritt 2.2: Eine 'offizielle' Lösung, die ein 2-Dezimalzahlen fest Gleitkommawert anzuzeigen ist, die dtostrf() Funktion zu verwenden, wie in "Arduino sprintf float not formatting" vorgeschlagen.

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 

Statt

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

Versuchen Sie folgendes:

Edit: Ich bearbeitet gerade von Spannung anzeigt, weil Wert int war. Aber das Prinzip wäre dasselbe.

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

Casting scheint falsch zu sein, oder zumindest nicht klar für jemanden, der diesen Code liest. Typisch ist Volt = (Wert * 5,0)/1023; (nicht hier diskutieren über 1023) –

+0

Die Besetzung gilt für die linke Seite der Abteilung, so scheint es richtig zu sein, auch wenn es unnötig für den Leser verwirrend ist. –

1

ich die Frage im letzten Satz des ursprünglichen Beitrags zu beantworten - nicht die Überschrift. Aber das ist die richtige Antwort für Ihr Projekt.

Sie sagen "Ich brauche nur 2 Dezimalstellen" - so sollte Ihnen das sagen, dass es keine Notwendigkeit für Fließkomma-Mathematik gibt. Physiker und Ingenieure brauchen Schwimmer, um sehr, sehr kleine oder sehr, sehr große Mengen darzustellen, aber Sie brauchen einen "festen Punkt" - was bedeutet, dass Sie ganzzahlige mathematische Berechnungen durchführen und Ihre Einheiten richtig wählen. Fixed Point ist schneller, genauer und reduziert die Größe Ihrer kompilierten Binärdatei, da der Fließkomma-Code nicht benötigt wird.

Die einfachste Lösung besteht darin, Ganzzahlen zu verwenden und Millivolt anzuzeigen, genauso wie die Funktion delay(), die Sie gerade verwendet haben, ein Argument mit einer Ganzzahl von Millisekunden und nicht mit einer Bruchzahl von Sekunden.

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

Wenn Sie Volt angezeigt werden muss, dann tut dies der Trick:

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

Hinweis, nebenbei gesagt, dass mVolt eine ganze Zahl 32 Bit ist, weil Sie jetzt eine 10-Bit-Zahl sind Multiplikation um 5000 und das wird nicht in 16 Bits passen. Dies ist erforderlich, da Sie während der Skalierung die Genauigkeit des Werts beibehalten müssen. Ich glaube nicht, dass dies Off-Topic ist, da ich davon ausgehe, dass Sie den korrekten Wert anzeigen möchten oder es keinen Sinn hat, diese zwei Dezimalstellen anzuzeigen.

Wenn Sie nicht vorsichtig sind, wird der Compiler den Wert 5000/1024 - 4.8828125 berechnen - und dann Integer-Arithmetik, die den Bruchteil abschneidet und am Ende Ihr ADC-Ergebnis um 4 multipliziert. Um das zu garantieren Verhalten, multiplizieren Sie mit 5000 und teilen Sie dann - 2 getrennte Operationen. Da 1024 gleich 2 ** 10 ist, ist die Verschiebung nach rechts um 10 Bits identisch mit

Schließlich - gehen Sie nicht davon aus, dass das Lesen von 1023 vom ADC tatsächlich 5.000 Volt bis 4 signifikante Zahlen bedeutet; kalibrieren Sie gegen ein getestetes Voltmeter, indem Sie #define VREF optimieren, um das richtige Ergebnis zu erhalten.

+0

Nachdem ich gerade meine Antwort bearbeitet habe, ist es nur für mich der Fall, dass der Grund dafür, dass Sie überhaupt Floats brauchen, der Skalierungsfaktor ist. Ist das so? Chux und msandiford beide kommentiert oben über die gleichen Probleme - ich erkläre nur ausführlich, was los ist. –

+0

Wenn Sie nur Cent Volt wollen, müssen Sie den letzten Ausdruck teilen, wenn der 'lcd_printf()' Aufruf durch zehn, um das richtige Ergebnis zu bekommen, als 'mvolts% 1000/10' –

+0

Luis: Guter Fang, ich neige dazu denke in mV. –