1#ifndef HUMIDISTAT_GRAPHICALDISPLAYUI_H
2#define HUMIDISTAT_GRAPHICALDISPLAYUI_H
23template<
class Hum
idistat_t>
75 u8g2.setFont(u8g2_font_6x12_tr);
78 u8g2.drawBox(12, 1, 26, 12);
80 u8g2.drawStr(13, 10,
"Info");
83 u8g2.drawStr(2, 10,
"C.");
84 u8g2.drawStr(40, 10,
"C.");
87 u8g2.drawVLine(67, 27, 18);
88 u8g2.drawStr(0, 23,
"Temperatures");
89 u8g2.drawHLine(0, 26, 128);
90 u8g2.drawStr(0, 35,
"Chamber");
92 u8g2.drawStr(0, 43,
"Thermistors");
93 u8g2.drawHLine(0, 44, 128);
96 for (
size_t i = 0; i <
trs.size(); ++i) {
101 u8g2.drawBox(0, 44, 65, 10);
102 u8g2.setDrawColor(0);
103 u8g2.drawStr(0, 52,
"SP profile:");
104 u8g2.setDrawColor(1);
109 u8g2.drawHLine(0, 54, 128);
110 u8g2.setFont(u8g2_font_unifont_t_75);
111 u8g2.drawGlyph(0, 66, 9664);
112 u8g2.drawGlyph(40, 66, 9650);
113 u8g2.drawGlyph(50, 66, 9660);
114 u8g2.setFont(u8g2_font_5x7_tr);
115 u8g2.drawStr(10, 63,
"tab");
116 u8g2.drawStr(60, 63,
"adj");
117 u8g2.setFont(u8g2_font_6x12_tr);
122 u8g2.setFont(u8g2_font_6x12_tr);
125 u8g2.drawBox(25, 1, 38, 12);
126 u8g2.setDrawColor(0);
127 u8g2.drawStr(26, 10,
"Config");
128 u8g2.setDrawColor(1);
130 u8g2.drawStr(2, 10,
"C.");
131 u8g2.drawVLine(12, 1, 12);
132 u8g2.drawStr(14, 10,
"I.");
135 for (uint8_t i = 0; i < 4; i++) {
144 uint8_t row = 22 + i * 10;
147 u8g2.drawStr(0, row, buf);
167 u8g2.setDrawColor(2);
168 u8g2.drawBox(x, row - 8, w, 10);
169 u8g2.setDrawColor(1);
175 u8g2.drawStr(100, 32,
"Save");
176 u8g2.drawStr(100, 42,
"Reset");
186 u8g2.setDrawColor(2);
187 u8g2.drawBox(100, y, 40, 10);
188 u8g2.setDrawColor(1);
193 u8g2.drawStr(80, 10,
"EEPROM");
196 u8g2.drawStr(85, 22,
"saved");
197 u8g2.setCursor(115, 22);
203 u8g2.setFont(u8g2_font_unifont_t_75);
204 u8g2.drawHLine(0, 54, 128);
205 u8g2.drawGlyph(0, 66, 9664);
206 u8g2.drawGlyph(30, 66, 9650);
207 u8g2.drawGlyph(36, 66, 9660);
208 u8g2.drawGlyph(65, 66, 9654);
209 u8g2.drawGlyph(98, 66, 9679);
210 u8g2.setFont(u8g2_font_5x7_tr);
212 u8g2.drawStr(10, 63,
"tab");
213 u8g2.drawStr(45, 63,
"par");
214 u8g2.drawStr(75, 63,
"menu");
215 u8g2.drawStr(108, 63,
"edit");
218 u8g2.drawStr(45, 63,
"adj");
219 u8g2.drawStr(108, 63,
"OK");
222 u8g2.drawStr(10, 63,
"back");
223 u8g2.drawStr(45, 63,
"");
224 u8g2.drawStr(75, 63,
"back");
225 u8g2.drawStr(108, 63,
"OK");
227 u8g2.setFont(u8g2_font_6x12_tr);
232 u8g2.setFont(u8g2_font_6x12_tr);
235 u8g2.drawBox(1, 1, 42, 12);
236 u8g2.setDrawColor(0);
237 u8g2.drawStr(1, 10,
"Control");
238 u8g2.setDrawColor(1);
240 u8g2.drawStr(44, 10,
"I.");
241 u8g2.drawVLine(55, 1, 12);
242 u8g2.drawStr(57, 10,
"C.");
243 u8g2.drawVLine(70, 1, 12);
246 u8g2.drawVLine(13, 27, 28);
247 u8g2.drawStr(0, 23,
"Humidity");
248 u8g2.drawHLine(0, 26, 51);
250 u8g2.drawStr(0, 35,
"PV");
253 u8g2.drawBox(0, 36, 13, 9);
254 u8g2.setDrawColor(0);
261 u8g2.drawStr(0, 44, buf);
264 u8g2.setDrawColor(1);
271 u8g2.drawBox(0, 45, 13, 9);
272 u8g2.setDrawColor(0);
274 u8g2.drawStr(0, 53,
"CV");
275 u8g2.setDrawColor(1);
280 u8g2.drawStr(80, 10,
"auto");
282 u8g2.drawStr(80, 10,
"manual");
286 u8g2.setFont(u8g2_font_5x7_tr);
288 u8g2.setFont(u8g2_font_6x12_tr);
292 u8g2.drawHLine(0, 54, 128);
293 u8g2.setFont(u8g2_font_unifont_t_75);
294 u8g2.drawGlyph(0, 66, 9664);
295 u8g2.drawGlyph(30, 66, 9650);
296 u8g2.drawGlyph(36, 66, 9660);
297 u8g2.drawGlyph(65, 66, 9654);
298 u8g2.drawGlyph(98, 66, 9679);
299 u8g2.setFont(u8g2_font_5x7_tr);
300 u8g2.drawStr(10, 63,
"tab");
301 u8g2.drawStr(45, 63,
"adj");
302 u8g2.drawStr(75, 63,
"prof");
303 u8g2.drawStr(108, 63,
"mode");
304 u8g2.setFont(u8g2_font_6x12_tr);
309 u8g2.setFont(u8g2_font_6x12_tr);
310 u8g2.drawFrame(0, 0, 128, 14);
313 u8g2.setFont(u8g2_font_unifont_t_75);
314 uint8_t i = (
frame / 2) % 4;
315 u8g2.drawGlyph(118, 10, 0x25f3 - i);
489 u8g2.setFont(u8g2_font_helvB12_tr);
490 u8g2.drawStr(0, 24,
"OpenHumidistat");
492 u8g2.setFont(u8g2_font_6x12_tr);
493 u8g2.drawStr(0, 40,
"Lars Veldscholte");
495 u8g2.setFont(u8g2_font_5x7_tr);
496 u8g2.drawStr(0, 50,
"https://github.com/");
497 u8g2.drawStr(0, 60,
"OpenHumidistat");
509 u8g2.setCursor(col, row);
566 double pTerm, iTerm, dTerm;
569 u8g2.drawFrame(52, 13, 47, 31);
570 u8g2.drawStr(54, 23,
"P");
571 u8g2.drawStr(54, 32,
"I");
572 u8g2.drawStr(54, 41,
"D");
573 u8g2.drawVLine(60, 13, 31);
575 printf(62, 23,
"%6.2f", pTerm);
576 printf(62, 32,
"%6.2f", iTerm);
577 printf(62, 41,
"%6.2f", dTerm);
580 u8g2.setCursor(105, 23);
589 u8g2.drawFrame(50, 13, 65, 42);
590 u8g2.drawStr(55, 23,
"F");
597 u8g2.drawStr(66, 23, buf);
605 u8g2.drawStr(91, 23, buf);
609 u8g2.drawHLine(50, 26, 64);
610 u8g2.drawVLine(64, 13, 32);
611 u8g2.drawVLine(89, 13, 32);
612 u8g2.drawHLine(50, 45, 64);
614 u8g2.drawStr(52, 35,
"PV");
615 u8g2.drawStr(52, 44,
"CV");
617 printf(65, 35,
"%3.2f",
humidistat.getInner(0)->pv);
618 printf(65, 44,
"%3.0f%%",
humidistat.getInner(0)->cv * 100);
619 printf(90, 35,
"%3.2f",
humidistat.getInner(1)->pv);
620 printf(90, 44,
"%3.0f%%",
humidistat.getInner(1)->cv * 100);
void advanceEnum(T &e, int8_t n=1)
Cycle through (advance) an enum.
Control humidity using cascade PID: outer PID loop sets setpoints of two inner flow controllers,...
A class for storing references to variables of various types (uint8_t, uint16_t, or double).
uint8_t magnitude() const
Get magnitude (number of digits before the decimal separator) of variable.
char * asprint() const
Print "label: value" to string. Automatically allocates string on the heap. Make sure to delete it im...
void adjust(int16_t delta) const
Add delta to the variable.
User interface (display and input) for humidistat. Hold references to ButtonReader for keypad input,...
const uint16_t refreshInterval
static void adjustValue(double delta, double &value, uint8_t min, uint8_t max)
In-/de-crement a variable, while clipping it to [min, max].
etl::span< const ThermistorReader, 4 > trs
unsigned long lastRefreshed
Last time display was updated (in millis)
void printf(uint8_t col, uint8_t row, const char *fmt, T... args)
Print formatted data to display, at (col, row). Calculates lengths and creates appropriate buffer int...
const ButtonReader & buttonReader
void printNTC(uint8_t col, uint8_t row, uint8_t i)
Print temperature read from thermistors. Handles NaN values as 0.
void blink(uint8_t col, uint8_t row, const char *buf)
Print blinking text.
Load/save an (internal) ConfigStore in EEPROM.
void reset()
Reset the config store: overwrite the configStore with the default values.
uint16_t save() const
Saves current content of configStore into EEPROM.
TUI for 128*64 px graphical display using U8g2. Holds references to a U8g2lib instance for writing to...
void setCursor(uint8_t col, uint8_t row) override
Set cursor to coordinates.
uint8_t configSaveTimer
Timer containing the current value of the cooldown on saving config to EEPROM.
Action
Config tab action definitions.
void clear() override
Clear screen.
GraphicalDisplayUI(U8G2 *u8g2, const ButtonReader *buttonReader, SingleHumidistat *humidistat, etl::span< const ThermistorReader, 4 > trs, EEPROMConfig *eepromConfig, SetpointProfileRunner *spr)
Constructor.
bool handleInputConfig(Buttons state, uint8_t pressedFor)
Handle input on the Config tab.
void drawMain()
Draw the Main tab.
Selection
Config tab selection definitions.
const uint16_t longPressDuration
Humidistat_t & humidistat
bool handleInput(Buttons state, uint16_t pressedFor) override
Handle input.
const uint8_t configSaveCooldown
GraphicalDisplayUI(U8G2 *u8g2, const ButtonReader *buttonReader, CascadeHumidistat *humidistat, etl::span< const ThermistorReader, 4 > trs, EEPROMConfig *eepromConfig, SetpointProfileRunner *spr)
const uint8_t nConfigPars
Total number of config parameters.
uint8_t currentPar
Currently active config parameter.
void drawTabBar()
Draw the tab bar.
void begin() override
Initialize the display.
bool handleInputInfo(Buttons state, uint16_t pressedFor)
Handle input on the Info tab.
EEPROMConfig & eepromConfig
bool handleInputMain(Buttons state, uint16_t pressedFor)
Handle input on the Main tab.
Tab currentTab
Currently active tab.
void drawConfig()
Draw the Config tab.
void draw() override
Draw main interface (main loop).
void drawSplash() override
Draw splash screen.
SetpointProfileRunner & spr
void drawInfo() override
Draw info screen.
const ConfigPar configPars[13]
Array of config parameters.
uint8_t frame
Frame counter (overflows, but that's OK)
void DrawMainCommon()
Draw common elements in Main tab.
Selection currentSelection
'Runs' a setpoint profile.
void setProfile(const etl::span< const Point > &profile)
Set the profile.
bool isRunning() const
Get the run state.
size_t getCurrentPoint() const
Get the index of the current Point in the profile.
void toggle()
Toggle the run state.
Control humidity using PID by driving two solenoid valves. Adjust the public setpoint variable and ca...
constexpr T ipow(T base, unsigned int pow)
Constexpr function for computing integer power.
SerialLogger< cHumidistat > serialLogger & humidistat
ButtonReader buttonReader(config::PIN_BTN, &voltLadder)
EEPROMConfig eepromConfig
const uint16_t longPressDuration
Duration for counting a press as 'long' (in millis)
const SPProfile profiles[]
Setpoint profile definitions.
const uint8_t configSaveCooldown
Cooldown on saving the config to EEPROM (in refresh cycles)
double HC_totalFlowrate
Total flowrate (for cascade controller) (L/min)
double a
Smoothing factor of EMA filter for derivative.
double HC_Kp
Humidity controller PID parameters.
bool loadedFromEEPROM
Whether this has been loaded from EEPROM.
double FC_Kp
Flow controller PID parameters.
double S_lowValue
Minimum solenoid duty cycle (deadband)
uint16_t dt
Global interval for PID/logger (based on polling rate of sensor, in millis)
const etl::span< const Point > profile