Seit dem c't artikel (in dem die Autoren auch schon das Gerät aufgeschraubt und die ersten Details ermittelt haben) war jedem (mir zumindest!) klar, dass das Gerät reverse-engineered und mit einer Datenschnittstelle versehen werden muss. Leider hat das nach drei Jahren dann doch noch niemand gemacht (und Veröffentlicht!), also muss ich selber ran.
Der Umbau eines KD302 verspricht, ein günstiges und genaues Leistungsmessgeraet mit Datenschnittstelle. Bei einem Eigenbau solch eines Gerätes währe idr. schon alleine das Gehäse (oder ein Mess-IC, so man eins verwendet) teurer, als das ganze KD302!
Der verwendete CS5460A beinhaltet A/D Konverter für Strom/Spannung mit 4k Samples/Sek. Bei 4.096Mhz Taktung, mit einer schnelleren Taktung des CS5460A ließe sich das ggfs. noch erhöhen. 4k Samples/Sek entsprechen 80 Samples/Vollwelle. Man vergleiche die ärmlichen 16 des tweet-a-watt).
Diese Daten lassen sich auslesen, so dass man die Strom/Spannungs-kurven angeschlossener Geräte ermitteln kann.
Aus den unten ermittelten Details, ergeben sich Probleme für den Einbau einer Schnittstelle:
es ergeben sich einige Ansätze:
Ich bevorzuge die Proxy-Variante, um alle Funktionen des CS5460A nutzen zu können.
Eine galvanische Trennung irgendwo zwischen CS5460A und Datenausgang ist erforderlich. Es kommt manchmal die Idee auf, die SPI-Schnittstelle des CS5460A zu isolieren, dies scheint mir jedoch unattraktiv, da hier (vor allem wenn wir alle Strom/Spannungs-Momentanwerte mitlesen wollen!) relativ hohe Datenraten vorliegen, außerdem besteht die Schnittselle aus sechs Leitungen. Dies würde relativ teurere Dausteine für eine Isolierung erfordern. Gegeigneter erscheint mir, einen Controller auf der Netzpotential-Seite zu verbauen, und dann den Datenausgang selbst zu isolieren. Im Idealfall einfach dadurch, dass er selbst über Funk kommuniziert.
Einbau eines Controllers und Durschschleifen der Signale
ich habe eine KD302 Platine umgebaut (mit Cuttermesser, Dremel und Bohrmaschine, feinem Draht, Lötkolben), und die unnützen SIP1-3 Anschlüsse durch einen Anschluss ersetzt, durch den alle Verbindungen zwischen Controller und CS5460A durchgeschleift sind (bis auf den ungenutzten Impulsausgang). Die „Präzisions“-Stift/Buchsenleisten sind… präzise, zuverlässig… und stapelbar, um einen grösseren Abstand der Platinen zu erreichen.
Und eine Tochterplatine mit eigenem Controller gebaut, die auf den neuen Anschluss, sowie J1 aufgesteckt wird (auf dem Bild ist der SPI-bus noch nicht verdrahtet, das Loch war für den Elko auf der Platine gedacht, aber bei entsprechendem Abstand passt es auch ohne):
Eine Funkschnittstelle (rf/BT) wäre am interessantesten, ist aber etwas komplexer.
für den Anfang habe ich ein galvanisch getrenntes UART-Interface gebaut. Das ist ein eigenes Unterprojekt und werde ich an anderer Stelle zu dokumentieren. Die aktuelle Variante funktioniert nur mit maximal 9600 Baud.
Man beachte die Glimmlampe im Phasenpruefer - die Schnittstelle auf KD302-Seite liegt auf Netzpotential! das USB-Kabel ist an einen PC angeschlossen.
Nach Auftrennen von SDA/SCL zwischen Controller und EEPROM zeigt das Gerät konstant 0W an.
Zugriff auf das EEPROM per BusPirate, hier in einem Gerät in dem ich SDA/SCL vom Controller getrennt habe. Es geht auch ohne die Leitungen zu aufzutrennen (natürlich ist I2C multimaster-fähig, wenn korrekt implementiert, außerdem greift der Controller im Betrieb wohl eh nicht auf das EEPROM zu).
I2C>[0b10100000 0 0] I2C START BIT WRITE: 0xA0 ACK WRITE: 0x00 ACK WRITE: 0x00 ACK I2C STOP BIT I2C>[0b10100001 r:256] I2C START BIT WRITE: 0xA1 ACK READ:
Inhalt aus dem 1. Gerät: (ich hatte beim herumspielen versehentlich die ersten drei byte ueberschrieben, scheinen aber eh immer 0x54 0xFF 0xFF zu sein )
0x?? 0x?? 0x?? 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x24 0x24 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x15 0x8C 0x71 0xFF 0xB5 0x62 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x44 0xCA 0x00 0x01 0x4A 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x3D 0x82 0xEF 0x3D 0x10 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00
Inhalt aus dem 2. Gerät:
0x54 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x24 0x24 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x16 0x5B 0xB1 0xFF 0xC0 0xF4 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x3F 0x60 0x00 0x01 0x2F 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x3E 0x87 0xFF 0x40 0xD9 0x86 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00
Inhalt aus dem 3. Gerät:
0x54 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x24 0x24 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x16 0x78 0x9C 0xFF 0xCC 0xE0 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0x7F 0xA4 0x00 0x01 0x3D 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x3E 0x77 0xFF 0x3E 0x94 0x80 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x00
Im Betrieb ca. einmal pro Sekunde ein Signal auf INT, und (daraufhin?) eine kurze Kommunikation auf dem seriellen Interface (vermutlich signalisiert der CS5460A die Verfügbarkeit neuer Daten, die der Controller dann abholt).
Folgende schöne Ansicht ergibt sich im Logic Analyzer Modus, getriggert auf das INT Signal auf Kanal 4:
Controller → CS5460A | CS5460A → Controller | Beschreibung |
---|---|---|
0x5E / 0b01011110 | - | Write Register 15 (SREG) (Datenblatt 4.1.7) |
0x80 / 0b10000000 ,0x00,0x00 | - | oberstes Bit im SREG = DRDY, Flag für Daten verfügbar, wird durch Schreiben einer 1 gelöscht. So dass das Interruptsignal zurück gesetzt wird (siehe Kanal 4, Datenblatt 3.4 , 5.11) |
0x16 / 0b00010110 | - | Read Register 11 (RMS current) |
- | 0x00,0x04,0x74 | 24-bit signed-int Wert (Datenblatt 4.6) |
0x18 / 0b00011000 | - | |
- | 0x01,0x0C,0x94 | 24-bit signed-int Wert (Datenblatt 4.6) |
0x14 / 0b00010100 | - | Read Register 10 (E (energy)) |
- | 0xFF,0xFF,0xFE | 24-bit signed-int Wert (Datenblatt 4.6) |
Irgendwann lief dann auch mal der SPI Sniffer Mode…
$ serialclient -r 115200 /dev/ttyUSB0 HiZ>m5 Set speed: 1. 30KHz 2. 125KHz 3. 250KHz 4. 1MHz (1)>4 Clock polarity: 1. Idle low *default 2. Idle high (1)> Output clock edge: 1. Idle to active 2. Active to idle *default (2)> Input sample phase: 1. Middle *default 2. End (1)> CS: 1. CS 2. /CS *default (2)> Select output type: 1. Open drain (H=Hi-Z, L=GND) 2. Normal (H=3.3V, L=GND) (1)> Ready SPI>(0) 0.Macro menu 1.Sniff CS low 2.Sniff all traffic SPI>(1) Sniffer Any key to exit [0x00(0x5E)0x00(0x80)0x00(0x00)0x00(0x00)0x00(0x16)0x00(0xFF)0x01(0xFF)0xE9(0xFF)] [0x00(0x18)0x00(0xFF)0x8E(0xFF)0x45(0xFF)] [0x00(0x14)0xFF(0xFF)0xFF(0xFF)0xFF(0xFF)] [0x00(0x5E)0x00(0x80)0x00(0x00)0x00(0x00)0x00(0x16)0x00(0xFF)0x01(0xFF)0xFA(0xFF)] [0x00(0x18)0x00(0xFF)0x8C(0xFF)0xC8(0xFF)] [0x00(0x14)0xFF(0xFF)0xFF(0xFF)0xFF(0xFF)]
Das sind die gleichen anfragen wie oben. Und dann nach einem Reset des Controllers, endlich die gesuchte Initialisierungssequenz (Hier aus meinem Gerät Nr. 1, dazugehöriger EEPROM Inhalt siehe oben):
[0x00(0x46)0x00(0x15)0x00(0x8C)0x00(0x71)0x00(0x42)0x00(0xFF)0x00(0xB5)0x00(0x62)] [0x00(0x62)0x00(0x00)0x00(0x44)0x00(0xCA)0x00(0x60)0x00(0x00)0x00(0x01)0x00(0x4A)] [0x00(0x4A)0x00(0x00)0x00(0x0F)0x00(0xA0)0x00(0x48)0x00(0x3D)0x00(0x82)0x00(0xEF)0x00(0x44)0x00(0x3D)0x00(0x10)0x00(0x00)0x00(0x40)0x00(0x01)0x00(0x00)0x00(0x01)0x00(0x5A)0x00(0x83)0x00(0x12)0x00(0x6E)0x00(0x78)0x00(0x00)0x00(0x00)0x00(0x40)0x00(0x74)0x00(0x80)0x00(0x00)0x00(0x00)0x00(0xE8)0x00(0x00)0x01(0x00)0x01(0x00)] # und dann wieder das uebliche: [0x01(0x5E)0x00(0x80)0x01(0x00)0x00(0x00)0x00(0x16)0x00(0xFF)0x01(0xFF)0x66(0xFF)] [0x00(0x18)0x00(0xFF)0x67(0xFF)0x6B(0xFF)] [0x00(0x14)0xFF(0xFF)0xFF(0xFF)0xFF(0xFF)] (...)
Nach Datenblatt:
[ 0x46 0b01000110 write register 3 (Voltage Channel DC Offset) 0x15 0b00010101 0x8C 0b10001100 : aus eeprom, offset 0x2F 0x71 0b01110001 0x42 0b01000010 write register 1 (Current Channel DC Offset) 0xFF 0b11111111 0xB5 0b10110101 : aus eeprom, offset 0x32 0x62 0b01100010 ] [ 0x62 0b01100010 write register 17 (Voltage Channel AC Offset) 0x00 0b00000000 0x44 0b01000100 : aus eeprom, offset 0x3F 0xCA 0b11001010 0x60 0b01100000 write register 16 (Current Channel AC Offset) 0x00 0b00000000 0x01 0b00000001 : aus eeprom, offset 0x42 0x4A 0b01001010 ] [ 0x4A 0b01001010 write register 5 (Number of A/D cycles per computation cycle) 0x00 0b00000000 0x0F 0b00001111 : dezimal 4000 0xA0 0b10100000 0x48 0b01001000 write register 4 (Voltage Channel Gain) 0x3D 0b00111101 0x82 0b10000010 : aus eeprom, offset 0x4F 0xEF 0b11101111 0x44 0b01000100 write register 2 (Current Channel Gain) 0x3D 0b00111101 0x10 0b00010000 : aus eeprom, offset 0x52 0x00 0b00000000 0x40 0b01000000 write register 0 (Configuration) 0x01 0b00000001 : phase compensation=0 (default), PGA gain = 50 0x00 0b00000000 : alles defaults... betrifft EOUT/EDIR, INT=active low,level 0x01 0b00000001 : filters disabled (?!), clock divider = 1 0x5A 0b01011010 write register 13 (Timebase Calibration) 0x83 0b10000011 : dieser wert steht NICHT im eeprom! 0x12 0b00010010 : lt. datenblatt skalierter wert zw. 0 und 2 0x6E 0b01101110 : der wert entspricht wohl 8589934/16777216*2 = 1.02398, das ist gerade 4096/4000 0x78 0b01111000 write register 28 (Control) 0x00 0b00000000 : alls nur reserved bits 0x00 0b00000000 : ebenso (und nicht relevantes autoboot bit) 0x40 0b01000000 : MECH=1 "widens EOUT and EDIR pulses for mechanical counters." ??!! 0x74 0b01110100 write register 26 (Mask) 0x80 0b10000000 : INT erzeugen wenn DRDY gesetzt 0x00 0b00000000 : alle anderen quellen aus 0x00 0b00000000 : ... 0xE8 0b11101000 start conversions! continuous mode
EOUT/EDIR ist ein Impulsausgang („S0-Ausgang“). Im einfachsten Fall kann könnte man ihn benutzen, sofern er vom Controller sinnvoll initialisiert wird werden würde:
Zitat Datenblatt:
3.1 Pulse-Rate Output
As an alternative to reading the real energy through the serial port, the EOUT and EDIR pins provide a simple interface with which signed energy can be accumulated. Each EOUT pulse represents a predetermined quantity of energy. The quantity of energy represented in one pulse can be varied by adjusting the value in the Pulse-Rate Register.
Nachdem ich bei ersten Messungen keine Impulse auf EOUT gesehen hatte, nahm ich an, dass meine Last zu klein war, und versuchte es mit mehreren kW Last. Leider ohne Erfolg. Erst dann stellte ich fest, das meine Last zu groß war!
Das „pulse-rate register“ wird vom Controller definitiv nicht sinnvoll programmiert. Vermutlich steht es auf Null o.ä.
(Update: an der oben analysierten Initialisierungssequenz ist abzulesen: das pulse-rate register wird nicht beschrieben. Dazu wird netterweise noch die Pulsweite auf extra lang eingesstellt, was das Problem noch begünstigt.)
Die Impulsrate liegt über 1 Impuls pro Wattsekunde, schon ab ca 2 Watt laufen die Impulse aufgrund der Impulslaenge ineinander, und es entsteht ein Dauerpegel!
Somit ist der Impulsausgang ohne Änderungen an der Programmierung definitv nicht nutzbar. Andererseits bedeutet dies auch, dass er vom vorhandenen Controller wohl nicht benutzt wird (obwohl er angeschlossen ist!). Möglicherweise ist es möglich über Änderungen der Daten im EEPROM den Wert im pulse-rate register zu ändern.
(Update: die EEPROM Daten sehen nicht danach aus, als ob man irgendwo einen Wert für das pulse-rate register eintragen könnte.)
Ansonsten wird man um den Einbau eines eigenen Controllers nicht herum kommen. Alternativ könnte man den Standalone-Betrieb des CS5460A nutzen, bei dem er seine Konfiguration aus einem EEPROM liest: Controller (und Display) hinauswerfen, das EEPROM umprogrammieren und direkt mit dem CS5460A verbinden.
Steckanschluss für Huckepack-Platine? im Gehäuse ist noch genügend Platz vorhanden!
Pin | Beschreibung |
---|---|
1 | GND (bzw. je nach Stecker-Steckrichtung identisch mit 230V-Phase. Keine galvanische Trennung! Das kann man nicht oft genug sagen) |
2 | 50Hz Signal aus der gegend des netzteils (C22/ZD1) |
3 | „Power“ Taste |
4 | „Function“ taste |
5 | i2c SCL (EEPROM) |
6 | i2c SDA (EEPROM) |
7 | RESET Eingang des Controllers |
8 | 5V Vcc |
Nur an den Controller angeschlossen (plus jeweils einmal GND), identisch zu den Testpunkten oberhalb des Controllers. Vermutlich Schnittstelle für Test/Kalibrierung beim Hersteller, ohne Dokumentation wohl wenig brauchbar.