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 );
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 :) ...
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
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
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.
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.
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.
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
Sorry habe mich versehen! bei 10,99 V ist die kleinste einheit 10mV und unter 9,99V ist die kleinste einheit 1mV
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.
Kannst du mir vieleicht einen tip geben wie ich dieses Problem lösen kann... bin da schon den ganzen abend dran am rumprobieren!
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)
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
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 ); |
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)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.