Wenn du für die LCD-Temperatur lcd_gotoxy(11,0); schreibst, dann kann es funktionieren, mit 0,11 schreibst du in die 11. Zeile. Sonst habe ich nichts angeschaut.
Hallo
Ich möchte mir gerade eine Temperaturmessung bauen. Bin auch schon soweit dass ich die Temperatur messen kann mit dem AD-Wandler. Wenn ich mir den binären Wert auf meine 8 LED`s ausgeben lasse und dann mit der Hand am Arm umrechne passt die Messung auch schon. Ich möchte die Temperatur nun auf einem zweizeiligen Display ausgeben. Aber das bekomme ich nicht hin. Sehe meistens nur kyrillisch...
Nach einigem lesen hier im Forum und auf mikrocontroller.net weiß ich nun dass ich zum Umrechnen wohl die Funktion itoa brauche, aber wirklich hinbekommen hab ich das so nicht. Vielleicht könntet ihr mal über meinen Code drüber schaun und mir einen Tip geben.
Ich verwende ein AtMega 8 und ein KTY Element mit 1k Vorwiderstand. Aber das funktioniert soweit ich das beurteilen kann auch schon.Code:#include <avr/io.h> #include <inttypes.h> #include <stdlib.h> #include <lcd.h> #define F_CPU = 4000000UL; uint16_t readADC(uint8_t); //Prototyp von readADC int main(void) { uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0, // also ADC0. In result steht das Ergebnis. result /=5; //result durch 5 teilen um richtiges Ergebnis zu bekommen DDRD = 0xff; //PORT D als Ausgang definieren (Hier sind 8 LED`s angeschlossen) PORTD = result; //Den Digitalen Wert mit Hilfe der LED`s anzeigen DDRB = 0xff; lcd_init(LCD_DISP_ON_CURSOR); //LCD initialisieren lcd_gotoxy(0,0); lcd_puts ("Temperatur:"); char Buffer[20]; itoa(result,Buffer,10); lcd_gotoxy(0,11); lcd_puts('Buffer'); //ADC Wert auf Display ausgeben return 0; } uint16_t readADC(uint8_t channel) { uint8_t i; uint16_t result = 0; // Den ADC aktivieren und Teilungsfaktor auf 32 stellen ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS2); // Kanal des Multiplexers waehlen (ADC 0) ADMUX = (!(1<<MUX0)) | (!(1<<MUX1)) | (!(1<<MUX2)); // interne Referenzspannung verwenden (also 2,56 V) ADMUX |= (1<<REFS1) | (1<<REFS0); // Den ADC initialisieren und einen sog. Dummyreadout machen ADCSRA |= (1<<ADSC); while(ADCSRA & (1<<ADSC)); // Jetzt 3x die analoge Spannung and Kanal channel auslesen // und dann Durchschnittswert ausrechnen. for(i=0; i<4; i++) { // Eine Wandlung ADCSRA |= (1<<ADSC); // Auf Ergebnis warten... while(ADCSRA & (1<<ADSC)); result += ADCW; } // ADC wieder deaktivieren ADCSRA &= ~(1<<ADEN); result /= 4; return result; }
Vielen Dank schonmal!
Grüße!!
Bean
Wenn du für die LCD-Temperatur lcd_gotoxy(11,0); schreibst, dann kann es funktionieren, mit 0,11 schreibst du in die 11. Zeile. Sonst habe ich nichts angeschaut.
Ändere noch dein main so in etwa ab, ohne Endlosschleife tut sich sonst nicht viel sinnvolles.Code:int main(void) { DDRD = 0xff; //PORT D als Ausgang definieren (Hier sind 8 LED`s angeschlossen) DDRB = 0xff; lcd_init(); //LCD initialisieren for(;;){ uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0, // also ADC0. In result steht das Ergebnis. result /=5; //result durch 5 teilen um richtiges Ergebnis zu bekommen lcd_gotoxy(0,0); lcd_puts ("Temperatur:"); char Buffer[20]; itoa(result,Buffer,10); lcd_gotoxy(11,0); lcd_puts(Buffer); //ADC Wert auf Display ausgeben PORTD = result; //Den Digitalen Wert mit Hilfe der LED`s anzeigen } }
Mh komisch, also ich bin der Meinung dass wenn ich LCD_gotoxy (0,11) schreibe geht der Courser in die oberste Zeile an die 11te Stelle und da soll eigentlich auch das Ergebniss hingeschrieben werden, weil davor "Temperatur:" steht. Darum hab ich das so geschrieben. Die for-schleife habe ich gerade ausprobiert (Kein anderes Verhalten erkennbar), warum soll sich ohne die nicht viel sinnvolles tun? Die Wandlung hat bereits vorhin getan (ohne schleife). Der Wert hat sich auch geändert wenn ich den Temperaturfühler erwärme. Also warum soll sich da nichts sinnvolles tun?
Mein Problem liegt im Moment eher an der Umwandlung des 10Bit Wertes in eine dezimale Kommazahl mit einer Kommastelle.
Denke der Wert in "result" ist im Moment einfach noch zu groß um vom Display verarbeitet werden zu können. Darum auch die kyrillischen Zeichen. Aber kann mich auch irren.
Grüße!!
Bean
Jo, ist ja auch richtig so. Aber (11,0) nichtZitat von Mr Bean
Dann habe ich einen andere LCD-lib oder ein anderes LCD, ich muss jedenfalls lcd_gotoxy(11,0) schreiben, sonst geht es nicht, hab das jetzt extra noch ausprobiert.
Ich habe auch noch in meinem *.h file nachgesehen, dort steht es auch so drinnen, wäre ja auch von der Bezeichnung x y logisch.
Hallo
Also ich hab das auch noch einmal ausprobiert. Das mit dem lcd_gotoxy passt in jedem Fall. Mein Courser steht dann an der richtigen Stelle. Wie sieht es mit der Umrechnung in eine Dezimale Kommazahl aus? Denke da liegt mein Hauptproblem. Habt ihr da ein paar gute Tipps?
Grüße!!
Bean
besonders schön ist das nicht, aber hat bei mir immer funktioniert:
value ist der 10bit wert, zuerst wird umgerechnet und der ganzzahlige wert ausgegeben, dann wird der rest (die kommastellen) mit 1000 multipliziert und die daraus entstehende dezimalzahl hinter dem komma ausgegeben.Code:void display(int value) { char buffer[8]; float f=((float)value*5)/1023; // mit "5" erhält man eine kommazahl von 0,0 bis 5,0 if(f<0)f=0; itoa((int)f,buffer,10); lcd_puts(buffer); lcd_putc(','); f=(f-(int)f)*1000; if(f<100)lcd_putc('0'); if(f<10)lcd_putc('0'); itoa((int)f,buffer,10); lcd_puts(buffer); return; }
gruesse
Hallo robocat!
Das sieht schon mehr nach dem aus was ich denke zu brauche. Werde das heut Mittag/Abend nach der Arbeit gleich mal ausprobieren. Melde mich dann wieder.
Grüße!!
Bean
Ich nehm für solche Berechnungen eigentlich immer int werte her, da die der Controller schneller bearbeiten kann als float.
Um eine Nachkommastelle zu kriegen nehm ich immer den zehnfachen Wert der tatsächlichen Temperatur.
Das funktioniert aber nur mit einer Nachkommastelle, da die Funktion itoa führende Nullen unterdrückt.Code://Berechnung der Temperatur si_temp=((si_adwert-ad_nullwert)*si_multiplyer)/si_const; // Die Ganzen Grade Berechnen si_ones=si_temp/10; //Die eine Nachkommastelle Berechnen si_komma=si_temp%10; // Die Zehnerstellen ans Display ausgeben itoa(si_ones,uc_disp); lcd_puts(uc_disp); lcd_putchar(","); itoa(si_komma,uc_disp); lcd_puts(uc_disp);
Die Variable ad_nullwert ist der Wert, den der A/D Wandler bei 0°C ausgibt. Die Variable si_mutiplyer ist der Steilheitsfaktor zur kalibrierung der Temperatur. si_const ist eine feste Teilerkonstante die natürlich von von si_multiplyer und der gewünschten Auflösung abhängig ist.
Vorschlag 1024.
Lesezeichen