added macro _MODBUS_AVERAGE_TEMPERATURES, bug fixes
This commit is contained in:
parent
a71fc8e176
commit
efa9fd8ea0
|
@ -20,24 +20,6 @@ bool timeStampOverflow = false; // true, wenn mehr als 0xFFF Zehntelsekunden ver
|
||||||
unsigned long timeStamp;
|
unsigned long timeStamp;
|
||||||
u16 lastRefTime = 0xFFFF;
|
u16 lastRefTime = 0xFFFF;
|
||||||
|
|
||||||
#if _MODBUS == 1
|
|
||||||
#include "src/modbus/ModbusRTUSlave.h"
|
|
||||||
|
|
||||||
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]; // 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
|
|
||||||
|
|
||||||
u8 &states = modbusStates[0];
|
|
||||||
u8 &valves = modbusValves[0];
|
|
||||||
u16 &eventCounter = modbusData[0];
|
|
||||||
u16 &refTime = modbusRefTime[0];
|
|
||||||
|
|
||||||
ModbusRTUSlave mb(&Serial1, 2);
|
|
||||||
|
|
||||||
void checkParamINT16(int16_t *source, int16_t *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);
|
_print("source: "); _print(*source);
|
||||||
if (*source == _SENSOR_FAULT) {
|
if (*source == _SENSOR_FAULT) {
|
||||||
|
@ -88,6 +70,24 @@ void checkParamUINT8(u8 *source, u8 *target, const u8 &std) {
|
||||||
_print(", target: "); _print(*target); _print(", source: "); _println(*source);
|
_print(", target: "); _print(*target); _print(", source: "); _println(*source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _MODBUS == 1
|
||||||
|
#include "src/modbus/ModbusRTUSlave.h"
|
||||||
|
|
||||||
|
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]; // 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
|
||||||
|
|
||||||
|
u8 &states = modbusStates[0];
|
||||||
|
u8 &valves = modbusValves[0];
|
||||||
|
u16 &eventCounter = modbusData[0];
|
||||||
|
u16 &refTime = modbusRefTime[0];
|
||||||
|
|
||||||
|
ModbusRTUSlave mb(&Serial1, 2);
|
||||||
|
|
||||||
void checkParamBool(u8 &p, const u8 &bitNr, u8 *p2=nullptr) {
|
void checkParamBool(u8 &p, const u8 &bitNr, u8 *p2=nullptr) {
|
||||||
u8 *p_ = (p2) ? p2 : &p;
|
u8 *p_ = (p2) ? p2 : &p;
|
||||||
if (paramsChangedByUI) {
|
if (paramsChangedByUI) {
|
||||||
|
|
12
README.md
12
README.md
|
@ -4,12 +4,12 @@ Experimentelle Firmware für einen Tankregler, der die Temperatur und den Druck
|
||||||
|
|
||||||
Das Programm ist für den Atmega2560 (Arduino Mega 2560) geschrieben.
|
Das Programm ist für den Atmega2560 (Arduino Mega 2560) geschrieben.
|
||||||
|
|
||||||
## Probleme
|
## Probleme, offene Fragen
|
||||||
|
|
||||||
- ***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.
|
- ***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***
|
***### 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).
|
- 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 ;-) ).
|
||||||
***### 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)
|
***Frage:*** Ist die Mittelung der Temperatur wirklich nicht notwendig?
|
||||||
|
|
||||||
# Modbus
|
# Modbus
|
||||||
|
|
||||||
|
@ -51,11 +51,9 @@ Verschiedenes: Ausgangszustände Ventile, Betriebsart Regler, Flags:
|
||||||
|
|
||||||
Messwerte:
|
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)
|
- ***0x02***: Temperatur 1 - aktuelle Temperatur als INT16 in Hundertstel-°C
|
||||||
***### 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)
|
- ***0x03***: Temperatur 2 (noch nicht genutzt – gibt *0xFFFF* zurück)
|
||||||
- ***0x04***: Druck (siehe Temperatur)
|
- ***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)
|
||||||
|
|
||||||
gespeicherte Ereignisse:
|
gespeicherte Ereignisse:
|
||||||
|
|
||||||
|
|
12
src/common.h
12
src/common.h
|
@ -9,18 +9,20 @@
|
||||||
#define _VERSION_NUMBER _VERSION_MICRO | (_VERSION_MINOR << 6) | (_VERSION_MAJOR << 12)
|
#define _VERSION_NUMBER _VERSION_MICRO | (_VERSION_MINOR << 6) | (_VERSION_MAJOR << 12)
|
||||||
#define _VERSION_STRING "v0.0.1"
|
#define _VERSION_STRING "v0.0.1"
|
||||||
|
|
||||||
#define _DEBUG 0
|
#define _DEBUG 1
|
||||||
#define _DEBUG_SENSORS 0
|
#define _DEBUG_SENSORS 0
|
||||||
#define _MODBUS 1
|
#define _MODBUS 1
|
||||||
|
// Das Ermitteln einer Durchschnittstemperatur braucht viel RAM und ist wahrscheinlich unnötig
|
||||||
|
#define _MODBUS_AVERAGE_TEMPERATURES 0
|
||||||
|
|
||||||
#if _DEBUG == 1
|
#if _DEBUG == 1
|
||||||
#define _print(x) Serial.print(x)
|
#define _print(x) Serial.print(x)
|
||||||
#define _println(x) Serial.println(x)
|
#define _println(x) Serial.println(x)
|
||||||
struct _printTimeStruct {
|
struct __printTimeStruct {
|
||||||
_printTimeStruct(const char *text) : _text(text) {
|
__printTimeStruct(const char *text) : _text(text) {
|
||||||
_t0 = millis();
|
_t0 = millis();
|
||||||
};
|
};
|
||||||
~_printTimeStruct() {
|
~__printTimeStruct() {
|
||||||
_print("Vergangene Millisekunden ["); _print(_text);
|
_print("Vergangene Millisekunden ["); _print(_text);
|
||||||
_print("]: "); _println(millis() - _t0);
|
_print("]: "); _println(millis() - _t0);
|
||||||
};
|
};
|
||||||
|
@ -28,7 +30,7 @@ struct _printTimeStruct {
|
||||||
u32 _t0;
|
u32 _t0;
|
||||||
const char *_text;
|
const char *_text;
|
||||||
};
|
};
|
||||||
#define _printtime(text) _printTimeStruct __printt(text)
|
#define _printtime(text) __printTimeStruct __printt(text)
|
||||||
#if _DEBUG_SENSORS == 1
|
#if _DEBUG_SENSORS == 1
|
||||||
#define _prints(x) Serial.print(x)
|
#define _prints(x) Serial.print(x)
|
||||||
#define _printsln(x) Serial.println(x)
|
#define _printsln(x) Serial.println(x)
|
||||||
|
|
|
@ -102,7 +102,11 @@ void Controller::process()
|
||||||
_printsln();
|
_printsln();
|
||||||
}
|
}
|
||||||
#if _MODBUS == 1
|
#if _MODBUS == 1
|
||||||
|
#if _MODBUS_AVERAGE_TEMPERATURES == 1
|
||||||
_averageTemperature1();
|
_averageTemperature1();
|
||||||
|
#else
|
||||||
|
modbusData[_MODBUS_T1_INDEX] = _vals->t1;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else if (_requestConversion) {
|
} else if (_requestConversion) {
|
||||||
_requestConversion = false;
|
_requestConversion = false;
|
||||||
|
@ -220,18 +224,22 @@ void Controller::_setPValves(States state)
|
||||||
#if _MODBUS == 1
|
#if _MODBUS == 1
|
||||||
void Controller::resetAverageCounters()
|
void Controller::resetAverageCounters()
|
||||||
{
|
{
|
||||||
_print("Setze Zähler zurück (_t1_c: ");
|
_print("Setze Zähler zurück (");
|
||||||
_print(_t1_c); _print(", _t2_c: ");
|
#if _MODBUS_AVERAGE_TEMPERATURES == 1
|
||||||
_print(_t2_c); _print(", _p_c: ");
|
_print("_t1_c: "); _print(_t1_c);
|
||||||
_print(_p_c); _println(")");
|
_print(", _t2_c: "); _print(_t2_c);
|
||||||
|
_print(", ");
|
||||||
_t1_c = 0;
|
_t1_c = 0;
|
||||||
_t2_c = 0;
|
_t2_c = 0;
|
||||||
_p_c = 0;
|
|
||||||
_t1_of = false;
|
_t1_of = false;
|
||||||
_t2_of = false;
|
_t2_of = false;
|
||||||
|
#endif
|
||||||
|
_print("_p_c: "); _print(_p_c); _println(")");
|
||||||
|
_p_c = 0;
|
||||||
_p_of = false;
|
_p_of = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _MODBUS_AVERAGE_TEMPERATURES == 1
|
||||||
inline void Controller::_averageTemperature1()
|
inline void Controller::_averageTemperature1()
|
||||||
{
|
{
|
||||||
int32_t total = 0;
|
int32_t total = 0;
|
||||||
|
@ -265,6 +273,7 @@ inline void Controller::_averageTemperature2()
|
||||||
{
|
{
|
||||||
// noch nicht implementiert
|
// noch nicht implementiert
|
||||||
}
|
}
|
||||||
|
#endif // _MODBUS_AVERAGE_TEMPERATURES == 1
|
||||||
|
|
||||||
inline void Controller::_averagePressure()
|
inline void Controller::_averagePressure()
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
#define _TEMP_CONVERSION_DELAY 800
|
#define _TEMP_CONVERSION_DELAY 800
|
||||||
#define _ANALOG_READ_DELAY 500
|
#define _ANALOG_READ_DELAY 500
|
||||||
// Maximal nötige Anzahl an Temperatur-Einträgen, bevor der interne 12 Bit Timer überläuft
|
// Maximal nötige Anzahl an Temperatur-Einträgen, bevor der interne 12 Bit Timer überläuft
|
||||||
|
#define _P_ARR_LEN (409600 / _ANALOG_READ_DELAY) + 1
|
||||||
|
#if _MODBUS_AVERAGE_TEMPERATURES == 1
|
||||||
#define _T_ARR_LEN (409600 / _TEMP_CONVERSION_DELAY) + 1
|
#define _T_ARR_LEN (409600 / _TEMP_CONVERSION_DELAY) + 1
|
||||||
// Maximal nötige Anzahl an Druck-Einträgen, bevor der interne 12 Bit Timer überläuft
|
// Maximal nötige Anzahl an Druck-Einträgen, bevor der interne 12 Bit Timer überläuft
|
||||||
#define _P_ARR_LEN (409600 / _ANALOG_READ_DELAY) + 1
|
#endif
|
||||||
// #define _T_ARR_LEN 255
|
|
||||||
// #define _P_ARR_LEN 255
|
|
||||||
|
|
||||||
class Controller
|
class Controller
|
||||||
{
|
{
|
||||||
|
@ -29,12 +29,14 @@ private:
|
||||||
uint8_t _t1Pin;
|
uint8_t _t1Pin;
|
||||||
uint8_t _t2Pin;
|
uint8_t _t2Pin;
|
||||||
|
|
||||||
|
#if _MODBUS_AVERAGE_TEMPERATURES == 1
|
||||||
int16_t _t1_arr[_T_ARR_LEN]; // Array, aus dem der Durchschnittswert ermittelt wird
|
int16_t _t1_arr[_T_ARR_LEN]; // Array, aus dem der Durchschnittswert ermittelt wird
|
||||||
u16 _t1_c = 0; // Anzahl der Einträge, aus denen der Durchschnitt gebildet wird
|
u16 _t1_c = 0; // Anzahl der Einträge, aus denen der Durchschnitt gebildet wird
|
||||||
bool _t1_of = false; // Flag, die anzeigt, ob das _t1_arr-Array schon voll ist
|
bool _t1_of = false; // Flag, die anzeigt, ob das _t1_arr-Array schon voll ist
|
||||||
// int16_t _t2_arr[_T_ARR_LEN]; // Array, aus dem der Durchschnittswert ermittelt wird
|
// int16_t _t2_arr[_T_ARR_LEN]; // Array, aus dem der Durchschnittswert ermittelt wird
|
||||||
u16 _t2_c = 0; // Anzahl der Einträge, aus denen der Durchschnitt gebildet wird
|
u16 _t2_c = 0; // Anzahl der Einträge, aus denen der Durchschnitt gebildet wird
|
||||||
bool _t2_of = false; // Flag, die anzeigt, ob das _t2_arr-Array schon voll ist
|
bool _t2_of = false; // Flag, die anzeigt, ob das _t2_arr-Array schon voll ist
|
||||||
|
#endif
|
||||||
int16_t _p_arr[_P_ARR_LEN]; // Array, aus dem der Durchschnittswert ermittelt wird
|
int16_t _p_arr[_P_ARR_LEN]; // Array, aus dem der Durchschnittswert ermittelt wird
|
||||||
u16 _p_c = 0; // Anzahl der Einträge, aus denen der Durchschnitt gebildet wird
|
u16 _p_c = 0; // Anzahl der Einträge, aus denen der Durchschnitt gebildet wird
|
||||||
bool _p_of = false; // Flag, die anzeigt, ob das _p_arr-Array schon voll ist
|
bool _p_of = false; // Flag, die anzeigt, ob das _p_arr-Array schon voll ist
|
||||||
|
|
|
@ -14,7 +14,7 @@ Display::Display(
|
||||||
modbusParameters *modbus,
|
modbusParameters *modbus,
|
||||||
PSensor *sensor,
|
PSensor *sensor,
|
||||||
valveStates *vStates)
|
valveStates *vStates)
|
||||||
: U8G2_ST7920_128X64_2_HW_SPI(U8G2_R0, cs)
|
: U8G2_ST7920_128X64_F_HW_SPI(U8G2_R0, cs)
|
||||||
, btnNext(btnNext)
|
, btnNext(btnNext)
|
||||||
, btnPrev(btnPrev)
|
, btnPrev(btnPrev)
|
||||||
, btnSelect(btnSelect)
|
, btnSelect(btnSelect)
|
||||||
|
|
|
@ -77,7 +77,7 @@ extern "C" uint8_t my_UserInterfaceSelectionList(u8g2_t *u8g2, const char *title
|
||||||
// extern "C" void my_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char *pre, uint8_t value, uint8_t digits, const char *post);
|
// extern "C" void my_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char *pre, uint8_t value, uint8_t digits, const char *post);
|
||||||
extern "C" void my_UserInterfaceInputValueString(u8g2_t *u8g2, const char *title, const char *sub, const char *text);
|
extern "C" void my_UserInterfaceInputValueString(u8g2_t *u8g2, const char *title, const char *sub, const char *text);
|
||||||
|
|
||||||
class Display : public U8G2_ST7920_128X64_2_HW_SPI
|
class Display : public U8G2_ST7920_128X64_F_HW_SPI
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue