Hallo zusammen. Ich habe die Frage schonmal bei Mikrocontroller.net gestellt, aber ich bin nicht wirklich weitergekommen. Darum versuche ich es mal hier, da ich hier nicht der einzige mit RN-Control bin.
Also ich habe am RN-Control eine Temperatursensor an Kanal 6 des ADC's dran. Über den Kanal 7 lese ich aus wie die Referenzspannung eingestellt ist (einfach nur so, damit ich beim Betrieb den Referenzjumper umstecken kann).
Ich lese die Temperatur mit folgender Funktion aus:
Soweit so gut.Code:int get_temp(){ int value; if(read_adc(7) < 500){ //REF = 5V value = read_adc(6); value -= 265; // 0°C return (value*30)/5; } else{ //REF = 2,5V value = read_adc(6); value -= 536; // 0°C return (value*190)/64; } }
Nun ist mit aufgefallen, dass wenn ich die Referenz auf 2,5V habe der ADC Wert sich MEHR als nur verdoppelt. Angenommen ich messe vorher bei AREF=5V einen Wert von 300, dann messe ich bei AREF=2,5V einen Wert von 610 (also 1,49V anstatt 1,46V). Gut könnte man meinen, ist halt der Spannungsteiler ungenau oder so... denkste, denn wenn ich den Kanal 6 manuell auslese dann stimmt der Wert. Sprich, das schnelle auslesen von Kanal 7 und Kanal 6 hintereinander hat Auswirkungen auf den Messwert. Dies habe ich bestätigt bekommen als ich die Funktion mit einem Delay versehen habe:
Mit dem obigen Code wird in beiden Fällen richtig ausgelesen. Kann sich jemand erklären wie das zustande kommt?Code:int get_temp(){ int value; if(read_adc(7) < 500){ //REF = 5V value = read_adc(6); value -= 265; // 0°C return (value*30)/5; } else{ //REF = 2,5V _delay_ms(15); _delay_ms(15); _delay_ms(15); _delay_ms(15); value = read_adc(6); value -= 536; // 0°C return (value*190)/64; } }
Ich hatte später gedacht, dass der Schaltplan falsch ist, da der 100nF von AREF an VCC geschaltet ist, darum habe ich mal versucht den Kondensator von VCC auf GND zu legen. Das Resultat ist, dass der Wert bei 2,5V jetzt immer zu hoch ist, es jedoch keinen Unterschied mehr macht ob ich ein Delay einbaue oder nicht.
Der Vollständigkeit halber hier nochmal meine read_adc-Funktion:
Code:unsigned int read_adc(unsigned char channel) { unsigned char i; unsigned int result = 0; ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler = 128 ADCSRA |= (1<<ADEN); //Enable ADC ADMUX = channel; // Kanal waehlen ADMUX &= ~((1<<REFS1) | (1<<REFS0)); // externe Referenzspannung nutzen ADCSRA |= (1<<ADSC); // Dummy-Wandlung while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */ for(i=0;i<4;i++) { ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten result += ADCW; // Wandlungsergebnisse aufaddieren } ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2) result /= 4; // Summe durch vier teilen = arithm. Mittelwert return result; }







Zitieren

Lesezeichen