mikrocontroller.net

Forum: Compiler & IDEs ADC Wert auf LCD


Autor: S. W. (stew1337)
Datum:

Bewertung
0 lesenswert
nicht 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 );

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :) ...

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder du machst es ohne Floats, wie in Festkommaarithmetik.

Autor: S. W. (stew1337)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Dieter (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dieter (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
  utoa( xtr, Buffer, 10 );
  lcd_goto( 0, 1 );
  if( xtr < 10 )
    lcd_write_s( " " );
  lcd_write_s( Buffer );

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

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.
  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 ");

Und jetzt sieh dir deinen Code nochmal an.
Wovon hängt es ab, ob die Zeile
    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
  if( xtr < 100 )
  {
    lcd_write_s( " " );
  }
  lcd_write_s( Buffer );

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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).
   unsigned int xtr;

   ...

   xtr = ((long)buffer*10000)/1024;
   sprintf( Buffer, "%2u,%1u°C", xtr / 10, xtr % 10 );
   lcd_goto( 0, 1 );
   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)

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.