8 Messtechnik-Anwendungen Ein vielseitiger
Mikrocontroller wie der ATtiny85 kann die unterschiedlichsten Aufgaben im
Bereich der Messtechnik übernehmen. Hier sollen einige Messmethoden vorgestellt
werden, die besonders einfach und wirkungsvoll sind. So lässt sich aufwendige
Hardware oft durch passende Software umgehen. Der Mikrocontroller wird damit zu
einem vielseitigen Messgerät und Hilfsmittel im Elektronik-Labor. 8.1 DC-Millivoltmeter 0.1 mV …1100.0 mV Der AD-Wandler des Tiny85
liefert mit seiner internen Referenz von 1,1 V bereits eine Auflösung von etwa
einem Millivolt. Man kann die praktisch nutzbare Auflösung jedoch noch
erheblich steigern, wenn man eine Mittelung über viele Messwerte durchführt.
Hier werden zunächst 1075 Messwerte aufsummiert, wobei die genaue Zahl der
Messungen zugleich zur Kalibrierung eingesetzt wird. Das Messergebnis wird mit
einer Nachkommastelle ausgegeben. Der Eingang sollte mit einem Widerstand gegen
Überspannung geschützt werden.
Abb. 8.1: Der geschützte
Messeingang
'DCmV.bas
'Millivoltmeter 1 mV ... 1100 mV an B3 $regfile
= "attiny85.dat" $crystal
= 8000000 'ADC1.bas
ADC3 an B3 $hwstack
= 8 $swstack
= 8 $framesize
= 4 Dim
U1 As Long Dim
U2 As Long Dim
N As Integer Dim
S As String * 10 Config
Adc = Single , Prescaler = Auto , Reference = Internal_1.1 Open
"comb.1:9600,8,n,1" For Output As #1 Do
U2 = 0
For N = 1 To 1075
U1 = Getadc(3)
U2 = U2 + U1
Next N
U2 = U2 / 100
S = Str(u2)
S = Format(s , "00.0")
Print #1 , Chr(13);
Print #1 , S;
Print #1 , " ";
Print #1 , " mV "; Waitms 500 Loop End Listing 8.1: Mittelung von
Messwerten
Der Effektivwert einer
Wechselspannung ist die Spannung, bei der eine gleichgroße Gleichspannung zur
selben Leistung an einem ohmschen Verbraucher führt. Ein Rechtecksignal mit den
Scheitelspannungen + 1 V und – 1 V hat eine effektive Spannung von 1 Veff, eine
sinusförmige Spannung mit ebenfalls 1 Vs hat dagegen nur 0,707 Veff. Eine echte
Effektivwertmessung muss für jeden Spannungswert durch Quadrieren die momentane
Leistung berechnen, diese mitteln und dann daraus dann die Wurzel ziehen und so
die mittlere effektive Spannung berechnen. Wenn die Messung aus sehr vielen
Messpunkten besteht, erhält man eine zuverlässige Effektivwertanzeige. Hier wird eine Wechselspannung
direkt an den Eingang gelegt und damit nur die positive Halbwelle ausgewertet.
Die negative Halbwelle darf etwa -0,5 V nicht unterschreiten, denn dann würde
die interne Schutzdiode des Eingangs zu leiten beginnen. Sicherheitshalber wird
der Messbereich daher auf 250 mVeff (=354 mVs) begrenzt. Ein Spannungsteiler 1
kΩ / 10 kΩ sorgt einerseits für einen zuverlässigen Nullpunkt und
andererseits für eine wirksame Strombegrenzung, falls der Messbereich
überschritten wird. Damit bei der relativ kleinen Eingangsspannung noch eine
gute Auflösung erreicht wird, verwendet das Programm die interne Referenz von
1,1 V.
Abb. 8.3: Der
Wechselspannungs-Messeingang
Die Messungen besteht aus 280
Einzelmessungen, wobei die Messwerte quadriert und aufsummiert werden. Aus der
Summe wird dann die Wurzel gezogen. Das Ziel ist eine Auflösung von 0,1 mV,
d.h. für eine Spannung von 100 mV sollte am Ende eine Zahl von 1000 stehen. Ein
zehnfach höheres Endergebnis wird durch 100 Einzelmessungen erreicht. Dazu muss
man aber noch bedenken, dass nur die positiven Halbwellen erfasst werden, die
Hälfte aller Messwert also Null sind. Die Anzahl der Einzelmessungen muss daher
noch höher sein. Für eine genaue Bestimmung
der Anzahl und zur Überprüfung der Kalibrierung soll der Eingang einmal mit
einer Gleichspannung übersteuert werden. Der AD-Wandler liefert dann permanent
Werte von 1023, die für eine Spannung von 1,1 V am Eingang B3 stehen und damit
für 1,21 V am Messeingang, weil der Spannungsteiler noch einmal den Faktor 1,1
bringt. Weil in diesem Fall die negative Halbwelle nicht fehlt, wäre die
tatsächliche Leistung doppelt so hoch, und die effektive Spannung wäre noch
einmal um den Faktor 1,414 (Wurzel aus Zwei) höher, die Anzeige müsste also 1711,2
mVeff lauten. Die gesuchte Anzahl der Einzelmessungen beträgt damit
(17112/1023)^2 = 279,8, aufgerundet also 280. Mit diesem Schleifenwert zeigt
das Programm bei einer Übersteuerung mit einer positiven Gleichspannung tatsächlich
einen maximalen Wert von 1711,8 mVeff, was im Rahmen der Messgenauigkeit der
internen Referenz stimmt. Vergleichsmessungen zeigen, dass auch
Wechselspannungen korrekt gemessen werden.
'ACmV.bas
'Millivoltmeter 1 mVeff ... 250 mVeff an B3 $regfile
= "attiny85.dat" $crystal
= 8000000
$hwstack = 8 $swstack
= 8 $framesize
= 4 Dim
U1 As Long Dim
U2 As Long Dim
U3 As Long Dim
N As Integer Dim
S As String * 10 Config
Adc = Single , Prescaler = Auto , Reference = Internal_1.1 Open
"comb.1:9600,8,n,1" For Output As #1 Do
U3 = 0
For N = 1 To 263
U1 = Getadc(3)
U2 = U1 * U1
U3 = U3 + U2
Next N
U3 = Sqr(u3)
S = Str(u3)
S = Format(s , "00.0")
Print #1 , Chr(13);
Print #1 , S;
Print #1 , " ";
Print #1 , " mV "; Waitms 500 Loop
Das Programm zeigt
zuverlässig Effektivspannungen an, und zwar weitgehend unabhängig von der
Frequenz. Die Messwerte zeigen keine nennenswerten Abweichungen in einem
Frequenzbereich von 50 Hz bis 50 kHz. Obwohl die Abtastpunkte in keinem
Verhältnis zu den tatsächlichen Schwingungen der gemessenen Wechselspannung
stehen sorgt der Zufall bei der großen Anzahl der Einzelmessungen dafür, dass
sie statistisch gleichverteilt über dem Messsignal liegen.
Abb. 8.4: Anzeige der
Effektivspannung
8.3 Widerstandsmessung 100 Ω bis 1 MΩ Die Spannung an einem
Spannungsteiler lässt sich aus der Gesamtspannung und den beiden
Teilwiderständen bestimmen. Umgekehrt kann einer der Teilwiderstände bestimmt
werden, wenn man die Teilspannung misst und den zweiten Widerstand kennt. In
diesem Fall soll der bekannte Widerstand 10 kΩ sein. Ein solcher
Widerstand ist bereits auf der Platine vorhanden und führt vom B2-Pin zum
Ausgang TXD des USB-Seriell-Wandlers. Der Ausgang ist im Ruhezustand
hochgesetzt, sodass der Widerstand praktisch an Vcc liegt. Es gilt dann für
eine gemessene Spannung U als Rohwert im Bereich 1 … 1023: Rx = 10 kΩ * U /
(1023-U)
Abb. 8.5: Messung des
Widerstands Rx
Das Programm Rmess.bas misst
die Spannung an ADC1 (Port B2) und berechnet daraus in mehreren Schritten den
unbekannten Widerstand Rx. Damit mit Ganzzahlen gerechnet werden kann, werden
alle Variablen als Long (32-Bit-Zahl) dimensioniert. Weil in Bascom immer nur
ein Rechenschritt pro Zeile erlaubt ist, wird die Rechnung in drei Zeilen
aufgeteilt. Mit einer If-Abfrage wird eine Division durch Null vermieden, wenn
kein Widerstand Rx angeschlossen ist. Damit die relaiv umfangreiche Rechnung
ausgeführt werden kann, muss der Software-Stack vergrößert werden. 'Rmess.bas
Widerstand B2 gegen GND $regfile
= "attiny85.dat" $crystal
= 8000000 $hwstack
= 8 $swstack
= 20 'Rechnen! $framesize
= 4 Dim
U As Long Dim
R As Long Open
"comb.1:9600,8,n,1" For Output As #1 Config
Adc = Single , Prescaler = Auto Do
Print #1 , Chr(13);
U = Getadc(1)
R = 10200 * U '10k+Ron
U = 1023 - U 'R=10k*(U/1023-U)
If U > 0 Then
R = R / U
Else
R = 999999
End If
Print #1 , R;
Print #1 , " Ohm ";
Waitms 500 Loop End Listing 8.3: Widerstandsmessung Das Programm erreicht seine
beste Genauigkeit und Auflösung im Bereich um 10 kΩ. Der als Konstante
verwendete Vergleichswiderstand wurde mit 10200 Ohm eingetragen, um den
On-Widerstand des Ausgangs-FET im CH340 zu berücksichtigen. An dieser Stelle
kann man einen Feinabgleich vornehmen, der auch die Toleranz des eingebauten
SMD-Widerstands von 10 kΩ berücksichtigt. Der beste Wert kann durch
Probemessungen an genau bekannten Widerständen ermittelt werden. Die
Messmethode ist brauchbar im Bereich 100 Ω bis 1 MΩ, wobei allerdings
die Auflösung an den Rändern abnimmt.
Die einfache
Kapazitätsmessung beruht auf der Messung der Zeit, bis ein Kondensator auf die
Schaltschwelle eines Ports aufgeladen wurde. Wie schon bei der
Widerstandsmessung wird auch hier der Port B2 mit dem vorhandenen Widerstand
von 10 kΩ verwendet. Für die angezielte Auflösung von 1 nF ergibt sich
eine Zeitkonstante von 10 µs. Die Zählschleife muss also in weniger als 10 µs
durchlaufen werden. Innerhalb der Schleife wird ein Zähler erhöht. Der Zähler T
ist als Dword mit einer Breite von 32 Bit deklariert und nimmt daher Zahlen bis
4294967295 auf. Das reicht für den Messbereich bis über 1000 µF, wobei die
gesamte Messung dann allerdings mehr als 10 s dauert.
Abb. 8.7: Messung einer
Kapazität
'Cmess1.bas
Kapazität 1 nF ... 1000 µF $regfile
= "attiny85.dat" $crystal
= 8000000 $hwstack
= 8 $swstack
= 4 $framesize
= 4 Dim
T As Dword Open
"comb.1:9600,8,n,1" For Output As #1 Do
Portb.2 = 0
Ddrb.2 = 1 Waitms
500 'Entladen
Ddrb.2 = 0 T
= 0 Do
T = T + 1
Loop Until Pinb.2 = 1 T = T *
650 'Kalibrierung T
= T / 1000 Print #1 ,
Chr(13);
Print #1 , T;
Print #1 , " nF "; Loop End Listing 8.4: Zeitmessung zur
Kapazitätsbestimmung
Überprüfen Sie die beiden
vorhandenen Kondensatoren von 10 nF und 100 µF und nach Möglichkeit auch noch
andere Werte. Falls ein bekannter Referenz-Kondensator oder ein genaues
Kapazitätsmessgerät zur Verfügung steht, können Sie das Messprogramm durch
Anpassung des Faktors 650 individuell kalibrieren.
Abb. 8.8: Die Kapazität im Terminal
8.7 Kapazitätsmessung 1 pF … 1000 pF
Kapazitätsmessungen bis
herunter auf 1 pF stellen eine Herausforderung an die Messtechnik dar. Das hier
gezeigte Messverfahren entspricht dem Qtouch-Verfahren, das kapazitive
Berührungssensoren eingesetzt wird. Die Ladung einer sehr kleinen Kapazität
wird dabei in vielen Einzelschritten auf einen größeren Kondensator übertragen,
bis dessen Spannung eine Schaltschwelle erreicht. Die gezählten
Schleifendurchläufe sind ein Maß für das Verhältnis beider Kondensatoren.
Abb. 8.9: Messung kleiner
Kondensatoren
Im Terminal werden die Anzahl
der Schaltzyklen und die berechnete Kapazität in Pikofarad ausgegeben. Beim
Start darf noch kein Messobjekt angeschlossen sein, weil das Programm dann
einen Nullabgleich durchführt. 'Cmess2.bas
'1 pF bis 1000 pF $regfile
= "attiny85.dat" $crystal
= 8000000 'ADC1.bas
ADC3 an B3 $hwstack
= 8 $swstack
= 8 $framesize
= 4 Dim
D As Integer Dim
C As Integer Dim
C0 As Integer Open
"comb.1:9600,8,n,1" For Output As #1 Ddrb.3
= 1 Ddrb.4
= 1 C0
= 1000 Do
For D = 1 To 1500 Ddrb.3
=
0
'B3 hochohmig
Portb.4 = 1
'B4
high
Ddrb.4 = 1
'B4
niederohmig Waitus
1
If Pinb.3 = 0 Then Exit For 'B3 low? Ddrb.4
=
0
'B4 hochohmig
Portb.4 =
0
'ohne Pullup Ddrb.3
= 1
'B3
low
Waitus 1
Next D
Portb.3 = 0
Portb.4 = 0
Ddrb.3 = 1
Ddrb.4 = 1
Print #1 , Chr(13); Print #1 , D;
Print #1 , " "; C
= 7500 / D
'Kalibrierung If C < C0 Then
C0 = C
C = C - C0
Print #1 , C;
Print #1 , " pF ";
Waitms 500 Loop End Listing 8.5: Messung kleiner
Kapazitäten (Cmess2.bas) Nach einem Start des
Programms sollte 0 pF angezeigt werden. Berühren Sie nun die Isolierung des
Schaltdrahtes. Die Kapazität steigt um etwa 5 pF bis 10 pF. Diese geringe
Änderung kann für Sensoranwendungen verwendet werden und z.B. einen
Schaltvorgang auslösen. Das Messprogramm eignet sich auch
zur Messungen an Drehkondensatoren oder zur Bestimmung von Leitungskapazitäten.
Sogar eine Messung von Sperrschichtkapazitäten ist möglich, wenn die Kathode
eiern Diode am Messeingang liegt und die Anode an GND. Für eine rote LED wurde
eine Kapazität von 9 pF gemessen.
Abb. 8.10: Messung der
Kapazität einer roten LED
8.6 Sinusgenerator 0…5 kHz Der Sinusgenerator verwendet
den PWM-Ausgang mit einem nachfolgenden Tiefpassfilter. Die Signalerzeugung
arbeitet nach dem DDS-Prinzip (direkte digitale Synthese) mit einer
Sinustabelle mit Stützwerten im Byte-Format. Eine Phasenakkumulator (Akku) wird
jeweils um den konstanten Betrag in der Variablen F vergrößert und bestimmt so
eine neue Position in der Sinustabelle. Tatsächlich wird nur das Highbyte des
16-Bit-Akkus als Adresszeiger verwendet. Wenn F den Inhalt 1 hat, dauert es
daher 256 Timer-Überläufe bis der nächste Tabellenwert verwendet wird. Dabei
entsteht ein Sinus-Signal von 0,4768 Hz. Dies ist zugleich die Auflösung der
Frequenzeinstellung. Bei größeren Frequenzen wird die Tabelle entsprechend
schneller durchlaufen, bei Werten über 256 werden einzelne Stützwerte
übersprungen. Bei der höchsten Frequenz von 5 kHz kommen nur noch etwa 4
Ausgabewerte auf eine Sinusschwingung. Mit einem guten Tiefpassfilter lässt
sich daraus aber immer noch ein sauberes Signal erzeugen
Abb. 8.11 Tiefpassfilter am
PWM-Ausgang
Für den DDS-Generator muss
eine Sinus-Tabelle vorbereitet werden. Sie besteht aus 256 Stützpunkten im
Byte-Format. Dies sind die analogen Ausgabewerte, die im laufenden Betrieb an
den PWM-Ausgang übergeben werden. Die Frequenz kann erhöht oder verkleinert
werden, indem man B4 oder B3 an GND legt. Hier könnte man zwei Taster
anschließen.
Abb. 8.12: Das Sinussignal
mit 500 Hz
'DDS.bas
'DDS 0 ...5 kHz $regfile
= "attiny85.dat" $crystal
= 8000000 $hwstack
= 40 $swstack
= 40 $framesize
= 40 Dim
D As Byte Dim
Table(256) As Byte Dim
N As Integer Dim
Akku As Word Dim
A As Single Dim
B As Single Dim
F As Word Dim
Freq As Word Config
Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up Config
Timer1 = Timer , Prescale = 1 Pwm0a
= 127 For
N = 1 To 256
A = N - 1
A = A * 3.1415
A = A / 128
B = Sin(a)
B = B * 120
B = B + 128
D = Int(b)
Table(n) = D Next
N On
Ovf1 Tim1_isr Enable
Timer1 Enable
Interrupts Freq
= 500 Ddrb.2
= 1 Portb.3
= 1 Portb.4
= 1 Do
If Pinb.4 = 0 Then
If Freq < 5000 Thenfreq = Freq + 10
End If
If Pinb.3 = 0 Then
If Freq >= 10 Then Freq = Freq - 10
End If
Waitms 10
A = Freq
B = A / 0.4768
F = Int(b) Loop Tim1_isr: 'Timer1 8000
kHz / 256 = 31,25 kHz
Portb.2 = 1
Akku = Akku + F N = High(akku)
Pwm0a = Table(n) Portb.2 = 0 Return End Listing 8.6: Sinus-Tabelle
und Frequenzeinstellung (DDS.bas) Das Programm setzt zwei Timer
ein. Timer1 erzeugt das 8-Bit-PWM-Signal. Die PWM-Frequenz beträgt in diesem
Fall 15,625 kHz. Der 8-Bit-Zeitgeber Timer0 erzeugt ohne Vorteiler Überläufe
mit 31,25 kHz. Mit dieser Frequenz wird die Interruptroutine aufgerufen, die
jedes Mal einen neuen Ausgabewert berechnet und in das PWM-Register schreibt. Wenn man einen
Timer-Interrupt ohne Vorteiler bei hoher Frequenz laufen lässt, stehen
insgesamt nur noch 256 Taktimpulse für die komplette Interruptroutine zur
Verfügung. In dieser Zeit müssen nicht nur die Programmzeilen in der
Interruptroutine abgearbeitet werden, sondern es kommt noch das Sichern und
Zurückladen von Arbeitsregistern auf dem Stack hinzu. Man sollte daher in so
einem Fall untersuchen, wie viel der vorhandenen Zeit verbraucht wird. Die
einfachste Methode dazu verwendet einen Port, der am Anfang der Interruptroutine
hochgesetzt (Portb.2 = 1) und am Ende wieder zurückgesetzt wird (Portb.2 = 0).
Mit dem Oszilloskop kann dann die Rechenzeit direkt beobachtet werden. In
diesem Fall bleibt das Puls/Pausenverhältnis noch deutlich unter 50 % . Die
Restzeit steht dem Hauptprogramm zur Verfügung.