Hallo allerseits,
ich versuche mit einem ATtiny84, LC-Display und einem PT1000 die
Temperatur anzuzeigen.
Einen Teil vom Schaltplan habe ich hier im Anhang.
An X3 & X4 angeschlossen ist im Moment ein 1k Widerstand in Reihe mit
einem 500 Ohm Poti. Dies ist zu Testzwecken eine PT1000 Simulation.
Hier ein Teil von meinem Code:
1
while(1)
2
{
3
LCD_Anzeige(get_adc(2));// Poti an PA2 anzeigen
4
LCD_Anzeige(100+get_adc(0b00001001));// Temperatur anzeigen
_delay_us(500);//unbedingt notwendig für Differential Input channel!!!
14
15
ADCSRA=0b11000111;// Start Conversation
16
while(ADCSRA&1<<ADSC){};// Wait for End of Conversation
17
ADC_Wert+=ADCL;
18
ADC_Wert+=ADCH<<8;
19
returnADC_Wert;
20
}
Ich bin erst nach endlosem Gefummel zufällig darauf gekommen, das dieses
_delay in der get_adc Routine bei differentiellen Eingänge (PA0 & PA1)
notwendig ist.
Warum ist das so?
Jetzt geht es, aber bei Temperaturen unter ca 30°C schwankt die Anzeige
um ca. 10°! Woran mag das liegen?
Hallo Peter,
dann wäre noch interessant welche CPU Frequenz du verwendest, das sieht
man nicht alles.
Wenn Du einen atTiny84 @16MHz verwendest, dann passt ja der "ADC
Prescaler" ADPS2:0 = [111] mit 16MHz /128 = 125kHz.
Tut mir leid, aber diesmal landest Du in meinem CSS-File.
Kein kompletter, kompilierbarer Code. Selbst der Codeschnipsel wäre
überahaupt nicht kompilierbar. Falsche Variablennamen. Keine Schaltung.
Nichtmal der Typ des Sensors. Kein noch so laienhafter Ansatz einer
Analyse. Das langt.
Schönes Leben noch.
Hallo Peter,
wie sieht die Initialisierung des ADC aus?
wird eine "Dummy" ADC-Wandlung mit verwerfen des Ergebnisses, wie im
Datenblatt angegeben ist, durchgeführt ?
Uwe S. schrieb:> Hallo,>> hier ist noch ein Schreibfehler:while(ADCSRA & 1 << ADSC){};> Was soll das bedeuten ?
Steht im Kommentar:// Wait for End of Conversation
> Das kann doch keiner lesen !> ADCSRA = 0b11000111;
wie soll ich das besser schreiben?
z.B.
Uwe S. schrieb:> dann wäre noch interessant welche CPU Frequenz du verwendest, das sieht> man nicht alles.>
#define F_CPU 8000000
> Wenn Du einen atTiny84 @16MHz verwendest, dann passt ja der "ADC> Prescaler" ADPS2:0 = [111] mit 16MHz /128 = 125kHz.
äh, versteh ich nicht ganz. Will Temperaturen und langsame Sachen
messen, deshalb hatte ich den ADC so langsam wie möglich gemacht.
Uwe S. schrieb:> Hallo Peter,>> wie sieht die Initialisierung des ADC aus?
Es gibt keine Init_ADC, dies ist in der get_adc Routine enthalten.
> wird eine "Dummy" ADC-Wandlung mit verwerfen des Ergebnisses, wie im> Datenblatt angegeben ist, durchgeführt ?
Öh wenn der erste Messwert falsch sein sollte, ist mir das bisher nicht
aufgefallen.
Bitflüsterer schrieb:> Tut mir leid, aber diesmal landest Du in meinem CSS-File.>> Kein kompletter, kompilierbarer Code. Selbst der Codeschnipsel wäre> überahaupt nicht kompilierbar. Falsche Variablennamen. Keine Schaltung.> Nichtmal der Typ des Sensors. Kein noch so laienhafter Ansatz einer> Analyse. Das langt.>> Schönes Leben noch.
Wer kann mir das erklären?
Muß ich wissen was ein CSS_file ist?
Was will mir Bitflüsterer damit sagen?
Ist mein Thread wirklich so blöd?
Hallo Peter,
Danke.
Peter Zz schrieb:> Uwe S. schrieb:>> Hallo,>>>> hier ist noch ein Schreibfehler:while(ADCSRA & 1 << ADSC){};>> Was soll das bedeuten ?>> Steht im Kommentar:// Wait for End of Conversation
Ja ich weiss, wie der ADC läuft und wie man ihn benützt.
Ok, du hast es nicht gesehen:
1
{};
Ist unsinnig.
Ein
1
while(ADCSRA&1<<ADSC){}
reicht.
>> Das kann doch keiner lesen !>> ADCSRA = 0b11000111;>> wie soll ich das besser schreiben?> z.B.>
1
>ADCSRA=(1<<ADEN)|(1<<ADSC)|ADC_Prescaler_128;
2
>
> so zufrieden?
Super, so kann jeder schnell sehen, was gewollt ist und es entstehen
keine Kodierungsfehler.
while(ADCSRA&(1<<ADSC)){};// Wait for End of Conversation
10
returnADCW;
11
}
Habe jetzt dieses, "return ADCW" spart 10 Byte!
Thx!
Aber das Hauptproblem, warum brauche ich bei differentieller Wandlung
dieses _delay_us(500) und warum die Anzeige bei unter 30° schwankt ist
nicht gelöst.
Hallo Peter,
Peter Zz schrieb:> Uwe S. schrieb:>> dann wäre noch interessant welche CPU Frequenz du verwendest, das sieht>> man nicht alles.> #define F_CPU 8000000
Ok, dann weiß ich bescheid.
>>> Wenn Du einen atTiny84 @16MHz verwendest, dann passt ja der "ADC>> Prescaler" ADPS2:0 = [111] mit 16MHz /128 = 125kHz.>> äh, versteh ich nicht ganz. Will Temperaturen und langsame Sachen> messen, deshalb hatte ich den ADC so langsam wie möglich gemacht.
Nun man sollte nicht einfach etwas machen, ohne zu wissen ob es
funktioniert.
Aber hier passt die ADC Clockfrequzenz mit den Vorgaben überein:
Datenblatt S.135
---------------
By default, the successive approximation circuitry requires an input
clock frequency between 50 kHz and 200 kHz to get maximum resolution. If
a lower resolution than 10 bits is needed, the input clock frequency to
the ADC can be higher than 200 kHz to get a higher sample rate. It is
not recommended to use a higher input clock frequency than 1 MHz.
---------------
while(ADCSRA & 1 << ADSC){};
sieht mir Verdächtig aus.
Besser vielleicht noch ein Klammer:
while(ADCSRA & (1 << ADSC)){};
Wenn man die zeit hat, könnte man noch über 1/50 s Sekunde mitteln, um
50 Hz Störungen zu unterdrücken. Mit der Verstärkung können da schon
relativ kleine 50 Hz Störungen stören, die man so nicht unbedingt sieht.
Hallo Peter,
Peter Zz schrieb:> Habe jetzt dieses, "return ADCW" spart 10 Byte!> Thx!>> Aber das Hauptproblem, warum brauche ich bei differentieller Wandlung> dieses _delay_us(500) und warum die Anzeige bei unter 30° schwankt ist> nicht gelöst.
Da gibt es mehrere Dinge, die ich anders mache.
a) ich mache immer 8-32 Messungen nacheinander und bilde daraus einen
Mittelwert.
b) ich verwende eine Referenzspannungsquelle
c) NICHT die +5V = AVcc eines Spannungsreglers, der schwankt !
d) AVcc wird durch eine C-L-C Filter mit +5V versorgt.
e) durch einen 2 Punktabgleich werden die beiden geläufigsten Messfehler
heraus gerechnet: das ist der Offset- und der Linearitätsfehler.
Das steht in den Application Notes von Atmel zu der AVR ADC-Nutzung.
Ich würde nur in deinem Fall - single ended und danach eine
Differentialmessung -
nach dem Wechsel der ADC-Eingänge immer eine Dummywandlung machen und
den Wert verwerfen.
Ich finde gerade keine Anmerkung zum Zeitverhalten für die
Differentialmessung.