Experimentelle Firmware für einen Tankregler, der die Temperatur und den Druck eines Tanks regeln kann, und über Modbus-RTU (RS485) von einem Master gesteuert / abgefragt werden kann.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Bruno Hütter 636ec4df53 corrected README.md 1 month ago
src fixed blocking bug 1 month ago
.gitignore changed gitignore 1 month ago
DreherTankController.ino added macro _DEBUG_DISPLAY 1 month ago
LICENSE Initial commit 1 month ago
README.md corrected README.md 1 month ago

README.md

DreherTankController

Experimentelle Firmware für einen Tankregler, der die Temperatur und den Druck eines Tanks regeln kann, und über Modbus-RTU (RS485) von einem Master gesteuert / abgefragt werden kann.

Das Programm ist für den Atmega2560 (Arduino Mega 2560) geschrieben.

Abhängigkeiten

Die aktuell einzige externe Abhängigkeit ist die U8g2-Library von olikraus, da diese sehr groß ist (> 30 MB), und deshalb nicht in dieses Repository aufgenommen wird. Diese lässt sich einfach mit dem Arduino Library Manager installieren.

Probleme, offene Fragen

  • Das Macro _FAST_STEP_MS (Millisekunden, nach denen eine gedrückte Menütaste ein MenuEvent auslöst) darf nicht auf unter 100 gesetzt werden, da die Displayroutinen sonst zu sehr blockieren und Modbus nicht mehr funktioniert. Dabei muss jedenfalls der Konstruktor U8G2_ST7920_128X64_F_HW_SPI für das Display verwendet werden, da die Displayroutinen sonst zu langsam sind (siehe Liste unten). Eine Erhöhung der SPI-Clockrate kommt leider nicht in Frage, da im Test das Display dabei nicht mehr richtig funktionierte. Folgend die ungefähr benötigten Zeiten (abhängig vom Konstruktor) in ms, um den Displayinhalt aufzubauen (Homescreen, Startmenü):
    • U8G2_ST7920_128X64_1_HW_SPI: 192, 125
    • U8G2_ST7920_128X64_2_HW_SPI: 131, 92
    • U8G2_ST7920_128X64_F_HW_SPI: 87, 67
  • Der Durchschnittswert der Temperatur wird nicht mehr gebildet (außer das Macro _MODBUS_AVERAGE_TEMPERATURES ist 1 - dafür reicht der RAM aber eh nicht ;-) ).
    Frage: Ist die Mittelung der Temperatur wirklich nicht notwendig?

Modbus

Coils - FC 1, 5, 15

Betriebszustand Regler (durch die Modbus-Implementierung sind die Register 0xB4...0xB7 les-/schreibbar – diese Werte werden ignoriert):

  • 0xB0: (de)aktiviere Temperaturregelung
  • 0xB1: (de)aktiviere Drucksteigerung
  • 0xB2: (de)aktiviere Druckabfall
  • 0xB3: (de)aktiviere Regler (unabhängig von den vorigen Werten kann hier der Regler komplett deaktiviert werden)

Discrete Inputs - FC 2

Ausgangszustände Ventile (durch die Modbus-Implementierung sind die Register 0xD4...0xD7 lesbar und geben immer 0 zurück):

  • 0xD0: Ventil Temperatur 1
  • 0xD1: Ventil Temperatur 2 (noch nicht genutzt)
  • 0xD2: Ventil Drucksteigerung
  • 0xD3: Ventil Druckabfall

Input Register - FC 4

Anzahl der gespeicherten Ereignisse abfragen:

  • 0x00: gibt an, ob und wieviele Ereignisse (Ventil-Schaltvorgänge) aufgetreten sind. Dieses Register wird mit 0 initialisiert.

Verschiedenes: Ausgangszustände Ventile, Betriebsart Regler, Flags:

  • 0x01:
    • Bit 0...3: siehe Coils (Bit 0: 0xB0)
    • Bit 4...7: reserviert
    • Bit 8...11: siehe Discrete Inputs (Bit 8: 0xD0)
    • Bit 12...13: reserviert
    • Bit 14: ist gesetzt, falls der 12 Bit Timer übergelaufen ist
    • Bit 15: ist gesetzt, bevor das Holding-Register 0xC0 (setzen der Referenzzeit) erstmalig beschrieben wurde

Messwerte:

  • 0x02: Temperatur 1 - aktuelle Temperatur als INT16 in Hundertstel-°C
  • 0x03: Temperatur 2 - noch nicht genutzt – gibt 0xFFFF zurück
  • 0x04: Druck - Durchschnittswert zwischen 2 Abfragen (der letzten 409,6 Sekunden bzw. der letzten Referenzierung - siehe Holding-Register 0xC0) als INT16 in Hundertstel-Bar, einzeln vorkommende Sensorfehler werden ignoriert, bei häufigeren Fehlern wird 0xFFFF zurückgegeben

gespeicherte Ereignisse:

  • 0x05: Vergangene Zehntelsekunden seit letzter Referenzierung bzw Reglerstart. Ein Überlaufen der Variable wird vom Regler nicht geprüft, da der interne 12 Bit Timer viel früher überläuft, und dabei das ‚Überlauf-Bit‘ im Input-Register 0x01 gesetzt wird.

  • ab 0x06

    • Bit 0...11 geben den Zeitpunkt relativ zur gespeicherten Referenz (alles in 1/10-Sekunden – siehe Holding-Register 0xC0) an. Sobald dieser Offset aber den Wert 0x0FFF erreicht, wird er nicht mehr geändert, bis die Referenzzeit aktualisiert wird.
    • Bit 12...14 bezeichnen den geschalteten Ausgang (z.B.: x011-xxxx-xxxx-xxxx für ‚Druckabfall‘)
    • Bit 15 gibt an, ob der der Ausgang ein- / ausgeschaltet wurde.

sonstiges:

  • 0xF0: Firmware-Version Regler (4 MSBs: Major, 6 Bits Minor, 6 LSBs: Micro)
  • 0xF1: Anzahl der Kühlzonen (aktuell nur 1 Zone implementiert)

Holding Register - FC 3, 6, 16

Sollwerte:

  • 0xA0: Temperatur 1 Sollwert
  • 0xA1: Temperatur 1 Hysterese
  • 0xA2: Temperatur 2 Sollwert (noch nicht implementiert – Wert wird ignoriert)
  • 0xA3: Temperatur 2 Hysterese (noch nicht implementiert – Wert wird ignoriert)
  • 0xA4: Druck Sollwert
  • 0xA5: Druck Hysterese

Setzen der Referenzzeit:

  • 0xC0: Es muss ein vom vorigen Wert abweichender Wert (z.B. ein Zähler – beim ersten Mal jedenfalls NICHT 0xFFFF, da das Register damit initialisiert ist und kein Unterschied festgestellt werden könnte) übergeben werden. Der Regler verwendet diesen Wert prinzipiell für nichts, außer dass der interne 12 Bit-Timer (1/10 Sekunden) und der Event-Counter auf 0 zurückgesetzt werden (siehe Input-Register 0x00 und 0x06), wenn sich dieser Wert ändert. Der Master kann entweder

    • den entsprechenden Zeitstempel im speichern, und den Zeitstempel der Antwort (siehe Input-Register 0x06) dazu addieren, um den tatsächlichen Zeitpunkt des Ereignisses zu ermitteln, oder
    • den in 0x05 gespeicherten Referenzzeitpunkt (Zehntelsekunden seit Reglerstart bzw. letzter Referenzierung (siehe Holding-Register 0xC0)) mit dem Event-Zeitpunkt und dem aktuellen Zeitstempel des Masters gegenrechnen.