Milliamperemeter-Modul mit ATMega48          

von Gerd Sinning                       
Elektronik-Labor   Projekte   AVR 

Das Voltmeter-Modul leistet treue Dienste in meinem Netzteil und zeigt die variable Ausgangsspannung an, nun braucht es nur noch ein mA-Meter und es ist komplett.

Das mA-meter Modul, 39.3 mA wird angezeigt

Das mA-Meter Modul basiert auf dem Voltmeter- Modul mit praktisch gleicher Hardware und kann genauso aufgebaut werden, ausführlichere Beschreibung siehe DVM.html. Weiterhin wird ein AD8218 benötigt, um den Strom zu messen, dabei ist Vout = (Vin * 20) + 0.08 V. Ohne Strom hat der AD8218 80 mV Offset am Ausgang, daher noch ein 10k-Trimmer um den Offset zu kompensieren. Das Basic-Programm ist etwas anders, es braucht einen neuen Kalibrationsfaktor.

Der AD8218 in einer Schaltung lt. Datenblatt (unidirectional high-side current sensing). Das Teil ist schwierig zu löten, es ist winzig.

Hier ist der AD8218 auf einer Adapterplatine, der Shunt ist aus 10 Stück 1.5 Ohm Widerständen parallel, insgesamt 0.15 Ohm.

Der Schaltplan, der 10-kOhm-Trimmer geht hier an J1 und ADC0 wird ohne den Spannungsteiler direkt an den Ausgang des AD8218 angeschlossen.

Das Modul von oben, die Platine mit dem AD8218 wird gekürzt, dann passt es.

Das Modul muss kalibriert werden. Zunächst wird der offset mit dem 10k Trimmer auf Null gestellt. Es ist nötig, vorher die plus Seite (+IN) des shunt mit z.B. 5 V zu verbinden, sonst ist die Ausgangsspannung des AD8218 undefiniert. Dann wird der Strom durch den shunt mit einem guten mA Meter gemessen und im Programm der Const Calfactor = 358 angepasst.So kann man das ausrechnen: Multimeter Anzeige / Modul Anzeige * 358 = neuer Calfactor. Der wird im Programm eingetragen und es wird neu kompiliert, dann ist das Modul kalibriert. Das Display geht bis 999 mA, im Prinzip schon, aber dann sollte man einen belastbareren shunt einsetzen. Im Programm wird ein running average berechnet, das beruhigt die Anzeige.

Der AD8218 braucht eine Spannung von mindestens 3.5 V am +IN Eingang, erst ab da kann er den Strom messen.

Ab jetzt hat das Netzteil auch ein mA-Modul, für +5V und für +12V.

Download: DmAM0.zip

References

Voltmeter siehe 

Atmel datasheet ATMega48, Atmel.com

datasheet Analog Devices, AD8218, analog.com

display siehe https://www.lc-led.com/View/itemNumber/233

Bascom Basic Compiler

 

'*********************************************************************
' ATMega 48 digital voltmeter, display in front
' GS 2012
' with AD9832 for power supply ampere-meter module
'
' display updated in interrupt
'
' ADC channel 0 and 1, difference displayed ch0-ch1 or ch1-ch0
' Channel0/1 select which channel is displayed
' 8 ADC readings each channel
' 1 kHz output 50% duty cycle on OC1B (PB2) for mOhm meter
'
' calibrate factor: mA / ADC count

' 7 seg digits on PORTB, segments on PORTD
' 3 digit common anode 7 seg display wiring
'
' M48 7 6 5 4 3 2 1 0 PORTD
' 7seg 7 5 4 3 2 1 10 11 pin 12 9 8
' seg B G C dp D E F A dig 3 2 1 (1 = right dig)
' PB 0 1 3
' &B10111000 F &B01010001 U &B11110000 C &B00010101 Y

'*********************************************************************
' ATMega48 PDIP
'
' (RESET) PC6 1 28 PC5 (ADC5/SCL)
' (RXD) PD0 2 27 PC4 (ADC4/SDA)
' (TXD) PD1 3 26 PC3 (ADC3)
' (INT0) PD2 4 25 PC2 (ADC2)
' (INT1) PD3 5 24 PC1 (ADC1)
' (XCK/T0) PD4 6 23 PC0 (ADC0)
' VCC 7 22 GND
' GND 8 21 AREF
' (XTAL1/TOSC1)PB6 9 20 AVCC
' (XTAL2/TOSC2)PB7 10 19 PB5 (SCK)
' (T1) PD5 11 18 PB4 (MISO)
' (AIN0) PD6 12 17 PB3 (MOSI/OC2)
' (AIN1) PD7 13 16 PB2 (SS/OC1B)
' (ICP1) PB0 14 15 PB1 (OC1A)

'*********************************************************************

$regfile = "m48def.dat"
$crystal = 1000000
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space


'*********************************************************************
Showflag Alias Portb.5 'shows minus
Overfl Alias Portb.4 'overflow
Digitr Alias Portb.3
'PB2 = OC1B
Digitm Alias Portb.1
Digitl Alias Portb.0

Decpoint Alias Portd.4 'decimal point

Channel0 Alias Pinc.4 'select
Channel1 Alias Pinc.5 'a low turns off channel
'both on hi measures difference ch0-ch1 or ch1-ch0
'both on low measures nothing, ha

'*********************************************************************

Const Calfactor = 358 'calibrate

Dim A As Byte 'the digits A B C
Dim B As Byte
Dim C As Byte
Dim I As Byte
Dim N As Byte
Dim Dp As Byte 'decimal point
Dim Flag As Byte 'status flag
Dim Dispcnt As Byte 'display counter
Dim Icnt As Byte 'ISR counter
Dim W As Word
Dim Avgvalue As Word
Dim Ad As Long
Dim Adch0 As Word
Dim Adch1 As Word

'*********************************************************************


Portc = &B00111000
Ddrb = &B00001100 'output

Didr0 = &B00000011 'ch1 & 2


Ddrb = &B00111111 'output
Portb = &B00000000

Config Portd = Output
Portd = &B11111111

Ocr1b = 499 '1 kHz output
Ocr1a = 499 'for R-meter

Enable Timer1
Tccr1a = &B00010000 'CTC OC1B toggle
Tccr1b = &B00001001 'CTC, ck 1
Enable Interrupts

Enable Compare1a
On Compare1a T1cmp


Config Adc = Single , Prescaler = Auto , Reference = Internal
Start Adc

'*********************************************************************

Dp = 0
Adch0 = 0
Adch1 = 0
Flag = 0
Dispcnt = 0
W = 0

A = 0 'test display
B = 0
C = 0
While Dispcnt < 250 'inc in ISR
Wend 'wait
Dispcnt = 0


Do

' measure voltage loop

If Dispcnt > 99 Then '100 ms
Dispcnt = 0 ' update display

W = 0
Adch0 = 0
If Channel0 = 1 Then
For N = 1 To 8 'get ch 0
W = Getadc(0)
Adch0 = Adch0 + W
Next N
End If

W = 0
Adch1 = 0
If Channel1 = 1 Then
For N = 1 To 8 'get ch 1
W = Getadc(1)
Adch1 = Adch1 + W
Next N
End If

If Adch0 > Adch1 Then 'show difference
Ad = Adch0 - Adch1
Showflag = 0 'show +
Else
Ad = Adch1 - Adch0
Showflag = 1 'show -
End If

Shift Ad , Right , 3 'div 8

Avgvalue = Avgvalue * 7 ' (Avgvalue*7 + Currentvalue)/8
Avgvalue = Avgvalue + Ad
Shift Avgvalue , Right , 3 'running average

If Avgvalue >= 1000 Then 'overflow
Overfl = 1
A = &B00011101
B = &B10010100
C = &B11101111
Else
Overfl = 0

Ad = Avgvalue * Calfactor 'mA/count, calibrate
Ad = Ad / 100

If Ad < 1000 Then 'move decimal point
Dp = 1
Else
Dp = 0
Ad = Ad / 10
End If


W = Ad / 100
C = Lookup(w , D7seg)
W = Ad Mod 100
I = W
W = W / 10
B = Lookup(w , D7seg)
I = I Mod 10
A = Lookup(i , D7seg)

End If 'If Ad >= 1000


If Channel0 = 0 And Channel1 = 0 Then 'surprise
A = &B11110000
B = &B01010001
C = &B10111000
End If

End If 'if dispcnt

Loop ' do again

'*********************************************************************


T1cmp: '1 ms interrupt

Incr Icnt
Incr Dispcnt ' update display

If Icnt = 2 Then '2 ms
Digitl = 1 ' left digit
Portd = C

Elseif Icnt = 4 Then
Decpoint = 1
Digitl = 0
Digitm = 1 ' middle digit
Portd = B
If Dp = 1 Then
Decpoint = 0
End If

Elseif Icnt = 6 Then
Decpoint = 1
Digitm = 0
Digitr = 1 ' right digit
Portd = A

Elseif Icnt = 8 Then 'adjust brightness
Decpoint = 1
Digitr = 0
Portd = 0

Elseif Icnt = 10 Then
Icnt = 0

End If

Return 'reti


End

'*********************************************************************

' 0 1 2 3 4 5 6 7 8 9 dp F

D7seg:
Data &B01010000 , &B01011111 , &B00110010 , &B00010110 , &B00011101 , &B10010100 , &B10010001 , &B01011110 , &B00010000 , &B00011100 , &B11101111 , &B10111000

'*********************************************************************


 Elektronik-Labor   Projekte   AVR