Batteriemonitor mit Dual Slope Wandler

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

H.Stockhoff

Dieser Artikel nimmt am Artikelwettbewerb 2012/2013 teil.

Abbildung 1: Batteriemonitor mit Dual Slope Wandler

Der Dual Slope Wandler wird häufig in Vielfachmessgeräten eingesetzt, da dieser kostengünstig in der Fertigung ist, und eine relativ hohe Auflösung bietet. Ein Beispiel für ein IC nach dem Dual Slope Wandler Prinzip ist der ICL7107 der Firma Intersil. Das Verfahren basiert auf dem Vergleich zwischen einer integrierten Mess- und Referenzspannung. Es arbeitet also mit zwei Rampen. Daher wird dieses Verfahren auch Zweirampenverfahren oder Dual Slope genannt. Ich möchte in diesem Artikel ein Batteriemonitor zu Spannung- und Strommessung vorstellen. Das Messgerät kann später an einem 12V Akku betrieben werden und zeigt den aktuellen Stromfluss, die Spannung und die entnommene Ladung sowie die Laufzeit an.


Allgemeines

Der Dual Slope Wandler setzt sich im grundlegenden aus einem Integrator und einem nachfolgenden Komparator zusammen. Eine Steuerlogik legt die entsprechenden Signale an den Eingang des Integrators. Ein Zähler, der mithilfe des Komparators gestartet und gestoppt wird, misst die am Integrator angelegten Messsignale aus und stellt dann einen Wert in Form eines Zählerstandes zur Verfügung. Der Wert des Timers ist der Mittelwert der angelegten Messspannung über die Messzeit. Daher werden Störungen kompensiert und es können mit diesem Wandler Genauigkeiten von bis zu 0,01% erreicht werden.

Abbildung 2 : Dual Slope Wandler

Anhand der nebenstehenden Schaltung kann die Funktion des Wandlers noch einmal verdeutlicht werden (Abbildung 2).



Funktionprinzp

Zu Beginn sind die Schalter S1 und S2 geöffnet. Schalter S3 ist geschlossen. So wird der Integrationskondensator kurzgeschlossen und entladen. Im nächsten Schritt wird der Schalter S3 geöffnet und der Schalter S1 geschlossen. Es wird nun die zu messende Spannung am Integrator angelegt und aufsummiert. Der Vorteil des Integrators ist, dass der Integrationskondensator mit einem konstanten Strom geladen wird. Dadurch ergibt sich eine lineare Aufladung des Kondensators C. Die Spannung am Ausgang des Integrators besitzt eine umgekehrte Polarität, da die Eingangsspannung an den invertierenden Eingang des Operationsverstärkers gelegt wird. Da die Spannung am invertierenden Eingang des Komparators nun kleiner als 0V ist, gibt er das Tor frei(UND-Gatter). Das Signal wird nun so lange integriert, bis der Zähler einmal übergelaufen ist. Anschließend wird die Referenzspannung (umgekehrtes Vorzeichen zur Messspannung) an den invertierenden Eingang des Integrators angelegt. Dazu wird der Schalter S1 geöffnet und der Schalter S2 geschlossen. Die Spannung am Kondensator C des Integrators wird abintegriert. Sie sinkt linear, da auch hier der Kondensator C mit einem konstanten Strom geladen bzw. in diesem Fall entladen wird. Zu diesem Zeitpunkt gibt der Komparator das Tor noch frei, da die Spannung am invertierenden Eingang über ein Potential kleiner als 0V verfügt. Wenn der Kondensator nun so weit entladen bzw. aufgeladen ist und er das 0V Potential überschreitet, sperrt der Komparator das Tor. Er gibt dann ein negatives Signal am Ausgang aus. Somit ist die Messung beendet. Anschließend wird durch die Steuerschaltung der Schalter S2 wieder geöffnet. Um eine gleiche Anfangsbedienung vor jeder Messung zu bekommen, wird der Kondensator C wieder entladen. Dazu wird der Schalter S3 geschlossen. Der Kondensator C ist kurzgeschlossen.

Im nächsten Schritt kann mithilfe des Wertes des Zählers die gemessene Spannung Ue ermittelt werden. Dazu bediene ich mich der Formel für die Aufladung des Integrators über die Zeit t1:

[math]\displaystyle{ U_I(t_1)= -\tfrac{1}{\tau} \int_0^{t_1} U_e dt = -\tfrac{1}{RC} \int_0^{t_1} U_e dt }[/math]


mit [math]\displaystyle{ \tau }[/math] = R∙C

UI  : Spannung am Integrator
t1 : Zeit der Integration der Eingangsspannung
Ue : Eingangsspannung des Integrators

Das Prinzip des Dual Slope Wandlers besteht darin, die Mess- und Referenzspannung ([math]\displaystyle{ U_e, U_{ref} }[/math]) zu integrieren. Die Referenzspannung wird mit der Anfangsbedingung UI0 integriert, da sie nach dem Anlegen der Messspannung aufsummiert wird. Da ich eine zeitlich konstante Spannung integriere, gilt der Sonderfall für die Berechnung der Spannung UI des Integrators:

[math]\displaystyle{ U_I = -\tfrac{U_e}{\tau} \cdot t + U_{I0} }[/math]

mit [math]\displaystyle{ \tau }[/math] = R∙C


Ue : Eingangsspannung des Integrators
UI : Spannung am Integrator
UI0 : Anfangsbedingung des Integrators (Anfangsspannung an UI)
t : Zeit der Integration

Die Zeit t setzt sich zusammen aus dem maximalen Zählerstand Nmax und der Periode T.

[math]\displaystyle{ t = (N_{max} + 1) \cdot T }[/math]

Somit ist

[math]\displaystyle{ U_I = -\tfrac{U_e}{\tau} \cdot (N_{max} + 1) \cdot T + U_{I0} }[/math]

mit [math]\displaystyle{ \tau }[/math] = R∙C  Da beide zu integrierenden Spannungen entgegengesetzte Vorzeichen besitzen, ist die Summe beider Spannungen null. Es gilt:

[math]\displaystyle{ 0 = - \tfrac{U_e}{\tau} \cdot (N_{max} + 1) \cdot T + \tfrac {U_{ref}}{\tau} \cdot N \cdot T }[/math]
             Integration	       Integration
             der Messspannung          der Referenzspannung

Wird diese Gleichung vereinfacht erhält man:


[math]\displaystyle{ 0 = - \tfrac{U_e}{\tau} \cdot (N_{max} + 1) \cdot T + \tfrac {U_{ref}}{\tau} \cdot N \cdot T \quad | -(- \tfrac{U_e}{\tau} \cdot (N_{max} + 1) \cdot T) }[/math]
[math]\displaystyle{ \Leftrightarrow \tfrac{U_e}{\tau} \cdot (N_{max} + 1) \cdot T = \tfrac {U_{ref}}{\tau} \cdot N \cdot T \quad | \cdot \tau }[/math]
[math]\displaystyle{ \Leftrightarrow \tfrac{U_e}{\cancel{\tau}} \cdot (N_{max} + 1) \cdot T = \tfrac {U_{ref}}{\cancel{\tau}} \cdot N \cdot T \quad | : T }[/math]
[math]\displaystyle{ \Leftrightarrow U_e \cdot (N_{max} + 1) \cdot \cancel{T} = U_{ref} \cdot N \cdot \cancel {T}\quad | :N_{max}+1 }[/math]
[math]\displaystyle{ \Leftrightarrow U_e= \tfrac{N \cdot U_{ref}}{N_{max}+1} }[/math]


Durch diese Gleichung kann mithilfe des aus dem Zähler erhaltenen Wertes die Eingangsspannung des Integrators berechnet werden. Dazu ist die Gleichung nach [math]\displaystyle{ U_e }[/math] aufzulösen:

[math]\displaystyle{ U_e = \tfrac {N \cdot U_{ref}}{N_{max} + 1} }[/math]

Gut zu sehen ist, dass weder die Periode T bzw. die Taktfrequenz [math]\displaystyle{ f = \tfrac {1}{T} }[/math] , noch die Zeitkonstante [math]\displaystyle{ \tau }[/math] des RC-Gliedes mit in die Rechnung einfließen. Dies ist ein spezielles Merkmal des Dual Slope Wandlers. Wird ein Dual Slope Wandler aufgebaut, ist auf den Typ des Operationsverstärkers zu achten. OPs, aufgebaut aus bipolaren Transistoren, besitzen meist hohe Bias Ströme. Diese führen dazu, dass die Aufladung des Kondensators beeinflusst wird. So werden sich die Bias Ströme auf den Kondensator durch die lange Aufladung aufsummieren und das Messergebnis verfälschen. Es sollte daher ein Operationsverstärker mit geringen Bias Strömen gewählt werden, damit die Aufladung des Kondensators nicht beeinflusst oder gar verfälscht wird. Dazu eignen sich meistens OPs mit einem internen FET-Aufbau. Sie besitzen oft kleine Bias Ströme von wenigen Pikoampere (Diese können dann vernachlässigt werden). Somit müssen bei FET-Operationsverstärkern lediglich die Offsetspannungen kompensiert werden, um ein korrektes Ergebnis zu erhalten.


Hardware

Nun zur Hardware. Das Messgerät besteht aus einem Dual Slope Wandler, an den über ein Multiplexer (4051) die verschiedenen Messsignale angelegt werden. Gesteuert wird der Multiplexer mit einem ATmega168 der Firma Atmel. Auf dem Display können die aktuelle Spannung und der Strom eines Verbrauchers abgelesen werden.

Die Schaltung des Messgeräts besteht aus drei Teilen: der Spannungsversorgung, dem Analogteil (AD-Wandler) und dem Digitalteil (Mikrocontroller und Display).


Spannungsversorgung

Abbildung 3: Spannungsversorgung

Die Spannungsversorgung besteht aus einem Festspannungsregler und einer Ladungspumpe, sowie einer Diode zur Erzeugung der Referenzspannung von -2,5V. Als Festspannungsregler ist ein 7805 vorgesehen. Er stellt die Versorgungsspannung für den Mikrocontroller, das Display und den Analogteil zur Verfügung. Um einen höheren Wirkungsgrad zu erzielen, kann er aber auch gegen einen Schaltregler ersetzt werden, damit die Schaltung auch mit Spannungen größer als 20V versorgt werden kann. Der 7805 würde zwar die Eingangsspannung von 20V auf 5V herunter regeln; dies würde aber zu einer erhöhten Verlustleistung führen, was zur Folge hat, das sich der Festspannungsregler erwärmt und mit einem Kühlkörper ausgestattet werden müsste. Bei 20V Eingangsspannung und einer Stromaufnahme von 0,2A würde die Verlustleistung 3W betragen. Diese muss dann über die Kühlfläche in Abwärme umgesetzt werden. Die Ladungspumpe wurde mit einem ICL7660 realisiert. Sie stellt die negative Versorgungsspannung für die Operationsverstärker, die Referenzspannung und den Multiplexer her. Das einzige Problem bei dieser gewählten Ladungspumpe ist seine Belastbarkeit. Die Ausgangsspannung des ICL7660 kann mit nur wenigen Milliampere belastet werden, bevor sie einbricht. Daher wurden die Ladungskondensatoren etwas größer gewählt und die Ein- und Ausgangsspannung gepuffert. Ein zweites wichtiges Kriterium ist eine stabile Eingangsspannung. Diese ist, da die Ladungspumpe am Ausgang des Festspannungsreglers 7805 angeschlossen ist, gewährleistet.

Mithilfe kleiner 100nF Kondensatoren in den Eingangsleitungen beider Regler werden Spannungstransienten (Spannungsspitzen) sicher abgeleitet und so die nachfolgenden Bauteile geschützt.

Die Diode LM385 ist so konzipiert, dass sie eine Spannung von -2,5V erzeugt. Gespeist wird sie durch den ICL7660. Der Widerstand R9 begrenzt den Strom auf 0,5mA. Ein nachfolgender Kondensator fängt noch einmal Spannungsspitzen ab.

Analogteil

Abbildung 4: Analogteil


Der Analogteil der Schaltung besteht aus einem Differenz- (INA117) und Vierfachoperationsverstärker (TLC274) sowie einem Multiplexer (CD4051). Grundlegend kann der Analogteil auch noch einmal in den Wandlerteil und in den Strommessteil gespalten werden. Beginnen möchte ich mit dem Strommessteil. Dieser besteht aus einem INA117. Der Operationsverstärker besitzt die Eigenschaft, dass er zwei anliegende Signale voneinander subtrahieren kann. Die Verstärkung ist 1:1. Ausgewählt wurde der INA117, da er im HIGH-Side Anschluss der Schaltung messen kann. Er ist durch den internen Spannungsteiler im Eingang bis zu Spannungen von 500V abgesichert. Für den Zweck in dieser Anwendung ist es ausreichend, da maximal Spannungen von 28V herrschen. Die Teilungen der Eingangsspannungen belaufen sich auf jeweils 1:20.

Da das Signal am Ausgang des INA117 einen hohen Rauschpegel besitzt, wird es im nächsten Schritt durch ein RC-Glied gefiltert und anschließend mithilfe des 4-fach Operationsverstärkers auf das gewünschte Maximum, der Referenzspannung, verstärkt. In der Verstärkerstufe wird das Signal ebenfalls noch einmal gefiltert, um eine bessere Stabilität zu erlangen. Dies geschieht einerseits durch den Verstärker selber, da er ein geringeres Rauschen als der INA117 am Ausgang ausgibt und andererseits durch das Filter C in der Rückkopplung parallel zum Rückkoppelwiderstand. Hier wurde der Wert 68nF gewählt. Dies ergibt dann bei einer Frequenz von 100Hz einen Blindwiderstand XC von 24kΩ.

f = 100HZ
XC = 24000Ohm
[math]\displaystyle{ X_C = \tfrac{1}{2 \cdot \pi \cdot f \cdot C} }[/math]
[math]\displaystyle{ \Leftrightarrow 24000Ohm = \tfrac{1}{2 \cdot \pi \cdot 100Hz \cdot C} \quad | \cdot 2 \cdot \pi \cdot 100Hz }[/math]
[math]\displaystyle{ \Leftrightarrow 24000Ohm \cdot 2 \cdot \pi \cdot 100Hz= \tfrac{1}{C} \quad | (.)^{-1} }[/math]
[math]\displaystyle{ \Leftrightarrow 0,000000066F = C }[/math]
[math]\displaystyle{ \Leftrightarrow 66nF = C }[/math]

Es wird der nächst größere Kondensator gewählt. Somit 68nF.

Der Verstärker dient im genaueren hinsehen dazu, dass Messsignal auf das Maximum der Referenzspannung zu normieren. Die Referenzspannung beträgt, wie oben schon erwähnt, -2,5V. Das bedeutet, dass das Messsignal den Betrag dieser Spannung nicht überschreiten darf.

Um nun den kompletten Messbereich von |-2,5V| auszunutzen, wird das Signal des INA117 mit dem Faktor 25 verstärkt. Anschließend wird es über einen Eingangswiderstand auf den Multiplexer gelegt.

Weitere Eingangssignale des Multiplexers sind neben der zum Strom äquivalenten Spannung auch die Referenzspannung, die aktuelle Spannung vor dem Shunt und die Spannung des Integrationskondensators (Kurzschluss des Kondensators). Die aktuelle Spannung nach dem Shunt dient später dazu, wie weit der Akku bereits entladen ist. Bei einer gewissen Grenze soll der Controller ein Alarmsignal ausgeben, damit der Akku nicht tiefentladen wird oder die angeschlossenen Geräte sich dann plötzlich wegen zu geringer Spannung abschalten.

Ditigalteil

Abbildung 5: Digitalteil

Als Mikrocontroller wird ein ATmega168 eingesetzt. Er bietet einen Timer, bei dem der Zählerstand über einen Hardwareeingang gesichert und im nächsten Schritt Softwaremäßig verarbeitet werden kann. Dies ist besonders bei dieser Anwendung von Vorteil, da genaue Zeitmessungen mit schneller Umschaltung und Auswertung nötig sind, um exakt gewandelte Werte zu erhalten. Da auch die Zählerfrequenz auf den kleinsten Strom abgeglichen werden muss, wurde ein Quarz mit einer Frequenz von f = 16MHz gewählt. Hierdurch werden ausreichend große Zählerstände und Auflösung erreicht. Desweiteren ist an den Mikrocontroller das Display zur Anzeige der ausgerechneten Werte an PORTC angeschlossen. Die Beleuchtung des Displays kann wahlweise softwaremäßig über den OC2-Ausgang des Mikrocontrollers gedimmt oder auf konstante Helligkeit eingestellt werden. Anderweitig verfügt der Mikrocontroller über einen zweiten externen PIN, an den über eine Stiftleiste ein Piezosummer angesteuert werden kann. Er dient zur akustischen Warnmeldung bei Unterschreitung der Akkuspannung, um ein zu tiefes Entladen zu verhindern.


Funktion der Schaltung

Der eigentliche Dual Slope Wandler ist im Gegensatz zur obigen Erläuterung etwas anders aufgebaut. Das Integrationsglied ist in dieser Anwendung schon ein wenig negativ Vorgespannt, um einen definierten Umschaltpunkt zu erhalten. Dadurch ist gesichert, dass der Komparator nicht bei kleineren Masseschleifen umschaltet. Die Vorspannung beläuft sich auf -0.025V. Dadurch, dass der Operationsverstärker immer versucht, zwischen seinen beiden Eingängen (PIN 12 u. 13, IC3D) einen virtuellen Nullpunkt zu erzeugen, ist die Vorspannung auch an PIN 13 anzutreffen. Sie gibt nun, wie oben schon gesagt, die Schaltschwelle des Komparators an PIN 2 vor. Sobald nun die Messspannung an den Eingang des Integrators angelegt wird, lädt sich der Kondensator negativ auf. Dies geschieht über einen fest vom Mikrocontroller vorgegebenen Zeitraum. Ist die fest vorgegebene Zeit verstrichen, wird die Referenzspannung an den Integrator angelegt. Der Integrationskondensator wird nun mit positiver Spannug aufgeladen. Wird jetzt der definierte Schaltpunkt überschritten, also ist die Spannung des Integrationskondensators größer als -0.025V, kippt der Komparator um. Es gilt:

Komparator mit logischem Ausgang:

y = 1 für U1 > U2
U1 : Eingangsspannung nichtinvertierender Eingang
U2 : Eingangsspannung invertierender Eingang
y : logisches Ausgangssignal

Der Komparator gibt den Transistor am Ausgang frei. Der Transistor legt ein High-Signal an den ICP-Pin des Mikrocontrollers. Nachdem nun die Referenzspannung erfolgreich Integriert wurde, der Komparator den Transistor freigegeben hat, wird der Integrationskondensator durch den Multiplexer kurzgeschlossen. Dadurch wird der Kondensator auf das Potential der Vorspannung aufgeladen (UI0 = -0,025V). Zur Erläuterung sei hier nochmal ein Oszillogramm dargestellt, dass die Spannungen an den Messpunkten MP1, MP2, MP3 und MP4 zeigt.


Abbildung 6: Ausschnitt Analogteil mit MP1, MP2, MP3 und MP4
Abbildung 7: Oszillogramm zur Erläuterung der Spannungen in den Messpunkten MP1, MP2, MP3 und MP4



Das Platinenlayout

Die Platine des Messgerätes ist zweiseitig aufgebaut (es ist aber auch möglich, diese einseitig zu fertigen, da alle Drahtbrücken dementsprechend ausgelegt sind). Sie beläuft sich auf eine Größe von 71,11mm x 107,3mm.

Auf der Lötseite, bzw. auf der Unterseite, wurden die SMD-Bauteile, wie der Mikrocontroller, Operationsverstärker und Multiplexer untergebracht. Auf der Oberseite befinden sich neben den konventionellen Bauteilen (Spannungsversorgung und Display) auch noch Drahtbrücken, die eine sichere Verbindung zwischen der Unterseite und der Oberseite herstellen. Zusätzlich wurde auf der Oberseite noch eine Beschriftung zur Anschlussbelegung des Messgerätes eingefügt. Das Layout des Messgerätes wurde speziell darauf ausgelegt, möglichst keine Masseschleifen zu erzeugen. Daher besitzt jeder Schaltungsteil (Spannungs-, Analog- und Digitalteil) seine eigene Masseleitung. Es wurde kein Polygon als Massefläche gewählt, da dort nicht explizit der Stromfluss ermittelt werden kann. Zusätzlich wurden die Leiterbahnlängen im Analogteil möglichst kurz gehalten, um einem eventuellen Spannungsfall vorzubeugen.

Im rechten Bereich wurde der ISP-Stecker zur Programmierung des Mikrocontrollers ATmega168 herausgeführt. Das Display wird später mit ausreichend langen Abstandsbolzen über die Elektronik gesetzt. Dabei muss die Länge der Abstandsbolzen entsprechend der Bauhöhe der Kondensatoren und des Shunts gewählt werden. Für die Befestigung der Abstandsbolzen sind bereits vier Bohrungen hervorgesehen. Die 16-polige Stiftleiste verbindet die Platine mit dem Display. Außerdem kann später die Beleuchtung mithilfe des Mikrocontrollers gedimmt bzw. ein- und ausgeschaltet werden. Ein Trimmer für die Kontrastspannung ist auch vorgesehen. Da das Display auf die Top-Seite der Platine befestigt wird, musste die Anschlussklemme für die Spannungsversorgung (X1, X2) etwas nach links versetzt werden, um auch noch ein nachträgliches anbringen der Versorgungskabel zu ermöglichen. So muss bei einem Anschlusswechsel nicht jedes Mal das Display demontiert werden, um an die Schrauben der Anschlussklemme zu gelangen. Des weiteren wurden auch die vier Kurzhubbedientaster etwas unterhalb des Displays positioniert.

Abbildung 8: Platinenlayout Batteriemonitor

Software

Die Software für das Messgerät ist in der Programmiersprache C geschrieben. Der Mikrocontroller übernimmt das Zeitmanagement für die Umschaltung der zu integrierenden Spannungen sowie die darauf folgende Auswertung und Umrechnung der Zählerstände. Schließlich wird der ermittelte umgerechnete Wert auf dem LCD-Display angezeigt.

Das Programm des Batteriemonitors ist so aufgebaut, dass zuerst eine Spannungsmessung durchgeführt wird. Anschließend wird die Strommessung bei nicht angeschlossener Last initialisiert. Dieser Stromwert dient dann als relativer Nullpunkt für die späteren Messungen. Im nächsten Schritt wird der Timer2 initialisiert. Er dient zur Zeitmessung. Dabei wurde der Top-Wert so gewählt, dass er alle 500µs ein Überlauf auftritt. Dadurch kann leichter eine volle Sekunde errechnet werden. Nachdem nun die Zeitmessung gestartet wurde, betritt das Programm eine Endlossschleife, in der eine kontinuierliche Spannungs- und Strommessung durchgeführt werden. Die gewandelten Werte werden dann umgerechnet auf dem Display angezeigt. Innerhalb der kontinuierlichen Spannungs- und Strommessung kann über die Bedientaster die Errechnung der Ladung Q gestartet, gestoppt und zurückgesetzt werden. Eine nachträgliches abgleichen des relativen Nullpunktes für die Strommessung ist auch möglich.

AD-Wandlung

Die AD-Wandler-Routine habe ich in der Software so gestaltet, dass sie schnell auf einen anderen Mikrocontroller übertragen werden kann. Es muss lediglich die Belegung der Spannungen am Multiplexer unverändert bleiben. In der Headerdatei wird zunächst festgelegt, an welchem Port der Multiplexer angeschlossen ist und an welche Port sich Hardwaremäßig der ICP-Pin des Mikrocontrollers befindet. Dazu einmal ein kleiner Ausschnitt aus dem Programm:

<c> // Steuerbits des Multiplexers

  1. define A PD0
  2. define B PD1
  3. define C PD2

// PORT des Multiplexers

  1. define Multi_PORTx PORTD

// DDR des Multiplexers

  1. define Multi_DDRx DDRD
  1. define ICP_PINx PINB
  2. define ICP_Px PB0

</c> Hier sind auf einem Blick die wichtigen Anschlüsse des Multiplexers einsehbar und können schnell an den jeweiligen Mikrocontroller angepasst werden.

Damit das Signal auch gemessen werden kann, muss ein Timer eingesetzt werden, der die Aufladungszeiten in Form von Zählerständen ermitteln kann. Dazu eignet sich am Besten der 16-Bit Timer1 des ATmega168. Er verfügt zudem über einen Capture-Betrieb, bei dem der Zählerstand hardwaremäßig über einen Flankenwechsel am ICP-Pin im ICR1-Register gespeichert werden kann. Der Timer1 wird folgendermaßen initialisiert:

<c> TCCR1B |= (1<<WGM12); TCCR1B |= (1<<ICES1) | (1<<ICNC1); // Trigger auf steigender Flanke und Noise Canceler eingeschaltet TCCR1B |= (1<<CS10) | (1<<CS11); // Vorteiler 64 OCR1A = 0xFFFF;

TIMSK1 |= (1<<ICIE1); // Input Capture Interrupt einschalten

       sei();

</c>

Im nächste Teil kommt nun die eigentliche Wandler-Routine. Dort wird über eine switch-case Anwendung differenziert, ob der Strom oder die Spannung gemessen werden soll. Der spätere Zählerstand wird in der Variablen ad_wert abgespeichert. Welcher Steuereingang des Multiplexers zum Anlegen der korrekten Spannung eingeschaltet werden muss, wurde anhand einer Wahrheitstabelle aus dessen Datenblatt ermittelt. Es wird nun zuerst die zu messende Spannung an den Integrator angelegt. Im nächsten Schritt wird solange gewartet, bis der Komparator ein Low-Signal ausgibt. Erst danach wird der Zählerstand des Timer1 zurückgesetzt. Es wird nun das Messsignal über einen festen Zeitraum integriert. Festgelegt ist die Zeit durch die Variable timer_max. Nachdem das Register TCNT1 größer ist als die Variable timer_max, wird die Referenzspannung an den Integrator angelegt. Das Timer/Counter Daten-Register wird zurückgesetzt. Der nun folgende Zählerstand ist der entscheidende. Es wird nun so lange die Referenzspannung an den Integrator angelegt bzw. gewartet (while), bis die Schaltschwelle von -0,025V durchlaufen ist. Ist dies geschehen, erzeugt der Komparator eine steigende Flanke und der Zählerstand des Timer1 wird in dem ICR1-Register gespeichert. In der Interrupt-Routine für den Capture-Betrieb wird anschließend der Wert des ICR1-Registers in die Variable ad_wert kopiert. Nachdem die Interrupt-Routine beendet ist, wird der Integrator kurzgeschlossen und wieder entladen, um eine gleiche Anfangsbedingung für die nächste Wandlung zu erhalten. Dieser Vorgang ist nochmal in Form des Sourcecodes: <c>

<avr/io.h> <avr/interrupt.h>

unsigned int timer_max = 50000;

// gewandelter Analogwert in Form eines Zählerstandes unsigned int ad_wert = 0;

ISR (TIMER1_CAPT_vect) { ad_wert = 0; ad_wert = ICR1; }


// Analog-Digital-Wandlungen void ad_wandlung(unsigned char wert) {

// Anlegen von:

       // 'i' : Strom

// 'u' : Spannung

switch (wert) { case 'i': Multi_PORTx &=~ (1<<B); break;

case 'u': Multi_PORTx &=~ ((1<<B) | (1<<A)); break; }

       // Warte, solange der ICP-Pin noch High ist

while (ICP_PINx & (1<<ICP_Px)); TCNT1 = 0; // Timer zurücksetzen

while (TCNT1 < timer_max);

// Anlegen der Referenzspannung switch (wert) { case 'i': { Multi_PORTx &=~ (1<<C); Multi_PORTx |= (1<<B); } break;

case 'u': { Multi_PORTx &=~ (1<<C); Multi_PORTx |= (1<<B) | (1<<A); } break; }

TCNT1 = 0; while(!(ICP_PINx & (1<<ICP_Px)));

// Multiplexer kurzschließen Multi_PORTx |= (1<<C);

}

</c>

Korrektur Gleichtaktunterdrückung

Mit obiger Software ist es jetzt möglich, den Strom bei konstanter Spannung zu messen. Da das Messgerät jedoch durch einen Akku betrieben wird, sinkt die Spannung nach einer gewissen Zeit zwangsläufig. Es muss jetzt festgestellt werden, ob der zuvor initialisierte relative Nullpunkt auch bei sinkender Spannung gleich bleibt bzw. der gemessene Wert größer ist als der relative Nullpunkt. Um dies zu überprüfen, wird das Messgerät so programmiert und eingeschaltet, dass der aktuell gewandelte Wert(Zählerstand) auf dem Display angezeigt wird. Es wurde nun folgende Messreihe für den maximalen Aufladungsbereich von timer_max = 50000 aufgenommen:

Betriebsspannung U in V Betriebsspannung U in Zähler Strom I in A Strom I in Zähler
14 2251 0 543
13 2088 -0,005 517
12 1931 -0,009 497
11 1773 -0,013 473
10 1622 -0,018 450
9 1468 -0,023 427

Anhand der Messwerte kann man gut erkennen, dass die Abweichung annähernd linear ist. Somit kann daraus folgende lineare Gleichung erstellt werden:

[math]\displaystyle{ y = 0,1471 \cdot x+211,5 }[/math]
y : Strom I in Zähler
x :Betriebsspannung U in Zähler

Die lineare Gleichung korrigiert den relativen Nullpunkt in Abhängigkeit von der Eingangsspannung. Der y-Achsenabschnitt n = 211,5 wird später noch durch eventuelle weitere Abweichungen im Programm automatisch abgeglichen. Im Sourcecode sieht die Korrektur mit vorangegangener Wandlung folgendermaßen aus:

Definieren von Konstanten und Variablen: <c>

// Betrag der Referenzspannung in V

  1. define ref 2.44375

float null_wert_r = 0;

signed int nach_null = 0; // Nachträglicher Nullableich

float mittel_i = 0; // Zählerstand Strom float mittel_u = 0; // Zählerstand Spannung

float i = 0; //Strom float korrekt = 1;

// Speicherarrays für Spannung und Strom unsigned int speicher_i[5]; unsigned int speicher_u[5];

</c>


Wandlung mit anschließender Korrektur durch lineare Gleichung: <c>

// Strommessung

for (unsigned char z=0; z<3; z++) { ad_wandlung('i'); speicher_i[z] = ad_wert; }

for (unsigned char z=1; z<=2; z++) { mittel_i += speicher_i[z]; }

mittel_i /= 2;


// Spannungsmessung

timer_max_zwischen = timer_max;

timer_max = timer_max_u;

for (unsigned char z=0; z<4; z++) { ad_wandlung('u'); speicher_u[z] = ad_wert; }

for (unsigned char z=1; z<=3; z++) { mittel_u += speicher_u[z]; } mittel_u /= 3;

timer_max = timer_max_zwischen;

null_wert_r = 0.1471*mittel_u+211.5;

i = (((((((float)mittel_i-null_wert_r+nach_null) * ref) / timer_max))/25)*100)*korrekt; // Umrechnung von Zählerstand nach Strom

</c>

Bei den Wandlungen werden die Zählerstände in einem Array gespeichert. Der erste gewandelte Wert wird jeweils verworfen, da dort noch Differenzen durch eventuelle Vorspannungen auf dem Integrationskondensator vorhanden sein können. Anschließend wird der Mittelwert aus den restlichen Messwerten gebildet und in der zugehörigen Variable (mittel_i, mittel_u) gespeichert.

Zeitmessung

Die Zeitmessung wurde, wie oben schon kurz erwähnt, mit dem Timer2 des ATmega168 realisiert. Initialisiert wird der Timer2 im CTC-Mode. Hier kann die Obergrenze durch das Register OCR2A festgelegt, und so die Periode T der Überläufe variabel gestaltet werden. Es wurde hier der Wert 250 bei einem Timer Vorteiler von 32 gewählt. Begründung:

f = 16000000Hz

[math]\displaystyle{ f_{vorteiler} = \tfrac {16000000Hz}{32} }[/math]
[math]\displaystyle{ \Leftrightarrow f_{vorteiler} = 500000Hz }[/math]


[math]\displaystyle{ T = \tfrac{1}{f_{vorteiler}} }[/math]
[math]\displaystyle{ \Leftrightarrow T = \tfrac{1}{500000Hz} }[/math]
[math]\displaystyle{ \Leftrightarrow T = 0,000002s }[/math]


Überläufe bei einem Top-Wert von 250:

[math]\displaystyle{ T = 0,000002s \cdot 250 }[/math]
[math]\displaystyle{ \Leftrightarrow T = 0,0005s }[/math]
[math]\displaystyle{ \Leftrightarrow T = 500\mu s }[/math]

Um jetzt auf eine volle Sekunde zu gelangen, müssen demnach 2000 Überläufe erfolgt sein. Die Zeitroutine ist im Sourcecode folgend aufgebaut:

Timer2 Initialisierung <c> void timer2_init() { TCCR2A |= (1<<WGM21); TCCR2B |= (1<<CS21) | (1<<CS20);

OCR2A = 0xFA;

TIMSK2 |= (1<<OCIE2A); sei(); } </c>

Timer Compare Match Interrupt Service Routine: <c>

// Zeit volatile unsigned int t = 0; volatile unsigned char sek = 0; volatile unsigned char min = 0; volatile unsigned char h = 0;

ISR (TIMER2_COMPA_vect) { if (t >= 1999 ) { t = 0; if (sek >= 59) { sek = 0; if (min >= 59) { min = 0; if (h >= 23) { h = 0; } else { h++; } } else { min++; } } else {

                    sek++;

} } else { t++; } } </c>



... Diese Seite befindet sich noch im Aufbau



Downloads

Siehe auch

Am Ende des Artikels erfolgt eine Einsortierung in Artikel-Schublade(n), auch Kategorie(n) genannt. Damit ist Dein Artikel leichter auffindbar.

Such aus den vorhandenen Kategorien diejenige(n) aus, die am besten auf den Artikel passen. Kategorie:Wettbewerb wird durch die Vorlage {{Wettbewerb Header}} automatisch eingebunden und muss nicht angegeben werden!