Translate

15 Mai 2013

Strommessung mit einem LEM HASS 200-S am MCP3426

Die Ansteuerung des MCP3426 funktioniert sehr gut,
Das Umrechnen der beiden Datenbyte zu einem Integer-Wert (mit Vorzeichen)
klappt auch ohne Probleme, also habe ich jetzt auch noch einen LEM HASS 200-S
Stromwandler am AD-Wandler angeschlossen.
Ich hatte zwar insgeheim gehofft, auf den Nullabgleich verzichten zu können, wenn ich
die Referenz des Stromwandlers benutze, aber ganz passte der Nullpunkt dann doch nicht.
Es fehlt um 0,00375 Volt was doch immerhin 1,2A entspricht Bei einem Messbereich von
+ - 655A sind das 0,1% vom Messbereich.

Am Programm habe ich noch ein bisschen rumgebastelt,
deshalb hier nochmalder aktuelle Hauptteil
Die Variable Ergebnis1a ist übrigens eine "long"-Variable
weil die Multiplikation mit 0,8 ganzzahlig anders nicht verlustfrei machbar ist.
Die Offset- einstellung ist nicht zufällig an dieser Stelle zwischen den Rechnungen,
Ich wollte den Offset unbedingt am Anfang der Berechnungen bitweise einstellen können.
Die Integer-Variable ist im 16Bit-Modus voll ausgenutzt, da kann ich nichts
addieren oder subtrahieren ohne dass es dann irgendwo am Ende zu Fehlern kommt,
das geht dann erst in der "long"-Variablen
und wenn ich es vor der Multiplikation mit 100
gemacht hätte dann hätte ich eine Zeile mehr gebraucht.
Statt * 100 und dann / 125 hätte auch * 4 und / 5 funktioniert, aber so könnte ich noch die
linearität ein bisschen korrigieren falls nötig


Do
'init
I2cstart
'Adressierung
I2cwbyte &B1101_0000 '3426 Schreibadresse

'Konfigurieren
'Bit 7 "Ready/"
'Bit6-5: 00:kanal1 01:Kanal2 10:Kanal3 11:Kanal4
'bit4 1=cont 0=Single
'bit3-2 00:12bit 240sps 01:14bit 60sps 10:16bit 15sps
'bit1-0: gain 00:x1 01:x2 10:x4 11:x8

'I2cwbyte &B0001_0000 'kanal1 12Bit
'I2cwbyte &B0001_0100 'kanal1 14bit
'I2cwbyte &B0001_1000 'kanal1 16bit
I2cwbyte &B0011_0100 'kanal2 14bit
'I2cwbyte &B0011_1000 'kanal2 16bit

I2cstop

Waitms 100 'auf Sample-Zeit + reserve einstellen
'Ready/ -bit muss 0 sein, wird hier in Readbyte3 eingelesen
'lesen
I2cstart

'I2creceive &B1101_0001 , Ergebnis1 , 1 , 3

I2cwbyte &B1101_0001 '3426 Leseadresse

I2crbyte Readbyte1 , Ack 'hohes Byte
I2crbyte Readbyte2 , Ack 'niedriges Byte
I2crbyte Readbyte3 , Nack 'Konfigurationsbyte zurück

'inclusive "ready-bit"
Ergebnis1 = Readbyte1 * 256
Ergebnis1 = Ergebnis1 + Readbyte2
Ergebnis1a = Ergebnis1 * 100
Ergebnis1a = Ergebnis1a - 1500 'offset
Ergebnis1a = Ergebnis1a / 125

Ergebniss1 = Str(ergebnis1a)
Ergebniss1 = Format(ergebniss1 , " 0.0")


Ich habe als Funktionsdemonstration ein kleines Video gemacht,
aber das ist noch nicht fertig hochgeladen.
das kommt noch!

vermutlich hier:
http://youtu.be/sfVUjZq0aCI

Bis dann!

Ach ja, und ein kleines Foto will ich Euch nicht vorenthalten:

Das E-Motorrad meiner Tochter hat jetzt einen Beiwagen bekommen!

13 Mai 2013

Messen mit dem MCP3426 16bit "delta-sigma" I²C AD-Wandler

........Wieder mal ein kleines Programm in BASCOM....

Hiermit steuere ich mit einer Franzbox-Platine einen MCP3426 an und lese die Werte aus.
erst mal nur ein Kanal, aber dann sollte der zweite Kanal auch funktionieren.
Der MCP3426 ist der kleinste und einfachste aus der MCP342X-Reihe von Microchip.
Ein sehr ähnlicher Baustein ist der ADS1112 von Texas den es bei Watterott sogar auf einem
kleinen Platinchen vormontiert gibt. Die ganze Ansteuerung ist nahezu gleich, nur mit anderen
Default-Werten. Ich will da jetzt nicht allzusehr ausschweifen, schaut Euch mal die Datenblätter an,
und staunt, was die Dinger können........

Kurz zusammengefasst:
Der MCP3426 ist ein "Delta-Sigma"-AD-Wandler mit eingebauter Referenz und I²C Ansteuerung.
Das Ganze mit einer Referenzspannung von 2,048Volt und bis zu 16Bit Auflösung.
Delta Sigma bedeutet, dass die Spannung nicht gegen GND sondern gegen einen Referenzpin
gemessen wird, der nicht auf GND liegen muss (aber kann) und Spannungen von + - 2,048V
gegen den Referenzpin in 1mV(12bit) 250µV(14bit) oder 62,5µV Schritten gemessen werden können!!!
Beide Eingangspins müssen aber innerhalb des Versorgungsspannungsbereichs liegen!
Negative Spannungen sind nicht messbar.
Zusätzlich gibt es noch eine "Gain"-Funktion, damit kann die Empfindlichkeit nochmal um die Faktoren
1  2  4 oder 8 erhöht werden (bei entsprechend kleinerem Messbereich) so dass maximal
in 0,000007812V -Schritten  +- 0,256V gemessen werden können.........
das ist z.B. ideal für 200mV-Shunts zur Strommessung.
Ich will damit aber zunächst mal den LEM HASS-200-S Stromwandler auswerten,
dessen  Ausgang von +- 1,875V gegen eine Referenz von 2,5V bei + - 600A ausgibt.
Da war die Auflösung des 10-Bit Wandlers im Atmega bisher einfach nicht ausreichend
um auch Ladeströme genau genug zu messen. Erschwerend kam noch die Messung
gegen GND dazu, so dass auch noch der Nullpunkt korrigiert werden musste.

In der Praxis ergeben sich dadurch folgende Auflösungen bei der Messung:
Beim 10bit AD-Wandler im Atmega sind 0-5V in 1024 Schritte aufgeteilt.
daraus ergibt sich mit dem LEM HASS 200-S eine Auflösung von 1,5625A.

beim MCP3426 muss man ein bisschen anders rechnen.
Hier geht der Messbereich nur bis + oder - 2,048V relativ zum Referenzpin.
Das wären beim LEM HASS 200-S + oder - 655,4A , dieser Wert wird aber wohl kaum erreicht,
da der HASS 200-S nur bis + - 600A angegeben ist. aber das ist hier auch egal.
Die Auflösung beträgt hier bei 12bit 0,32A, bei 14bit 0,08A und bei 16bit
geradezu unglaubliche 0,02A  also 20mA bei einem Messbereich von + - 600A!

Die Auflösung von 0,08A bei 14bit-Messung ermöglicht immerhin eine Auflösung von 0,1A
im Display bei einem Messbereich von + - 650A und der Fehler ist erstaunlich gering
so im 0,2A-Bereich.......   1% vom Skalenendwert wären da schon 13A!!!!!!!
nur mal, um die Dimension und Problematik solch einer Messung zu verdeutlichen

Auflösung ist hier nicht zu verwechseln mit Messgenauigkeit, und ein gewisser Offset
ist beim LEM Stromwandler auch zu berücksichtigen, aber mit einer Auflösung im
Bereich von 0,5 bis 0,1 A kann man Ladeströme von ca 30A durchaus messen.
bei 1,6A ist aber nur eine sehr grobe Schätzung möglich.

Auf die Offset-Einstellung werde ich wohl doch nicht ganz verzichten können,
aber das ist jetzt alles wesentlich!!!!!! stabiler, seit die Referenz des LEM als Messreferenz
genutzt werden kann. Der Offset des LEM-Wandlers in meinem Versuchsaufbau
liegt bei ziemlich genau 1,2A und ist nach der Korrektur absolut stabil.(+ - 1Digit)

Dieser Offset von 1,2A beträgt 15Digits des AD-Wandlers bei 14bit, das sind gerade mal
15 x 250µV bzw 0,00375V, die der Nullpunkt des LEM bei 0A von 0V abweicht.
Mehr kann man hier nicht erwarten, das passt schon!

Die Möglichkeit, durch entsprechende "Gain"-Einstellung auch Mess-Shunts direkt
einzulesen eröffnet aber auch noch ganz andere Möglichkeiten.
So ein Shunt ist wesentlich unempfindlicher gegen äussere Einflüsse als ein Hallgeber-Stromwandler,
und die Messgenauigkeit ist eigentlich nur von der Qualität der Auswerteschaltung abhängig. Größter Nachteil eines Shunt ist die fehlende galvanische Trennung des Meßsignals.
Großter Vorteil ist die feste Nulllage und die Symmetrie in beide (Strom-) Richtungen.
Wenn die Energie die in die eine Richtung fliesst mit der Energie in die andere Richtung
verglichen werden soll, dann kommt es vor Allem auf die "Symmetrie" der Messung an
und nicht auf den tatsächlichen Fehler. Ob jetzt die Akkukapazität auf zwei Nachkommastellen
stimmt oder nicht ist völlig egal, aber die Energiemenge muss am Nullpunkt wieder passen.

Nicht zu vernachlässigen ist auch die Erwärmung so eines Shunt.
100mV bei 500A sind beachtliche 50Watt. Sehr viel mehr an Messsignal bei 500A
ist also wohl nicht möglich.Das wären dann bei 14bit und Gain 8  1600 Digits in jede Richtung,
also 0,3125A Auflösung. (0,078125A Auflösung bei 16bit und Gain 8)

Die Messung per I²C kann an der bisherigen Franzbox nachgerüstet werden.
Alle Leiterbahnen sind bereits vorhanden, nur zwei schon vorgesehene Widerstände und eine neue
Programmversion sind dafür nötig.

Ich habe I²C gewählt, weil ich da nur zwei Leitungen brauche. Obwohl I²C eigentlich nicht
ideal ist für galv.Trennung, so ist das aber mittlerweile auch kein Problem mehr dank Bausteinen wie dem
ADUM2250 und ähnlichen.
Damit kann ich jetzt endlich mal galv.getrennt Spannungen messen, und noch dazu sehr genau!
Die Leitung von der Box bis zum Messwandler sollte allerdings nicht allzu lang sein.
Ein halber Meter funktioniert aber problemlos.




$regfile = "m168def.dat"
$crystal = 8000000
'$hwstack = 40
'$swstack = 32
'$framesize = 60

Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.5 , Rs = Portb.4
Config Lcdbus = 4

Config Lcd = 20 * 4a , Chipset = Ks077
Cls
Cursor Off
Waitms 250
Config Sda = Portc.4
Config Scl = Portc.5
I2cinit
Dim Slaveadresse As Byte
Dim Readbyte1 As Byte
Dim Readbyte2 As Byte
Dim Readbyte3 As Byte
Dim Ergebnis1 As Integer
'Do
Cls
Locate 1 , 1
Lcd "I2C MCP3426"
Wait 1
Cls
Do
'init
I2cstart
'Adressierung
I2cwbyte &B1101_0000                  '3426 Schreibadresse
'Konfigurieren
'I2cwbyte &B0001_0000                    'kanal1 12Bit
I2cwbyte &B0001_0100                     'kanal1 14bit
I2cstop

Waitms 10                                          'eventuell nicht nötig
'lesen
I2cstart
I2cwbyte &B1101_0001                    '3426 Leseadresse

I2crbyte Readbyte1 , Ack
I2crbyte Readbyte2 , Ack
I2crbyte Readbyte3 , Nack

Ergebnis1 = Readbyte1 * 256
Ergebnis1 = Ergebnis1 + Readbyte2

'womöglich muss ich hier noch was korrigieren........
'falls die Umrechnung so nicht passt, weil Ergebnis1 ja eine
'Integer-Variable ist......Readbyte1 bestimmt das Vorzeichen
'das würde sicher passen, wenn erst
'in einer Word-Variable multipliziert und addiert würde,
'und erst dann das Ergebnis in eine Integer-Variable übertragen würde.
Durch den Überlauf bei 32768 ergibt sich dann das Vorzeichen
'>>>>Nachtrag: man kann es tatsächlich so lassen, auch wenn es mathematisch eigentlich
'nicht korrekt ist...... Bascom rechnet manchmal ein bisschen seltsam.......
' das versteht man etwas besser, wenn man weiss dass Bascom immer
'mit den binären Werten rechnet und nur entsprechend darstellt bei Word und Integer.
'Integer, das muss erst mal verstanden werden, wie das funktioniert!
'Das wäre mal einen eigenen Post wert!....ein andermal!
'vielleicht lassen sich die beiden Byte sogar direkt in eine Integer-Variable einlesen.
'da fehlte die nötige Zeit, das alles durchzutesten, das kommt erst noch
'>>>>>>>Ich habs versucht, hat nicht geklappt, weil mindestens drei Byte zu lesen sind und bei
'I2Cread die ganzen Ack und Nack-Geschichten nicht so gesteuert werden können
'dass es passt.....dann halt nicht...

If Err = 0 Then
Locate 1 , 1
Lcd ":" ; Readbyte1 ; ":" ; Readbyte2 ; ":" ; Readbyte3 ; " "
Locate 2 , 1
Lcd Ergebnis1 ; " "
End If
I2cstop 'Bus freigeben

Loop
End