Solarthermie SunGo SXL: Unterschied zwischen den Versionen
Zeile 467: | Zeile 467: | ||
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 | 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 | + | 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. | Das einzige Problem ist das fehlende ChipSelect zu diesen Datenpaketen. | ||
Aktuelle Version vom 18. September 2021, 13:07 Uhr
Suchwort: Prozeda
Inhaltsverzeichnis
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
Den Datenumfang sieht man am schönsten in der Datalog-Software (Datalogging Solareg II)
Datalogging-Software (V2.02.16) Menüstruktur:
- Datei
- Lese Datastick (STRG-L)
- Öffnen (STRG-O)
- Initialisiere Datastick (Initialisierung Datenstick)
- Log-Intervall setzen (LogIntervall setzen)
- Speichern
- Drucken..
- Beenden
- Optionen
- Sprache
- Auslesegeschwindigkeit anpassen (Delay ermitteln)
- Rohdaten Datastick lesen (Datenstick Rohdaten)
- Datastick löschen (Datenstick löschen)
- Bezeichnungsänderungen löschen
- Schreiben des Datasticks ermöglichen (?)
- Ertrag dokumentieren
- Hilfe
- Inhalt...
- Über..
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.
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:
- 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.
- Uhrzeit 2 Byte Little Endian uint16 Anzahl der Minuten seit Mitternacht.
- Kollektor 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- Speicher unten 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- Speicher oben 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- Thermostat 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- Poolschutz 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- Ertrag 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- Rücklaufanhebung 1 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- Rücklaufanhebung 2 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle
- T (?) 2 Byte Little Endian uint16 Teiler 10 damit 1 Nachkommastelle Zweier-Komplement
- Dummy 2 Byte 00 00
- Strahlung 2 Byte bei mir immer 00 00 , daher kann ich nicht kontrollieren
- Dummy 2 Byte 00 00
- Dummy 2 Byte 00 00
- Ausgang 1 1 Byte Prozent
- Ausgang 2 1 Byte Prozent
- Ausgang 3 1 Byte Prozent
- Ausgang 4 1 Byte Prozent
- Ausgang 5 1 Byte Prozent
- Ausgang 6 1 Byte Prozent
- Fehler (0D) X Byte
- Fehler (0D) X Byte
- Fehler (0E) Y Byte X+X+Y = 8
- Speicher (07)
- Dummy (00) 2 Byte 00 00
- Dummy (00) 2 Byte 00 00
- Speicher (15) 2 Byte Little Endian uint16
- Dummy (00) 2 Byte 00 00
- Dummy (00) 2 Byte 00 00
- Funktion aktiv (11) 2 Byte Little Endian uint16
- Funktion aktiv (12) 2 Byte Little Endian uint16
AB Byte 60 gibt es keinen Hinweis mehr im Typ 0301
- Volumenstrom 2 Byte Little Endian uint16
- Dummy 2 Byte 00 00
- Dummy 2 Byte 00 00
- (Checksumme ?) 2 Byte
;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.
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).
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.
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
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.
Delay ermitteln
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.
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.
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.
- 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
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
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
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.
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.
- Die vier I/Os (MISO, MOSI, SCK, /SS) entsprechend Master-Mode setzen. (siehe Tabelle)
- Die 8 Schalter im SPCR und SPI2X im SPSR setzen.
- 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.
- Pollen von WCOL
- 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.
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:
- Weitere Opcodes
- Tastencodes interpretieren und daraus den Index auf das Opcode-Array bestimmen
- define DEBUG
- erweitern des Opcode-Arrays, nicht nur Transferleaenge, sondern "richtige" Aufteilung Opcode,<Adresse>,Antwort ->Gesamttransferlaenge daraus berechnen
- Buffer an Gesamtlaenge anpassen
- Interpetieren des Status und Ausgabe in Klartext
- Aufforderung zur Eingabe
- Hilfetext beim Start im Terminal
- Begrenzen der Ausgabe auf die Nutzbytes
- ...
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
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.
Emulator-Mode
Diese Version verfogle ich erst weiter, sobald der Sniffing-Mode kein befriedigendes Ergebnis liefert.
Die automatische Aktualisierung der Kommentare aktivieren.