DreherTankController/README.md

96 lines
5.6 KiB
Markdown
Raw Normal View History

2020-12-03 09:18:46 +01:00
# DreherTankController
2020-12-03 15:01:36 +01:00
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.
2020-12-04 11:24:46 +01:00
## Abhängigkeiten
Die aktuell einzige externe Abhängigkeit ist die [U8g2-Library von olikraus](https://github.com/olikraus/u8g2), 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
2020-12-03 19:04:27 +01:00
2020-12-04 14:32:52 +01:00
- 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?
2020-12-03 19:04:27 +01:00
2020-12-03 15:01:36 +01:00
# Modbus
## Coils - FC 1, 5, 15
Betriebszustand Regler (durch die Modbus-Implementierung sind die Register ***0xB4...0xB7*** les-/schreibbar diese Werte werden ignoriert):
2020-12-04 14:56:35 +01:00
- ***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)
2020-12-03 15:01:36 +01:00
---
## 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
2020-12-04 14:56:35 +01:00
- Bit 8...11: siehe Discrete Inputs (Bit 8: ***0xD0***)
2020-12-03 15:01:36 +01:00
- 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
2020-12-04 11:24:46 +01:00
- ***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
2020-12-03 15:01:36 +01:00
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:
2020-12-03 19:04:27 +01:00
- ***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
2020-12-03 15:01:36 +01:00
- 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.