Misc updated
This commit is contained in:
parent
1095be2283
commit
93ef495c3c
83
README.md
83
README.md
|
@ -1,3 +1,84 @@
|
|||
# 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.
|
||||
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.
|
||||
|
||||
# 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 oder die 16 LSBs der UNIX-Zeit in Zehntelsekunden – 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.
|
||||
|
|
|
@ -170,7 +170,7 @@ public:
|
|||
void (*reset)() = 0;
|
||||
|
||||
/* Callback-Funktionen */
|
||||
void(*setParams)(const parameters&);
|
||||
void(*setParams)(parameters&);
|
||||
void(*setModbusParams)(const modbusParameters&);
|
||||
void(*setPSensor)(const PSensor&);
|
||||
};
|
||||
|
|
|
@ -3,5 +3,7 @@ This is a modified version of ModbusRTU_Slave_RS485 version 1.0.2 by Łukasz Śl
|
|||
|
||||
https://github.com/lucasso/ModbusRTUSlaveArduino
|
||||
|
||||
*Modified by brunotic.*
|
||||
|
||||
## License
|
||||
See ./LICENSE file (GNU GPL v3.0 or later)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#ifndef ARDUINO_AVR_MEGA2560
|
||||
#error This program was written for an Atmega2560
|
||||
#endif
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include "src/OneWire/OneWire.h"
|
||||
#include "src/DallasTemperature/DallasTemperature.h"
|
||||
|
@ -22,7 +26,7 @@ u16 lastRefTime = 0xFFFF;
|
|||
u8 modbusStates[1]; // Bit0: tEn, Bit1: pInc, Bit2: pDec, Bit3: cEn
|
||||
u8 modbusValves[1]; // Bit0: Temp1, Bit1: Temp2, Bit2: Druck
|
||||
// 0: Event-Counter, 1: high: modbusValves[0], low: modbusStates[0], 2...4: Temp 1, 2, Druck, ab5: gespeicherte Schaltvorgänge
|
||||
u16 modbusData[_REGS_INFRONTOF_EVENTS + _MODBUS_MAX_EVENTS];
|
||||
u16 modbusData[_REGS_INFRONTOF_EVENTS + _MODBUS_MAX_EVENTS]; // Main Input Registers
|
||||
u16 modbusMiscReadable[2]; // Version, Kühlzonen
|
||||
u16 modbusSetpoints[6]; // Temp1, 2, Druck jeweils Sollwert + Hysterese
|
||||
u16 modbusRefTime[1]; // setzt bei Änderung Event-Counter und -Timer zurück
|
||||
|
@ -34,7 +38,7 @@ u16 &refTime = modbusRefTime[0];
|
|||
|
||||
ModbusRTUSlave mb(&Serial1, 2);
|
||||
|
||||
void checkParamINT16(int *source, int *target, const int &std, const int &min, const int &max) {
|
||||
void checkParamINT16(int16_t *source, int16_t *target, const int &std, const int &min, const int &max) {
|
||||
_print("source: "); _print(*source);
|
||||
if (*source == _SENSOR_FAULT) {
|
||||
*source = *target = std;
|
||||
|
@ -103,40 +107,40 @@ void checkModbusParams() {
|
|||
if (modbusSetpoints[0] != params.ts1) {
|
||||
if (paramsChangedByUI) {
|
||||
_print("ts1 - UI -> Modbus - ");
|
||||
checkParamINT16(¶ms.ts1, &modbusSetpoints[0], _STD_TEMP_SETPOINT, _MIN_TEMP_SETPOINT, _MAX_TEMP_SETPOINT);
|
||||
checkParamINT16(¶ms.ts1, (int16_t*)&modbusSetpoints[0], _STD_TEMP_SETPOINT, _MIN_TEMP_SETPOINT, _MAX_TEMP_SETPOINT);
|
||||
} else {
|
||||
_print("ts1 - Modbus -> UI - ");
|
||||
checkParamINT16(&modbusSetpoints[0], ¶ms.ts1, _STD_TEMP_SETPOINT, _MIN_TEMP_SETPOINT, _MAX_TEMP_SETPOINT);
|
||||
checkParamINT16((int16_t*)&modbusSetpoints[0], ¶ms.ts1, _STD_TEMP_SETPOINT, _MIN_TEMP_SETPOINT, _MAX_TEMP_SETPOINT);
|
||||
p.ts1 = params.ts1;
|
||||
}
|
||||
}
|
||||
if (modbusSetpoints[1] != params.th1) {
|
||||
if (paramsChangedByUI) {
|
||||
_print("th1 - UI -> Modbus - ");
|
||||
checkParamINT16(¶ms.th1, &modbusSetpoints[1], _STD_TEMP_HYSTERESIS, _MIN_TEMP_HYSTERESIS, _MAX_TEMP_HYSTERESIS);
|
||||
checkParamINT16(¶ms.th1, (int16_t*)&modbusSetpoints[1], _STD_TEMP_HYSTERESIS, _MIN_TEMP_HYSTERESIS, _MAX_TEMP_HYSTERESIS);
|
||||
} else {
|
||||
_print("th1 - Modbus -> UI - ");
|
||||
checkParamINT16(&modbusSetpoints[1], ¶ms.th1, _STD_TEMP_HYSTERESIS, _MIN_TEMP_HYSTERESIS, _MAX_TEMP_HYSTERESIS);
|
||||
checkParamINT16((int16_t*)&modbusSetpoints[1], ¶ms.th1, _STD_TEMP_HYSTERESIS, _MIN_TEMP_HYSTERESIS, _MAX_TEMP_HYSTERESIS);
|
||||
p.th1 = params.th1;
|
||||
}
|
||||
}
|
||||
if (modbusSetpoints[4] != params.ps) {
|
||||
if (paramsChangedByUI) {
|
||||
_print("ps - UI -> Modbus - ");
|
||||
checkParamINT16(¶ms.ps, &modbusSetpoints[4], _STD_P_SETPOINT, _MIN_P_SETPOINT, _MAX_P_SETPOINT);
|
||||
checkParamINT16(¶ms.ps, (int16_t*)&modbusSetpoints[4], _STD_P_SETPOINT, _MIN_P_SETPOINT, _MAX_P_SETPOINT);
|
||||
} else {
|
||||
_print("ps - Modbus -> UI - ");
|
||||
checkParamINT16(&modbusSetpoints[4], ¶ms.ps, _STD_P_SETPOINT, _MIN_P_SETPOINT, _MAX_P_SETPOINT);
|
||||
checkParamINT16((int16_t*)&modbusSetpoints[4], ¶ms.ps, _STD_P_SETPOINT, _MIN_P_SETPOINT, _MAX_P_SETPOINT);
|
||||
p.ps = params.ps;
|
||||
}
|
||||
}
|
||||
if (modbusSetpoints[5] != params.ph) {
|
||||
if (paramsChangedByUI) {
|
||||
_print("ph - UI -> Modbus - ");
|
||||
checkParamINT16(¶ms.ph, &modbusSetpoints[5], _STD_P_HYSTERESIS, _MIN_P_HYSTERESIS, _MAX_P_HYSTERESIS);
|
||||
checkParamINT16(¶ms.ph, (int16_t*)&modbusSetpoints[5], _STD_P_HYSTERESIS, _MIN_P_HYSTERESIS, _MAX_P_HYSTERESIS);
|
||||
} else {
|
||||
_print("ph - Modbus -> UI - ");
|
||||
checkParamINT16(&modbusSetpoints[5], ¶ms.ph, _STD_P_HYSTERESIS, _MIN_P_HYSTERESIS, _MAX_P_HYSTERESIS);
|
||||
checkParamINT16((int16_t*)&modbusSetpoints[5], ¶ms.ph, _STD_P_HYSTERESIS, _MIN_P_HYSTERESIS, _MAX_P_HYSTERESIS);
|
||||
p.ph = params.ph;
|
||||
}
|
||||
}
|
||||
|
@ -366,10 +370,8 @@ void setPSensor(const PSensor &sensor) {
|
|||
void setup() {
|
||||
#if _DEBUG == 1
|
||||
Serial.begin(19200);
|
||||
// char test[60];
|
||||
// sprintf(test, "test: %u, %u, %u", 115200, 57600, 38400);
|
||||
// Serial.println(test);
|
||||
#endif
|
||||
|
||||
pinMode(53, OUTPUT); // Mega CS-Pin (um Slave-Betrieb zu vermeiden)
|
||||
|
||||
paramsChangedByUI = true;
|
||||
|
|
Loading…
Reference in New Issue