Forum: Compiler & IDEs ADC Wert auf LCD


von S. W. (stew1337)


Lesenswert?

Hallo Leute ich hab ei kleines problem mit der anzeige des adc wertes 
vielleicht könnt ihr mir helfen

ich hab ne am adc ne spannung von 5V und im display zeigt er mir 1023 an
wenn ich 2,5 einstelle 511  ich möchte aber die spannungswerte anzeigen 
lassen was mach ich falsch oder muss ich ändern

hier der auszug aus meinem programm



        ADCSRA |= (1<<ADSC);

        // Warten bis die AD-Wandlung abgeschloßen ist
        while ( !(ADCSRA & (1<<ADIF)));

        /* AD-Wert auslesen.
        ADCH muss als zweites gelesen werden, da nachdem ADCL gelesen 
wurde
        das ADC-Register gesperrt ist bis ADCH auch ausgelesen wurde. */
        buffer = ADCL | (ADCH<<8);

        // oder einfacher
        buffer = ADC;

xtr=buffer;

utoa(xtr,Buffer,10);
lcd_goto(0,1);
lcd_write_s( Buffer );

von Andi (Gast)


Lesenswert?

also so ohne weiteres den adc-wert aufs display zu geben wird dir immer 
nur was zwischen 0 und 1024 anzeigen :)

du mußt dir überlegen, daß ja z.b. 100mV einem bestimmten wert im ADC 
entsprechen. dann kannst du ja z.b. das was im adc steht durch diesen 
wert teilen, der 100mV entspricht. dann bekommst du z.b. 230 raus. dann 
weißt du du hast also den wert für 100mV 230 mal im adc stehen. das sind 
dann ja 2,3V. wie du das mit dem "," machst überlass ich mal dir :) ...

von lkmiller (Gast)


Lesenswert?

Ja, der ADC ist halt so ein binärer Sack.
Der gibt 10 Bit aus. Mehr kanner nich.

Also, wenn du das human lesbar ohne Kopfrechen willst,
dann musst du das vor der Ausgabe im uC umrechnen.

Der Faktor zwischen Anzeige und Adc ist 5/1024
(5V werden auf 1024 Schritte aufgeteilt).

Fazit: du musst deinen Adc-Wert mit (5/1024) multiplizieren.
Wenn du jetzt aber schreibst
:
        buffer = ADC;
        xtr = buffer*(5/1024);
:
dann kommt immer 0 raus, weil als Ganzzahl (5/1024) eben 0 ist.
Und 0 mal irgendwas gibt 0.


Andere können das aber auch, also nehmen wir Fliesskommazahlen
:
        buffer = ADC;
        xtr = (unsigned short)((float)buffer*(5.0/1024.0));
:
Dann gibt es aber nur Werte zwischen 0.00 und 4.99,
als Ganzkommazahl demnach nur 0..4 weil die Nachkommastellen
einfach abgeschnitten werden.

Also multiplizieren wir das nochmal mit 100 -->
die Werte gehen von 0..499.
:
:
        buffer = ADC;
        xtr = (unsigned short)((100.0*(float)buffer*(5.0/1024.0));
:
:
Alternativ kann man einfach durch den Faktor 100 weniger teilen:
:
:
        buffer = ADC;
        xtr = (unsigned short)((float)buffer*(5.0/10.240));
:
:

Aber Achtung: durch die Umrechnerei mit float wird viel Zeit benötigt

von Jörg X. (Gast)


Lesenswert?

Oder du machst es ohne Floats, wie in Festkommaarithmetik.

von S. W. (stew1337)


Lesenswert?

danke für die antwor  das hat geklappt  lkmiller

wie kann ich das denn machen das er den wert nicht mehr nach links 
verschiebt am besten noch mit nem komma anzeigt

das mit dem festkomma bekomme ich net hin dan zeigt er komische werte an 
-3546 und dann 0298

von lkmiller (Gast)


Lesenswert?

Die Festkommaarithmetik ist nichts anderes als ein
logisches Verschieben des Kommas nach rechts.

So betrachtet sage ich jetzt einfach:
Ich muss 5000mV auf 1024 Schritte verteilen.
:
:
        buffer = ADC;
        xtr = ((long)buffer*5000)/1024;
:
Die Variable buffer muß den Wert 1023*5000 = 5120000 halten können,
da ist ein long nötig --> buffer ist short und muss gecastet werden.

Die Anzeige mit itoa ist auch in Festkommaarithmetik beschrieben.

von Dieter (Gast)


Lesenswert?

HAllo, habe es hinbekommen... lag irgendwie am dem Projekt, habe den C 
code einfach in ein neues Projekt rein kopiert und da ging es^^. Ich 
kann Spannungen bis 9,99V super messen ( Also liegen mit einem 
Spannungsteiler vorm Eingang des µC). Mein Problem ist im moment das ich 
die Spannungen über 10V nicht richtig anzeigen kann... alles bis 10V 
wird richtig angezeigt, nur wenn ich unte 9,9V komme wo er nun 
eigentlich 09,9V oder halt nur 9,9V anzeigen sollte, zeigt er 99,9V an.

von Karl H. (kbuchegg)


Lesenswert?

Dieter wrote:
> eigentlich 09,9V oder halt nur 9,9V anzeigen sollte, zeigt er 99,9V an.

Dann wirst du halt vor der Ausgabe der 'Zahl' einfach ein Leerzeichen
ausgeben müssen, wenn die Zahl kleiner als '10' ist. Und schon
steht da nicht mehr '99.9V' sondern ' 9.9V'.
Du musst dir immer vor Augen halten, dass dein neuer Wert den alten
überschreibt! Was nicht überschrieben wird steht nachher immer noch
so am LCD wie es vor der bewussten Ausgabe dort stand.

von Dieter (Gast)


Lesenswert?

Mein Problem ist es das die zehner Zahlen durch die einer ersetzt werden 
und somit alle zahlen um einen aufrücken. D.h eigentlich habe ich die 
anzeige 10,99V also ist die kleinste einheit in 100mV wenn ich aber 
unter 9,9V kommer steht das denn 99,99V und die kleinste einheit ist auf 
einmal 10mV. Anstatt die zehner Zahl mit 0 anzuzeigen wird diese einfach 
durch die einer zahl ersetzt

von Dieter (Gast)


Lesenswert?

Sorry habe mich versehen! bei 10,99 V ist die kleinste einheit 10mV und 
unter 9,99V ist die kleinste einheit 1mV

von Karl H. (kbuchegg)


Lesenswert?

Dieter wrote:
> Anstatt die zehner Zahl mit 0 anzuzeigen wird diese einfach
> durch die einer zahl ersetzt

Solange du utoa oder eine sonstige Funktion aus dieser Familie
benutzt wird dir in so einem Fall auch niemals eine führende 0
ausgegeben. Diese Funktionen machen das nicht! Genau deshalb
musst du selbst dafür Sorge tragen, dass in so einem Fall die
Zehner-Stelle mit einem Leerzeichen überschrieben wird.

"10.99V" sind nun mal 6 Zeichen, während "9.99V" nur 5 Zeichen
sind. Du musst aber immer alle 6 Zeichen überschreiben, damit
bei der Ausgabe von "9.99V" nicht noch ein Zeichen von den
"10.99V", die vorher dort standen, zu sehen ist.

Ist wie mit einem Stück Papier, einem Bleistift und einem Radiergummi.
Wenn auf deinem Papier
ABCD
steht, und du radierst nur die ersten 3 Buchstaben aus und ersetzt
sie durch XYZ, dann steht auf deinem Papier nun mal
XYZD
und nicht
XYZ
wie du es vielleicht beabsichtigt hättest.

von Dieter (Gast)


Lesenswert?

Kannst du mir vieleicht einen tip geben wie ich dieses Problem lösen 
kann... bin da schon den ganzen abend dran am rumprobieren!

von Karl H. (kbuchegg)


Lesenswert?

Dieter wrote:
> Kannst du mir vieleicht einen tip geben wie ich dieses Problem lösen
> kann... bin da schon den ganzen abend dran am rumprobieren!

Sag ich doch:
Du bestimmst mit einem if ob du ein Leerzeichen ausgeben musst
oder nicht.
1
  utoa( xtr, Buffer, 10 );
2
  lcd_goto( 0, 1 );
3
  if( xtr < 10 )
4
    lcd_write_s( " " );
5
  lcd_write_s( Buffer );

(musst du natürlich auf deine jetzige Ausgabefunktion anwenden)

von Dieter (Gast)


Lesenswert?

Habe es nun so eingefügt:
xtr = ((long)buffer*10000)/1024;
utoa(xtr,Buffer,10);

Buffer[4]=0;            // String-Ende
Buffer[3]=Buffer[2];    // Einer
Buffer[2]=Buffer[1];
Buffer[2]=',';      // Zehner
lcd_goto( 0, 1 );

if( xtr < 10 )
{
lcd_write_s( " " );
lcd_write_s( Buffer );
}

lcd_goto(0,6);
lcd_write_s("C ");

nun wird garnichts mehr auf dem Display angezeigt

von Karl H. (kbuchegg)


Lesenswert?

Dieter wrote:
> Habe es nun so eingefügt:
> xtr = ((long)buffer*10000)/1024;
> utoa(xtr,Buffer,10);
>
> Buffer[4]=0;            // String-Ende
> Buffer[3]=Buffer[2];    // Einer
> Buffer[2]=Buffer[1];
> Buffer[2]=',';      // Zehner
> lcd_goto( 0, 1 );
>
> if( xtr < 10 )
> {
> lcd_write_s( " " );
> lcd_write_s( Buffer );
> }
>
> lcd_goto(0,6);
> lcd_write_s("C ");
>
> nun wird garnichts mehr auf dem Display angezeigt


Bitte, bitte, bitte.
Fang an deinen Code vernünftig zu formatieren!
Dazu gehören auch Einrückungen.
1
  Buffer[4]=0;            // String-Ende
2
  Buffer[3]=Buffer[2];    // Einer
3
  Buffer[2]=Buffer[1];
4
  Buffer[2]=',';      // Zehner
5
6
  lcd_goto( 0, 1 );
7
 
8
  if( xtr < 10 )
9
  {
10
    lcd_write_s( " " );
11
    lcd_write_s( Buffer );
12
  }
13
14
  lcd_goto(0,6);
15
  lcd_write_s("C ");

Und jetzt sieh dir deinen Code nochmal an.
Wovon hängt es ab, ob die Zeile
1
    lcd_write_s( Buffer );

ausgeführt wird oder nicht?

Richtig! Davon ob xtr kleiner als 10 ist.
Das willst du aber nicht!
Buffer soll immer ausgegeben werden!
Nur dann wenn deine Ausgangszahl kleiner als 10 ist, dann soll
noch ein Leerzeichen vor der Zahl ausgegeben werden, damit die
Einerstelle am LCD immer an dieselbe Stelle kommt und die Zehner-
stelle auf jeden Fall zu einem Leerzeichen wird.

xtr hat bei dir bei einem Wert am LCD von 10 den Wert 100, also muss
es heissen
1
  if( xtr < 100 )
2
  {
3
    lcd_write_s( " " );
4
  }
5
  lcd_write_s( Buffer );

von Karl H. (kbuchegg)


Lesenswert?

Ist dein µC schon arg voll?

Wenn nein, dann spar dir doch das ganze Gerödel mit der
Buffermanipulation und nimm den einfachen (aber speicherhungrigen)
Weg über sprintf. Dort kannst du von jeder Zahl gezielt angeben,
mit wievielen Stellen und in welcher Feldbreite sie ausgegeben
werden soll (und eventuelle führende Nullen sind auch kein
Problem).
1
   unsigned int xtr;
2
3
   ...
4
5
   xtr = ((long)buffer*10000)/1024;
6
   sprintf( Buffer, "%2u,%1u°C", xtr / 10, xtr % 10 );
7
   lcd_goto( 0, 1 );
8
   lcd_write_s( Buffer );

Mehr zu sprintf zb hier
http://www.mikrocontroller.net/articles/FAQ#sprintf.28.29
bzw. in jedem noch so grindigem Einführungsbuch zu C (und ohne
so ein Buch wirst du nicht weit kommen, also besser gleich morgen
eines kaufen und auch durcharbeiten)

von Dieter (Gast)


Lesenswert?

xtr = ((long)buffer*10000)/1024;


    utoa(xtr,Buffer,10);

    Buffer[4]=0;            // String-Ende
    Buffer[3]=Buffer[2];    // Einer
    Buffer[2]=Buffer[1];    // Zehner
    Buffer[2]=',';
    lcd_goto( 0, 1 );
     if( xtr < 1000 )
    {
            lcd_write_s( "0" );
    Buffer[1]=Buffer[2];
    Buffer[2]=Buffer[3];
      }
    lcd_write_s( Buffer );
    lcd_goto(0,7);
    lcd_write_s("C ");


Habe es nun so gelöst! nun geht das Komma auch auf die richtige stelle. 
Er zeigt mir nun nur an wenn ich unter 0,3V komme dieses komische 
Kommagewirr an 0,,,,3V

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.