From ee9ee7319505793ed7371010bdb1de67845bc060 Mon Sep 17 00:00:00 2001 From: Petr Mikhalicin Date: Thu, 31 Oct 2024 10:29:16 +0500 Subject: [PATCH] Move to more efficient method of printing to display --- src/DisplayLine.cpp | 29 +++++++++++++------ src/DisplayLine.h | 1 + src/ModeProcessor.cpp | 2 +- src/ModeProcessor.h | 4 ++- src/Modes/FStopTestMode.cpp | 53 ++++++++++++++++++++++++----------- src/Modes/FStopTestMode.h | 2 ++ src/Modes/LinearTestMode.cpp | 47 +++++++++++++++++++++++-------- src/Modes/LinearTestMode.h | 2 ++ src/Modes/MaskMode.cpp | 54 ++++++++++++++++++++++++------------ src/Modes/MaskMode.h | 2 ++ src/Modes/PrintMode.cpp | 9 ++++++ src/Modes/PrintMode.h | 2 ++ src/SettingsSetter.cpp | 2 ++ src/main.cpp | 13 +++++++-- 14 files changed, 166 insertions(+), 56 deletions(-) diff --git a/src/DisplayLine.cpp b/src/DisplayLine.cpp index 14daac8..4e656d7 100644 --- a/src/DisplayLine.cpp +++ b/src/DisplayLine.cpp @@ -4,6 +4,8 @@ #include +#include "Tools.h" + void DisplayLine::concat(char* dst, const char* src) { int srcLen = strlen(src); int shift = strlen(dst); @@ -31,6 +33,8 @@ bool DisplayLine::tryPrint(const char* src, bool blink, uint8_t alignSize, const if (alignSize + dstlen > DISPLAY_COLS) return false; + m_needRepaint = true; + memset(m_fwInfo + dstlen, ' ', alignSize - srclen); m_fwInfo[dstlen + alignSize - srclen] = 0; @@ -47,6 +51,7 @@ bool DisplayLine::tryPrint(const char* src, bool blink, uint8_t alignSize, const } void DisplayLine::reset() { + m_needRepaint = true; m_fwInfo[0] = 0; m_bwInfo[0] = 0; m_blinkLength = 0; @@ -59,11 +64,18 @@ void DisplayLine::resetBlink(bool state) { } void DisplayLine::tick() { + if (!m_needRepaint && !m_blinkLength) + return; + m_needRepaint = false; + + char printBuf[DISPLAY_COLS + 1]; + auto fwLen = strlen(m_fwInfo); - memset(m_fwInfo + fwLen, ' ', DISPLAY_COLS - fwLen); + memcpy(printBuf, m_fwInfo, fwLen); + memset(printBuf + fwLen, ' ', DISPLAY_COLS - fwLen); auto bwLen = strlen(m_bwInfo); - memcpy(m_fwInfo + DISPLAY_COLS - bwLen, m_bwInfo, bwLen); + memcpy(printBuf + DISPLAY_COLS - bwLen, m_bwInfo, bwLen); if (m_blinkLength) { if (millis() - m_blinkTimer > 500) { @@ -72,38 +84,39 @@ void DisplayLine::tick() { } if (m_blinkState) { - memset(m_fwInfo + m_blinkPos, ' ', m_blinkLength); + memset(printBuf + m_blinkPos, ' ', m_blinkLength); if (m_mark) { uint8_t marklen = strlen(m_mark); - memcpy(m_fwInfo + m_blinkPos + m_blinkLength - marklen, m_mark, marklen); + memcpy(printBuf + m_blinkPos + m_blinkLength - marklen, m_mark, marklen); } } } m_lcd.setCursor(0, m_line); - - m_lcd.print(m_fwInfo); - - reset(); + m_lcd.print(printBuf); } DisplayLine& DisplayLine::operator<<(const char* src) { + m_needRepaint = true; concat(m_fwInfo, src); return *this; } DisplayLine& DisplayLine::operator<<(int value) { + m_needRepaint = true; concatInt(m_fwInfo, value); return *this; } DisplayLine& DisplayLine::operator>>(const char* src) { + m_needRepaint = true; concat(m_bwInfo, src); return *this; } DisplayLine& DisplayLine::operator>>(int value) { + m_needRepaint = true; concatInt(m_bwInfo, value); return *this; } diff --git a/src/DisplayLine.h b/src/DisplayLine.h index 7c680b2..ecaab38 100644 --- a/src/DisplayLine.h +++ b/src/DisplayLine.h @@ -26,6 +26,7 @@ class DisplayLine { static void concat(char* dst, const char* src); static void concatInt(char* dst, int value); + bool m_needRepaint = false; int m_line; LiquidCrystal& m_lcd; diff --git a/src/ModeProcessor.cpp b/src/ModeProcessor.cpp index 712c414..7860ec1 100644 --- a/src/ModeProcessor.cpp +++ b/src/ModeProcessor.cpp @@ -4,7 +4,7 @@ #include "Tools.h" void ModeProcessor::printTimeHelper(Time (*timeGetter)(const void* ctx, uint8_t id, bool& current, const char*& mark), - const void* ctx) const { + const void* ctx) const { uint8_t id = 0; for (uint8_t row = 0; row != DISPLAY_ROWS; ++row) { diff --git a/src/ModeProcessor.h b/src/ModeProcessor.h index 770d844..d264d3b 100644 --- a/src/ModeProcessor.h +++ b/src/ModeProcessor.h @@ -11,7 +11,9 @@ class ModeProcessor { virtual const char* preview() const = 0; + virtual void repaint() const = 0; + protected: void printTimeHelper(Time (*timeGetter)(const void* ctx, uint8_t id, bool& current, const char*& mark), - const void* ctx) const; + const void* ctx) const; }; diff --git a/src/Modes/FStopTestMode.cpp b/src/Modes/FStopTestMode.cpp index 3acd0d7..db1d003 100644 --- a/src/Modes/FStopTestMode.cpp +++ b/src/Modes/FStopTestMode.cpp @@ -12,6 +12,8 @@ FStopTestMode::FStopTestMode(bool splitGrade) : kSplit(splitGrade) { m_FStopPartId = 5; m_step = kSplit ? Step::baseTime : Step::initTime; m_currentRun = kSplit ? 0 : 1; + + repaint(); } void FStopTestMode::switchMode() { @@ -21,35 +23,30 @@ void FStopTestMode::switchMode() { m_currentRun = kSplit ? 0 : 1; gTimer.reset(); + + repaint(); } void FStopTestMode::process() { switch (m_step) { case Step::baseTime: - gDisplay[0] << preview(); - - getTime(m_baseTime); - gDisplay[1] << "Base t:" << m_baseTime; + if (getTime(m_baseTime)) + repaint(); return; case Step::initTime: - gDisplay[0] << preview(); - - getTime(m_initTime); - gDisplay[1] << "Init t:" << m_initTime; + if (getTime(m_initTime)) + repaint(); return; - case Step::fstopSet: { - gDisplay[0] << preview(); - - getInt(m_FStopPartId, 0, sizeof(kFStopPartVarinatns) - 1); - gDisplay[1] << "F stop: 1/" << kFStopPartVarinatns[m_FStopPartId]; - } + case Step::fstopSet: + if (getInt(m_FStopPartId, 0, sizeof(kFStopPartVarinatns) - 1)) + repaint(); return; case Step::run: break; } - gDisplay[0] << "Run "; - printTimes(); + if (gTimer.state() == Timer::RUNNING) + repaint(); if (gTimer.state() == Timer::STOPPED && gStartBtn.click() && getStepTotalTime(m_currentRun) != kBadTime) gTimer.start(getPrintTime()); @@ -60,6 +57,30 @@ void FStopTestMode::process() { gBeeper.alarm("Change filter"); } ++m_currentRun; + repaint(); + } +} + +void FStopTestMode::repaint() const { + gDisplay.reset(); + + switch (m_step) { + case Step::baseTime: + gDisplay[0] << preview(); + gDisplay[1] << "Base t:" << m_baseTime; + return; + case Step::initTime: + gDisplay[0] << preview(); + gDisplay[1] << "Init t:" << m_initTime; + return; + case Step::fstopSet: + gDisplay[0] << preview(); + gDisplay[1] << "F stop: 1/" << kFStopPartVarinatns[m_FStopPartId]; + return; + case Step::run: + gDisplay[0] << "Run "; + printTimes(); + return; } } diff --git a/src/Modes/FStopTestMode.h b/src/Modes/FStopTestMode.h index df8605a..fb79c8e 100644 --- a/src/Modes/FStopTestMode.h +++ b/src/Modes/FStopTestMode.h @@ -15,6 +15,8 @@ class FStopTestMode final : public ModeProcessor { const char* preview() const override; + void repaint() const override; + private: void printTimes() const; Time getPrintTime() const; diff --git a/src/Modes/LinearTestMode.cpp b/src/Modes/LinearTestMode.cpp index 946cf00..5104a5c 100644 --- a/src/Modes/LinearTestMode.cpp +++ b/src/Modes/LinearTestMode.cpp @@ -8,6 +8,8 @@ LinearTestMode::LinearTestMode(bool splitGrade) : kSplit(splitGrade) { m_stepTime = 2_s; m_step = kSplit ? Step::baseTime : Step::initTime; m_currentRun = kSplit ? 0 : 1; + + repaint(); } void LinearTestMode::switchMode() { @@ -17,31 +19,30 @@ void LinearTestMode::switchMode() { m_currentRun = kSplit ? 0 : 1; gTimer.reset(); + + repaint(); } void LinearTestMode::process() { switch (m_step) { case Step::baseTime: - gDisplay[0] << preview(); - getTime(m_baseTime); - gDisplay[1] << "Base t:" << m_baseTime; + if (getTime(m_baseTime)) + repaint(); return; case Step::initTime: - gDisplay[0] << preview(); - getTime(m_initTime); - gDisplay[1] << "Init t:" << m_initTime; + if (getTime(m_initTime)) + repaint(); return; case Step::stepTime: - gDisplay[0] << preview(); - getTime(m_stepTime); - gDisplay[1] << "Step t:" << m_stepTime; + if (getTime(m_stepTime)) + repaint(); return; case Step::run: break; } - gDisplay[0] << "Run "; - printTimes(); + if (gTimer.state() == Timer::RUNNING) + repaint(); if (gTimer.state() == Timer::STOPPED && gStartBtn.click() && getTotalTime(m_currentRun) != kBadTime) gTimer.start(getPrintTime()); @@ -52,6 +53,30 @@ void LinearTestMode::process() { gBeeper.alarm("Change filter"); } ++m_currentRun; + repaint(); + } +} + +void LinearTestMode::repaint() const { + gDisplay.reset(); + + switch (m_step) { + case Step::baseTime: + gDisplay[0] << preview(); + gDisplay[1] << "Base t:" << m_baseTime; + return; + case Step::initTime: + gDisplay[0] << preview(); + gDisplay[1] << "Init t:" << m_initTime; + return; + case Step::stepTime: + gDisplay[0] << preview(); + gDisplay[1] << "Step t:" << m_stepTime; + return; + case Step::run: + gDisplay[0] << "Run "; + printTimes(); + break; } } diff --git a/src/Modes/LinearTestMode.h b/src/Modes/LinearTestMode.h index a1911c0..cd85ecc 100644 --- a/src/Modes/LinearTestMode.h +++ b/src/Modes/LinearTestMode.h @@ -15,6 +15,8 @@ class LinearTestMode final : public ModeProcessor { const char* preview() const override; + void repaint() const override; + private: void printTimes() const; Time getPrintTime() const; diff --git a/src/Modes/MaskMode.cpp b/src/Modes/MaskMode.cpp index 3808435..441c581 100644 --- a/src/Modes/MaskMode.cpp +++ b/src/Modes/MaskMode.cpp @@ -12,6 +12,8 @@ MaskMode::MaskMode() { for (uint8_t i = 1; i != kMasksMaxNumber; ++i) m_masks[i] = kBadTime; + + repaint(); } void MaskMode::switchMode() { @@ -26,30 +28,34 @@ void MaskMode::switchMode() { for (uint8_t i = m_numberOfMasks; i != kMasksMaxNumber; ++i) m_masks[i] = kBadTime; + repaint(); return; } if (m_currentMask + 1 == m_numberOfMasks) { m_step = Step::run; m_currentMask = 0; + repaint(); return; } ++m_currentMask; - if (m_currentMask == 0 || m_masks[m_currentMask] != kBadTime) + if (m_currentMask == 0 || m_masks[m_currentMask] != kBadTime) { + repaint(); return; + } // let's guess unknown masks m_masks[m_currentMask] = m_masks[m_currentMask - 1]; + repaint(); } void MaskMode::process() { switch (m_step) { case Step::setNum: - gDisplay[0] << preview(); - getInt(m_numberOfMasks, 2, kMasksMaxNumber); - gDisplay[1] << "Mask num: " << m_numberOfMasks; + if (getInt(m_numberOfMasks, 2, kMasksMaxNumber)) + repaint(); return; case Step::setMasks: processSetMasks(); @@ -66,23 +72,15 @@ void MaskMode::processSetMasks() { gDisplay.resetBlink(true); } - bool changed = getTime(m_masks[m_currentMask]); - - if (changed) + if (getTime(m_masks[m_currentMask])) { + repaint(); gDisplay.resetBlink(); - - gDisplay[0] << "Set "; - - printTimes(); + } } void MaskMode::processRun() { - gDisplay[0] << "Run "; - - printTimes(); - - if (m_currentMask == m_numberOfMasks) - gDisplay[1] >> " Finish"; + if (gTimer.state() == Timer::RUNNING) + repaint(); if (gTimer.state() == Timer::STOPPED && gStartBtn.click() && m_currentMask < m_numberOfMasks) gTimer.start(m_masks[m_currentMask]); @@ -91,6 +89,28 @@ void MaskMode::processRun() { if (m_notifyMask & (1 << m_currentMask)) gBeeper.alarm("Notification"); ++m_currentMask; + repaint(); + } +} + +void MaskMode::repaint() const { + gDisplay.reset(); + + switch (m_step) { + case Step::setNum: + gDisplay[0] << preview(); + gDisplay[1] << "Mask num: " << m_numberOfMasks; + return; + case Step::setMasks: + gDisplay[0] << "Set "; + printTimes(); + return; + case Step::run: + gDisplay[0] << "Run "; + printTimes(); + if (m_currentMask == m_numberOfMasks) + gDisplay[1] >> " Finish"; + return; } } diff --git a/src/Modes/MaskMode.h b/src/Modes/MaskMode.h index a7fc8a6..4d2073e 100644 --- a/src/Modes/MaskMode.h +++ b/src/Modes/MaskMode.h @@ -15,6 +15,8 @@ class MaskMode final : public ModeProcessor { const char* preview() const override { return "Mask printing"; } + void repaint() const override; + private: void processRun(); void processSetMasks(); diff --git a/src/Modes/PrintMode.cpp b/src/Modes/PrintMode.cpp index ac315fc..d1dc999 100644 --- a/src/Modes/PrintMode.cpp +++ b/src/Modes/PrintMode.cpp @@ -6,13 +6,18 @@ PrintMode::PrintMode() { m_printTime = 8_s; m_triggerByHold = false; m_logSize = 0; + + repaint(); } void PrintMode::switchMode() { m_triggerByHold = !m_triggerByHold; + repaint(); } void PrintMode::process() { + gDisplay.reset(); + gDisplay[0] << "Prnt " << (m_triggerByHold ? "HLD T:" : "CLK T:") << gTimer.total(); if (gTimer.stopped()) @@ -62,6 +67,10 @@ void PrintMode::process() { } } +void PrintMode::repaint() const { + // TODO +} + void PrintMode::reset() { appendPrintLog(gTimer.afterLastResume()); } diff --git a/src/Modes/PrintMode.h b/src/Modes/PrintMode.h index e99f57f..e674d58 100644 --- a/src/Modes/PrintMode.h +++ b/src/Modes/PrintMode.h @@ -15,6 +15,8 @@ class PrintMode final : public ModeProcessor { const char* preview() const override { return "Printing"; } + void repaint() const override; + private: void appendPrintLog(const Time&); void resetPrintInfo(); diff --git a/src/SettingsSetter.cpp b/src/SettingsSetter.cpp index 8e20fb5..f0689e2 100644 --- a/src/SettingsSetter.cpp +++ b/src/SettingsSetter.cpp @@ -104,6 +104,8 @@ void SettingsSetter::processSetMelody() const { } void SettingsSetter::process() { + gDisplay.reset(); + if (m_timer.state() != Timer::RUNNING) { int8_t shift = 0; if (gModeSwitchBtn.click()) diff --git a/src/main.cpp b/src/main.cpp index ccd4b4c..672c316 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,8 +54,9 @@ void processModeSwitch() { if (gBlocked && !gBlockedByPreview) return; - if (!gModeSwitchBtn.pressing()) { + if (!gModeSwitchBtn.pressing() && gBlockedByPreview) { gBlocked = gBlockedByPreview = false; + gModeProcessor->repaint(); return; } @@ -73,8 +74,10 @@ void processModeSwitch() { gTimer.reset(); } - if (gBlockedByPreview) + if (gBlockedByPreview) { + gDisplay.reset(); gDisplay[0] << gModeProcessor->preview(); + } gBlocked = gBlockedByPreview; } @@ -95,6 +98,7 @@ void processSettings() { return; delete gSettingsSetter; gSettingsSetter = nullptr; + gModeProcessor->repaint(); } else { gSettingsSetter = new SettingsSetter; } @@ -118,6 +122,9 @@ void processView() { gViewState = !gViewState; digitalWrite(RELAY, gViewState); gViewModeTurnOffTime = millis() + gSettings.autoFinishViewMinutes * 60000L; + + if (gViewState == LOW) + gModeProcessor->repaint(); } gBlocked = gViewState; @@ -125,6 +132,7 @@ void processView() { if (gViewState != HIGH) return; + gDisplay.reset(); gDisplay[0] << "View"; if (!gSettings.autoFinishViewMinutes) { @@ -153,6 +161,7 @@ void processMode() { if (gExtraBtn.hold()) { gModeProcessor->reset(); gTimer.reset(); + gModeProcessor->repaint(); } if (!gBlocked && gModeSwitchBtn.click())