src | ||
.gitignore | ||
DreherTankController.ino | ||
LICENSE | ||
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.
Modbus
Coils - FC 1, 5, 15
Regler-Settings:
- 0xB0: aktiviere Temperaturregelung
- 0xB1: aktiviere Drucksteigerung
- 0xB2: aktiviere Druckabfall
- 0xB3: aktiviere Regler (unabhängig von den vorigen Werten kann hier der Regler komplett deaktiviert werden)
- 0xB4: aktiviere akustisches Warnsignal
- 0xB5: aktiviere optisches Warnsignal (pulsierende Displaybeleuchtung)
- 0xB6: aktiviere Temperaturregelung im Fehlerfall
- 0xB7: aktiviere Druckregelung im Fehlerfall
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...7: siehe Coils (Bit 0: 0xB0)
- Bit 8...11: siehe Discrete Inputs (Bit 8: 0xD0)
- Bit 12: ist gesetzt, falls ein neuer Alarm seit der letzten Referenzierung (siehe Holding-Register 0xC0 - setzen der Referenzzeit) aufgetreten ist, auch wenn er nicht mehr aktiv sein sollte.
- Bit 13: ist gesetzt, falls ein Alarm aktiv ist
- Bit 14: ist gesetzt, falls der 12 Bit Timer übergelaufen ist (wenn das Holding-Register 0xC0 (setzen der Referenzzeit) vor über 409,6 Sekunden zuletzt beschrieben wurde)
- 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 0x8000 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 0x8000 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 (bis 0xFF)
- 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.
Alarme:
- 0x0100: Anzahl der gespeicherten Alarme (0 ... 30)
- ab 0x0101 (bis 0x0160): Ein aufgetretener Alarm wird in drei Registern abgebildet (folglich wäre der z.B. 10te Alarm in den Registern 0x0131 ... 0x0133 auszulesen)
- Register 1: Die ID des Alarms. Wenn der Master die IDs speichert, kann er diese zuordnen, wenn der gleiche Alarm mehrmals ausgelesen wird (aktive Alarme bzw. nicht gelöschte deaktivierte Alarme). Unter der Annahme, dass der Regler während seiner gesamten Einsatzdauer nicht mehr als 65534 Alarme registriert (0 und 0xFFFF sind keine gültigen IDs), ist diese ID praktisch eindeutig.
- Register 2:
- Bit 0...11: Zeitpunkt als der Alarm ausgelöst wurde (siehe Input-Register 0x06) bzw. einen Zähler, der mit jedem Einschalten/Reset des Reglers inkrementiert wird (siehe Register 3 Bit 12). Der Wert ist auf 0xFFF gesetzt, falls Register 3 Bit 13 (Timer-Überlauf) gesetzt ist.
- Bit 12...15 geben den Fehlercode an:
- 0: Sollte nur aus Registern zu lesen sein, welche noch nicht mit einem Fehler belegt sind.
- 1: Temperatur 1 zu hoch
- 2: Temperatur 1 zu niedrig
- 3: Temperatur 1 Sensorfehler
- 4: Temperatur 2 zu hoch
- 5: Temperatur 2 zu niedrig
- 6: Temperatur 2 Sensorfehler
- 7: Druck zu hoch
- 8: Druck zu niedrig
- 9: Druck-Sensorfehler (Nur für 1-5 Volt Sensor verfügbar)
- Register 3:
- Bit 0...11: Zeitpunkt, als der Alarm durch Beheben des Fehlers inaktiv wurde bzw. einen Zähler, der mit jedem Einschalten/Reset des Reglers inkrementiert wird (siehe Bit 14). Der Wert ist auf 0xFFF gesetzt, falls Bit 15 (Timer-Überlauf) gesetzt ist. Der Wert 0 besagt, dass der Alarm noch aktiv ist. Falls der Alarm nie deaktiviert wurde, aber trotzdem inaktiv ist (weil z.B. ein 'Druck zu niedrig'-Alarm direkt von einem 'Druck zu hoch'-Alarm abgelöst wird) und Bit 14 NICHT gesetzt ist, ist der Wert 1. Gültige Zeitpunkte sind somit immer > 1.
- Bit 12: wenn gesetzt: Register 2 enthält die Anzahl der Resets seitdem der Alarm ausgelöst wurde
- Bit 13: ist gesetzt, falls der interne 12 Bit Timer für Register 2 (Alarm wurde aktiviert) übergelaufen sein sollte (siehe Input-Register 0x01 Bit 14)
- Bit 14: wenn gesetzt: Register 3 enthält die Anzahl der Resets seitdem der Alarm inaktiv wurde
- Bit 15: ist gesetzt, falls der interne 12 Bit Timer für Register 3 (Alarm wurde deaktiviert) übergelaufen sein sollte (siehe Input-Register 0x01 Bit 14)
Regler-Info:
- 0x0F00: Firmware-Version (4 MSBs: Major, 6 Bits Minor, 6 LSBs: Micro)
- 0x0F01: Anzahl der Kühlzonen (aktuell nur 1 Zone implementiert - In Zukunft wird man (z.B. bei der Inbetriebnahme) zwischen 1- und 2-Zonen-Betrieb wählen können)
- 0x0F02: Wie oft der Regler bis jetzt eingeschaltet wurde (beginnend bei 1)
- 0x0F03: Werkseinstellung für Coils 0xB0...0xB7 -> Bit0(LSB)...Bit7 - Das MSByte ist zu ignorieren
- 0x0F04: Werkseinstellung Sollwert Temperatur/en (in Hundertstel-°C)
- 0x0F05: Werkseinstellung Hysterese Temperatur/en (in Hundertstel-°C)
- 0x0F06: Werkseinstellung Sollwert Druck (in Hundertstel-Bar)
- 0x0F07: Werkseinstellung Hysterese Druck (in Hundertstel-Bar)
- 0x0F08: Werkseinstellung Sollwert min. Temperatursteigerungsrate (in Hundertstel-°C - zur Alarmauslösung)
- 0x0F09: Werkseinstellung Sollwert min. Temperaturabfallrate (in Hundertstel-°C - zur Alarmauslösung)
- 0x0F10: Werkseinstellung Sollwert min. Druckänderungsrate (in Hundertstel-Bar - zur Alarmauslösung)
- 0x0F11: Mindestwert Sollwert Temperatur/en (in Hundertstel-°C)
- 0x0F12: Maximalwert Sollwert Temperatur/en (in Hundertstel-°C)
- 0x0F13: Mindestwert Hysterese Temperatur/en (in Hundertstel-°C)
- 0x0F14: Maximalwert Hysterese Temperatur/en (in Hundertstel-°C)
- 0x0F15: Mindestwert Sollwert Druck (in Hundertstel-Bar)
- 0x0F16: Maximalwert Sollwert Druck (in Hundertstel-Bar)
- 0x0F17: Mindestwert Hysterese Druck (in Hundertstel-Bar)
- 0x0F18: Maximalwert Hysterese Druck (in Hundertstel-Bar)
- 0x0F19: Mindestwert Änderungsrate für Temperatur/en und Druck (in Hundertstel - zur Alarmauslösung)
- 0x0F20: Maximalwert Änderungsrate für Temperatur/en und Druck (in Hundertstel - zur Alarmauslösung)
Holding Register - FC 3, 6, 16
- 0xA0: Bit 0...7: siehe Coils (Bit 0: 0xB0)
Sollwerte in Hundertsel- [ °C | Bar ]:
- 0xA1: Temperatur 1 Sollwert
- 0xA2: Temperatur 1 Hysterese
- 0xA3: Temperatur 2 Sollwert (noch nicht implementiert – Wert wird ignoriert)
- 0xA4: Temperatur 2 Hysterese (noch nicht implementiert – Wert wird ignoriert)
- 0xA5: Druck Sollwert
- 0xA6: Druck Hysterese
Werte zur Alarmauslösung (Hundertsel- [°C / 1 Stunde | Bar / 10 Sekunden) - bei Nichterreichen dieser Werte wird ein entsprechender Alarm ausgelöst:
- 0xA7: Temperatur-Steigerungsrate
- 0xA8: Temperatur-Abfallrate
- 0xA9: Druckrate (Steigerung und Abfall)
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 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) mit dem Event-Zeitpunkt und dem aktuellen Zeitstempel des Masters gegenrechnen.
Löschen von Alarmen:
- 0x0200: Wird in dieses Register eine gültige Alarm-ID (siehe Input-Register 0x0101) geschrieben, wird der Alarm aus dem Regler gelöscht, insofern er existiert und nicht aktiv ist. Wurde der Alarm erfolgreich gelöscht, enthält das Register danach den Wert 0, ansonsten 0xFFFF (Alarm nicht vorhanden oder noch aktiv). Dieses Register ist mit 0 initialisiert.
- 0x0201: Wird in dieses Register ein anderer Wert als 0 oder 0xFFFF geschrieben, werden alle nicht aktiven Alarme aus dem Regler gelöscht. War mindestens ein nicht aktiver Alarm zum Löschen vorhanden, enthält dieses Register danach den Wert 0, ansonsten 0xFFFF. Dieses Register ist mit 0 initialisiert.