Hallo,
ich möchte die Spannung eines aktiven Thermistors MCP9701A von Microchip
mit einem AVR Mega32 messen.
Ich versorge den MCP über einen Portpin des Mega32 mit Spannung um bei
Bedarf Strom zu sparen. Wenn ich nun die Spannung messen will, schalte
ich also den Portpin bzw. die Versorgungsspannung zum MCP ein, warte 1ms
und mache 10 AD Wandlungen, die ich nebenbei mittele.
Das eigentliche Problem ist, dass die Spannung die ich messe im Schnitt
ca. 100mV zu hoch ist. Das heißt bei Zimmertemperatur liegen am Ausgang
des MCP ca. 850mV an (gemessen mit Multimeter), was mit der Temperatur
auch übereinstimmt. Sobald die Wandlung gestartet wird(ADCSRA |=
(1<<ADSC)), erhöht sich die Spannung aber auf ca. 950mV und die messe
ich dann auch mit dem AD-Wandler, was ja aber falsch ist.
Die Ursache ist definitv der AD-Wandler was ich mit einer Messung in
Dauerschleife überprüft habe.
Laut Datenblatt des MCP ist der Anschluss ja denkbar einfach: Vout mit
AD-Eingang verbinden - fertig ggf. noch ein RC-Tiefpass dazwischen.
Ich hab auch schon einen 100k Widerstand auf Masse mit reingeschaltet,
damit der MCP ein bisschen was zu treiben hat - leider ohne Erfolg.
Hat das schon mal jemand mit einem AVR zum Laufen gebracht? Oder sollte
ich doch einen PIC nehmen, falls Microchip Sensoren und AVR's
inkompatibel sind..? Die Kombination MCP mit einem MSP430 funktioniert
jedenfalls!
Bin für jede Anregung dankbar!
Hallo,
ich würde erst mal schauen ob es wirklich der ADC ist oder nur das aus
und eingeschalte des Sensors (ergibt laut Datenblatt einen kräftigen
Überschwinger). Vielleicht ist ja der delay(1ms) zu kurz, sei es der
Sensor braucht doch etwas mehr oder die Quarzfrequenz stimmt nicht.
Ansonsten: ich sehe nicht ob die Pull-ups des AVR wirklich aus sind.
Etwas ungewöhnlich ist auch der Zugriff auf den ADC mit 2 einzelnen
Bytes: a) Die Reihenfolge ist falsch es muß zuerst das LOW-Byte gelesen
werden.
b) Wozu gibt es eigentlich das ADCW-Register? Da bräuchte man sich um
die richtige Reihenfolge keine Gedanken zu machen.
Danke für die Hinweise! Das Makro ADCW kannte ich bisher noch nicht.
Selbst wenn ich den delay nach dem Einschalten auf 100ms setze, ändert
sich nichts daran, dass der erste Wert zu hoch ist. Laut Datenblatt
benötigt der MCP 800us zum Einschwingen und mit 1ms warte ich schon um
ein Viertel länger. Die delays passen, hab ich mit dem Oszi überprüft.
Der Pull-Up war aus. Jetzt schalte ich ihn in der Init aber explizit
nochmal aus. Daran liegts also auch nicht.
Was mir noch aufgefallen ist:
Wenn ich in der Zeile
1
meas+=ADCW;
einen Breakpoint setze und die 9 Messungen langsam durchstepe, stimmen
die Ergebnisse. Füge ich allerdings in der for-Schleife einen delay von
z.B. 100ms mit ein und lass das Programm ohne Breakpoints laufen,
stimmen die Ergebnisse wieder nicht. Also kanns doch nicht daran liegen,
dass die Messungen zu schnell nacheinander ablaufen, oder?
Ich komm einfach nicht drauf, woran das liegen könnte. Hier der
aktualisierte Code:
Vielleicht heizt sich der Sensor durch die vielen Messungen auf.
Was passiert bei einer Messung von 1x pro Sekunde?
Wie sieht Dein Schaltplan aus? Hast Du genug Kondensatoren verbaut,
damit die Spannung beim Messen nicht einbricht?
Hallo,
> einen Breakpoint setze und die 9 Messungen langsam durchstepe, stimmen> die Ergebnisse. Füge ich allerdings in der for-Schleife einen delay von> z.B. 100ms mit ein und lass das Programm ohne Breakpoints laufen,> stimmen die Ergebnisse wieder nicht. Also kanns doch nicht daran liegen,> dass die Messungen zu schnell nacheinander ablaufen, oder?
Das beweist doch gerade daß Dein Problem irgendwas mit Timing zu tun hat
(möglicherweise geht auch nur die 1. Messung schief).
1. Schritt ADC und Temperatursensor dauernd eingeschaltet lassen
Eventuell liegt es ja an Deiner VAREF-Beschaltung daß die
Referenzspannung sich zu langsam aufbaut. (laut Datenblatt ist der Pin
sehr hochohmig)
Du schaltest schließlich nicht nur den Sensor sondern auch den ADC ein.
2. alle Zeiten deutlich vergrößern.
Wenn Du dann einen ordentlichen Zustand hast kannst Du einen Schritt
nach dem Anderen aufrüsten. Ich würde auch mal alle Messungen in ein
Array speichern vielleicht sieht man ja einen Trend.
3. Datenblatt lesen:
The first ADC conversion result after switching reference voltage source
may be inaccurate, and the user is advised to discard this result.
Hallo,
ich hab den Sensor und AD-Wandler nun ständig eingeschaltet.
Aber leider bringt das auch nichts. Das die erste Messung nach dem
Einschalten Müll ist, ok. Hat aber mit meinem eigentlichen Problem in
erster Linie nicht viel zu tun.
Ich hab mir das Ausgangssignal des Sensors nochmal mit dem Oszi
angeschaut, wieder einen Breakpoint nach jeder einzelnen Messung gesetzt
und das Programm durchgestept. Ich kann dabei deutlich erkennen, wie die
Ausgangsspannung des Sensors um 0,1V steigt sobald eine Messung
gestartet wird und dann wieder auf den eigentlichen Sollwert abfällt.
Leider hab ich keinen DSO sonst könnt ich ein Bild vom Signalverlauf
hier reinstellen. Wenn ich die Messung ohne Breakpoint laufen lasse, ist
die Ausgangsspannung ständig um 0,1V höher. Ich kann delays einfügen so
viel ich will und auch Kondensatoren an Vcc und die Ausgangsspannung
packen. Ändert alles nichts...
Ist es möglich, dass die beiden Stromquellen im analog input circuitry
des Mega32 (Datenblatt S.217) irgendwie dagegentreiben und so die
Spannung erhöhen? Wie die Ausgangsstufe des MCP aussieht geht aus dessen
Datenblatt ja nicht hervor.
Wie schon gesagt, mit dem MSP430 funktioniert die Messroutine
einwandfrei.
irgendwo hab ich gelesen, daß die erste ADC wandlung nach dem
einschalten des ADC müll ist und weggeschmissen werden sollte. wieso
machst du das nicht einfach?
>Ist es möglich, dass die beiden Stromquellen im analog input circuitry>des Mega32 (Datenblatt S.217) irgendwie dagegentreiben und so die>Spannung erhöhen? Wie die Ausgangsstufe des MCP aussieht geht aus dessen>Datenblatt ja nicht hervor.
Hallo,
im aktuellen Datenblatt ist das Bild ein paar Seiten vorher.
Das sind aber keine Stromquellen, sondern nur das Ersatzbild für die
Leckströme. Die sind unter 1uA. Das reicht nicht um den MCP aus dem
Tritt zu bringen. Der statische Ausgangswiderstand ist 20 Ohm der
dynamische ca 1 Ohm. Da macht der Leckstrom maximal 20uV. Kritisch wird
es erst sobald Ströme oberhalb 100uA auftreten, da geht die Endstufe des
MCP wohl dann in Sättigung. Meiner Meinung bleiben dann nur noch die
Pull-ups des ATMEGA übrig um einen solchen Fehler zu produzieren.
(welche andern Programmteile könnten da noch in die Messung
reinspucken?)
Versuch mal ein paar externe Pull-ups um rauszukriegen welchen
Widerstand man braucht um exakt denselben Fehler zu produzieren.
Hallo,
wenn ich einen 1,8k Pull-up ranhänge ist die Spannung um den selben Wert
angehoben. Allerdings kann ich Dir nicht ganz folgen was mir diese
Erkenntniss jetzt bringt..?
Parallel dazu hab ich den MCP9700A mal ausprobiert. Der hat einen
anderen Offset und nur 10mV/°C statt 19,5mV/°C. Auf jeden Fall tritt
dabei der gleiche Fehler auf. Zwar steigt die Spannung nicht um 100mV
sondern nur um 60mV. Liegt vermutlich an dem kleineren Temperatur
Koeffizienten.
Hallo,
>wenn ich einen 1,8k Pull-up ranhänge ist die Spannung um den selben Wert>angehoben. Allerdings kann ich Dir nicht ganz folgen was mir diese>Erkenntniss jetzt bringt..?
Deine Vermutung war daß die Leckströme 1uA die Ursache sind.
Meine Vermutung war daß die Pull-ups ca 20-50K also ca 150uA die Ursache
sind.
1,8k für denselben Fehler bedeutet daß man mehr als 2mA braucht um
denselben Effekt zu erzielen. Wo kommen die 2mA her?
Bleibt nur noch die Idee daß der Pin (kurzzeitig?) als Ausgang
konfiguriert wird???
Wie ist eigentlich TEMP_VCC definiert? (Bitposition oder Bitmaske?)
>Bleibt nur noch die Idee daß der Pin (kurzzeitig?) als Ausgang>konfiguriert wird???
Das müsste der AVR dann aber selbst machen bzw. gebe ich nirgends den
Befehl dafür.
Ich werd heut mal den Controller tauschen und mal einen anderen Mega32
einsetzen.
Hallo,
einen Mega32 hatte ich leider nicht mehr zur Hand deswegen hab ich's mal
mit einem Mega16 probiert. Allerdings tritt bei dem der selbe Fehler
auf...
Am asm Code fällt mir nichts Außergewöhnliches auf:
1
meas = 0;
2
3
for(i=0; i<9; i++){ // averaging 10 measurements
4
_delay_ms(1);
5
ADCSRA |= (1<<ADSC); // start conversion
6
3ee: 36 9a sbi 0x06, 6 ; 6
7
while(ADCSRA & (1<<ADSC)); // wait until conversion complete
8
3f0: 36 99 sbic 0x06, 6 ; 6
9
3f2: fe cf rjmp .-4 ; 0x3f0 <tempMeasRead+0x20>
10
11
meas += ADCW;
12
3f4: 84 b1 in r24, 0x04 ; 4
13
3f6: 95 b1 in r25, 0x05 ; 5
14
3f8: 28 0f add r18, r24
15
3fa: 39 1f adc r19, r25
Ich werd's die Tage nochmal mit dem IAR Compiler probieren. Wenn das
nichts hilft, werd ich wohl einen anderen Sensor nehmen müssen.
Trotzdem wäre ich dankbar wenn jemand diesen Fehler bestätigen könnte..?
> Am asm Code fällt mir nichts Außergewöhnliches auf:
na ja, der Delay-Aufruf wurde "wegoptimiert",
die for-Schleife steht jetzt plötzlich vor dem Delay befehl
Das ganze sieht schon ein bischen merkwürdig aus oder?
Was mir auffällt, ist:
Du schreibst in Deinem Code etwas von Vref=2,56V
Aber sollten die Temperaturfühler nicht mit Vref=2,5V betrieben, bzw.
berechnet werden?
Also mit IAR ist der Messfehler immer noch da. Hätte mich auch
gewundert. Denn auch wenn der asm Code in der Tat etwas merkwürdig
aussieht, zwischen dem Einschalten des ADC
1
ADCSRA |= (1<<ADSC); // start conversion
2
3ee: 36 9a sbi 0x06, 6 ; 6
und der busy-wait schleife
1
while(ADCSRA & (1<<ADSC)); // wait until conversion complete