Solarthermie SunGo SXL

Aus TippvomTibb
Zur Navigation springen Zur Suche springen

Suchwort: Prozeda

Motivation

Angeregt durch drei Artikel unter https://hobbyelektronik.org[1][2][3] habe ich mein Vorhaben, die SunGo SXL Solarthermie Steuerung in meine Gebäudeautomation zu integrieren, wieder aufgenommen. Die Artikel sind als für mich eine schöne Quelle (gewesen) meine Informationen und Daten abzugleichen und die Sicherheit zu haben, dass so wie ich mir das Ganze vorgestellt habe, scheinbar funktioniert. Was durchaus erstaunlich ist. Denn bereits zu Beginn habe ich bei der Analyse des Datensticks im Datenblatt des AT45DB081D die Taktfrequenz bis zu 66 MHz gelesen. Sollte die SunGo diese Rate ausnutzen ist eine Emulation des Datensticks doch schon recht aufwendig und alle Mikrocontroller und RasPis dieser Welt als reine Softwareemulatoren außen vor. Aber dazu weiter unten mehr.

Allgemeines

Die SunGo SXL ist eine Steuerung für solarthermische Anlagen der Firma Wagner&Co. Die Steuerung bietet die Möglichkeit des Datenloggings. Zu diesem Zweck wird an der markierten Stelle ein kleiner Stick eingesteckt. Um die Daten, die auf dem Stick aufgezeichnet werden zu visualisieren muss der Stick abgezogen werden und am PC in einen Leseadapter gesteckt werden. Dann lassen sich mit der mitgelieferten Software (Datalogging Solareg II; DtSol2.exe)die Daten einlesen, anzeigen und exportieren.

Artikel

Die Artikel liefern eine Vielzahl von mitprotokollierten Daten und deren Analyse bis hin zur Beschreibung des möglichen Nachrichtenformats. Dafür herzlichen Dank, das hat mir viel Zeit gespart. Auch die Interface-Implementierung mit Hilfe eines ATmega328 und die Datenaufbereitung durch einen RasPi ist eine gelungene Referenz. Zwischendrin haben mich dann aber immer mal wieder Aussagen unsicher gemacht, die ich nicht nachvollziehen konnte. Dazu gehörten z. B. die Aussagen "Datenstick als Sackgasse herausgestellt" und "Leider stellte sich heraus, dass der Regler für den "zweiten Kanal" keinen Chip select herausführt." Der Interface-ATmega ist auch z.B. MISO nicht angeschlossen. Was ist mit den Daten, die die SunGo lesen will!!! Da ich diese Dinge nicht nachvollziehen kann habe ich mich entschlossen "meinen" Weg zu gehen und mir mit den Erkenntnissen der Artikel nur Gewissheit zu verschaffen, dass ich nicht in Fallen tappe, die bereits ausfindig gemacht wurden.

Vorbemerkungen

Im ersten Analyseschritt konzentriere ich mich ganz auf die Daten auf dem Datenstick. Wenn es gelingt das Datenformat zu "lesen" kann man daraus schließen welche Daten am Port der Steuerung übertragen werden und zwar in beide Richtungen! Es ist doch sehr erstaunlich, dass durch einen fehlenden Stick am Steckplatz der Steuerung und damit fehlender Parameter z.B. des Log-Intervalls, die Steuerung freiwillig trotzdem Daten an den Stick sendet. Die Analyse der Kommunikation der SunGo über den MiniDIN-Port kommt erst später, sobald die Daten des Datensticks interpretierbar sind.

Analyse

SunGoSXL AT45DB081D.png

Den Datenumfang sieht man am schönsten in der Datalog-Software (Datalogging Solareg II)

Datalogging-Software (V2.02.16) Menüstruktur:

Als Analysezeitraum diente eine Aufzeichnung vom 03.11. (Start 04:16 Uhr) bis 14.11. (Ende 12:56 Uhr). Zur Aufzeichnung stehen folgende Werte zu Verfügung:

  • Uhrzeit
  • T1 Kollektor °C
  • T2 Speicher unten
  • T3 Speicher oben
  • T4 Thermostat A
  • T5 Poolschutz
  • T6 Ertrag T
  • T7 Rücklaufanhebung T
  • T8 Rücklaufanhebung T
  • T9 T
  • Strahlung W/m²
  • Speicher kWh
  • Speicher h
  • Funktion aktiv 1
  • Funktion aktiv 2
  • Volumenstrom l/min

Wobei hier noch nicht deutlich erkennbar ist, ob gerade die Werte Strahlung und Speicher, Werte sind die in der Datalog-Software aufbereitet sind und sich somit gar nicht als Rohdaten auf dem Datenstick befinden.

Anzahl Datensätze: (Aufzeichnungsintervall 1 Minute)

  • 03.11. 1184
  • 04.11. 1440
  • 05.11. 1440
  • 06.11. 1440
  • 07.11. 1440
  • 08.11. 1440
  • 09.11. 1440
  • 10.11. 1440
  • 11.11. 1440
  • 12.11. 1440
  • 13.11. 1440
  • 14.11. 777 in Summe 16361 Einträge

Der benutzte Datenstick hat eine Größe von 8 Mbit. Die Funktion "Rohdaten Datastick lesen" erzeugt eine Datei namens "debug.bin" mit einer Größe von 2 MiB. Da kommen doch Zweifel auf, dass es sich wirklich um die Rohdaten auf dem Stick handelt.

Mein FlashCat-EEPROM-Programmer liefert den tatsächlichen Inhalt des EEPROMS. Und siehe da. Das was da in debug.bin drin steht ist nach meinem Verständnis gar kein "binärer" Inhalt, sondern eine TXT-Datei, die die hexadezimale Entsprechung der eigentlichen Binärdatei in ASCII enthält. Beispiel: In der Binärdatei steht HEX AA 55 01 05 ... Dies ist die hexadezimale Darstellung der Binärdaten 10101010 01010101 00000001 00001001 ... im EEPROM. Wenn man nun diese AA 55 01 05 (4 Byte) in ASCII codiert erhält man 61 61 35 35 30 31 30 35 (8 Byte).... Dadurch erklärt sich die doppelte Dateigröße. Die Verwendung eines solchen Formates (Codierung) erschließt sich mir nicht. NB: Endian habe ich nicht kontrolliert. Die Bin-Datei lässt Little-Endian vermuten. Ist aber eigentlich auch egal. Ich muss sowieso später im Ausleseprogramm individuell darauf reagieren.

Als Grundlage für die weitere Untersuchung dient natürlich jetzt die "korrekte" Bin-Datei.

Inhalt EEPROM

0000:0000 | AA 55 01 05 23 01 FF FF FF FF FF FF FF FF FF 01 | ŠU..#.ĸĸĸĸĸĸĸĸĸ. 0000:0010 | 20 57 61 67 6E 65 72 20 26 20 43 6F 20 20 00 00 | Wagner & Co .. 0000:0020 | 00 00 00 00 00 00 00 00 00 00 20 53 6F 6C 61 72 | .......... Solar 0000:0030 | 20 53 6F 6C 61 72 74 65 63 68 6E 69 6B 20 31 34 | Solartechnik 14 0000:0040 | 31 35 31 36 53 50 31 32 30 31 31 32 35 31 30 30 | 1516SP1201125100 0000:0050 | 20 20 53 79 73 74 65 6D 2D 4E 72 2E 20 20 04 BB | System-Nr. .ŧ 0000:0060 | 20 53 79 73 74 65 6D 2D 56 65 72 2E 20 20 00 66 | System-Ver. .f 0000:0070 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0080 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0090 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:00A0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:00B0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:00C0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:00D0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:00E0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:00F0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0100 | BF FF 7E FF F7 E7 DF FF FF FF FF FF FF FF FF FF | ŋĸ~ĸũįßĸĸĸĸĸĸĸĸĸ 0000:0110 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0120 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0130 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0140 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0150 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0160 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0170 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0180 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0190 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:01A0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:01B0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:01C0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:01D0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:01E0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:01F0 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0200 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸĸ 0000:0210 | 20 20 20 20 44 61 74 75 6D 20 20 20 20 20 00 08 | Datum .. 0000:0220 | 20 20 20 55 68 72 7A 65 69 74 20 20 20 20 00 09 | Uhrzeit .. 0000:0230 | 20 20 4B 6F 6C 6C 65 6B 74 6F 72 20 20 20 00 01 | Kollektor .. 0000:0240 | 20 20 53 70 65 69 63 68 65 72 20 B9 20 20 00 01 | Speicher đ .. 0000:0250 | 20 20 53 70 65 69 63 68 65 72 20 B3 20 20 00 01 | Speicher ģ .. 0000:0260 | 20 54 68 65 72 6D 6F 73 74 61 74 20 41 20 00 01 | Thermostat A .. 0000:0270 | 20 20 50 6F 6F 6C 73 63 68 75 74 7A 20 20 00 01 | Poolschutz .. 0000:0280 | 20 20 45 72 74 72 61 67 20 20 20 54 20 20 00 01 | Ertrag T .. 0000:0290 | 52 FC 63 6B 6C 2E 41 6E 68 2E 20 54 20 20 00 01 | Rückl.Anh. T .. 0000:02A0 | 52 FC 63 6B 6C 2E 41 6E 68 2E 20 54 20 20 00 01 | Rückl.Anh. T .. 0000:02B0 | 20 20 20 54 20 20 20 20 20 20 00 00 00 00 00 01 | T ...... 0000:02C0 | 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 00 | Dummy........... 0000:02D0 | 53 74 72 61 68 6C 75 6E 67 20 00 00 00 00 00 02 | Strahlung ...... 0000:02E0 | 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 00 | Dummy........... 0000:02F0 | 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 00 | Dummy........... 0000:0300 | 20 20 41 75 73 67 61 6E 67 20 31 20 20 20 00 0A | Ausgang 1 .. 0000:0310 | BF FF 3E FF E7 E7 DF FF 20 20 41 75 73 67 61 6E | ŋĸ>ĸįįßĸ Ausgan 0000:0320 | 67 20 32 20 20 20 00 0A 20 20 41 75 73 67 61 6E | g 2 .. Ausgan 0000:0330 | 67 20 33 20 20 20 00 0A 20 20 41 75 73 67 61 6E | g 3 .. Ausgan 0000:0340 | 67 20 34 20 20 20 00 0A 20 20 41 75 73 67 61 6E | g 4 .. Ausgan 0000:0350 | 67 20 35 20 20 20 00 0A 20 20 41 75 73 67 61 6E | g 5 .. Ausgan 0000:0360 | 67 20 36 20 20 20 00 0A 20 20 46 65 68 6C 65 72 | g 6 .. Fehler 0000:0370 | 20 20 00 00 00 00 00 0D 20 20 46 65 68 6C 65 72 | ...... Fehler 0000:0380 | 20 20 00 00 00 00 00 0D 20 20 46 65 68 6C 65 72 | ...... Fehler 0000:0390 | 20 20 00 00 00 00 00 0E 20 20 20 53 70 65 69 63 | ...... Speic 0000:03A0 | 68 65 72 20 20 20 00 07 44 75 6D 6D 79 00 00 00 | her ..Dummy... 0000:03B0 | 00 00 00 00 00 00 00 00 44 75 6D 6D 79 00 00 00 | ........Dummy... 0000:03C0 | 00 00 00 00 00 00 00 00 20 20 20 53 70 65 69 63 | ........ Speic 0000:03D0 | 68 65 72 20 20 20 00 0F 44 75 6D 6D 79 00 00 00 | her ..Dummy... 0000:03E0 | 00 00 00 00 00 00 00 00 44 75 6D 6D 79 00 00 00 | ........Dummy... 0000:03F0 | 00 00 00 00 00 00 00 00 46 75 6E 6B 74 69 6F 6E | ........Funktion 0000:0400 | 20 61 6B 74 69 76 00 0B 46 75 6E 6B 74 69 6F 6E | aktiv..Funktion 0000:0410 | 20 61 6B 74 69 76 00 0C BF FF 3E FF E7 E7 DF FF | aktiv..ŋĸ>ĸįįßĸ 0000:0420 | 20 56 6F 6C 75 6D 65 6E 73 74 72 6F 6D 20 00 13 | Volumenstrom .. 0000:0430 | 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 00 | Dummy........... 0000:0440 | 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 00 | Dummy........... 0000:0450 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:0460 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:0470 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:0480 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:0490 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:04A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:04B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:04C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:04D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:04E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:04F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:0500 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0000:0510 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C | ................ 0000:7F60 | BF FF 7E FF F7 E7 DF FF 4F 04 00 01 2E 00 E6 00 | ŋĸ~ĸũįßĸO.....æ. 0000:7F70 | 25 01 C4 09 C4 09 C4 09 0D 01 DE 00 A2 FE 00 00 | %.Ä.Ä.Ä...Þ.Ēþ.. 0000:7F80 | 00 00 00 00 00 00 00 00 00 00 00 64 00 15 15 08 | ...........d.... 0000:7F90 | 00 00 00 00 00 00 00 00 7D 01 00 00 00 00 01 00 | ........}....... 0000:7FA0 | 00 00 00 00 00 00 00 004F 04 01 01 2E 00 E6 00 | ........O.....æ. 0000:7FB0 | 25 01 C4 09 C4 09 C4 09 0D 01 DE 00 A2 FE 00 00 | %.Ä.Ä.Ä...Þ.Ēþ.. 0000:7FC0 | 00 00 00 00 00 00 00 00 00 00 00 64 00 15 15 08 | ...........d.... 0000:7FD0 | 00 00 00 00 00 00 00 00 7D 01 00 00 00 00 01 00 | ........}....... 0000:7FE0 | 00 00 00 00 00 00 00 00 4F 04 02 01 2E 00 E6 00 | ........O.....æ. 0000:7FF0 | 25 01 C4 09 C4 09 C4 09 0B 01 DF 00 A2 FE 00 00 | %.Ä.Ä.Ä...ß.Ēþ.. 0000:8000 | 00 00 00 00 00 00 00 00 00 00 00 64 00 15 15 08 | ...........d.... 0000:8010 | 00 00 00 00 00 00 00 00 7D 01 00 00 00 00 01 00 | ........}....... 0000:8020 | 00 00 00 00 00 00 00 00 4F 04 03 01 2E 00 E6 00 | ........O.....æ. 0000:8030 | 25 01 C4 09 C4 09 C4 09 0D 01 DE 00 A2 FE 00 00 | %.Ä.Ä.Ä...Þ.Ēþ.. 0000:8040 | 00 00 00 00 00 00 00 00 00 00 00 64 00 15 15 08 | ...........d.... 0000:8050 | 00 00 00 00 00 00 00 00 7D 01 00 00 00 00 01 00 | ........}....... 0000:8060 | 00 00 00 00 00 00 00 00 BF FF 7E FF F7 E7 DF FF | ........ŋĸ~ĸũįßĸ 0000:8070 | 4F 04 04 01 2E 00 E7 00 25 01 C4 09 C4 09 C4 09 | O.....į.%.Ä.Ä.Ä. 0000:8080 | 0D 01 DE 00 A2 FE 00 00 00 00 00 00 00 00 00 00 | ..Þ.Ēþ.......... 0000:8090 | 00 00 00 64 00 15 15 08 00 00 00 00 00 00 00 00 | ...d............ 0000:80A0 | 7D 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 | }............... 0000:80B0 | 4F 04 05 01 2E 00 E6 00 25 01 C4 09 C4 09 C4 09 | O.....æ.%.Ä.Ä.Ä. 0000:80C0 | 0C 01 DD 00 A2 FE 00 00 00 00 00 00 00 00 00 00 | ..Ý.Ēþ.......... 0000:80D0 | 00 00 00 64 00 15 15 08 00 00 00 00 00 00 00 00 | ...d............ 0000:80E0 | 7D 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 | }............... 0000:80F0 | 4F 04 06 01 2D 00 E6 00 24 01 C4 09 C4 09 C4 09 | O...-.æ.$.Ä.Ä.Ä. 0000:8100 | 0B 01 DD 00 A2 FE 00 00 00 00 00 00 00 00 00 00 | ..Ý.Ēþ.......... 0000:8110 | 00 00 00 64 00 15 15 08 00 00 00 00 00 00 00 00 | ...d............ 0000:8120 | 7D 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 | }............... 0000:8130 | 4F 04 07 01 2F 00 E6 00 26 01 C4 09 C4 09 C4 09 | O.../.æ.&.Ä.Ä.Ä. 0000:8140 | 0E 01 DE 00 A2 FE 00 00 00 00 00 00 00 00 00 00 | ..Þ.Ēþ.......... 0000:8150 | 00 00 00 64 00 15 15 08 00 00 00 00 00 00 00 00 | ...d............ 0000:8160 | 7D 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00 | }...............

In der Darstellung des BIN-Files musste ich etwas tricksen. Man erkennt den Sprung an Adresse 0000:0510 - 0000:7F60. Das kommt daher, dass ich die hier die passenden Daten zu der nachfolgenden Exportdatei zeigen will. Da die Daten im EEPROM in einem Ringpuffer-Verfahren abgelegt sind und in der Exportdatei chronologisch gezeigt werden, erklärt sich dass der älteste Eintrag im Ringpuffer in der Regel nicht am Anfang des EEPROM-Speichers abgelegt ist.


Die Binärdatei hat folgende Struktur:

Offset (hex) Offset (dez) Datenbytes Bemerkung
0x00000 0 AA 55 LI XX XX XX File Signatur erinnert an die Magic Number. Das dritte Byte ist das Logintervall.
0x00006 6 FF ... FF 01
0x00010 16 20 57 61 67 ... Wagner& Co ... System-Nr. und System-Version sind als 2 Byte Integer codiert
0x00100 256 8 Byte (Identifier ?)
0x00210 528 Kopfdaten (Kopfzeile Messwerte incl. Typ und Reihenfolge). Pro Eintrag 16 Bytes.
0x00520 In Blöcken von jeweils 264 Byte Daten (Datum (8 Byte) + 4 * Werte (64 Byte))


Was im Vergleich mit der auf hobbyelektronik.org veröffentlichen Binärdatei auffällt ist, dass der Wert 0x40 (64) in der Datalogging Software kein zulässiges LogIntervall ist. Es werden nur die Werte 1,2,5,10,15,20 und 30 Minuten vorgeschlagen. Die nächsten Bytes sind bei mir 05 23 01, in der Vergleichsdatei 05 24 01. Die darauf folgende Reihe von FF schließen mit 01 oder 00 ab. Ein weiterer großer Unterschied ist an Offset-Position 0000:0100 zu sehen. In meiner Binärdatei steht ab dieser Stelle ein 8 Byte (Zufallswert). Dieser Wert fehlt in der Vergleichsdatei. Der Grund liegt in der (Page-)Organisation des EEPROMs. Dort sind 256 bzw. 264 Bytes pro Page einstellbar. Die Differenz sind genau die fraglichen 8 Bytes. Aber egal ob sie nun mitgelesen/geschrieben werden, sie lassen sich leicht im Programm ausfiltern.

00000000 AA 55 40 05 24 01 FF FF FF FF FF FF FF FF FF 00 ªU@.$.ÿÿÿÿÿÿÿÿÿ. 00000010 20 20 57 61 67 6E 65 72 20 26 20 43 6F 20 00 00 Wagner & Co .. 00000020 00 00 00 00 00 00 00 00 00 00 20 53 6F 6C 61 72 .......... Solar 00000030 20 53 6F 6C 61 72 74 65 63 68 6E 69 6B 20 XX XX Solartechnik XX 00000040 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX 00000050 20 20 53 79 73 74 65 6D 2D 4E 72 2E 20 20 XX XX System-Nr. XX 00000060 20 53 79 73 74 65 6D 2D 56 65 72 2E 20 20 XX XX System-Ver. XX

Die darauf folgenden Kopfdaten haben immer 16 Bytes. Das zweitletzte Byte ist wohl immer 0x00 und stellt den Stringabschluss dar. Das letzte (16.) Byte ist der Typ des (Mess-)wertes.

  • 00 Dummy
  • 01 Temperatur
  • 02 (Strahlung) W/m²
  • 07 (Speicher) kWh
  • 08 Datum
  • 09 Uhrzeit
  • 0A Prozent
  • 0B (Funktion aktiv)
  • 0C (Funktion aktiv)
  • 0D (Fehler)
  • 0E (Fehler)
  • 0F (Speicher) h
  • 13 (Volumenstrom) l/min

Es werden folgende Werte geschrieben:

  1. Datum 2 Byte Little Endian uint16 Ob die führenden Nullen mit gerechnet werden muss ich noch testen. Sonst wäre z.B. 112 nicht eindeutig 1.12. oder 11.2.
  2. Uhrzeit 2 Byte Little Endian uint16 Anzahl der Minuten seit Mitternacht.
  3. Kollektor 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  4. Speicher unten 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  5. Speicher oben 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  6. Thermostat 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  7. Poolschutz 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  8. Ertrag 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  9. Rücklaufanhebung 1 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  10. Rücklaufanhebung 2 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
  11. T (?) 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle Zweier-Komplement
  12. Dummy 2 Byte 00 00
  13. Strahlung 2 Byte bei mir immer 00 00 , daher kann ich nicht kontrollieren
  14. Dummy 2 Byte 00 00
  15. Dummy 2 Byte 00 00
  16. Ausgang 1 1 Byte Prozent
  17. Ausgang 2 1 Byte Prozent
  18. Ausgang 3 1 Byte Prozent
  19. Ausgang 4 1 Byte Prozent
  20. Ausgang 5 1 Byte Prozent
  21. Ausgang 6 1 Byte Prozent
  22. Fehler 8 Byte bis Speicher
  23. Fehler
  24. Speicher
  25. Dummy 2 Byte 00 00
  26. Dummy 2 Byte 00 00
  27. Speicher (15) 2 Byte Little Endian uint16
  28. Dummy 2 Byte 00 00
  29. Dummy 2 Byte 00 00
  30. Funktion aktiv 2 Byte Little Endian uint16
  31. Funktion aktiv 2 Byte Little Endian uint16
  32. Volumenstrom 2 Byte Little Endian uint16
  33. Dummy 2 Byte 00 00
  34. Dummy 2 Byte 00 00


Die Exportdatei der Datalogging-Software dient als Abgleich.
;Datalogging
; Wagner & Co  
;
; Solartechnik 
1317SP1201105100
;  System-Nr.  	1211
; System-Ver.  	102
Datum	Uhrzeit	Kollektor	Speicher  unten	Speicher  oben	Thermostat A	Poolschutz	Ertrag   T	Rückl.Anh. T	Rückl.Anh. T	T	Strahlung	Ausgang 1	Ausgang 2	Ausgang 3	Ausgang 4	Ausgang 5	Ausgang 6	Speicher	Speicher	Funktion aktiv	Funktion aktiv	Volumenstrom
8	9	1	1	1	1	1	1	1	1	1	2	10	10	10	10	10	10	7	15	11	12	19

03.11.21	04:16:00	4.600	23.000	29.300	250.000	250.000	250.000	26.900	22.200	-35.000	0.000	0.000	0.000	0.000	0.000	0.000	100.000	0	381	0.100	0.000	0.000
03.11.21	04:17:00	4.600	23.000	29.300	250.000	250.000	250.000	26.900	22.200	-35.000	0.000	0.000	0.000	0.000	0.000	0.000	100.000	0	381	0.100	0.000	0.000
03.11.21	04:18:00	4.600	23.000	29.300	250.000	250.000	250.000	26.700	22.300	-35.000	0.000	0.000	0.000	0.000	0.000	0.000	100.000	0	381	0.100	0.000	0.000
03.11.21	04:19:00	4.600	23.000	29.300	250.000	250.000	250.000	26.900	22.200	-35.000	0.000	0.000	0.000	0.000	0.000	0.000	100.000	0	381	0.100	0.000	0.000
03.11.21	04:20:00	4.600	23.100	29.300	250.000	250.000	250.000	26.900	22.200	-35.000	0.000	0.000	0.000	0.000	0.000	0.000	100.000	0	381	0.100	0.000	0.000
...

Initialisierung Datenstick

Der Vorgang wird durch den entsprechenden Menüeintrag aufgerufen. In der Übersicht erkennt man, dass der Initialisierungsprozess ca. 16 Sekunden dauert. Die Unterbrechnung am Anfang bis ca. 8 Sekunden hat die Ursache in der Reaktion auf die Meldung, dass der Stick bereits eine Kennung besitzt und ob wirklich neu geschrieben werden soll.

Screenshot SunGo Datastick Initialisierung Overview.png

Man erkennt bei der Startabfrage die aktuelle Kennung AA 55 01 00 ab Offset 8 und BD FF 26 55 A5 05 94 2F AA 55 01 00 ( am Ende dann: DE EF 93 2A D2 82 CA 17 D5 2A 80 80 7F).

Screenshot SunGo Datastick Initialisierung Start.png

Die Erase-Methode ist hier das Block-Erase. Die 50h ist der Opcode gefolgt von der Blockadresse.

A block of eight pages can be erased at one time. This command is useful when large amountsof data has to be written into the device. This will avoid using multiple Page Erase Commands.To perform a block erase  for the DataFlash standard page size (264-bytes), an opcode of 50Hmust be loaded into the device, followed by three address bytes comprised of three don’t carebits, nine page address bits (PA11 -PA3) and 12 don’t care bits. The nine page address bits areused to specify which block of eight pages is to be erased. To perform a block erase for thebinary page size (256-bytes), the opcode 50H must be loaded into the device, followed by threeaddress bytes consisting of four don’t care bits, nine page address bits (A19 - A11) and 11 don’tcare bits. The nine page address bits are used to specify which block of eight pages is to beerased. When a low-to-high transition occurs on the CS pin, the part will erase the selectedblock of eight pages. The erase operation is internally self-timed and should take place in a max-imum time of tBE. During this time, the status register will indicate that the part is busy.

Screenshot SunGo Datastick Initialisierung Erase.png

Die letzte Blockadresse die gelöscht wird ist 1F F0 00. Dann folgt noch ein Main Memory Page Program Through Buffer 1 82h und ein Main Memory Page Read D2h

Screenshot SunGo Datastick Initialisierung End.png

LogIntervall setzen

Das LogIntervall setzen besteht wirklich nur im Verändern des Wertes nach AA 55. Hier in diesem Fall 1E für 30 Minuten.

Screenshot SunGo Datastick LogIntervall setzen.png

Delay ermitteln

SunGo Software Screenshot Lesegeschwindigkeit.png

Screenshot SunGo Lesegeschwindigkeittest.png

SunGo Software Screenshot Lesegeschwindigkeit Delay.png

Datenstick Rohdaten

TODO

Datenstick löschen

TODO

Arduino als SPI-Master

Datastick Adapter

Als erste Quelle habe ich https://www.arduino.cc/en/Tutorial/SPIEEPROM benutzt. Ich hatte mir für den Anschluss von DigiAnalyzer auf die Schnelle einen Adapter gebastelt. Leider hat er am orginal Interface seinen Dienst versagt. Ich gehe von Laufzeitproblemen aus. Er bekommt eine zweite Chance als Brücke zum Arduino.

SPI Master EEPROM
 1 #define DATAOUT 11//MOSI
 2 #define DATAIN  12//MISO
 3 #define SPICLOCK  13//sck
 4 #define SLAVESELECT 10//ss
 5 //opcodes
 6 #define WREN  6
 7 #define WRDI  4
 8 #define RDSR  5
 9 #define WRSR  1
10 #define READ  3
11 #define WRITE 2
12 byte eeprom_output_data;
13 byte eeprom_input_data=0;
14 byte clr;
15 int address=0;
16 //data buffer
17 char buffer [128];
18 void fill_buffer()
19 {
20   for (int I=0;I<128;I++)
21   {
22     buffer[I]=I;
23   }
24 }
25 char spi_transfer(volatile char data)
26 {
27   SPDR = data;                    // Start the transmission
28   while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
29   {
30   };
31   return SPDR;                    // return the received byte
32 }
33 void setup()
34 {
35   Serial.begin(9600);
36   pinMode(DATAOUT, OUTPUT);
37   pinMode(DATAIN, INPUT);
38   pinMode(SPICLOCK,OUTPUT);
39   pinMode(SLAVESELECT,OUTPUT);
40   digitalWrite(SLAVESELECT,HIGH); //disable device
41   // SPCR = 01010000
42   //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
43   //sample on leading edge of clk,system clock/4 rate (fastest)
44   SPCR = (1<<SPE)|(1<<MSTR);
45   clr=SPSR;
46   clr=SPDR;
47   delay(10);
48   //fill buffer with data
49   fill_buffer();
50   //fill eeprom w/ buffer
51   digitalWrite(SLAVESELECT,LOW);
52   spi_transfer(WREN); //write enable
53   digitalWrite(SLAVESELECT,HIGH);
54   delay(10);
55   digitalWrite(SLAVESELECT,LOW);
56   spi_transfer(WRITE); //write instruction
57   address=0;
58   spi_transfer((char)(address>>8));   //send MSByte address first
59   spi_transfer((char)(address));      //send LSByte address
60   //write 128 bytes
61   for (int I=0;I<128;I++)
62   {
63     spi_transfer(buffer[I]); //write data byte
64   }
65   digitalWrite(SLAVESELECT,HIGH); //release chip
66   //wait for eeprom to finish writing
67   delay(3000);
68   Serial.print('h',BYTE);
69   Serial.print('i',BYTE);
70   Serial.print('\n',BYTE);//debug
71   delay(1000);
72 }
73 byte read_eeprom(int EEPROM_address)
74 {
75   //READ EEPROM
76   int data;
77   digitalWrite(SLAVESELECT,LOW);
78   spi_transfer(READ); //transmit read opcode
79   spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
80   spi_transfer((char)(EEPROM_address));      //send LSByte address
81   data = spi_transfer(0xFF); //get data byte
82   digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
83   return data;
84 }
85 void loop()
86 {
87   eeprom_output_data = read_eeprom(address);
88   Serial.print(eeprom_output_data,DEC);
89   Serial.print('\n',BYTE);
90   address++;
91   if (address == 128)
92     address = 0;
93   delay(500); //pause for readability
94 }

Jetzt das Ganze entsprechend anpassen. Erst mal nur lesender Zugriff.

SPI Master EEPROM
  1 // Anschluesse kann man so lassen
  2 #define DATAOUT 11//MOSI
  3 #define DATAIN  12//MISO
  4 #define SPICLOCK  13//sck
  5 #define SLAVESELECT 10//ss
  6 
  7 // Opcodes muessen angepasst werden
  8 #define MainMemoryPageRead  210 // D2h
  9 // weitere folgen
 10 
 11 byte eeprom_output_data;
 12 byte eeprom_input_data=0;
 13 byte clr;
 14 int address=0;
 15 
 16 //data buffer auf Pagegroesze setzen 
 17 char buffer [264];
 18 
 19 // die Buffer Obergrenze anpassen
 20 void fill_buffer(){
 21   for (int i=0;i<buffer.length();i++){
 22     buffer[i]=0;
 23   }
 24 }
 25  
 26 char spi_transfer(volatile char data){
 27   SPDR = data;                    // Start the transmission
 28   while (!(SPSR & (1<<SPIF)))  {     // Wait the end of the transmission
 29 
 30   };
 31   return SPDR;                    // return the received byte
 32 }
 33 
 34 //READ EEPROM
 35 byte read_eeprom(int address){
 36   int data;
 37   digitalWrite(SLAVESELECT,LOW);
 38    spi_transfer(READ); //transmit read opcode
 39    spi_transfer((char)(address>>8));   //send MSByte address first
 40    spi_transfer((char)(address));      //send LSByte address
 41    data = spi_transfer(0xFF); //get data byte
 42   digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
 43   return data;
 44 }
 45 
 46 void setup(){
 47   Serial.begin(9600);
 48 
 49   pinMode(DATAOUT, OUTPUT);
 50   pinMode(DATAIN, INPUT);
 51   pinMode(SPICLOCK,OUTPUT);
 52   pinMode(SLAVESELECT,OUTPUT);
 53   digitalWrite(SLAVESELECT,HIGH); //disable device
 54   // SPCR = 01010000
 55   //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
 56   //sample on leading edge of clk,system clock/4 rate (fastest)
 57   SPCR = (1<<SPE)|(1<<MSTR);
 58   clr=SPSR;
 59   clr=SPDR;
 60 
 61   delay(10);
 62 
 63   //fill buffer with data
 64   fill_buffer();
 65  
 66  //fill eeprom w/ buffer
 67   digitalWrite(SLAVESELECT,LOW);
 68 
 69   spi_transfer(WREN); // 
 70   digitalWrite(SLAVESELECT,HIGH);
 71 
 72   delay(10);
 73 
 74   digitalWrite(SLAVESELECT,LOW);
 75   spi_transfer(WRITE); //write instruction
 76   address=0;
 77   spi_transfer((char)(address>>8));   //send MSByte address first
 78   spi_transfer((char)(address));      //send LSByte address
 79   //write 128 bytes
 80   for (int i=0;i<128;i++){
 81     spi_transfer(buffer[i]); //write data byte
 82   }
 83 
 84   digitalWrite(SLAVESELECT,HIGH); //release chip
 85   //wait for eeprom to finish writing
 86 
 87   delay(3000);
 88 
 89   Serial.print('h',BYTE);
 90   Serial.print('i',BYTE);
 91   Serial.print('\n',BYTE);//debug
 92   delay(1000);
 93 }
 94 
 95 void loop(){
 96   eeprom_output_data = read_eeprom(address);
 97   Serial.print(eeprom_output_data,DEC);
 98   Serial.print('\n',BYTE);
 99   address++;
100   if (address == 264)
101     address = 0;
102   delay(500); //pause for readability
103 }

Arduino als SPI-Slave

In SPI slave mode, the control logic will sample the incoming signal of the SCK pin. To ensure correct sampling of the clock signal, the minimum low and high periods should be:Low periods: Longer than 2 CPU clock cycles.High periods: Longer than 2 CPU clock cycles.

Diese Aussage macht mir noch etwas Sorgen. Ich habe die Taktrate am SCK noch nicht an der Steuerung nachgemessen. Der eingesetzte AT45DB081D verträgt Frequenzen bis 66 MHz. Damit wäre der Atmega völlig überfordert. Allerdings bezieht sich diese Angabe auf lesenden Zugriff. Im SPI-Slave-Betrieb will ich ja die schreibenden Zugriffe der Steuerung entgegnehmen. Will ich mal hoffen, dass die Steuerung es eher gemächlich mag. Dass es bei hobbyelektronik.org scheinbar mit einem ATmega328 geklappt hat, lässt hoffen.

Request for Comments


Kommentar hinzufügen
TippvomTibb freut sich über alle Kommentare. Sofern du nicht anonym bleiben möchtest, registriere dich bitte oder melde dich an.

Quellen

https://github.com/chris-heo/pirozeda