- Akku Tests und Balkonkraftwerk Speicher         
Seite 4 von 5 ErsteErste ... 2345 LetzteLetzte
Ergebnis 31 bis 40 von 47

Thema: Temperaturmessung und Anzeige auf Display

  1. #31
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Anzeige

    Powerstation Test
    Hallo

    Danke für die Tips, hab ich gleich umgesetzt. Hab jetzt auch mal versucht meine Schaltung im Eiswasser abzugleichen. Das hat auch funktioniert. Nur werden jetzt bei Zimmertemperatur 34°C angezeigt, und das kann nicht sein. Hab hier vielleicht 21°C. Ich schließe also daraus dass die Steigung noch nicht stimmt. Werde jetzt noch etwas rumprobieren ob ich das ganze zum laufen bekomme.

    Vielen Dank auch den Tip mit der Tabelle. Werde das vielleicht auch mal probieren. Mein Problem ist dass ich später im Bereich 200°C messen will. Und da brauch ich erstmal die Werte um in die Tabelle einzutragen. Naja mir reicht bei den Temperaturen auch wenn es auf 2°C genau ist, hoffe das bekomme ich hin.

    Grüße!!

    Bean

  2. #32
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Hallo

    Ich bin immernoch mit der Temperaturmessung beschäftigt. Ich habe das ganze nun zwar so hinbekommen dass die angezeigte Temperatur bei 0°C und bei ~Zimmertemperatur stimmt. \/ \/
    Aber ich habe leider immer noch nicht so ganz verstanden wie die Werte si_multiplyer und si_const zusammenhängen.
    Tut mir Leid dass ich da so begriffstutzig bin aber könnte mir das noch einmal jemand erklären? Ich hab das jetzt halt so gemacht dass ich so lange an den Werten herumgespielt habe bis es gepasst hat. Aber die muss man doch auch irgendwie berechnen können...
    Außerdem könnte mir vielleicht noch jemand sagen wie ich aus der LCD Lib von Peter Fleury das "°" Zeichen auslese. Das steht ja im LCD Memory drin wenn ich mich nicht täusche. Auch das hab ich schon probiert, aber leider nicht hin bekommen.
    Ach ja, nebenbei ist mir noch etwas anderes aufgefallen: Wenn ich nun die Spannung mit dem Multimeter messe die am AD-Wandler anliegt habe ich 0,901V. Wenn ich das durch 0,0025 (2,56/1024) teile müsste ich doch auf den AD-Wert kommen. Das gibt bei mir ~360. Ich lasse mir in dem Display ja auch den ADWert direkt anzeigen, da werden mir aber 341 angezeigt. Woher kann das kommen? Hab ich an dieser Stelle doch noch ein Fehler in meinem Code?

    Vielen Dank im Voraus!!

    Grüße!!

    Bean
    Code:
    #include <avr/io.h>
    #include <inttypes.h>
    #include <stdlib.h>
    #include <lcd.h>
    
    #define F_CPU = 4000000UL
    #define ad_nullwert 311
    #define si_multiplyer 60
    #define si_const 12
    
    
    uint16_t readADC(uint8_t);			//Prototyp von readADC
    void display_temp(uint16_t result);		//Prototyp von display
    
    char buffer[8];						//Array für itoa anlegen
    int si_temp;						//Hilfvariable für Temperaturberechnung anlegen
    int	si_ones;
    int si_komma;
    
    int main(void) 
    {
    	DDRB = 0xff;						//PORT B als Ausgang
    
    	//Auslesen der analogen Spannungen an Pin 0, also ADC0. In result steht das Ergebnis.
    	uint16_t result = readADC(0);	
    									 
    	display_temp(result);				//Umrechnung und Ausgabe der Temperatur auf Display und LED`s
    	return 0;
    }
    
    
    void display_temp(uint16_t result)
    {
    	lcd_init(LCD_DISP_ON);			//LCD initialisieren
    	lcd_gotoxy(0,0);				//Cursor an erste Stelle setzen
    	lcd_puts("Temp.:");				//"Temperatur" ausgeben
    	lcd_gotoxy(0,1);				// Cursor in die zweite Zeile setzen
    	itoa(result,buffer,10);			//AD-Wert umrechnen
    	lcd_puts(buffer);				//AD-Wert in der zweiten Zeile ausgeben
    	
    	lcd_gotoxy(9,0);				// Cursor hinter "Temperatur:" setzen
    
    	//Berechnung der Temperatur 
    	si_temp=((result-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,buffer,10); 
    	lcd_puts(buffer); 
    	lcd_putc(','); 
    	itoa(si_komma,buffer,10); 
    	lcd_puts(buffer);
    	lcd_putc("°");;
    	lcd_putc('C');
    	return;
    }
    
    
    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<3; i++) 
    	{
    		// Eine Wandlung
    		ADCSRA |= (1<<ADSC);
    		// Auf Ergebnis warten...
    		while(ADCSRA & (1<<ADSC));
    		
    		result += ADC;
    	}
    	
    	
    	//ADC wieder deaktivieren
    	ADCSRA &= ~(1<<ADEN);
    	
    	result /= 3;
    	
    	return result;
    }

  3. #33
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.236
    Das mit deinen Werten bestätigt das, was ich Dir schon in einem früheren Post zu diesem Thema schrieb.

    1. Die A/D Wandler der ATMEL Controller sind nicht besonders genau.
    Miss mal die Spannung am AREF Ausgang des Controllers und berechne dann den A/D Wert nicht mit den 2,56V die der Pin eigentlich haben sollte, sondern mit dem gemessenen Wert.
    Ausserdem sind die A/D Wandler nicht besonders linear.

    2. Die KTY Sensoren haben eine ziemliche Serienstreuung. Das kannst Du auch sehen, wenn Du Dir die Tabellen in den Datenblättern anschaust.


    Diese Fehlmessungen sind also letztendlich Bauteiletoleranzen.
    Da man aber lineare Toleranzen mit Korrekturwerten ziemlich gut rausrechnen kann ist das eigentlich gar nicht so schlimm, erfordert aber einen Abgleich. Und zwar für jeden neuen Controller und jeden neuen Temperatursensor.
    Die si_const ist eigentlich ein willkürlich gewählter Wert der 2 Vorraussetzungen erfüllen muss. Er darf nicht dazu führen, das bei einem Maximal A/D Wert die signed int Variable überschritten wird ( 32767 ).
    Er muss aber auch mindestens so groß sein, das mit der si_multiplyer vernünftige Schrittweiten einstellen lassen.
    Das Ganze hängt damit zusammen, das int Variablen nur Ganze Zahlen darstellen können. 0,5 wird also in einer int Variablen zu 0.

    Nichtlineare Fehler, also krumme Kennlinien, erfordern das schon mehr Aufwand. Es kommt also darauf an, welche Genauigkeit man bei der Messung haben will.

  4. #34
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Also das finde ich ja schon etwas komisch. Ich hab jetzt mal an meinem Aref Pin gemessen und da habe ich 1,75V. Wenn ich das durch 1024 teile komme ich auf eine Schrittweite von 0,001709V. Dann teile ich meine AD-Spannung bei 0°C von 1,332V durch diesen Wert und erhalte einen theoretischen digitalten Wert von 779. Tatsächlich habe ich aber 521. Das wäre ja also noch schlechter als wenn ich mit 2,56Vref rechnen würde. Da kann ja was nicht stimmen.
    Dass die Sensoren eine große Streuung haben das denke ich mir schon. Das haben auch Messungen gezeigt die ich jetzt mit der gleichen Schaltung aber einem anderen KTY Sensor gemacht habe. Aber wenn ich doch 2,56Vref einstelle, dann sollten die doch auch passen. Oder wo liegt jetzt mein Denkfehler? Sonst wäre es doch einfacher den Aref Pin einfach auf Vcc zu legen. Da hab ich wenigstens halbwegs konstant 5V und weiß mit was ich rechnen kann. Oder sehe ich das falsch?

    Grüße und vielen Dank für die Geduld!

    Bean

  5. #35
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.236
    @Mr Bean
    Also das mit deinen 1,75V am ARef Pin mag ich jetzt fast nicht glauben.
    Hast Du da ein Uralt Analog Multimeter verwendet ?
    Ist der A/D Wandler des Controller richtig konfiguriert ?
    Ich hab da Unterschiede von maximal 0,1V festgestellt.
    Klar kannst Du auch deine 5V Als Referenzspannung verwenden. Dazu musst Du den A/D Wandler etwas anders konfigurieren - ADMUX Register.

    Ich meine Du solltest mal für die Temperatur Berechnungen eine signed long int Variable vorsehen, sonst passiert das mit dem Überlauf was "robocat" schrieb, wenn die Werte über 32767 bzw. 65535 gehen.
    Ausserdem könnten dann die Korrekturwerte etwas größer gewählt werden, was eine feinere Abstufung ergäbe.

    Da bei der Temperaturmessung auch negative Werte rauskommen können sollten alle darin verwendeten Variablen als signed angegeben werden.
    Sonst könnte es Stress bei der Berechnung geben.

    Teil mal die Formel auseinander ( aus der einen Formel 3 machen ) und lass das Programm mal im Simulator laufen. Dann sollte sich zeigen wo die Berechnung nicht stimmt.

  6. #36
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Hallo!

    Also ich weiß auch nichtsmehr was da los ist. Ich hab jetzt mal einen neuen Controller genommen und die gleichen Fusebits und das geiche Programm rein geschrieben. Ergo: An Aref weiterhin 1,71V. Wenn ich den Kondensator gegen Masse dann abklemme und den Pin einfach offen lasse messe ich 0V. Weiß jetzt selber nicht ob das so richtig ist.
    Muss ich an den Fusebits auch noch etwas einstellen um den AD-Wandler zu benutzen? Ich denke schon dass ich ihn softwaremäßig richtig initialisiert habe. (ADMUX |= (1<<REFS1) | (1<<REFS0))
    An der Umänderung zu signed Variablen bin ich dran. Aber will nicht zu viel Baustellen auf einmal. Möchte eigentlich zuerst das mit der Referenzspg. geklärt haben.
    Das Multimeter ist schon etwas älter und war auch ein billiges, aber wenn ich die Spannung meines Labornetzteiles messe stimmt es eigentlich recht gut.

    Grüße!!

    Bean

  7. #37
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.236
    Ich hab jetzt auch bei meinen beiden ATMEGA 8 nachgemessen.
    Bei einem ATMEG 8 L 8 hab ich 2,59V gemessen ( 3,3V Betriebsspannung ), bei dem ATMEGA 8 - 16 hab ich 2,66V gemessen ( 5V Betriebsspannung ).

    Welchen Controller hast Du denn genau benutzt ?
    Es gibt auch welche mit 1,1V oder 1,76V Referenzspannung.
    Der ATMEGA 88 hat z.B. eine Referenzspannung von 1,1V.

    Aufschluß darüber gibt das Datenblatt unter der Rubrik "Analog to digital Converter".

    Wenn da natürlich eine andere Spannung angegeben ist, musst Du auch mit diesem Wert rechnen - Steht auch im Datenblatt.

    Hast Du schon deine Temperatur Variable auf signed long umgebaut ?

  8. #38
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Also ich hab den AtMega8-16PU. Ich bin der Meinung dass im Datenblatt schon 2,56V Uref steht. Finde das schon komisch.
    An der Umwandlung in signed long bin ich dran. Hab das jetzt mal soweit gemacht:

    Code:
    #include <avr/io.h>
    #include <inttypes.h>
    #include <stdlib.h>
    #include <lcd.h>
    
    #define F_CPU = 4000000UL
    #define ad_nullwert 311
    #define si_multiplyer 60
    #define si_const 12
    
    
    uint16_t readADC(uint8_t);			//Prototyp von readADC
    void display_temp(uint16_t result);		//Prototyp von display
    
    char buffer[8];						//Array für itoa anlegen
    signed long int si_temp1;					//Hilfvariable für Temperaturberechnung anlegen
    signed long int si_temp2;
    signed long int si_temp3;
    signed long int si_ones;
    signed long int si_komma;
    
    int main(void) 
    {
    	DDRB = 0xff;						//PORT B als Ausgang
    
    	//Auslesen der analogen Spannungen an Pin 0, also ADC0. In result steht das Ergebnis.
    	uint16_t result = readADC(0);	
    									 
    	display_temp(result);				//Umrechnung und Ausgabe der Temperatur auf Display und LED`s
    	return 0;
    }
    
    
    void display_temp(uint16_t result)
    {
    	lcd_init(LCD_DISP_ON);			//LCD initialisieren
    	lcd_gotoxy(0,0);				//Cursor an erste Stelle setzen
    	lcd_puts("Temp.:");				//"Temperatur" ausgeben
    	lcd_gotoxy(0,1);				// Cursor in die zweite Zeile setzen
    	itoa(result,buffer,10);			//AD-Wert umrechnen
    	lcd_puts(buffer);				//AD-Wert in der zweiten Zeile ausgeben
    	
    	lcd_gotoxy(9,0);				// Cursor hinter "Temperatur:" setzen
    
    	//Berechnung der Temperatur 
    	si_temp1= (result-ad_nullwert);
    	si_temp2= (si_temp1*si_multiplyer);
    	si_temp3= (si_temp2/si_const);
    	// Die Ganzen Grade Berechnen 
    	si_ones=si_temp3/10;
    	//Die eine Nachkommastelle Berechnen 
    	si_komma=si_temp3%10; 
    	// Die Zehnerstellen ans Display ausgeben 
    	itoa(si_ones,buffer,10); 
    	lcd_puts(buffer); 
    	lcd_putc(','); 
    	itoa(si_komma,buffer,10); 
    	lcd_puts(buffer);
    	lcd_putc('C');
    	return;
    }
    
    
    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<3; i++) 
    	{
    		// Eine Wandlung
    		ADCSRA |= (1<<ADSC);
    		// Auf Ergebnis warten...
    		while(ADCSRA & (1<<ADSC));
    		
    		result += ADC;
    	}
    	
    	
    	//ADC wieder deaktivieren
    	ADCSRA &= ~(1<<ADEN);
    	
    	result /= 3;
    	
    	return result;
    }
    Wie habt ihr denn euren AD-Wandler beschaltet? So viel kann man da ja eigentlich nicht falsch machen....

    Grüße!!

    Bean

  9. #39
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.236
    Also das mit deiner Referenzspannung ist definitiv Mist.
    Die beiden REFS sollten 1 sein - das müsste stimmen.
    An AVCC wirst Du auch +5V haben und An AGND auch GND.
    Der Controller hat ach Takt, sonst ginge das Display nicht.

    Es wäre jetzt noch möglich, das dein Messgerät einen sehr geringen Einganswiderstand hat und somit die AREF in den Keller zieht.
    Miss mal alle Versorgungsspannungen (VCC, AVCC, GND, AGND) am Controller nach, evtl. hast Du ja eine kalte Lötstelle reingebastelt.
    Ansonsten fällt mir nicht mehr viel dazu ein.

    Der A/D Wandler muss natürlich vor der Messung der Spannung AREF initialisiert sein, aber ich Denke so schlau bist Du auch.

    Das Problem mit den zu kleinen Temperaturwerten wird aber vermutlich an der signed long - Geschichte liegen.

  10. #40
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Also

    Ich hab nun noch einmal alles durchgemessen. Hier meine Ergebnisse. Die ganze Messung fand statt nach dem der Controller initialisiert war und auch schon eine Temperatur gemessen wurde:

    AVcc -> 5V
    Aref -> 1,72V
    AGND -> 0,03V
    Vcc -> 5,05V

    Ich hab jetzt in meinen Code noch eine while Schleife eingefügt, brachte aber keine Veränderung. Dachte dass ohne diese Schleife der AD Wandler ja immer wieder neu initialisiert wird und ich dadruch vielleicht nicht die gewollten 2,56V messe (Zugegeben sehr theoretisch aber was will ich machen ). Aber dem war nicht so.

    Code:
    #include <avr/io.h>
    #include <inttypes.h>
    #include <stdlib.h>
    #include <lcd.h>
    
    #define F_CPU = 4000000UL
    #define ad_nullwert 311
    #define si_multiplyer 60
    #define si_const 12
    
    
    uint16_t readADC(uint8_t);			//Prototyp von readADC
    void display_temp(uint16_t result);		//Prototyp von display
    
    char buffer[8];						//Array für itoa anlegen
    signed long int si_temp1;					//Hilfvariable für Temperaturberechnung anlegen
    signed long int si_temp2;
    signed long int si_temp3;
    signed long int si_ones;
    signed long int si_komma;
    
    int main(void) 
    {
    	DDRB = 0xff;						//PORT B als Ausgang
    
    	//Auslesen der analogen Spannungen an Pin 0, also ADC0. In result steht das Ergebnis.
    	uint16_t result = readADC(0);	
    									 
    	display_temp(result);				//Umrechnung und Ausgabe der Temperatur auf Display und LED`s
    	return 0;
    	while (1)
    	{
    	}
    }
    
    
    void display_temp(uint16_t result)
    {
    	lcd_init(LCD_DISP_ON);			//LCD initialisieren
    	lcd_gotoxy(0,0);				//Cursor an erste Stelle setzen
    	lcd_puts("Temp.:");				//"Temperatur" ausgeben
    	lcd_gotoxy(0,1);				// Cursor in die zweite Zeile setzen
    	itoa(result,buffer,10);			//AD-Wert umrechnen
    	lcd_puts(buffer);				//AD-Wert in der zweiten Zeile ausgeben
    	
    	lcd_gotoxy(9,0);				// Cursor hinter "Temperatur:" setzen
    
    	//Berechnung der Temperatur 
    	si_temp1= (result-ad_nullwert);
    	si_temp2= (si_temp1*si_multiplyer);
    	si_temp3= (si_temp2/si_const);
    	// Die Ganzen Grade Berechnen 
    	si_ones=si_temp3/10;
    	//Die eine Nachkommastelle Berechnen 
    	si_komma=si_temp3%10; 
    	// Die Zehnerstellen ans Display ausgeben 
    	itoa(si_ones,buffer,10); 
    	lcd_puts(buffer); 
    	lcd_putc(','); 
    	itoa(si_komma,buffer,10); 
    	lcd_puts(buffer);
    	lcd_putc(0xdf);
    	lcd_putc('C');
    	return;
    }
    
    
    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<3; i++) 
    	{
    		// Eine Wandlung
    		ADCSRA |= (1<<ADSC);
    		// Auf Ergebnis warten...
    		while(ADCSRA & (1<<ADSC));
    		
    		result += ADC;
    	}
    	
    	
    	//ADC wieder deaktivieren
    	ADCSRA &= ~(1<<ADEN);
    	
    	result /= 3;
    	
    	return result;
    }
    Ich werde die das ganze morgen noch einmal mit einem besseren Multimeter im Geschäft messen. Glaube aber nicht dass das andere Werte bringt. Wir werden sehen.

    Grüße und gute Nacht!!

    Bean

Seite 4 von 5 ErsteErste ... 2345 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen