Lernpaket Mikrocontroller Kap 8       

Elektronik-Labor  Lernpakete  AVR  LPmikros                  

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
 

 
Abb. 8.2: Messwertanzeige im Terminal
 
 
8.2 RMS-Millivoltmeter 0.1 mV bis 250.0 mV
 
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.  
 

 
Abb. 8.6: Messung mit Rx = 10 kΩ 

 
8.4 Kapazitätsmessung 1 nF bis 1000 µF
 
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.


Elektronik-Labor  Lernpakete  AVR  LPmikros