Forum: Mikrocontroller und Digitale Elektronik Schnelle Auswertung einer kleinen Kapazität


von Alexander S (Gast)


Lesenswert?

Hallo,

Wir die Aufgabe eine Kapazität von 5 pF 200 mal die Sekunde auszuwerten. 
Wir haben uns für einen RC Schwingkreis entschieden.

Wir haben schon einen Testaufbau gemacht und dieser funktioniert auch 
alles soweit, nur ist unser Schmitt trigger ziemlich groß da er 8 Kanäle 
besitzt, wir aber nur einen brauchen.Weiterhin legt unser Zähler das 
Ausgangssignal an 14 pins an, was eine ziemlich Platzverschwendung ist. 
Außerdem wäre ein "serielles" ? Signal leichter auszuwerten. Zum 
auswerten wollten wir einen Mikrocontroller benutzen. SPI vielleicht ?

Der Zähler muss bis etwa 10.000 Zählen können, also wäre ein 14 bit 
Zähler sinnvoll. Dies muss er in 5 ms bewältigen, das wären etwa 2 Mhz 
entwpricht, was kein großes Problem sein dürfte.
Der Schmitt trigger liegt in dem gleichen Anforderungsbereich.

Wie sieht das mit dem abfragen und resetten von dem Zähler aus ? Ist das 
ohne Probleme mit einem Mikrocontroller möglich ? Da wir auf 0,5 fF 
Auflösen müssen, ist uns eine hohe Genauigkeit wichtig. Das Signal muss 
alle 5ms vom Zähler ausgelesen werden und der Zählerstand resettet 
werden.

Da wir uns nciht so gut mit Elektronik auskennen wollten wir uns mal an 
euch vom Fach richten, da wir in dem Wust der Datenblätter leicht den 
Überblick verlieren.

Mfg ALexander

von Gast (Gast)


Lesenswert?

Hört sich nach einem kapazitiven Taster an...

von Latissimo (Gast)


Lesenswert?

Prinzipiell würde ich aufgrund von Erfahrungn sagen, dass man die 
Kapazität größer wählt.

Diese würde man dann mit digitalen Ladepulsen aufladen, bis ein 
Komparator feststellt, dass der C die Referenzspannung erreicht hat. Ein 
Zähler zählt die Ladepulse mit.

Wenn kurze Ladezeiten notwendig sind, sollte man jedoch nicht auf eine 
große Anzahl von Ladepulsen verzichten, sondern vielmehr die Zeiten 
zwischen den Ladepulsen sehr klein halten. So spart man Zeit während des 
Ladens, aber erhält trotzdem eine hohe Anzahl an Ladepulsen. Diese hohe 
Anzahl ändert sich durch Einflüsse(welche du auch immer detektieren 
willst) sehr stark(absolut gesehen). Das kannst du dann per Software 
sauberer Auswerten. Von 200 auf 190 ist besser, als von 40 auf 38 obwohl 
es beides 5% Änderung darstellt.

(Hier sei eine PWM von hoher Frequenz erwähnt, wobei der Duty Cycle bei 
ca 95% liegt.)

Eine Schaltung als Sensor hätte ich auch parat...

von Oszi40 (Gast)


Lesenswert?

Temperaturstabilität=?

5pF sind natürlich keine besonders große Kapazität, die dann beim 
Schaltungsaufbau der restlichen Schaltung noch zu betrachten wäre.

Interessant wären die Befehlslaufzeiten bei der Auswertung.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Alexander S wrote:
>
> Wir haben schon einen Testaufbau gemacht und dieser funktioniert auch
> alles soweit, nur ist unser Schmitt trigger ziemlich gro da er 8 Kanle
> besitzt, wir aber nur einen brauchen.Weiterhin legt unser Zhler das
> Ausgangssignal an 14 pins an, was eine ziemlich Platzverschwendung ist.
> Auerdem wre ein "serielles" ? Signal leichter auszuwerten. Zum
> auswerten wollten wir einen Mikrocontroller benutzen. SPI vielleicht ?

Fallls dies die Topologie ist: Warum

trigger->zhler->spi->µC ?

Viel einfacher wäre doch

trigger->µC

d.h. man nimmt den µC selbst als Zahler. Die meisten µC können Timer per
extern asynchron takten lassen.

Die Genauigkeit ist dann bestimmt durch
1) Genauigkeit, mit der der µC getaktet wird
2) Genauigkeit, mit der Zählintervalle (hier 5ms) erzeugt werden.

Um 2) groß zu machen, geht folgendes:

Ein Pin des µC wird als Enable verwendet, indem das Signal als Eingang
in den S-Trigger geht (zB NAND-Trigger, AND-Trigger, je nach Flanke).
Das Enable selbst wird im µC per Hardware-PWM erzeugt, um maximale
Genauigkeit zu bekommen.

So eine Aufgabe ist schon mit einem kleinen AVR zu bewlätigen, man
braucht einen extern tickbaren, asynchronen 16-Bit-Zähler und einen 
weiteren Zähler mit PWM-Einheit.

In den ON-Phasen macht der µC nix und seine Hardware zählt brav vor sich
hin (hier wäre sogar SLEEP möglich um Störungen zu minimieren).

Am Ende der ON-Phase wird eine IRQ getriggert; in der ISR wird der Wert
des nun stehenden (Enable blockiert ja den S-Trigger) Timers gelesen und
dieser für die nächste ON-Phase auf Null zurückgesetzt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

...wobei das mit AVR einen kleinen Schönheitsfehler hätte: Die asynchron 
taktbaren Timer (zB Timer2 beim ATmega48/88/168) sind nur 8-Bit-Timer. 
Man muss dann von Hand per Overflow-ISR das High-Byte weiterzählen -- 
also auch nix mit sleep während der ON-Phase der PWM.

von Alexander (Gast)


Lesenswert?

Hallo, danke für die Antworten,

Also der aktuelle Stand sieht so aus:

Die 5pf sind fest und wir müssen eben auf diese 0,5 fF auflösen.
Wir haben nochmal mit unserem projektbetreuer geredet und die Ideee 
einen µC als Zähler zu benutzen scheint im Moment ziemlich gut. :)
Wir hatten gedacht, das wir den Zähler alle xx Takte einen Interrupt 
erzeugen (etwa alle 5 ms) und den Zähler abfragen und resetten.
5ms müssen wir ja nicht genau messen, da die Takte von einem µC immer 
gleich lange dauern oder ? (z.B. ein Takt 50ns, dann fragen wir alle 
100.000 Takte den Zähler ab.

Wir haben uns jetzt mal einen ATmega168 besorgt, da er relativ klein und 
und bei uns vorrätig ist. Ist das eine gute Wahl ? kann man den Zähler 
asynchron laufen lassen ?
Und falls er synchron läuft, mit welcher Geschwindigkeit kann er dann 
Zählen ?

von Latissimo (Gast)


Lesenswert?

Vllt. bin ich schwer von Verstand, aber was genau willst du machen???

Willst du eine Kapazität bestimmen? Hast du eine Kapazität, die Variable 
ist? Und willst du immer die aktuelle Kapazitätsgröße bestimmen oder 
was?

Sry wegen dem Verständnisproblem, aber beschreib mal genauer, worum es 
geht.(für die Blöden wie mich....)

von Alexander (Gast)


Lesenswert?

Genau, wir haben eine Zahnspange in der Sensoren stecken. Diese Sensoren 
ändern jenach Zungendruck ihre Kapazität von etwa 5pf auf 5.5pF

Wir sollen diese Sensoren 200 mal die Sekunde abfragen und auf 1000 
Schritte genau Auflösen.
Zahnspange-> wenig Platz, aber das ist erstmal halb nebensächlich, da 
wir zuerst eine Prototypenschaltung für einen Sensor aufbauen wollen.

D.h. in 5 ms ein Messwert. Wir brauchen etwa 1200 Schritte differenz bei 
ungefähr 7000 Gesamtschritten die wir bei 10% Kapazitätsdifferenz haben.

da f² = 1/(RC) haben wir da eben eine nichtlinearität die wir dann 
später noch im µC korregieren müssen.

Aber das kommt danach,
Der Schwingkreis mit einem Schmitt trigger geht, und ein externer Zähler 
hat auchs chon seine Dienste geleistet, nur das abgleichen mit einem µC 
hat Probleme gemacht. Außerdem war das ganze etwas groß, daher war etzt 
die Überlegung den Zählervon einem µC zu benutzen.
Im aktuellen Status der ATmega 168. Ob er dazu geeignet ist weiss ich 
"noch" nicht

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Alexander wrote:
> Hallo, danke für die Antworten,
>
> Also der aktuelle Stand sieht so aus:
>
> Die 5pf sind fest und wir müssen eben auf diese 0,5 fF auflösen.
> Wir haben nochmal mit unserem projektbetreuer geredet und die Ideee
> einen µC als Zähler zu benutzen scheint im Moment ziemlich gut. :)
> Wir hatten gedacht, das wir den Zähler alle xx Takte einen Interrupt
> erzeugen (etwa alle 5 ms) und den Zähler abfragen und resetten.
> 5ms müssen wir ja nicht genau messen, da die Takte von einem µC immer
> gleich lange dauern oder ? (z.B. ein Takt 50ns, dann fragen wir alle
> 100.000 Takte den Zähler ab.

Die Takte eines µC sind wie gesagt so genau wie seine Taktquelle. Gute 
Ergebnisse gibt's mit einem t-kompensierten Quarzoszillator. Die 
Ganggenauigkeit muss mindestens so hoch sein wie die zu erzielende 
Messgenauigkeit.

Wichtig ist hier aber auch, dass die Aktionen an den Ports exakt zu den 
geplanten Zeiten erscheinen, und nicht zB ein Port von Hand in einer ISR 
gesetzt wird, weil eine IRQ unterschiedlich Latenz haben kann, je 
nachdem, welche Instruktion gerade in der Mache ist, während die IRQ 
getriggert wird. Daher Enable und Hard-PWM wie oben skizziert.

Ein Timer inkrementiert also nicht schneller als mit 20MHz, wenn wir 
davon ausgehen, dass der AVR nicht übertaktet wird und er an einem 20MHz 
Quarz oder Oszi hängt.


> Wir haben uns jetzt mal einen ATmega168 besorgt, da er relativ klein und
> und bei uns vorrätig ist. Ist das eine gute Wahl ? kann man den Zähler
> asynchron laufen lassen ?

Ja, der ist geeignet. Aber AFAIR nur Timer2, ein 8-Bit-Timer. Um 16 Bit 
Auflösung (oder auch mehr) zu bekommen, muss man wie gesagt über die 
Overflow-IRQ gehen.

> Und falls er synchron läuft, mit welcher Geschwindigkeit kann er dann
> Zählen ?

Synchron ist hier nicht zu gebrauchen, wenn von extern getickt werden 
soll, weil dann das Tick-Signal mit dem µC-Takt synchronisiert wird. Das 
gibt dann sowas wie Moiré-Effekte.

Ein intern getakteter Timer bei AVR zählt im durch eine 2er-Potenz 
geteilten CPU-Takt. Im Nenner steht also zB 2^0 oder 2^64 oder ... Das 
ist schnödes Teilen durch 2, eine PLL gibt's nicht. Näheres gibt's im 
Datenblatt.

von Alexander S (Gast)


Lesenswert?

Hallo,

Also..
Zuerst hatten wir den Timer 2 zum Zählen programmiert. Bie jedem 
Überlauf hat er ein Interrupt erzeugt, den wir dann mitgezählt haben.
Alles super, nur leider hat das Crumb Modul, das wir zur Vorführung 
benutzen sollen, die Pins des Timers 2 nicht nach außen geführt.

Naja umdenken. Frequenzen und Bauteile neu berechnet und wir sind jetzt 
bei einer zu messenden Frequenz von 2-4 Mhz.
Da unser ATmega mit 20 Mhz läuft sollte das kein Problem sein zu Zählen.
Im Datenblatt steht 1/2.5 -1/4 fsys.

Nun haben wir den Zähler 0 zur erzeugunf vom Zeitfenster programmiert. 
Wenn er ein Compare Match wirft, wird ein Interrupt geworfen. Das ist 
alle 5ms. Das funktioniert auch soweit.

In dieser Interrupt Routine lesen wir Zähler 1 aus. Dies funktioniert 
ganz gut wenn wir dem Zähler 1 den Systemtakt runtergeteilt auf 2.5 Mhz 
vorgeben. Er zählt schön bis etwa 12.000.
Stellen wir als Quelle aber nun T1 ein, und hängen unsere Schaltung 
dran, dann messen wir immer 0 Pulse.

Wir haben mit einem Oszi unsere Schaltung ausgemessen, die funktioniert.
Ebenfalls haben wir einen FUnktionsgenerator mit einem idealen 
Rechteckpuls an T1 gehängt also PD5.
Wir haben ein Rechtecksignal mit 1-2 Mhz und eine Amplitude von 0-3 bzw 
0-5 V angelegt. Wir haben T1 bzw PD5 als EIngang deklariert, obwohl es 
laut Datenplatt egal ist

so haben wir Timer 1 initialisiert

TCCR1A=0x00;
TCCR1B=0x07;  // Zählt steigende Flanken an T1
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

Port D
PORTD=0x20;    //Pins von Port D werden als Eingang gesetzt
DDRD=0x00;


Zusammenfassend:

Timer 1 bekommt als SIgnal den Systemtakt heruntergeteil:
alles funktioniert
Timer 1 bekommt als Signal ein externes an Pin T1-> er zählt nur 0

woran kann es liegen ?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Soweit kann ich da nix sehen...

Auf D.5 liegt ebenso OC0B, evtl wiederspricht sich da die 
Initialisierung mit Timer0?

Stört der PullUp an D.5?

Kann sein, daß die Hardware immer wieder resettet wegen 
nicht-Implementierter ISR?

Zudem: man sollte auf 16-Bit-Register auch so zugreifen. Also:
1
TCNT1=0; // statt TCNT1H=... TCNT1L=...

von Gast (Gast)


Lesenswert?

Vielleicht auch brauchbar:
http://www.acam.de/index.php?id=16&L=1

von Alexander (Gast)


Lesenswert?

Pullup haben wir geändert, hat nix gebracht.
Direkt darauf zugreifen mit TCNT1 geht leider nicht, geht wohl nur mit 
GNU Compiler ? mit unserem leider nicht.

Wie meinst du wegen nciht initialisierter ISR ?
Wir lassen die Timer abfrage sowie den Timer reset in dem Interrupt 
ablaufen der bei Compare Match Timer0 geworfen wird

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Alexander wrote:
> Direkt darauf zugreifen mit TCNT1 geht leider nicht, geht wohl nur mit
> GNU Compiler ? mit unserem leider nicht.

Mit avr-gcc geht das, ja. Ob das nur mit dem geht, weiß ich net.

> Wie meinst du wegen nciht initialisierter ISR ?

Wenn eine IRQ aktiviert wird, für die keine ISR implementiert wird, 
macht der µC was undefiniertes oder wird zum RESET-Vektor weiter 
geleitet (avr-gcc). Das sieht dann u.U. so aus, als würde der µC nix 
tun.

> Wir lassen die Timer abfrage sowie den Timer reset in dem Interrupt
> ablaufen der bei Compare Match Timer0 geworfen wird

Um ein Programmfehler auszuschliessen geht vielleicht auch:
ein Bit von TCNT1 in ner Endlosschleife (ohne IRQs) auf ein Portpin 
ausgeben und anschauen ob das Pin wackelt. Wenn ja, ist ds Problem in 
der Software (zB Timer0-ISR). Wenn nicht

-- ist der µC im Eimer
-- ist das Datenblatt ist falsch (glaub ich net)
-- hat der µC nen Solicon-Bug (recht unwahrscheinlich)
-- hat der Compiler hat nen Bug (nicht sooo unwahrscheinlich)

Die Initialisierung sieht wie gesagt ok aus.
Und wenn die Pulse breiter sind als eine Periode der CPU-Clock sollte 
der Timer tickern.

von Alexander (Gast)


Lesenswert?

Bei unserem Comiler geht das leider nicht.

Hm also den internen Takt zählt er ja innerhalb der ISR ganz normal 
hoch,
Problem besteht wiegesagt nur beim abgreifen des Signals an einem PIN.

Ich werde mal einen anderen µC sowie alle Pins ausprobieren ;)
Weiterhin schaue ich mal ob alle IRQ mit einer ISR implementiert sind.

Danke schonmal ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.