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.
Go to file
2020-12-03 19:07:40 +01:00
src Added support for average measurements 2020-12-03 19:04:27 +01:00
.gitignore changed gitignore 2020-12-03 12:10:19 +01:00
DreherTankController.ino Added support for average measurements 2020-12-03 19:04:27 +01:00
LICENSE Initial commit 2020-12-03 09:18:46 +01:00
README.md typo README.md 2020-12-03 19:07:40 +01:00

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.

Probleme

  • Großes Problem: Während des Gedrückthaltens einer Menütaste am Regler blockiert das Programm fast (nur noch ca. 10 Loops / Sekunde). In diesem Fall funktioiert Modbus nicht mehr.
    ### TODO - Das liegt an der Zeit, die gebraucht wird, um das Display zu beschreiben (70 - 100+ ms). Wenn praktisch dauernd das Display neu beschrieben wird, bleibt einfach keine Zeit für was anderes -- SCHNELL EINE LÖSUNG FINDEN
  • Solange nur ein Kühlkreis implementiert ist, lässt sich das maximale Abfrageintervall (siehe Modbus-Holding-Register 0xC0; wenn _TEMP_CONVERSION_DELAY und _ANALOG_READ_DELAY nicht reduziert werden (800 bzw. 500 ms)) auf dem Wert des internen 12 Bit Timers halten (409,6 Sekunden), da der RAM wegen den Arrays zur Messwert-Mittelung schon jetzt gerade so ausreicht (Bei einem Test waren nur noch 874 Bytes für lokale Variablen über).
    ### Temperatur-Mittelung wieder entfernen, da die Temperaturschwankungen BEI WEITEM nicht so stark sind wie die des Drucks? (Da der Drucksensor in einer Leitung außerhalb des Tanks sitzt, schwankt der Druck extrem beim Schalten der Druckventile)

Modbus

Coils - FC 1, 5, 15

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

  • 0xB0: Temperaturregelung aktiv
  • 0xB1: Drucksteigerung aktiv
  • 0xB2: Druckabfall aktiv
  • 0xB3: Regler aktiv (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 7: 0x00)
    • 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 (Durchschnittswert zwischen 2 Abfragen als INT16 in Hundertstel-°C max ?? Minuten, einzeln vorkommende Sensorfehler werden ignoriert, bei häufigeren Fehlern wird 0xFFFF zurückgegeben)
    ### TODO Durchschnittswerte ermitteln (aktuell nur letzter Wert ganz schlecht beim Druck, da dieser extrem bei den Schaltvorgängen schwankt)
    ### TODO maximale Zeit ermitteln (auch für Druck)
  • 0x03: Temperatur 2 (noch nicht genutzt gibt 0xFFFF zurück)
  • 0x04: Druck (siehe Temperatur)

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.