Toto zařízení může být rozšířením Vašeho zdroje, nebo spíše nabíječky. Měří DC napětí a proud a vypočítává dodaný/odebraný výkon a energii. [A,V,W,Wh]. Pro mě zajímavým je použití integrovaného bočníku (shuntu) MCP2060.

Zdrojový kód je v BasComu.



'******************************************************************************
'* M32 Wh-Meter1.bas                                                          *
'* frei nach mikrocontroller.net (for_ro) bearbeitet von DL3JIN               *
'* 12.12.2008                                                                 *
'* misst Strom und Spannung, errechnet Leistung und zählt Wattstunden         *
'* startet bei Zuschalten der Betriebsspannung                                *
'******************************************************************************

$regfile = "m32def.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 10
$framesize = 40
$prog &HFF , &HFF , &HD9 , &H00         'lock and fuse bytes für M32
                                         'externer Quarz, JTAG disabled,
                                         'Port C frei für Anwender

Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , _
                       Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
Config Lcd = 16 * 2
Config Portd.7 = Output                 'LED an PortD.7  (device running)
Config Timer1 = Timer , Prescale = 256
Config Adc = Single , Prescaler = 128 , Reference = Internal


'Die Timervorgabe für 1s errechnet sich zu:
'(Zählumfang Timer) - (Quarzfrequenz / Prescaler) = Timervorgabe
'(65536           ) - (16000000      / 256      ) = 3036
Const Timervorgabe = 3036
Const Vref = 2.48                       'interne Vref = ADW max. Vin !
Const Vende = 30                        'Endwert Spannungsmessbereich
Const Iende = 30                        'Endwert Strommessbereich

Dim Iststunde As Byte
Dim Istminute As Byte
Dim Istsekunde As Byte
Dim Letzte_sekunde As Byte              'Merker zum Vergleich ob neue Sekunde
Dim Uwert As Word                       '0...1023
Dim Iwert As Word                       'dito
Dim Volt As Single                      'angezeigte Spannung
Dim Amp As Single                       'angezeigter Strom
Dim Vfaktor As Single                   'umrechnen auf Messbereichsendwert
Dim Ifaktor As Single                   'dito
Dim Pwr As Single                       'angezeigte Leistung
Dim E As Single                         'Arbeit in 1s (zum Addieren)
Dim Wh As Single                        'angezeigte Wattstunden

Vfaktor = Vende / 1023                  'da der ADW nur 0...1023 ausgibt
Ifaktor = Iende / 1023                  'dito

Iststunde = 0                           'bei "0" starten
Istminute = 0
Istsekunde = 0

On Timer1 Timer_irq

Enable Timer1
Enable Interrupts

Cursor Off
Cls                                     'Begrüßungsfenster
Locate 1 , 3
Lcd "M32 Wh-Meter"
Locate 2 , 6
Lcd "DL3JIN"
Wait 2
Cls

Start Adc

Do
   If Istsekunde    <> Letzte_sekunde Then 'neue Sekunde da? Wenn ja, dann:

      Uwert = Getadc(0)                 'Wert "U" im Kanal0 holen
      Volt = Uwert * Vfaktor            'Wert "U" umrechnen in Volt
      Locate 1 , 1                      'gilt für alle Spannungen
      If Volt    < 10 then                 'fülle links mit einem Leerzeichen auf
         lcd " ";
      end if
      lcd fusing(volt , "#.#") ; " V "  'runde und formatiere vor Ausgabe

      iwert = getadc(1)                 'Wert "I" im Kanal1 holen
      amp = iwert * ifaktor             'Wert "I" umrechnen in Ampere
      locate 2 , 1
      if amp    < 10 then
         lcd " ";
      end if
      lcd fusing(amp , "#.#") ; " A "

      pwr = volt * amp                  'Leistung  "P"
      locate 1 , 9
      if pwr    < 100 then                 'fülle links mit einem Leerzeichen auf
         lcd " ";
      end if
      if pwr    < 10 then                  'fülle mit einem weiteren Leerzeichen
         lcd " ";
      end if
      lcd fusing(pwr , "#.#") ; " W "

      e = pwr / 3600                    'Arbeit "E in einer Sekunde"
      wh = wh + e                       'die Wattstunden seit letztem Reset
      locate 2 , 8
      if wh    < 1000 then                 'fülle links mit einem Leerzeichen auf
         lcd " ";
      end if
      if wh    < 100 then
         lcd " ";
      end if
      if wh    < 10 then
         lcd " ";
      end if
      lcd fusing(wh , "#.#") ; " Wh"
      if wh > 9999 Then                   'bei > 9999 Wh erfolgt Hinweis im LCD
         Cls                            'und Programmende
         Locate 1 , 1
         Lcd "     Error"
         Locate 2 , 1
         Lcd "  Wh Overflow"
         End
      End If

      If Istsekunde = 60 Then           'Istsekundenzähler zurücksetzen
         Istsekunde = 0
         Incr Istminute                 'Minutenzähler +1
      End If
      If Istminute = 60 Then            'Istminutenzähler zurücksetzen
         Istminute = 0
         Incr Iststunde                 'Stundenzähler +1
      End If
      If Iststunde = 24 Then            'Hinweis auf LCD
         Cls
         Locate 1 , 1
         Lcd "     Error"
         Locate 2 , 1
         Lcd "  24h Overflow"
         End                            ' Programmende
      End If

      Toggle Portd.7                    'Kontroll-LED
      Letzte_sekunde = Istsekunde       'aktualisieren
   End If
Loop

Timer_irq:
   Timer1 = Timervorgabe                'Timer wieder voreinstellen
   Incr Istsekunde                      'Sekundenzähler +1
   Return

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