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 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 vorstelle, es 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 auszen 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.

Ergänzung nach fortgeschrittener Entwicklung: Meine weiter oben dargestellten Bedenken haben sich eigentlich in Luft aufgelöst. Der Datenstick ist in sofern ein Sackgasse, da es nicht notwendig ist die SungoSXL zu bewegen den Datenstick zu beschreiben, da (alle) die notwendigen Daten zweimal auf dem SPI anliegen. Ein mögliche Erklärung ist schnell gefunden. An dem nach außen geführten SPI hängt intern wenigstens ein weiterer Client, dessen #CS (leider) nicht nach außen geführt ist. Somit kann man am MOSI die Daten mitlauschen. Für die Datenaufbereitung ist allerdings die Analyse der Datenspeicherung auf dem Datastick von (entscheidender) Bedeutung. Den (außen) fehlenden ChipSelect habe ich virtuell durch eine Timingroutine erzeugt. Ich gebe zu, dass ich mit meiner derzeitigen Lösung, die zwar funktioniert, eigentlich nicht glücklich bin. Kurz gesagt, ich würde die Daten lieber schön nach jedem Paket in der Datenlücke per seriellem Interface an den PC übertragen. Dumm ist halt nur, dass man die Lücke nicht richtig findet. Da muss ich mir noch was ausdenken, aber dazu unten mehr.

Datastick 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 00 4F 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 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 (0D) X Byte
  23. Fehler (0D) X Byte
  24. Fehler (0E) Y Byte X+X+Y = 8
  25. Speicher (07)
  26. Dummy (00) 2 Byte 00 00
  27. Dummy (00) 2 Byte 00 00
  28. Speicher (15) 2 Byte Little Endian uint16
  29. Dummy (00) 2 Byte 00 00
  30. Dummy (00) 2 Byte 00 00
  31. Funktion aktiv (11) 2 Byte Little Endian uint16
  32. Funktion aktiv (12) 2 Byte Little Endian uint16

AB Byte 60 gibt es keinen Hinweis mehr im Typ 0301

  1. Volumenstrom 2 Byte Little Endian uint16
  2. Dummy 2 Byte 00 00
  3. Dummy 2 Byte 00 00
  4. (Checksumme ?) 2 Byte
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 (User-)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

Steuerung Analyse

Zu Beginn der Analyse der Steuerung gleich etwas Beruhigendes. Der SPI-Takt (5 us/200 kHz) der Steuerung ist gemütlich. Die Bits werden auf der Mitte (fallende Flanke) des Taktes übernommen. Als Grundlage diente mir ein knapp 20 Sekunden langer Mitschnitt.

SunGo Steuerung Screenshot 20Sekunden Sample.png

Der Zyklus wiederholt sich jede Sekunde. Es kommen 5 Doppelpakete (DPA) mit einem Abstand von 200 ms. Je nachdem wie man den Anfang festlegt, kommen bevor der Zyklus von neuem beginnt in der 146ms Lücke noch ein Doppelpaket (DPB) und die EEPROM-Abfrage.

SunGo Steuerung Screenshot Pulseview Overview.png

Refresh: 200ms

DPA_1 ist ein AA 55 55 AA 02 00 17x AA 16x AA

DPA_2 ist ein AA 55 55 AA 01 00 und enthält die Daten für das Display.

SunGo Steuerung Screenshot Pulseview Paketabstaende.png

  • DPA_1 (AB): 3,5ms
  • P (BC): 46,5ms (AC): 50ms
  • DPA_2 (CD): 4,4ms
  • P (DE): 145,6ms (CE): 150ms
  • Periode (AE): 200ms

Refresh: 1s

DPB_1 ist ein AA 55 55 AA 03 01 Inhalt noch nicht untersucht

DPB_2 ist ein AA 55 55 AA 03 00 Nutzdaten

SunGo Screenshot Datenpaket B.png

Nach jedem fünften DPA_2 folgt

  • Pause 21ms
  • DPB_1 5ms
  • Pause 15ms
  • DPB_2 5ms
  • Pause 10ms
  • EEPROM 2ms
  • Pause 88ms

DPA_1:"kleines" Paket (AB): 320us: AA 55 55 AA 02 00 (P970us) 1100us: 17*AA (P67us) 1033us:16*AA gesamt:3491us dann Abstand 46ms Pause: 50ms

DPA_2:"großes" Paket (CD) 320us: AA 55 55 AA 01 00 (P290us) 3787us: 64 Byte (10P=592us) gesamt:4387us

Vor dem CS (Periodendauer: 1000ms) kommt immer noch ein weiteres Doppelpaket dazwischen

  • 0s: DPA (+DPB+EEPROM-Abfrage in der 145,6ms Lücke)
  • 200ms: DPA
  • 400ms: DPA
  • 600ms: DPA
  • 800ms: DPA
  • 1000ms: next Cycle


Inhalt der "Nicht-EEPROM" Pakete

Daten der Pakete ohne EEPROM Chip Select

Zeile 5924 AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 03 01 0D 11 04 08 52 FC 63 6B 6C 2E 41 6E 68 2E 20 54 20 20 01 09 52 FC 63 6B 6C 2E 41 6E 68 2E 20 54 20 20 01 0A 20 20 20 54 20 20 20 20 20 20 00 00 00 00 01 0B 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 00 23 4C AA 55 55 AA 03 00 20 00 35 01 1B 04 7D 00 18 01 1D 01 C4 09 C4 09 C4 09 23 01 2D 01 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 08 00 00 00 00 00 00 00 00 FD 38 00 00 00 00 01 00 00 00 00 00 00 00 00 00 20 0A

Zeile 18438 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 03 01 0D 11 04 0C 53 74 72 61 68 6C 75 6E 67 20 00 00 00 00 02 0D 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 0E 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 0F 20 20 41 75 73 67 61 6E 67 20 31 20 20 20 0A 00 23 2E AA 55 55 AA 03 00 20 00 35 01 1B 04 7D 00 18 01 1D 01 C4 09 C4 09 C4 09 23 01 2D 01 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 08 00 00 00 00 00 00 00 00 FD 38 00 00 00 00 01 00 00 00 00 00 00 00 00 00 20 0A

Zeile 30952 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 35 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 AA 55 55 AA 03 01 0D 11 04 10 20 20 41 75 73 67 61 6E 67 20 32 20 20 20 0A 11 20 20 41 75 73 67 61 6E 67 20 33 20 20 20 0A 12 20 20 41 75 73 67 61 6E 67 20 34 20 20 20 0A 13 20 20 41 75 73 67 61 6E 67 20 35 20 20 20 0A 00 23 99 AA 55 55 AA 03 00 20 00 35 01 1B 04 7D 00 18 01 1C 01 C4 09 C4 09 C4 09 22 01 2D 01 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 08 00 00 00 00 00 00 00 00 FD 38 00 00 00 00 01 00 00 00 00 00 00 00 00 00 20 08

Zeile 43466 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 03 01 0D 11 04 14 20 20 41 75 73 67 61 6E 67 20 36 20 20 20 0A 15 20 20 46 65 68 6C 65 72 20 20 00 00 00 00 0D 16 20 20 46 65 68 6C 65 72 20 20 00 00 00 00 0D 17 20 20 46 65 68 6C 65 72 20 20 00 00 00 00 0E 00 23 0B AA 55 55 AA 03 00 20 00 35 01 1B 04 7D 00 18 01 1C 01 C4 09 C4 09 C4 09 22 01 2D 01 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 08 00 00 00 00 00 00 00 00 FD 38 00 00 00 00 01 00 00 00 00 00 00 00 00 00 20 08

Zeile 55980 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 03 01 0D 11 04 18 20 20 20 53 70 65 69 63 68 65 72 20 20 20 07 19 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 1A 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 1B 20 20 20 53 70 65 69 63 68 65 72 20 20 20 0F 00 23 BF AA 55 55 AA 03 00 20 00 35 01 1B 04 7D 00 18 01 1C 01 C4 09 C4 09 C4 09 22 01 2D 01 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 08 00 00 00 00 00 00 00 00 FD 38 00 00 00 00 01 00 00 00 00 00 00 00 00 00 20 08

Zeile 68494 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 02 00 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E 34 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 AA 55 55 AA 03 01 0D 11 04 1C 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 1D 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 1E 46 75 6E 6B 74 69 6F 6E 20 61 6B 74 69 76 0B 1F 46 75 6E 6B 74 69 6F 6E 20 61 6B 74 69 76 0C 00 23 04 AA 55 55 AA 03 00 20 00 35 01 1B 04 7C 00 17 01 1C 01 C4 09 C4 09 C4 09 21 01 2D 01 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 08 00 00 00 00 00 00 00 00 FD 38 00 00 00 00 01 00 00 00 00 00 00 00 00 00 20 05

Mann kann in den Paketen "Steuersequenzen" ausmachen. Sie werden durch 'AA 55 55 AA' eingeleitet und von einem Selektor (2 Byte ?) 01 00, 02 00, 03 00 und 03 01 gefolgt.

Hier die sind Beipieldaten sortiert nach den Selektoren:

AA 55 55 AA 01 00 20 20 53 70 65 69 63 68 65 72 20 DE 20 20 20 20 32 38 2E (35 oder 34) 01 43 20 20 20 31 36 20 05 2D 01 43 2D 06 31 30 35 20 01 01 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  (61 bei 34 und 62 bei 35)
                       S  p  e  i  c  h  e  r      ^             2  8  .   5       4    °  C          1  6        -  °  C  -     1  0  5      

Der '01 00' spricht das Display an.

AA 55 55 AA 02 00 33xAA

Der '02 00' hat "keinen" Inhalt.

AA 55 55 AA 03 00 Einleitung 20 00 (64 Nutzbytes)  35 01 1B 04 7C 00 17 01 1C 01 C4 09 C4 09 C4 09 21 01 2D 01 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 15 08 00 00 00 00 00 00 00 00 FD 38 00 00 00 00 01 00 00 00 00 00 00 00 00 00  Abschluss 20 05
                                                  Datum Uhrzeit
                                                  09.03. 17:31
Datensatz aus dem Stick:                           4F 04 03 01 2E 00 E6 00 25 01 C4 09 C4 09 C4 09 0D 01 DE 00 A2 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 64 00 15 15 08 00 00 00 00 00 00 00 00 7D 01 00 00 00 00 01 00 00 00 00 00 00 00 00 00

Der '03 00' ist der Interessante. Beim Vergleich der Nutzdaten mit dem Speicherstickinhalt-Datensatz sieht man die Übereinstimmung des Aufbaus. SUPER! Dann kann man sich die Emulation des Stick sparen und durch sniffen und einem Selektorscan nach '03 00' hat man das gleiche Ergebnis! Das einzige Problem ist das fehlende ChipSelect zu diesen Datenpaketen.

AA 55 55 AA 03 01 0D 11 04  (67 Byte)  
                           1C 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 
                           1D 44 75 6D 6D 79 00 00 00 00 00 00 00 00 00 00 
                           1E 46 75 6E 6B 74 69 6F 6E 20 61 6B 74 69 76 0B 
                           1F 46 75 6E 6B 74 69 6F 6E 20 61 6B 74 69 76 0C 
                           00 23 04

Die Bedeutung des '03 01' Datensatzes habe ich noch nicht untersucht. Nachtrag: Der Datensatz 0301 enthält die übermittelten Datenfelder (Klartext) des Datensatzes 0300. Dann ergibt es auch einen Sinn wenn 0301 immer vor 0300 gesendet wird.


Um den Arduino im Sniffing-Mode und nicht im Emulator-Mode zu betreiben ist das Timing der Pakete hilfreich. Durch das fehlende Chipselect ist man gezwungen irgendwie einen Rhythmus oder Trigger im Ausleseprogramm zu implementieren.

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.

The following code examples show how to initialize the SPI as a master and how to perform a simple transmission. DDR_SPI in the examples must be replaced by the actual data direction register controlling the SPI pins. DD_MOSI, DD_MISO and DD_SCK must be replaced by the actual data direction bits for these pins. E.g. if MOSI is placed on pin PB5, replace DD_MOSI with DDB5 and DDR_SPI with DDRB.
 1 void SPI_MasterInit(void){
 2  /* Set MOSI and SCK output, all others input */
 3  DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
 4  /* Enable SPI, Master, set clock rate fck/16 */
 5  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
 6 }
 7 
 8 void SPI_MasterTransmit(char cData){
 9  /* Start transmission */
10  SPDR = cData;
11  /* Wait for transmission complete */
12  while(!(SPSR & (1<<SPIF)));
13 }

Bei dem Beispiel aus dem Atmega328 Manual fehlt (natürlich) noch ein bisschen was. Fassen wir mal zusammen was zu tun ist.

  1. Die vier I/Os (MISO, MOSI, SCK, /SS) entsprechend Master-Mode setzen. (siehe Tabelle)
  2. Die 8 Schalter im SPCR und SPI2X im SPSR setzen.
  3. Den globalen Interrupt setzen (SEI). Bräuchte man im Master-Mode eigentlich nicht. Ich gehe auf Nummer sicher und lasse eine Interrupt-Routine zur Kontrolle mitlaufen.
  4. Pollen von WCOL
  5. Schreiben eines Bytes, evtl. als Unterroutine einer Transferfunktion.

Beispiel 1

PinDirection Master SPIDirection Slave SPI
MOSI User defined (Output) Input
MISO Input User defined (Output)
SCK User defined (Output) Input
SS User defined (Output or Input) Input

Anhand der Tabelle erkennt man, dass man als Nutzer selbst dafür Sorge tragen muss die Richtungen der I/Os richtig zu setzen.

When the SPI is enabled, the data direction of the MOSI, MISO, SCK, and SS pins is overridden according to the table.
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 }

Beispiel 2

Für meinen Test habe ich es mir etwas einfacher gemacht und die SPI-Library benutzt. Ich habe soweit alles kommentriert. Die nächsten Erweiterungen wären vielleicht:

  1. Weitere Opcodes
  2. Tastencodes interpretieren und daraus den Index auf das Opcode-Array bestimmen
  3. define DEBUG
  4. erweitern des Opcode-Arrays, nicht nur Transferleaenge, sondern "richtige" Aufteilung Opcode,<Adresse>,Antwort ->Gesamttransferlaenge daraus berechnen
  5. Buffer an Gesamtlaenge anpassen
  6. Interpetieren des Status und Ausgabe in Klartext
  7. Aufforderung zur Eingabe
  8. Hilfetext beim Start im Terminal
  9. Begrenzen der Ausgabe auf die Nutzbytes
  10. ...
SPI Master EEPROM
 1 #include <Arduino.h>
 2 
 3 #include<SPI.h>                             //Library fuer SPI
 4 
 5 #define MAXCOMBYTES 10
 6 
 7 //AT45DB081D Standard parts are shipped with the page size set to 264-bytes. The user is able to configure these parts to a 256-byte page size if desired
 8 unsigned char opcodes[][2]={
 9 {215,2}, // D7 Status Register Read
10 {159,4} // 9F Manufacturer and Device Read
11 };
12 unsigned char serialBuffer[MAXCOMBYTES];
13 
14 byte index=0;
15 
16 const int slaveSelectPin = 10;            // /SS bzw /CS ist an PIN 10 (PB2) angeschlossen
17 
18 void setup (void){
19   Serial.begin(115200);                   // Serielle Kommunikation vorbereiten
20   Serial.println("Master to EEPROM");     // schon mal was ausgeben, dass man sieht das es lebt
21 
22   SPI.begin();                            // SPI Kommunikation vorbereiten
23   SPI.setClockDivider(SPI_CLOCK_DIV8);    // Da das EEPROM bis 66 MHz verträgt kann man hier nix falsch machen (16/8=2Mhz)
24   pinMode(slaveSelectPin,OUTPUT);         // ist nicht notwendig wird in SPI.begin erledigt
25   digitalWrite(slaveSelectPin,HIGH);      // den SPI Slave "abschalten"
26 }
27 
28 void loop(void){
29   byte j; //Laufvariable keine weitere Bedeutung
30   //char *hexbyte="abcdefghij"; // in C++ nicht erlaubt
31   char outstr[5];  // outstr als pointer auf einen string nach dem Muster '0X## '
32   byte serialIncomingByte = 0; // zum Einlesen der Tastatureingaben ueber die serielle Schnittstelle
33   byte transferlength = 0; // Gesamtlaenge der Uebertragung OpCode+<Adresse>+Antwort
34 
35   if (Serial.available() > 0) { // nur reagieren wenn eine Taste im seriellen Terminal gedrueckt wurde
36     serialIncomingByte = Serial.read(); // einlesen der Taste, derzeit nur 1 und 2 erlaubt
37     sprintf(outstr,"%d ",serialIncomingByte);
38     Serial.println(outstr);
39 
40     for (index=0;index<MAXCOMBYTES;index++){
41       serialBuffer[index]='\0';
42     }
43 
44     if (serialIncomingByte==49){ // Taste 1 gedrueckt
45       serialBuffer[0]=opcodes[0][0];
46       transferlength=opcodes[0][1];
47     }
48     if (serialIncomingByte==50){ // Taste 2 gedrueckt
49       serialBuffer[0]=opcodes[1][0];
50       transferlength=opcodes[1][1];
51     }
52     Serial.print("Gesendet: ");
53     for(j=0;j<MAXCOMBYTES;j++){
54       sprintf(outstr,"0x%02X ",serialBuffer[j]);
55       Serial.print(outstr);
56     }
57     Serial.println();
58     digitalWrite(slaveSelectPin,LOW);
59     SPI.transfer(serialBuffer,transferlength);
60     digitalWrite(slaveSelectPin,HIGH);
61 
62     Serial.print("Empfangen: ");
63     for(j=0;j<MAXCOMBYTES;j++){
64       sprintf(outstr,"0x%02X ",serialBuffer[j]);
65       Serial.print(outstr);
66     }
67     Serial.println();
68 
69   }
70 
71 }

Ausgabe nach betätigen der Tasten 2 und 1:

Gesendet: 0x9F 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Empfangen: 0x9F 0x1F 0x25 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Gesendet: 0xD7 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Empfangen: 0xD7 0xA4 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

Screenshot PulseView SPI EEPROM 1.png Screenshot PulseView SPI EEPROM 2.png

Aus der Statusmeldung kann man ablesen, dass das EEPROM im 264-Byte-PageSize-Modus (Bit 0 = 0) arbeitet. Das erklärt vielleicht auch warum in den Beispielen von .org die 8 Byte zu Beginn jeder Page fehlen, wenn das verwendete EEPROM im 256-Byte Modus gearbeitet hat. Ob die Steuerung, dieses ausliest und darauf regiert muss ich noch feststellen. (Bug or Feature?)

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.

Wie weiter oben bereits erwähnt. Habe ich nachgemessen und den Takt der Steuerung mit 200 kHz festgestellt. Also ist die Geschwindigkeit des Arduino völlig ausreichend. Man könnte sogar auf die SPI-Schnittstelle verzichten.

Sniffing-Mode

1. Versuch

Bei diesem Versuch erzeugt sich der Mikrocontroller sein SlaveSelect selbst. Der SS (PIN10) wird auf einen anderen Output-Pin verbunden, der vom Programm nach bestimmen Kriterien geschaltet wird.

Programmablauf:

  • warte auf eine Lücke (SCK low), die länger als 88 ms (< 146 ms) dauert.
  • setzte den Pseudo-SS auf low.
  • lese SPI
  • Endlosschleife

Das Warten auf die Lücke kann man sich vermutlich sogar ganz sparen. Da die Bytesequenz 'AA 55 55 AA' einen Datensatz ankündigt kann man man ein SPI-Dauerlesen einrichten und warten bis die Startsequenz "vorbeikommt" und alle nachfolgenden Bytes in den Puffer schreiben. Ein Lücke, die dann länger als 10 ms ist gibt den Trigger zur Verarbeitung. Sollten die 10 ms zur Verarbeitung nicht ausreichen könnte man den EEPROM-SS als Trigger nehmen. Wenn also EEPROM-SS kommt, SPI anhalten und die Verarbeitung starten. Dann hätte man 88 ms zur Verarbeitung, das sollte für den ersten Versuch reichen.

Verdeutlichung

Der ATmega soll als Interface zwischen dem SPI-Port der SunGoSXL und einer seriellen Verbindung (auch über SER2USB-Adapter an USB) eines Auswerte-Systems (Raspi, PC, ...) dienen. Dazu sind im Wesentlichen 2 Programmroutinen notwendig. Eine Sniffer-Routine, die die SPI-Daten aufnimmt und in einem Puffer ablegt und eine zweite Routine die regelmäßig (Sekundentakt?) die Pufferdaten über die serielle Schnittstelle weiterreicht. Die Aufnahme und Abgabe sind leicht zu implementieren, das passende Timing ist eine Herausforderung. Da ich keine Lust habe, das ganze in Assembler zu schreiben, da hätte ich ja die volle Kontrolle über die Timer und Interruptabläufe, wollte ich doch bei C bleiben. Das Problem sei kurz geschildert. Sobald man mehr als eine Library benutzt hat man kaum noch eine Kontrolle über die Nutzung der Hardwareresourcen eines Mikrocontrollers. Vorausgesetzt, die Libraries sind sauber implementiert wird aber durch das harmonische Nebeneinander automatisch eine Programm-Overhead (oft über 80%) erzeugt, der Echtzeitanwendungen das Leben schwer macht. Ein Methode, die ich schon praktiziert habe ist, den Code per C zu erzeugen und dann den daraus gewonnen Assembler-Code zu bereinigen. Das erspart das mühsame Assembler from the scratch.

Also was ist zu tun?

Grob gesagt haben wir im Sekundentakt (bietet sich durch das EEPROM-CS an) insgesamt x Pakete einzulesen, in den Puffer zu schreiben und seriell auszugeben.

Sungo Gesamtpakete Timing.png

Sungo Gesamtpakete Tabelle.png

Emulator-Mode

Diese Version verfogle ich erst weiter, sobald der Sniffing-Mode kein befriedigendes Ergebnis liefert.

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