Hallo,
um es vorweg zu sagen: Ich bin noch relativ unerfahren, was Elektronik
und Mikrocontroller angeht, jedoch möchte mit Hilfe eines Atmega8 einen
Feuchtesensor auslesen (ist der HS1101 von Humirel, Datenblatt gibt es
z.B. hier: http://www.humirel.com/product/fichier/HS1101-HS1100.pdf ),
sprich dessen Kapazität bestimmen. Diese muss ungefähr zwischen 160 und
200 pF liegen.
Das erledige ich, indem ich einen astabilen Multivibrator herstelle nach
diesem Schaltplan:
http://upload.wikimedia.org/wikipedia/commons/e/e2/NE555_astable.png.
Die 3 ist in dem Fall direkt mit dem ICP1-Pin vom Atmega verbunden. Als
R1 hab ich jetzt in dem Fall 291kOhm und als R2 203kOhm gewählt, damit
ich auf Frequenzen um 10kHZ komme, die in dem Datenblatt angegen wurde.
Die Periodendauer der Schwingung berechnet sich ja dann nach T =
ln(2)*(2*R1 + R2)*C, richtig?
Softwaremäßig messe ich die Zeiten zwischen zwei
Input-Capture-Interrupts (Timer1 mit Vorteiler 1) und schmeiße dann die
Differenz in den EEPROM, den ich dann am Ende auslese und mir aus den
ganzen 16-Bit-Werten meine Kapazitäten berechne.
Soweit so gut, das Problem ist bloß, dass ich z.T. sehr merkwürdige
Werte bekomme. Ich habe hier mal einige Ergebnisse angehängt. Der erste
Wert ist die Timer-Wert-Differenz zwischen zwei ICP-Interrupts, der
zweite Wert die daraus berechnete Kapazität Teilweise scheinen sie
vollkommen zufällig zu sein, teilweise habe ich Messreihen mit
aufsteigenden Werten, dann wieder habe ich Reihen mit über 100%-igen
Luftfeuchten (>200pF). Am häufigsten sind mir aber Reihen aufgefallen,
wo sich zu hohe und zu niedrige Werte periodisch abwechseln (bei
mess4.txt sehr schön zu sehen).
Jetzt ist meine Frage, was ich falsch gemacht haben könnte bzw. ob ich
schon bei der Programmierung irgendeinen Fehler reingebaut habe oder ob
irgendwas in der Schaltung falsch ist.
Danke im Voraus,
Siedler
Deine Messroutine berücksichtigt nicht, dass du mit einem 16-Bit Timer
ICR1 arbeitest. Irgendwann passiert ein Überlauf bei dieser Geschichte:
uint16_t startzeit = 0;
ISR Input_Capture
uint16_t aktuellezeit = ICR1;
in_eeprom_speichern(aktuellezeit - startzeit);
startzeit = aktuellezeit;
Du kannst das auf zwei Arten behandeln:
1/ Zähle mit wie oft ein Überlauf stattfindet und berücksichtige das bei
der Berechnung der Messzeit. Vorteil: Längere Messzeiten als 16-Bit sind
möglich. Nachteil: Mehr Platzbedarf im EEprom und zweite ISR
erforderlich.
2/ Resette den Input Capture Timer auf 0 nach jedem Durchlauf. Vorteil:
Code kann im wesentlichen so bleiben. Nachteil: Begrenzung der Messzeit
auf 16-Bit Zeiträume.
Die Umrechnung Messzeit in Kapazität ist in deinem Code nicht drin,
daher kann ich nichts dazu schreiben. Prüfe halt die verwendete Formel.
Ja, dass es einen Überlauf geben kann, war mir schon klar, allerdings
gibt es den ja erst nach 2^16 ~= 65000 Taktzyklen und da die gemessene
Periodauer nur im Bereich von 200-400 liegt, sollte das nicht allzuoft
passieren. Allerdings kommen diese Wechsel von "zu hoch" zu "zu niedrig"
ja alle 3 Messvorgänge, also sprich so alle 1000 Taktzyklen, was somit
nicht am Überlauf liegen kann, oder? Ansonsten könnte ich ihn wohl
einfach resetten..
Bei der Kapazitätsberechnung habe ich mir ein kleines C-Programm
geschrieben, was aber denke ich fehlerfrei sein sollte, aber ich hänge
es trotzdem nochmal mit an.
Siedler schrieb:> Softwaremäßig messe ich die Zeiten zwischen zwei> Input-Capture-Interrupts (Timer1 mit Vorteiler 1) und schmeiße dann die> Differenz in den EEPROM,
Hallo,
das was Du mißt ist die Dauer des Schreibzugriffes auf das EEPROM
synchronisiert durch irgendwelche Flanken an Deinem Pin.
Schau mal wie lange der Schreibzugriff dauert im Verhältnis zu der
Periodendauer.
Wenn Du ein Oszi hast könntest Du mit einem Portpin am Anfang und Ende
der Interrupt-Routine wackeln um zu sehen was da abläuft.
Gruß Anja
OK, ich hab jetzt das Programm so umgebaut, dass die Werte zunächst im
RAM zwischengespeichert werden und wenn er 64 zusammen hat, überträgt er
sie auf den EEPROM.
Dabei habe ich nun zwei Probleme:
1. Wenn ich beim Kommentar "Timer zurücksetzen" die out TCNT1L, r20 und
out TCNT1H, r20 drin lasse, kriege ich irgendwelchen Datenmüll (oberes
Byte irgendwie alle 4 Byte erhöht?). Allerdings versteh ich den Fehler
nicht. Wie setzt man sonst den Timer zurück?
2. Wenn ich die outs weglasse, bekomme ich die richtigen aufsteigenden
Werte mit konstanter Differenz um die 393-394. Wenn man das jetzt
allerdings mal nachrechnet:
R = 697000 Ohm
F_(MC) = 4 Mhz
C = (394 / F_(MC)) / (ln(2) * R)
= 204 pF was einer Luftfeuchte nahe 100% entspricht. ;)
Siedler schrieb:> Allerdings versteh ich den Fehler> nicht. Wie setzt man sonst den Timer zurück?
Normalerweise gar nicht. Man läßt ihn weiterlaufen und rechnet die
Differenz.
Oder wenn schon zurücksetzen dann vorher den Timer anhalten und wieder
neu starten. Wobei allerdings dann einige Takte verlorengehen.
Siedler schrieb:> = 204 pF was einer Luftfeuchte nahe 100% entspricht. ;)
Wie lang ist denn das Kabel bis zum Sensor? Da kommen locker 33-100pF je
Meter Leitung dazu. Der NE555 hat auch noch 5-10 pF Eingangskapazität.
Und bei so hochohmigen Widerständen spielen auch schon die Leckströme
des ICs eine Rolle.
Es wird dir nichts anderes übrig bleiben als mit 2 Referenzkondensatoren
die Du anstelle des Sensors anschließt das System zu kalibrieren.
Gruß Anja
Anja schrieb:> Normalerweise gar nicht. Man läßt ihn weiterlaufen und rechnet die> Differenz.
Jagut, ich war eben zu faul, den Overflow zu behandeln. Mein Fehler war
allerdings, dass ich beim setzen von TCNT1 das High-Byte zuerst zuerst
setzen musste. (Wieso eigentlich? Darauf soll mal jemand kommen..) Was
erhalte ich denn so für Verzögerungen, wenn ich es so lassen würde? Das
wäre dann ja im Prinzip nur die Verzögerung zwischen dem Setzen von dem
Capture Wert und Auslösen des Interrupts?
Anja schrieb:> Wie lang ist denn das Kabel bis zum Sensor? Da kommen locker 33-100pF je> Meter Leitung dazu.
Also das "Kabel" ist vielleicht ein paar cm lang. ;) Also es befindet
sich alles auf einer kleinen ca 10x10cm großen/kleinen
Lochrasterplatine.
Anja schrieb:> Es wird dir nichts anderes übrig bleiben als mit 2 Referenzkondensatoren> die Du anstelle des Sensors anschließt das System zu kalibrieren.
Hmm, weiß leider nicht so richtig wie ich das am dümmsten machen soll.
Nehme ich einfach einen Kondensator mit Kapazität X an, der parallel
geschaltet ist? Dann müsste ich ja deren genaue Kapazität kennen und das
von irgendwelchen Teilen im pF-Bereich...