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.
- ***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)
- 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.
- ***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.