From 3d68f483ce9a4493d213c1c81dc279ee015c0896 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Mon, 27 Nov 2017 15:28:00 +0100 Subject: [PATCH 1/9] PlatformIO folder structure Moved and renamed files, not compiled yet --- .gitignore | 1 + UVControl.sublime-project | 9 +++++++++ build.ps1 | 1 + platformio.ini | 20 +++++++++++++++++++ Buzzer.cpp => src/Buzzer.cpp | 0 Buzzer.h => src/Buzzer.h | 0 Config.cpp => src/Config.cpp | 0 Config.h => src/Config.h | 0 ExposureTimer.cpp => src/ExposureTimer.cpp | 0 ExposureTimer.h => src/ExposureTimer.h | 0 .../ScreenCountdown.cpp | 0 ScreenCountdown.h => src/ScreenCountdown.h | 0 ScreenManager.cpp => src/ScreenManager.cpp | 0 ScreenManager.h => src/ScreenManager.h | 0 ScreenMenu.cpp => src/ScreenMenu.cpp | 0 ScreenMenu.h => src/ScreenMenu.h | 0 ScreenSetTime.cpp => src/ScreenSetTime.cpp | 0 ScreenSetTime.h => src/ScreenSetTime.h | 0 UVControl.ino => src/main.cpp | 0 upload.ps1 | 1 + 20 files changed, 32 insertions(+) create mode 100644 .gitignore create mode 100644 UVControl.sublime-project create mode 100644 build.ps1 create mode 100644 platformio.ini rename Buzzer.cpp => src/Buzzer.cpp (100%) rename Buzzer.h => src/Buzzer.h (100%) rename Config.cpp => src/Config.cpp (100%) rename Config.h => src/Config.h (100%) rename ExposureTimer.cpp => src/ExposureTimer.cpp (100%) rename ExposureTimer.h => src/ExposureTimer.h (100%) rename ScreenCountdown.cpp => src/ScreenCountdown.cpp (100%) rename ScreenCountdown.h => src/ScreenCountdown.h (100%) rename ScreenManager.cpp => src/ScreenManager.cpp (100%) rename ScreenManager.h => src/ScreenManager.h (100%) rename ScreenMenu.cpp => src/ScreenMenu.cpp (100%) rename ScreenMenu.h => src/ScreenMenu.h (100%) rename ScreenSetTime.cpp => src/ScreenSetTime.cpp (100%) rename ScreenSetTime.h => src/ScreenSetTime.h (100%) rename UVControl.ino => src/main.cpp (100%) create mode 100644 upload.ps1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c51a0ea --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.sublime-workspace \ No newline at end of file diff --git a/UVControl.sublime-project b/UVControl.sublime-project new file mode 100644 index 0000000..b01586b --- /dev/null +++ b/UVControl.sublime-project @@ -0,0 +1,9 @@ +{ + "folders": + [ + { + "path": ".", + "file_exclude_patterns": ["*.sublime-project"] + } + ] +} \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..c2fb43d --- /dev/null +++ b/build.ps1 @@ -0,0 +1 @@ +& platformio run \ No newline at end of file diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..557489b --- /dev/null +++ b/platformio.ini @@ -0,0 +1,20 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + +[env:attiny85] +platform = atmelavr +board = atmega328p +framework = arduino +upload_protocol = stk500v1 +upload_flags = -P$UPLOAD_PORT -b$UPLOAD_SPEED +board_f_cpu = 1000000L + +upload_port = COM7 +upload_speed = 19200 \ No newline at end of file diff --git a/Buzzer.cpp b/src/Buzzer.cpp similarity index 100% rename from Buzzer.cpp rename to src/Buzzer.cpp diff --git a/Buzzer.h b/src/Buzzer.h similarity index 100% rename from Buzzer.h rename to src/Buzzer.h diff --git a/Config.cpp b/src/Config.cpp similarity index 100% rename from Config.cpp rename to src/Config.cpp diff --git a/Config.h b/src/Config.h similarity index 100% rename from Config.h rename to src/Config.h diff --git a/ExposureTimer.cpp b/src/ExposureTimer.cpp similarity index 100% rename from ExposureTimer.cpp rename to src/ExposureTimer.cpp diff --git a/ExposureTimer.h b/src/ExposureTimer.h similarity index 100% rename from ExposureTimer.h rename to src/ExposureTimer.h diff --git a/ScreenCountdown.cpp b/src/ScreenCountdown.cpp similarity index 100% rename from ScreenCountdown.cpp rename to src/ScreenCountdown.cpp diff --git a/ScreenCountdown.h b/src/ScreenCountdown.h similarity index 100% rename from ScreenCountdown.h rename to src/ScreenCountdown.h diff --git a/ScreenManager.cpp b/src/ScreenManager.cpp similarity index 100% rename from ScreenManager.cpp rename to src/ScreenManager.cpp diff --git a/ScreenManager.h b/src/ScreenManager.h similarity index 100% rename from ScreenManager.h rename to src/ScreenManager.h diff --git a/ScreenMenu.cpp b/src/ScreenMenu.cpp similarity index 100% rename from ScreenMenu.cpp rename to src/ScreenMenu.cpp diff --git a/ScreenMenu.h b/src/ScreenMenu.h similarity index 100% rename from ScreenMenu.h rename to src/ScreenMenu.h diff --git a/ScreenSetTime.cpp b/src/ScreenSetTime.cpp similarity index 100% rename from ScreenSetTime.cpp rename to src/ScreenSetTime.cpp diff --git a/ScreenSetTime.h b/src/ScreenSetTime.h similarity index 100% rename from ScreenSetTime.h rename to src/ScreenSetTime.h diff --git a/UVControl.ino b/src/main.cpp similarity index 100% rename from UVControl.ino rename to src/main.cpp diff --git a/upload.ps1 b/upload.ps1 new file mode 100644 index 0000000..9b3c625 --- /dev/null +++ b/upload.ps1 @@ -0,0 +1 @@ +& platformio run --target upload \ No newline at end of file From bd7a616e2be99557d6830ae8eadbcf07c8a4befe Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Mon, 27 Nov 2017 15:51:32 +0100 Subject: [PATCH 2/9] Fixed code for PlatformIO --- .gitignore | 4 +++- platformio.ini | 6 +++++- src/ScreenCountdown.cpp | 16 ++++++++-------- src/ScreenManager.h | 26 ++++++++++++++------------ src/main.cpp | 6 +++--- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index c51a0ea..b2d534d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -*.sublime-workspace \ No newline at end of file +*.sublime-workspace +.pioenvs +.piolibdeps \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 557489b..cb3284e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,11 +10,15 @@ [env:attiny85] platform = atmelavr -board = atmega328p +board = pro16MHzatmega328 framework = arduino upload_protocol = stk500v1 upload_flags = -P$UPLOAD_PORT -b$UPLOAD_SPEED board_f_cpu = 1000000L +lib_deps = + Bounce2 + Encoder + upload_port = COM7 upload_speed = 19200 \ No newline at end of file diff --git a/src/ScreenCountdown.cpp b/src/ScreenCountdown.cpp index 8779439..f19290f 100644 --- a/src/ScreenCountdown.cpp +++ b/src/ScreenCountdown.cpp @@ -13,14 +13,14 @@ void ScreenCountdown::printRemainingTime() void ScreenCountdown::onShow() -{ +{ mLastDisplayed = -1; - + getDisplay()->setCursor(0, 0); getDisplay()->print("Exposing... "); printRemainingTime(); - digitalWrite(PinLED, HIGH); + digitalWrite(PinLED, HIGH); } @@ -40,24 +40,24 @@ void ScreenCountdown::onButton() void ScreenCountdown::onEncoder(long lastPosition, long newPosition) { - // TODO Allow adding / removing time? + // TODO Allow adding / removing time? } void ScreenCountdown::onTick() { - int elapsed = (getCurrentTime() - ExposureTimerStart) / 1000; + long elapsed = (getCurrentTime() - ExposureTimerStart) / 1000; if (elapsed >= ExposureTime) { getDisplay()->setCursor(0, 0); getDisplay()->print("Done! "); - + printRemainingTime(); digitalWrite(PinLED, LOW); - + buzzCompleted(); - + ExposureTimerStart = 0; getScreenManager()->show(); } diff --git a/src/ScreenManager.h b/src/ScreenManager.h index d0dce59..f0340b8 100644 --- a/src/ScreenManager.h +++ b/src/ScreenManager.h @@ -13,22 +13,24 @@ class BaseScreen ScreenManager* mScreenManager; protected: - ScreenManager* getScreenManager(); + ScreenManager* getScreenManager(); unsigned long getCurrentTime(); LiquidCrystal* getDisplay(); void printTime(int value); - + public: BaseScreen(ScreenManager* screenManager) { mScreenManager = screenManager; } + virtual ~BaseScreen() {} + virtual void onShow() = 0; virtual void onHide() = 0; - + virtual void onButton() = 0; virtual void onEncoder(long lastPosition, long newPosition) = 0; virtual void onTick() = 0; @@ -41,17 +43,17 @@ class ScreenManager private: LiquidCrystal* mDisplay; unsigned long* mCurrentTime; - + BaseScreen* mCurrent = NULL; - + public: ScreenManager(LiquidCrystal* display, unsigned long* currentTime) { mDisplay = display; mCurrentTime = currentTime; } - - + + inline BaseScreen* getCurrent() { return mCurrent; @@ -66,17 +68,17 @@ class ScreenManager inline LiquidCrystal* getDisplay() { return mDisplay; - } - - - template void ScreenManager::show() + } + + + template void show() { if (mCurrent != NULL) { mCurrent->onHide(); delete(mCurrent); } - + mCurrent = new T(this); mCurrent->onShow(); } diff --git a/src/main.cpp b/src/main.cpp index a98b0d5..526ccab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "Config.h" #include "ScreenManager.h" #include "ScreenSetTime.h" @@ -54,11 +54,11 @@ void loop() { currentTime = millis(); button.update(); - + long newPosition = encoder.read(); if (abs(newPosition - lastPosition) >= EncoderSensitivity) { - screenManager->getCurrent()->onEncoder(lastPosition, newPosition); + screenManager->getCurrent()->onEncoder(lastPosition, newPosition); lastPosition = newPosition; } From 9b62af6f11da2010c87dfadb0b0825bf4562c558 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Sat, 2 Dec 2017 12:47:29 +0100 Subject: [PATCH 3/9] Moved screens to subfolder --- src/{ => Screen}/ScreenCountdown.cpp | 0 src/{ => Screen}/ScreenCountdown.h | 0 src/{ => Screen}/ScreenMenu.cpp | 0 src/{ => Screen}/ScreenMenu.h | 0 src/{ => Screen}/ScreenSetTime.cpp | 8 ++++---- src/{ => Screen}/ScreenSetTime.h | 0 src/main.cpp | 2 +- 7 files changed, 5 insertions(+), 5 deletions(-) rename src/{ => Screen}/ScreenCountdown.cpp (100%) rename src/{ => Screen}/ScreenCountdown.h (100%) rename src/{ => Screen}/ScreenMenu.cpp (100%) rename src/{ => Screen}/ScreenMenu.h (100%) rename src/{ => Screen}/ScreenSetTime.cpp (92%) rename src/{ => Screen}/ScreenSetTime.h (100%) diff --git a/src/ScreenCountdown.cpp b/src/Screen/ScreenCountdown.cpp similarity index 100% rename from src/ScreenCountdown.cpp rename to src/Screen/ScreenCountdown.cpp diff --git a/src/ScreenCountdown.h b/src/Screen/ScreenCountdown.h similarity index 100% rename from src/ScreenCountdown.h rename to src/Screen/ScreenCountdown.h diff --git a/src/ScreenMenu.cpp b/src/Screen/ScreenMenu.cpp similarity index 100% rename from src/ScreenMenu.cpp rename to src/Screen/ScreenMenu.cpp diff --git a/src/ScreenMenu.h b/src/Screen/ScreenMenu.h similarity index 100% rename from src/ScreenMenu.h rename to src/Screen/ScreenMenu.h diff --git a/src/ScreenSetTime.cpp b/src/Screen/ScreenSetTime.cpp similarity index 92% rename from src/ScreenSetTime.cpp rename to src/Screen/ScreenSetTime.cpp index e0c3d3c..1f0f3ed 100644 --- a/src/ScreenSetTime.cpp +++ b/src/Screen/ScreenSetTime.cpp @@ -1,5 +1,5 @@ #include "ScreenSetTime.h" -#include "ScreenMenu.h" +#include "Screen/ScreenMenu.h" #include "ExposureTimer.h" #include "Buzzer.h" #include "Config.h" @@ -8,12 +8,12 @@ void ScreenSetTime::printExposureTime() { getDisplay()->setCursor(0, 1); - printTime(ExposureTime); + printTime(ExposureTime); } void ScreenSetTime::onShow() -{ +{ getDisplay()->setCursor(0, 0); getDisplay()->print("Exposure time: "); @@ -36,7 +36,7 @@ void ScreenSetTime::onButton() void ScreenSetTime::onEncoder(long lastPosition, long newPosition) { buzzSelect(); - + if (newPosition > lastPosition) ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; else if (ExposureTime > 0) diff --git a/src/ScreenSetTime.h b/src/Screen/ScreenSetTime.h similarity index 100% rename from src/ScreenSetTime.h rename to src/Screen/ScreenSetTime.h diff --git a/src/main.cpp b/src/main.cpp index 526ccab..2a04dff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,7 @@ #include #include "Config.h" #include "ScreenManager.h" -#include "ScreenSetTime.h" +#include "Screen/ScreenSetTime.h" #include "Buzzer.h" #include "ExposureTimer.h" From 70dfde856214a127dc90305c262f534550816e9b Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Sun, 3 Dec 2017 21:27:45 +0100 Subject: [PATCH 4/9] Changed menu system to allow for more settings like intensity --- platformio.ini | 12 +- src/Config.cpp | 41 +++++- src/Config.h | 12 +- src/ExposureTimer.cpp | 8 ++ src/ExposureTimer.h | 2 + src/Screen/BaseMenuScreen.cpp | 119 ++++++++++++++++++ src/Screen/BaseMenuScreen.h | 41 ++++++ ...creenCountdown.cpp => CountdownScreen.cpp} | 25 ++-- .../{ScreenCountdown.h => CountdownScreen.h} | 16 +-- src/Screen/IntensityScreen.cpp | 84 +++++++++++++ src/Screen/IntensityScreen.h | 36 ++++++ src/Screen/ScreenMenu.cpp | 100 --------------- src/Screen/ScreenMenu.h | 33 ----- src/Screen/ScreenSetTime.cpp | 52 -------- src/Screen/ScreenSetTime.h | 26 ---- src/Screen/SetTimeScreen.cpp | 74 +++++++++++ src/Screen/SetTimeScreen.h | 35 ++++++ src/Screen/StartScreen.cpp | 30 +++++ src/Screen/StartScreen.h | 29 +++++ src/ScreenManager.cpp | 19 --- src/ScreenManager.h | 3 - src/main.cpp | 10 +- 22 files changed, 544 insertions(+), 263 deletions(-) create mode 100644 src/Screen/BaseMenuScreen.cpp create mode 100644 src/Screen/BaseMenuScreen.h rename src/Screen/{ScreenCountdown.cpp => CountdownScreen.cpp} (59%) rename src/Screen/{ScreenCountdown.h => CountdownScreen.h} (66%) create mode 100644 src/Screen/IntensityScreen.cpp create mode 100644 src/Screen/IntensityScreen.h delete mode 100644 src/Screen/ScreenMenu.cpp delete mode 100644 src/Screen/ScreenMenu.h delete mode 100644 src/Screen/ScreenSetTime.cpp delete mode 100644 src/Screen/ScreenSetTime.h create mode 100644 src/Screen/SetTimeScreen.cpp create mode 100644 src/Screen/SetTimeScreen.h create mode 100644 src/Screen/StartScreen.cpp create mode 100644 src/Screen/StartScreen.h diff --git a/platformio.ini b/platformio.ini index cb3284e..3ed92f3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,13 +12,13 @@ platform = atmelavr board = pro16MHzatmega328 framework = arduino -upload_protocol = stk500v1 -upload_flags = -P$UPLOAD_PORT -b$UPLOAD_SPEED -board_f_cpu = 1000000L + +;upload_protocol = stk500v1 +;upload_flags = -P$UPLOAD_PORT -b$UPLOAD_SPEED +;upload_speed = 19200 + +board_f_cpu = 16000000L lib_deps = Bounce2 Encoder - -upload_port = COM7 -upload_speed = 19200 \ No newline at end of file diff --git a/src/Config.cpp b/src/Config.cpp index 77acd5f..f88fa33 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -1,6 +1,6 @@ #include "Config.h" -byte LCDCharArrow[8] = { +byte LCDCharArrowRightMap[8] = { B00000, B01000, B01100, @@ -10,3 +10,42 @@ byte LCDCharArrow[8] = { B00000, }; +byte LCDCharArrowLeftMap[8] = { + B00000, + B00100, + B01100, + B11100, + B01100, + B00100, + B00000, +}; + +byte LCDCharArrowRightHollowMap[8] = { + B00000, + B01000, + B00100, + B00010, + B00100, + B01000, + B00000, +}; + +byte LCDCharArrowLeftHollowMap[8] = { + B00000, + B00100, + B01000, + B10000, + B01000, + B00100, + B00000, +}; + +byte LCDCharUpDownMap[8] = { + B00000, + B00100, + B01110, + B00000, + B01110, + B00100, + B00000, +}; diff --git a/src/Config.h b/src/Config.h index d69e990..3ffe9d5 100644 --- a/src/Config.h +++ b/src/Config.h @@ -28,6 +28,16 @@ static const int LargeStep = 10; static const int MenuTimeout = 2000; -extern byte LCDCharArrow[8]; +static const uint8_t LCDCharArrowRight = 0; +static const uint8_t LCDCharArrowLeft = 1; +static const uint8_t LCDCharArrowRightHollow = 2; +static const uint8_t LCDCharArrowLeftHollow = 3; +static const uint8_t LCDCharUpDown = 4; + +extern byte LCDCharArrowRightMap[8]; +extern byte LCDCharArrowLeftMap[8]; +extern byte LCDCharArrowRightHollowMap[8]; +extern byte LCDCharArrowLeftHollowMap[8]; +extern byte LCDCharUpDownMap[8]; #endif diff --git a/src/ExposureTimer.cpp b/src/ExposureTimer.cpp index 06d4160..907a7a3 100644 --- a/src/ExposureTimer.cpp +++ b/src/ExposureTimer.cpp @@ -16,3 +16,11 @@ void StartExposureTimer(unsigned long currentTime) ExposureTimerStart = currentTime; } + +String FormatTime(unsigned int Time) +{ + String minutes = String(ExposureTime / 60); + String seconds = String(ExposureTime % 60); + + return minutes + ':' + (seconds.length() == 1 ? '0' + seconds : seconds); +} \ No newline at end of file diff --git a/src/ExposureTimer.h b/src/ExposureTimer.h index c35652d..62a89b6 100644 --- a/src/ExposureTimer.h +++ b/src/ExposureTimer.h @@ -10,4 +10,6 @@ extern unsigned long ExposureTimerStart; void ResetExposureTime(); void StartExposureTimer(unsigned long currentTime); +String FormatTime(unsigned int Time); + #endif diff --git a/src/Screen/BaseMenuScreen.cpp b/src/Screen/BaseMenuScreen.cpp new file mode 100644 index 0000000..ae6bf78 --- /dev/null +++ b/src/Screen/BaseMenuScreen.cpp @@ -0,0 +1,119 @@ +#include "Screen/BaseMenuScreen.h" +#include "Config.h" +#include "Buzzer.h" + + +void BaseMenuScreen::setEnableMenuScroll(bool value) +{ + if (value != mEnableMenuScroll) + { + mEnableMenuScroll = value; + printScrollIndicators(); + } +} + + +void BaseMenuScreen::onShow() +{ + printTitle(); + printScrollIndicators(); + printValue(); +} + + +void BaseMenuScreen::onHide() +{ +} + + +void BaseMenuScreen::printTitle() +{ + LiquidCrystal* display = getDisplay(); + + const char* title = getTitle(); + uint8_t titleLength = strlen(title); + uint8_t maxWidth = LCDWidth - 2; + + display->setCursor(1, 0); + + if (titleLength >= maxWidth) + { + // Title too long, cut off + char* character = (char*)title; + for (uint8_t i = 0; i < maxWidth; i++) + { + display->write(byte(*character)); + character++; + } + } + else + { + // Center title + uint8_t offset = (maxWidth - titleLength) / 2; + + for (uint8_t i = 0; i < offset; i++) + display->write(' '); + + display->print(title); + offset += titleLength; + + while (offset < LCDWidth - 2) + { + display->print(' '); + offset++; + } + } +} + + +void BaseMenuScreen::printScrollIndicators() +{ + LiquidCrystal* display = getDisplay(); + + display->setCursor(0, 0); + if (hasPrevious()) + display->write(getEnableMenuScroll() ? LCDCharArrowLeft : LCDCharArrowLeftHollow); + else + display->write(' '); + + display->setCursor(LCDWidth - 1, 0); + if (hasNext()) + display->write(getEnableMenuScroll() ? LCDCharArrowRight : LCDCharArrowRightHollow); + else + display->write(' '); +} + + +void BaseMenuScreen::printValue() +{ + LiquidCrystal* display = getDisplay(); + + display->setCursor(0, 1); + for (uint8_t x = 0; x < LCDWidth; x++) + display->write(' '); +} + + + +void BaseMenuScreen::onEncoder(long lastPosition, long newPosition) +{ + if (mEnableMenuScroll) + { + if (newPosition > lastPosition) + { + if (hasNext()) + { + buzzSelect(); + gotoNext(); + } + } + else + { + if (hasPrevious()) + { + buzzSelect(); + gotoPrevious(); + } + } + } +} diff --git a/src/Screen/BaseMenuScreen.h b/src/Screen/BaseMenuScreen.h new file mode 100644 index 0000000..6454f6e --- /dev/null +++ b/src/Screen/BaseMenuScreen.h @@ -0,0 +1,41 @@ +#ifndef __BaseMenuScreen +#define __BaseMenuScreen + +#include +#include "ScreenManager.h" + +/* + * Base menu screen + * Provides the base for a menu screen, allows scrolling to + * the previous or next menu screen or performs an action. + */ +class BaseMenuScreen : public BaseScreen +{ + private: + bool mEnableMenuScroll = true; + + protected: + bool getEnableMenuScroll() { return mEnableMenuScroll; } + void setEnableMenuScroll(bool value); + + virtual bool hasPrevious() = 0; + virtual bool hasNext() = 0; + + virtual const char* getTitle() = 0; + virtual void gotoPrevious() {} + virtual void gotoNext() {} + + void printTitle(); + void printScrollIndicators(); + virtual void printValue(); + + public: + BaseMenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { } + + virtual void onShow(); + virtual void onHide(); + + virtual void onEncoder(long lastPosition, long newPosition); +}; + +#endif \ No newline at end of file diff --git a/src/Screen/ScreenCountdown.cpp b/src/Screen/CountdownScreen.cpp similarity index 59% rename from src/Screen/ScreenCountdown.cpp rename to src/Screen/CountdownScreen.cpp index f19290f..2d4a2cc 100644 --- a/src/Screen/ScreenCountdown.cpp +++ b/src/Screen/CountdownScreen.cpp @@ -1,18 +1,21 @@ -#include "ScreenCountdown.h" -#include "ScreenSetTime.h" +#include "CountdownScreen.h" +#include "Screen/SetTimeScreen.h" #include "ExposureTimer.h" #include "Config.h" #include "Buzzer.h" -void ScreenCountdown::printRemainingTime() +void CountdownScreen::printRemainingTime() { getDisplay()->setCursor(0, 1); - printTime(ExposureTime - ((getCurrentTime() - ExposureTimerStart) / 1000)); + String time = FormatTime(ExposureTime - ((getCurrentTime() - ExposureTimerStart) / 1000)); + + // TODO blank out, center, etc + getDisplay()->print(time); } -void ScreenCountdown::onShow() +void CountdownScreen::onShow() { mLastDisplayed = -1; @@ -24,27 +27,27 @@ void ScreenCountdown::onShow() } -void ScreenCountdown::onHide() +void CountdownScreen::onHide() { digitalWrite(PinLED, LOW); } -void ScreenCountdown::onButton() +void CountdownScreen::onButton() { // TODO Confirmation? buzzClick(); - getScreenManager()->show(); + getScreenManager()->show(); } -void ScreenCountdown::onEncoder(long lastPosition, long newPosition) +void CountdownScreen::onEncoder(long lastPosition, long newPosition) { // TODO Allow adding / removing time? } -void ScreenCountdown::onTick() +void CountdownScreen::onTick() { long elapsed = (getCurrentTime() - ExposureTimerStart) / 1000; @@ -59,7 +62,7 @@ void ScreenCountdown::onTick() buzzCompleted(); ExposureTimerStart = 0; - getScreenManager()->show(); + getScreenManager()->show(); } else if (elapsed != mLastDisplayed) { diff --git a/src/Screen/ScreenCountdown.h b/src/Screen/CountdownScreen.h similarity index 66% rename from src/Screen/ScreenCountdown.h rename to src/Screen/CountdownScreen.h index 48cb77b..9927cda 100644 --- a/src/Screen/ScreenCountdown.h +++ b/src/Screen/CountdownScreen.h @@ -1,5 +1,5 @@ -#ifndef __ScreenCountdown -#define __ScreenCountdown +#ifndef __CountdownScreen +#define __CountdownScreen #include "ScreenManager.h" @@ -7,20 +7,20 @@ * Countdown screen * Shows the remaining time. */ -class ScreenCountdown : public BaseScreen +class CountdownScreen : public BaseScreen { private: int mLastDisplayed; - + protected: void printRemainingTime(); - + public: - ScreenCountdown(ScreenManager* screenManager) : BaseScreen(screenManager) { } - + CountdownScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { } + void onShow(); void onHide(); - + void onButton(); void onEncoder(long lastPosition, long newPosition); void onTick(); diff --git a/src/Screen/IntensityScreen.cpp b/src/Screen/IntensityScreen.cpp new file mode 100644 index 0000000..99c58f5 --- /dev/null +++ b/src/Screen/IntensityScreen.cpp @@ -0,0 +1,84 @@ +#include "Screen/IntensityScreen.h" +#include "Screen/SetTimeScreen.h" +#include "Screen/StartScreen.h" +#include "ExposureTimer.h" +#include "Buzzer.h" +#include "Config.h" + + +void IntensityScreen::printValue() +{ + LiquidCrystal* display = getDisplay(); + display->setCursor(0, 1); + + String intensity = "100%"; + uint8_t offset = (LCDWidth - intensity.length()) / 2; + + for (uint8_t space = 0; space < offset; space++) + display->print(' '); + + display->print(intensity); + offset += intensity.length(); + + if (getEditMode()) + { + display->write(LCDCharUpDown); + offset++; + } + + for (uint8_t space = offset; space < LCDWidth; space++) + display->print(' '); +} + + +void IntensityScreen::gotoPrevious() +{ + buzzSelect(); + getScreenManager()->show(); +} + + +void IntensityScreen::gotoNext() +{ + buzzSelect(); + getScreenManager()->show(); +} + + +void IntensityScreen::onHide() +{ +} + + +void IntensityScreen::onButton() +{ + buzzSelect(); + setEditMode(!getEditMode()); + printValue(); +} + + +void IntensityScreen::onEncoder(long lastPosition, long newPosition) +{ + if (getEditMode()) + { + buzzSelect(); + +/* + if (newPosition > lastPosition) + ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; + else if (ExposureTime > 0) + ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; + */ + + printValue(); + } + else + BaseMenuScreen::onEncoder(lastPosition, newPosition); +} + + +void IntensityScreen::onTick() +{ +} + diff --git a/src/Screen/IntensityScreen.h b/src/Screen/IntensityScreen.h new file mode 100644 index 0000000..42de608 --- /dev/null +++ b/src/Screen/IntensityScreen.h @@ -0,0 +1,36 @@ +#ifndef __IntensityScreen +#define __IntensityScreen + +#include "ScreenManager.h" +#include "Screen/BaseMenuScreen.h" + +/* + * Intensity screen + * Allows changing of the intensity. + */ +class IntensityScreen : public BaseMenuScreen +{ + protected: + inline bool getEditMode() { return !getEnableMenuScroll(); } + inline void setEditMode(bool value) { setEnableMenuScroll(!value); } + + bool hasPrevious() { return true; } + bool hasNext() { return true; } + + const char* getTitle() { return "Intensity"; } + void gotoPrevious(); + void gotoNext(); + + void printValue(); + + public: + IntensityScreen(ScreenManager* screenManager) : BaseMenuScreen(screenManager) { } + + void onHide(); + + void onButton(); + void onEncoder(long lastPosition, long newPosition); + void onTick(); +}; + +#endif diff --git a/src/Screen/ScreenMenu.cpp b/src/Screen/ScreenMenu.cpp deleted file mode 100644 index e677a39..0000000 --- a/src/Screen/ScreenMenu.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "ScreenMenu.h" -#include "ScreenSetTime.h" -#include "ScreenCountdown.h" -#include "ExposureTimer.h" -#include "Config.h" -#include "Buzzer.h" - - -void ScreenMenu::updateLastActivity() -{ - mLastActivity = getCurrentTime(); -} - - -void ScreenMenu::printExposureTime() -{ - getDisplay()->setCursor(0, 1); - printTime(ExposureTime); -} - - -void ScreenMenu::printMenuCursor() -{ - getDisplay()->setCursor(0, 0); - getDisplay()->write(mSelected == 0 ? (byte)0 : ' '); - - getDisplay()->setCursor(9, 0); - getDisplay()->write(mSelected == 1 ? (byte)0 : ' '); -} - - -void ScreenMenu::onShow() -{ - updateLastActivity(); - mSelected = 0; - - getDisplay()->setCursor(0, 0); - getDisplay()->print(" Start Reset "); - - printMenuCursor(); - printExposureTime(); -} - - -void ScreenMenu::onHide() -{ -} - - -void ScreenMenu::onButton() -{ - buzzClick(); - - switch (mSelected) - { - case 0: - digitalWrite(PinLED, HIGH); - - StartExposureTimer(getCurrentTime()); - getScreenManager()->show(); - break; - - case 1: - ResetExposureTime(); - getScreenManager()->show(); - } -} - - -void ScreenMenu::onEncoder(long lastPosition, long newPosition) -{ - updateLastActivity(); - - if (newPosition > lastPosition) - { - if (mSelected < 1) - { - buzzSelect(); - mSelected++; - printMenuCursor(); - } - } - else - { - if (mSelected > 0) - { - buzzSelect(); - mSelected--; - printMenuCursor(); - } - } -} - - -void ScreenMenu::onTick() -{ - if (getCurrentTime() - mLastActivity >= MenuTimeout) - getScreenManager()->show(); -} - diff --git a/src/Screen/ScreenMenu.h b/src/Screen/ScreenMenu.h deleted file mode 100644 index cbf2764..0000000 --- a/src/Screen/ScreenMenu.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __ScreenMenu -#define __ScreenMenu - -#include "ScreenManager.h" - -/* - * Menu screen - * Allows starting the timer or resetting the time to the last used value. - */ -class ScreenMenu : public BaseScreen -{ - private: - int mSelected; - unsigned long mLastActivity; - - protected: - void updateLastActivity(); - - void printExposureTime(); - void printMenuCursor(); - - public: - ScreenMenu(ScreenManager* screenManager) : BaseScreen(screenManager) { } - - void onShow(); - void onHide(); - - void onButton(); - void onEncoder(long lastPosition, long newPosition); - void onTick(); -}; - -#endif diff --git a/src/Screen/ScreenSetTime.cpp b/src/Screen/ScreenSetTime.cpp deleted file mode 100644 index 1f0f3ed..0000000 --- a/src/Screen/ScreenSetTime.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "ScreenSetTime.h" -#include "Screen/ScreenMenu.h" -#include "ExposureTimer.h" -#include "Buzzer.h" -#include "Config.h" - - -void ScreenSetTime::printExposureTime() -{ - getDisplay()->setCursor(0, 1); - printTime(ExposureTime); -} - - -void ScreenSetTime::onShow() -{ - getDisplay()->setCursor(0, 0); - getDisplay()->print("Exposure time: "); - - printExposureTime(); -} - - -void ScreenSetTime::onHide() -{ -} - - -void ScreenSetTime::onButton() -{ - buzzClick(); - getScreenManager()->show(); -} - - -void ScreenSetTime::onEncoder(long lastPosition, long newPosition) -{ - buzzSelect(); - - if (newPosition > lastPosition) - ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; - else if (ExposureTime > 0) - ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; - - printExposureTime(); -} - - -void ScreenSetTime::onTick() -{ -} - diff --git a/src/Screen/ScreenSetTime.h b/src/Screen/ScreenSetTime.h deleted file mode 100644 index fca59e9..0000000 --- a/src/Screen/ScreenSetTime.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __ScreenSetTime -#define __ScreenSetTime - -#include "ScreenManager.h" - -/* - * Time screen - * Allows changing of the exposure time. Pressing the button will switch to the menu. - */ -class ScreenSetTime : public BaseScreen -{ - protected: - void printExposureTime(); - - public: - ScreenSetTime(ScreenManager* screenManager) : BaseScreen(screenManager) { } - - void onShow(); - void onHide(); - - void onButton(); - void onEncoder(long lastPosition, long newPosition); - void onTick(); -}; - -#endif diff --git a/src/Screen/SetTimeScreen.cpp b/src/Screen/SetTimeScreen.cpp new file mode 100644 index 0000000..2e7f0fd --- /dev/null +++ b/src/Screen/SetTimeScreen.cpp @@ -0,0 +1,74 @@ +#include "Screen/SetTimeScreen.h" +#include "Screen/IntensityScreen.h" +#include "ExposureTimer.h" +#include "Buzzer.h" +#include "Config.h" + + +void SetTimeScreen::printValue() +{ + LiquidCrystal* display = getDisplay(); + display->setCursor(0, 1); + + String time = FormatTime(ExposureTime); + uint8_t offset = (LCDWidth - time.length()) / 2; + + for (uint8_t space = 0; space < offset; space++) + display->print(' '); + + display->print(time); + offset += time.length(); + + if (getEditMode()) + { + display->write(LCDCharUpDown); + offset++; + } + + for (uint8_t space = offset; space < LCDWidth; space++) + display->print(' '); +} + + +void SetTimeScreen::gotoNext() +{ + buzzSelect(); + getScreenManager()->show(); +} + + +void SetTimeScreen::onHide() +{ +} + + +void SetTimeScreen::onButton() +{ + buzzSelect(); + setEditMode(!getEditMode()); + printValue(); +} + + +void SetTimeScreen::onEncoder(long lastPosition, long newPosition) +{ + if (getEditMode()) + { + buzzSelect(); + + if (newPosition > lastPosition) + ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; + else if (ExposureTime > 0) + ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; + + printValue(); + } + else + BaseMenuScreen::onEncoder(lastPosition, newPosition); +} + + +void SetTimeScreen::onTick() +{ +} + diff --git a/src/Screen/SetTimeScreen.h b/src/Screen/SetTimeScreen.h new file mode 100644 index 0000000..464d843 --- /dev/null +++ b/src/Screen/SetTimeScreen.h @@ -0,0 +1,35 @@ +#ifndef __SetTimeScreen +#define __SetTimeScreen + +#include "ScreenManager.h" +#include "Screen/BaseMenuScreen.h" + +/* + * Time screen + * Allows changing of the exposure time. + */ +class SetTimeScreen : public BaseMenuScreen +{ + protected: + inline bool getEditMode() { return !getEnableMenuScroll(); } + inline void setEditMode(bool value) { setEnableMenuScroll(!value); } + + bool hasPrevious() { return false; } + bool hasNext() { return true; } + + const char* getTitle() { return "Time"; } + void gotoNext(); + + void printValue(); + + public: + SetTimeScreen(ScreenManager* screenManager) : BaseMenuScreen(screenManager) { } + + void onHide(); + + void onButton(); + void onEncoder(long lastPosition, long newPosition); + void onTick(); +}; + +#endif diff --git a/src/Screen/StartScreen.cpp b/src/Screen/StartScreen.cpp new file mode 100644 index 0000000..c4f2e77 --- /dev/null +++ b/src/Screen/StartScreen.cpp @@ -0,0 +1,30 @@ +#include "Screen/StartScreen.h" +#include "Screen/IntensityScreen.h" +#include "ExposureTimer.h" +#include "Buzzer.h" +#include "Config.h" + + +void StartScreen::gotoPrevious() +{ + buzzSelect(); + getScreenManager()->show(); +} + + +void StartScreen::onHide() +{ +} + + +void StartScreen::onButton() +{ + buzzSelect(); + //setEditMode(!getEditMode()); +} + + +void StartScreen::onTick() +{ +} + diff --git a/src/Screen/StartScreen.h b/src/Screen/StartScreen.h new file mode 100644 index 0000000..7369150 --- /dev/null +++ b/src/Screen/StartScreen.h @@ -0,0 +1,29 @@ +#ifndef __StartScreen +#define __StartScreen + +#include "ScreenManager.h" +#include "Screen/BaseMenuScreen.h" + +/* + * Start screen + * Allows starting the exposure. + */ +class StartScreen : public BaseMenuScreen +{ + protected: + bool hasPrevious() { return true; } + bool hasNext() { return false; } + + const char* getTitle() { return "Start"; } + void gotoPrevious(); + + public: + StartScreen(ScreenManager* screenManager) : BaseMenuScreen(screenManager) { } + + void onHide(); + + void onButton(); + void onTick(); +}; + +#endif diff --git a/src/ScreenManager.cpp b/src/ScreenManager.cpp index f637161..287e2b5 100644 --- a/src/ScreenManager.cpp +++ b/src/ScreenManager.cpp @@ -17,22 +17,3 @@ LiquidCrystal* BaseScreen::getDisplay() return mScreenManager->getDisplay(); } - -void BaseScreen::printTime(int value) -{ - String minutes = String(value / 60); - String seconds = String(value % 60); - int textLength = minutes.length() + 1 + 2; - - getDisplay()->print(minutes); - getDisplay()->print(":"); - - if (seconds.length() == 1) - getDisplay()->print("0"); - - getDisplay()->print(seconds); - - for (int space = textLength + 1; space < LCDWidth; space++) - getDisplay()->print(" "); -} - diff --git a/src/ScreenManager.h b/src/ScreenManager.h index f0340b8..f1c4b85 100644 --- a/src/ScreenManager.h +++ b/src/ScreenManager.h @@ -17,9 +17,6 @@ class BaseScreen unsigned long getCurrentTime(); LiquidCrystal* getDisplay(); - - void printTime(int value); - public: BaseScreen(ScreenManager* screenManager) { diff --git a/src/main.cpp b/src/main.cpp index 2a04dff..979b7ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,7 @@ #include #include "Config.h" #include "ScreenManager.h" -#include "Screen/ScreenSetTime.h" +#include "Screen/SetTimeScreen.h" #include "Buzzer.h" #include "ExposureTimer.h" @@ -36,11 +36,15 @@ void setup() ResetExposureTime(); - lcd.createChar(0, LCDCharArrow); + lcd.createChar(LCDCharArrowRight, LCDCharArrowRightMap); + lcd.createChar(LCDCharArrowLeft, LCDCharArrowLeftMap); + lcd.createChar(LCDCharArrowRightHollow, LCDCharArrowRightHollowMap); + lcd.createChar(LCDCharArrowLeftHollow, LCDCharArrowLeftHollowMap); + lcd.createChar(LCDCharUpDown, LCDCharUpDownMap); lcd.begin(LCDWidth, LCDHeight); screenManager = new ScreenManager(&lcd, ¤tTime); - screenManager->show(); + screenManager->show(); buzzStartup(); } From 5efc605d1d445ed69996630b6a1f381e26bf5854 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Thu, 7 Dec 2017 16:49:57 +0100 Subject: [PATCH 5/9] Code cleanup Ongoing refactoring... it compiles, but that's about it --- src/Buzzer.cpp | 47 +++--- src/Buzzer.h | 23 ++- src/Config.cpp | 10 +- src/Config.h | 69 ++++---- src/ExposureTimer.cpp | 26 --- src/ExposureTimer.h | 15 -- src/Screen/BaseMenuScreen.cpp | 119 -------------- src/Screen/BaseMenuScreen.h | 41 ----- src/Screen/IntensityScreen.cpp | 84 ---------- src/Screen/IntensityScreen.h | 36 ----- src/Screen/SetTimeScreen.h | 35 ---- src/Screen/StartScreen.cpp | 30 ---- src/Screen/StartScreen.h | 29 ---- src/display.cpp | 23 +++ src/display.h | 13 ++ src/main.cpp | 33 ++-- src/menu/intensity.cpp | 46 ++++++ src/menu/intensity.h | 20 +++ .../SetTimeScreen.cpp => menu/time.cpp} | 128 +++++++-------- src/menu/time.h | 20 +++ src/{ScreenManager.cpp => screen.cpp} | 4 +- src/{ScreenManager.h => screen.h} | 5 +- .../countdown.cpp} | 33 ++-- .../CountdownScreen.h => screen/countdown.h} | 8 +- src/screen/menu.cpp | 151 ++++++++++++++++++ src/screen/menu.h | 51 ++++++ src/state.cpp | 34 ++++ src/state.h | 17 ++ 28 files changed, 550 insertions(+), 600 deletions(-) delete mode 100644 src/ExposureTimer.cpp delete mode 100644 src/ExposureTimer.h delete mode 100644 src/Screen/BaseMenuScreen.cpp delete mode 100644 src/Screen/BaseMenuScreen.h delete mode 100644 src/Screen/IntensityScreen.cpp delete mode 100644 src/Screen/IntensityScreen.h delete mode 100644 src/Screen/SetTimeScreen.h delete mode 100644 src/Screen/StartScreen.cpp delete mode 100644 src/Screen/StartScreen.h create mode 100644 src/display.cpp create mode 100644 src/display.h create mode 100644 src/menu/intensity.cpp create mode 100644 src/menu/intensity.h rename src/{Screen/SetTimeScreen.cpp => menu/time.cpp} (53%) create mode 100644 src/menu/time.h rename src/{ScreenManager.cpp => screen.cpp} (84%) rename src/{ScreenManager.h => screen.h} (96%) rename src/{Screen/CountdownScreen.cpp => screen/countdown.cpp} (57%) rename src/{Screen/CountdownScreen.h => screen/countdown.h} (79%) create mode 100644 src/screen/menu.cpp create mode 100644 src/screen/menu.h create mode 100644 src/state.cpp create mode 100644 src/state.h diff --git a/src/Buzzer.cpp b/src/Buzzer.cpp index c9f355a..e930d27 100644 --- a/src/Buzzer.cpp +++ b/src/Buzzer.cpp @@ -1,53 +1,50 @@ -#include "Buzzer.h" +#include "buzzer.h" #include -#include "Config.h" +#include "config.h" -void buzzStartup() + +void Buzzer::playNote(uint16_t frequency, uint16_t duration) { - tone(PinBuzzer, 1000); - delay(50); - noTone(PinBuzzer); + tone(PinBuzzer, frequency); + delay(duration); + noTone(PinBuzzer); } -void buzzSelect() +void Buzzer::startup() { - tone(PinBuzzer, 1000); - delay(1); - noTone(PinBuzzer); + playNote(1000, 50); } -void buzzClick() +void Buzzer::select() { - tone(PinBuzzer, 1000); - delay(25); - noTone(PinBuzzer); + playNote(1000, 1); } -void buzzCompleted() +void Buzzer::click() +{ + playNote(1000, 25); +} + + +void Buzzer::completed() { for (int i = 0; i < 3; i++) { - tone(PinBuzzer, 1000); - delay(250); - noTone(PinBuzzer); - + playNote(1000, 250); delay(500); } } -void buzzMemoryCleared() +void Buzzer::memoryCleared() { for (int i = 0; i < 5; i++) { - tone(PinBuzzer, 1000); - delay(25); - noTone(PinBuzzer); - + playNote(1000, 25); delay(250); - } + } } diff --git a/src/Buzzer.h b/src/Buzzer.h index bc42739..fdc2127 100644 --- a/src/Buzzer.h +++ b/src/Buzzer.h @@ -1,10 +1,19 @@ -#ifndef __Buzzer -#define __Buzzer +#ifndef __buzzer +#define __buzzer -void buzzStartup(); -void buzzSelect(); -void buzzClick(); -void buzzCompleted(); -void buzzMemoryCleared(); +#include + +class Buzzer +{ + protected: + static void playNote(uint16_t frequency, uint16_t duration); + + public: + static void startup(); + static void select(); + static void click(); + static void completed(); + static void memoryCleared(); +}; #endif diff --git a/src/Config.cpp b/src/Config.cpp index f88fa33..f4a54ba 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -1,6 +1,6 @@ #include "Config.h" -byte LCDCharArrowRightMap[8] = { +uint8_t LCDCharArrowRightMap[8] = { B00000, B01000, B01100, @@ -10,7 +10,7 @@ byte LCDCharArrowRightMap[8] = { B00000, }; -byte LCDCharArrowLeftMap[8] = { +uint8_t LCDCharArrowLeftMap[8] = { B00000, B00100, B01100, @@ -20,7 +20,7 @@ byte LCDCharArrowLeftMap[8] = { B00000, }; -byte LCDCharArrowRightHollowMap[8] = { +uint8_t LCDCharArrowRightHollowMap[8] = { B00000, B01000, B00100, @@ -30,7 +30,7 @@ byte LCDCharArrowRightHollowMap[8] = { B00000, }; -byte LCDCharArrowLeftHollowMap[8] = { +uint8_t LCDCharArrowLeftHollowMap[8] = { B00000, B00100, B01000, @@ -40,7 +40,7 @@ byte LCDCharArrowLeftHollowMap[8] = { B00000, }; -byte LCDCharUpDownMap[8] = { +uint8_t LCDCharUpDownMap[8] = { B00000, B00100, B01110, diff --git a/src/Config.h b/src/Config.h index 3ffe9d5..2b45816 100644 --- a/src/Config.h +++ b/src/Config.h @@ -1,43 +1,44 @@ #ifndef __Config #define __Config -#include "Arduino.h" +#include + +const int PinLCDRS = 7; +const int PinLCDEN = 8; +const int PinLCDDB4 = 9; +const int PinLCDDB5 = 10; +const int PinLCDDB6 = 11; +const int PinLCDDB7 = 12; +const int PinEncoderClock = 2; +const int PinEncoderData = 3; +const int PinButton = 4; +const int PinBuzzer = 5; +const int PinLED = 6; + +const int LCDWidth = 16; +const int LCDHeight = 2; + +const int EncoderSensitivity = 4; +const int SmallStep = 1; +const int LargeStepTreshold = 60; +const int LargeStep = 10; + +const int MenuTimeout = 2000; -static const int PinLCDRS = 7; -static const int PinLCDEN = 8; -static const int PinLCDDB4 = 9; -static const int PinLCDDB5 = 10; -static const int PinLCDDB6 = 11; -static const int PinLCDDB7 = 12; -static const int PinEncoderClock = 2; -static const int PinEncoderData = 3; -static const int PinButton = 4; -static const int PinBuzzer = 5; -static const int PinLED = 6; +const uint32_t DefaultExposureTime = 60; +const uint8_t DefaultExposureIntensity = 100; -// You probably don't wanna change these without a proper review of the code, since most of it assumes 16x2 anyways -static const int LCDWidth = 16; -static const int LCDHeight = 2; +const uint8_t LCDCharArrowRight = 0; +const uint8_t LCDCharArrowLeft = 1; +const uint8_t LCDCharArrowRightHollow = 2; +const uint8_t LCDCharArrowLeftHollow = 3; +const uint8_t LCDCharUpDown = 4; -static const int EncoderSensitivity = 4; -static const int SmallStep = 1; -static const int LargeStepTreshold = 60; -static const int LargeStep = 10; - -static const int MenuTimeout = 2000; - - -static const uint8_t LCDCharArrowRight = 0; -static const uint8_t LCDCharArrowLeft = 1; -static const uint8_t LCDCharArrowRightHollow = 2; -static const uint8_t LCDCharArrowLeftHollow = 3; -static const uint8_t LCDCharUpDown = 4; - -extern byte LCDCharArrowRightMap[8]; -extern byte LCDCharArrowLeftMap[8]; -extern byte LCDCharArrowRightHollowMap[8]; -extern byte LCDCharArrowLeftHollowMap[8]; -extern byte LCDCharUpDownMap[8]; +extern uint8_t LCDCharArrowRightMap[8]; +extern uint8_t LCDCharArrowLeftMap[8]; +extern uint8_t LCDCharArrowRightHollowMap[8]; +extern uint8_t LCDCharArrowLeftHollowMap[8]; +extern uint8_t LCDCharUpDownMap[8]; #endif diff --git a/src/ExposureTimer.cpp b/src/ExposureTimer.cpp deleted file mode 100644 index 907a7a3..0000000 --- a/src/ExposureTimer.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "ExposureTimer.h" -#include - -unsigned int ExposureTime = 0; -unsigned long ExposureTimerStart = 0; - -void ResetExposureTime() -{ - EEPROM.get(0, ExposureTime); -} - - -void StartExposureTimer(unsigned long currentTime) -{ - EEPROM.put(0, ExposureTime); - ExposureTimerStart = currentTime; -} - - -String FormatTime(unsigned int Time) -{ - String minutes = String(ExposureTime / 60); - String seconds = String(ExposureTime % 60); - - return minutes + ':' + (seconds.length() == 1 ? '0' + seconds : seconds); -} \ No newline at end of file diff --git a/src/ExposureTimer.h b/src/ExposureTimer.h deleted file mode 100644 index 62a89b6..0000000 --- a/src/ExposureTimer.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __ExposureTimer -#define __ExposureTimer - -#include "Arduino.h" - -extern unsigned int ExposureTime; -extern unsigned long ExposureTimerStart; - - -void ResetExposureTime(); -void StartExposureTimer(unsigned long currentTime); - -String FormatTime(unsigned int Time); - -#endif diff --git a/src/Screen/BaseMenuScreen.cpp b/src/Screen/BaseMenuScreen.cpp deleted file mode 100644 index ae6bf78..0000000 --- a/src/Screen/BaseMenuScreen.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "Screen/BaseMenuScreen.h" -#include "Config.h" -#include "Buzzer.h" - - -void BaseMenuScreen::setEnableMenuScroll(bool value) -{ - if (value != mEnableMenuScroll) - { - mEnableMenuScroll = value; - printScrollIndicators(); - } -} - - -void BaseMenuScreen::onShow() -{ - printTitle(); - printScrollIndicators(); - printValue(); -} - - -void BaseMenuScreen::onHide() -{ -} - - -void BaseMenuScreen::printTitle() -{ - LiquidCrystal* display = getDisplay(); - - const char* title = getTitle(); - uint8_t titleLength = strlen(title); - uint8_t maxWidth = LCDWidth - 2; - - display->setCursor(1, 0); - - if (titleLength >= maxWidth) - { - // Title too long, cut off - char* character = (char*)title; - for (uint8_t i = 0; i < maxWidth; i++) - { - display->write(byte(*character)); - character++; - } - } - else - { - // Center title - uint8_t offset = (maxWidth - titleLength) / 2; - - for (uint8_t i = 0; i < offset; i++) - display->write(' '); - - display->print(title); - offset += titleLength; - - while (offset < LCDWidth - 2) - { - display->print(' '); - offset++; - } - } -} - - -void BaseMenuScreen::printScrollIndicators() -{ - LiquidCrystal* display = getDisplay(); - - display->setCursor(0, 0); - if (hasPrevious()) - display->write(getEnableMenuScroll() ? LCDCharArrowLeft : LCDCharArrowLeftHollow); - else - display->write(' '); - - display->setCursor(LCDWidth - 1, 0); - if (hasNext()) - display->write(getEnableMenuScroll() ? LCDCharArrowRight : LCDCharArrowRightHollow); - else - display->write(' '); -} - - -void BaseMenuScreen::printValue() -{ - LiquidCrystal* display = getDisplay(); - - display->setCursor(0, 1); - for (uint8_t x = 0; x < LCDWidth; x++) - display->write(' '); -} - - - -void BaseMenuScreen::onEncoder(long lastPosition, long newPosition) -{ - if (mEnableMenuScroll) - { - if (newPosition > lastPosition) - { - if (hasNext()) - { - buzzSelect(); - gotoNext(); - } - } - else - { - if (hasPrevious()) - { - buzzSelect(); - gotoPrevious(); - } - } - } -} diff --git a/src/Screen/BaseMenuScreen.h b/src/Screen/BaseMenuScreen.h deleted file mode 100644 index 6454f6e..0000000 --- a/src/Screen/BaseMenuScreen.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __BaseMenuScreen -#define __BaseMenuScreen - -#include -#include "ScreenManager.h" - -/* - * Base menu screen - * Provides the base for a menu screen, allows scrolling to - * the previous or next menu screen or performs an action. - */ -class BaseMenuScreen : public BaseScreen -{ - private: - bool mEnableMenuScroll = true; - - protected: - bool getEnableMenuScroll() { return mEnableMenuScroll; } - void setEnableMenuScroll(bool value); - - virtual bool hasPrevious() = 0; - virtual bool hasNext() = 0; - - virtual const char* getTitle() = 0; - virtual void gotoPrevious() {} - virtual void gotoNext() {} - - void printTitle(); - void printScrollIndicators(); - virtual void printValue(); - - public: - BaseMenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { } - - virtual void onShow(); - virtual void onHide(); - - virtual void onEncoder(long lastPosition, long newPosition); -}; - -#endif \ No newline at end of file diff --git a/src/Screen/IntensityScreen.cpp b/src/Screen/IntensityScreen.cpp deleted file mode 100644 index 99c58f5..0000000 --- a/src/Screen/IntensityScreen.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "Screen/IntensityScreen.h" -#include "Screen/SetTimeScreen.h" -#include "Screen/StartScreen.h" -#include "ExposureTimer.h" -#include "Buzzer.h" -#include "Config.h" - - -void IntensityScreen::printValue() -{ - LiquidCrystal* display = getDisplay(); - display->setCursor(0, 1); - - String intensity = "100%"; - uint8_t offset = (LCDWidth - intensity.length()) / 2; - - for (uint8_t space = 0; space < offset; space++) - display->print(' '); - - display->print(intensity); - offset += intensity.length(); - - if (getEditMode()) - { - display->write(LCDCharUpDown); - offset++; - } - - for (uint8_t space = offset; space < LCDWidth; space++) - display->print(' '); -} - - -void IntensityScreen::gotoPrevious() -{ - buzzSelect(); - getScreenManager()->show(); -} - - -void IntensityScreen::gotoNext() -{ - buzzSelect(); - getScreenManager()->show(); -} - - -void IntensityScreen::onHide() -{ -} - - -void IntensityScreen::onButton() -{ - buzzSelect(); - setEditMode(!getEditMode()); - printValue(); -} - - -void IntensityScreen::onEncoder(long lastPosition, long newPosition) -{ - if (getEditMode()) - { - buzzSelect(); - -/* - if (newPosition > lastPosition) - ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; - else if (ExposureTime > 0) - ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; - */ - - printValue(); - } - else - BaseMenuScreen::onEncoder(lastPosition, newPosition); -} - - -void IntensityScreen::onTick() -{ -} - diff --git a/src/Screen/IntensityScreen.h b/src/Screen/IntensityScreen.h deleted file mode 100644 index 42de608..0000000 --- a/src/Screen/IntensityScreen.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __IntensityScreen -#define __IntensityScreen - -#include "ScreenManager.h" -#include "Screen/BaseMenuScreen.h" - -/* - * Intensity screen - * Allows changing of the intensity. - */ -class IntensityScreen : public BaseMenuScreen -{ - protected: - inline bool getEditMode() { return !getEnableMenuScroll(); } - inline void setEditMode(bool value) { setEnableMenuScroll(!value); } - - bool hasPrevious() { return true; } - bool hasNext() { return true; } - - const char* getTitle() { return "Intensity"; } - void gotoPrevious(); - void gotoNext(); - - void printValue(); - - public: - IntensityScreen(ScreenManager* screenManager) : BaseMenuScreen(screenManager) { } - - void onHide(); - - void onButton(); - void onEncoder(long lastPosition, long newPosition); - void onTick(); -}; - -#endif diff --git a/src/Screen/SetTimeScreen.h b/src/Screen/SetTimeScreen.h deleted file mode 100644 index 464d843..0000000 --- a/src/Screen/SetTimeScreen.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __SetTimeScreen -#define __SetTimeScreen - -#include "ScreenManager.h" -#include "Screen/BaseMenuScreen.h" - -/* - * Time screen - * Allows changing of the exposure time. - */ -class SetTimeScreen : public BaseMenuScreen -{ - protected: - inline bool getEditMode() { return !getEnableMenuScroll(); } - inline void setEditMode(bool value) { setEnableMenuScroll(!value); } - - bool hasPrevious() { return false; } - bool hasNext() { return true; } - - const char* getTitle() { return "Time"; } - void gotoNext(); - - void printValue(); - - public: - SetTimeScreen(ScreenManager* screenManager) : BaseMenuScreen(screenManager) { } - - void onHide(); - - void onButton(); - void onEncoder(long lastPosition, long newPosition); - void onTick(); -}; - -#endif diff --git a/src/Screen/StartScreen.cpp b/src/Screen/StartScreen.cpp deleted file mode 100644 index c4f2e77..0000000 --- a/src/Screen/StartScreen.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "Screen/StartScreen.h" -#include "Screen/IntensityScreen.h" -#include "ExposureTimer.h" -#include "Buzzer.h" -#include "Config.h" - - -void StartScreen::gotoPrevious() -{ - buzzSelect(); - getScreenManager()->show(); -} - - -void StartScreen::onHide() -{ -} - - -void StartScreen::onButton() -{ - buzzSelect(); - //setEditMode(!getEditMode()); -} - - -void StartScreen::onTick() -{ -} - diff --git a/src/Screen/StartScreen.h b/src/Screen/StartScreen.h deleted file mode 100644 index 7369150..0000000 --- a/src/Screen/StartScreen.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __StartScreen -#define __StartScreen - -#include "ScreenManager.h" -#include "Screen/BaseMenuScreen.h" - -/* - * Start screen - * Allows starting the exposure. - */ -class StartScreen : public BaseMenuScreen -{ - protected: - bool hasPrevious() { return true; } - bool hasNext() { return false; } - - const char* getTitle() { return "Start"; } - void gotoPrevious(); - - public: - StartScreen(ScreenManager* screenManager) : BaseMenuScreen(screenManager) { } - - void onHide(); - - void onButton(); - void onTick(); -}; - -#endif diff --git a/src/display.cpp b/src/display.cpp new file mode 100644 index 0000000..b059947 --- /dev/null +++ b/src/display.cpp @@ -0,0 +1,23 @@ +#include "display.h" +#include "config.h" + + +void LCDPrintLine(LiquidCrystal* display, uint8_t y, char* value, uint8_t margin) +{ + +} + + +void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, char* value, uint8_t margin) +{ + +} + + +const char* FormatTime(unsigned int time) +{ + String minutes = String(time / 60); + String seconds = String(time % 60); + + return (minutes + ':' + (seconds.length() == 1 ? '0' + seconds : seconds)).c_str(); +} \ No newline at end of file diff --git a/src/display.h b/src/display.h new file mode 100644 index 0000000..993a01a --- /dev/null +++ b/src/display.h @@ -0,0 +1,13 @@ +#ifndef __display +#define __display + +#include +#include + + +void LCDPrintLine(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin = 0); +void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin = 0); + +const char* FormatTime(unsigned int time); + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 979b7ac..83df5ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,20 +2,20 @@ #include #include #include -#include "Config.h" -#include "ScreenManager.h" -#include "Screen/SetTimeScreen.h" -#include "Buzzer.h" -#include "ExposureTimer.h" +#include "config.h" +#include "screen.h" +#include "screen/menu.h" +#include "buzzer.h" +#include "state.h" LiquidCrystal lcd(PinLCDRS, PinLCDEN, PinLCDDB4, PinLCDDB5, PinLCDDB6, PinLCDDB7); -// Before uploading the sketch, upload it once with ClearEEPROM defined to -// zero out the memory. -//#define ClearEEPROM -#ifndef ClearEEPROM +// Before uploading the sketch, upload it once with ResetEEPROM defined to +// write the default values to the EEPROM +//#define ResetEEPROM +#ifndef ResetEEPROM ScreenManager* screenManager; unsigned long currentTime; @@ -34,7 +34,7 @@ void setup() button.attach(PinButton); button.interval(5); - ResetExposureTime(); + LoadSettings(); lcd.createChar(LCDCharArrowRight, LCDCharArrowRightMap); lcd.createChar(LCDCharArrowLeft, LCDCharArrowLeftMap); @@ -44,9 +44,9 @@ void setup() lcd.begin(LCDWidth, LCDHeight); screenManager = new ScreenManager(&lcd, ¤tTime); - screenManager->show(); + screenManager->show(); - buzzStartup(); + Buzzer::startup(); } @@ -89,16 +89,21 @@ void setup() for (int i = 0 ; i < EEPROM.length() ; i++) { - EEPROM.write(i, 0); + EEPROM.update(i, 0); } + ExposureTime = DefaultExposureTime; + ExposureIntensity = DefaultExposureIntensity; + SaveSettings(); + lcd.setCursor(0, 0); lcd.print("Memory cleared"); - buzzMemoryCleared(); + Buzzer::memoryCleared(); } void loop() { } + #endif diff --git a/src/menu/intensity.cpp b/src/menu/intensity.cpp new file mode 100644 index 0000000..9dbab6e --- /dev/null +++ b/src/menu/intensity.cpp @@ -0,0 +1,46 @@ +#include "intensity.h" + +/* + LiquidCrystal* display = getDisplay(); + display->setCursor(0, 1); + + String intensity = "100%"; + uint8_t offset = (LCDWidth - intensity.length()) / 2; + + for (uint8_t space = 0; space < offset; space++) + display->print(' '); + + display->print(intensity); + offset += intensity.length(); + + if (getEditMode()) + { + display->write(LCDCharUpDown); + offset++; + } + + for (uint8_t space = offset; space < LCDWidth; space++) + display->print(' '); + +*/ + +char* IntensityMenuItem::getTitle() +{ + return NULL; +} + + +char* IntensityMenuItem::getValue() +{ + return NULL; +} + + +void IntensityMenuItem::incValue() +{ +} + + +void IntensityMenuItem::decValue() +{ +} \ No newline at end of file diff --git a/src/menu/intensity.h b/src/menu/intensity.h new file mode 100644 index 0000000..a6b7522 --- /dev/null +++ b/src/menu/intensity.h @@ -0,0 +1,20 @@ +#ifndef __intensitymenuitem +#define __intensitymenuitem + +#include "screen/menu.h" + +class IntensityMenuItem : public MenuItem +{ + public: + IntensityMenuItem() : MenuItem() { } + + char* getTitle(); + char* getValue(); + + bool editable() { return true; } + + void incValue(); + void decValue(); +}; + +#endif \ No newline at end of file diff --git a/src/Screen/SetTimeScreen.cpp b/src/menu/time.cpp similarity index 53% rename from src/Screen/SetTimeScreen.cpp rename to src/menu/time.cpp index 2e7f0fd..d1dba89 100644 --- a/src/Screen/SetTimeScreen.cpp +++ b/src/menu/time.cpp @@ -1,74 +1,54 @@ -#include "Screen/SetTimeScreen.h" -#include "Screen/IntensityScreen.h" -#include "ExposureTimer.h" -#include "Buzzer.h" -#include "Config.h" - - -void SetTimeScreen::printValue() -{ - LiquidCrystal* display = getDisplay(); - display->setCursor(0, 1); - - String time = FormatTime(ExposureTime); - uint8_t offset = (LCDWidth - time.length()) / 2; - - for (uint8_t space = 0; space < offset; space++) - display->print(' '); - - display->print(time); - offset += time.length(); - - if (getEditMode()) - { - display->write(LCDCharUpDown); - offset++; - } - - for (uint8_t space = offset; space < LCDWidth; space++) - display->print(' '); -} - - -void SetTimeScreen::gotoNext() -{ - buzzSelect(); - getScreenManager()->show(); -} - - -void SetTimeScreen::onHide() -{ -} - - -void SetTimeScreen::onButton() -{ - buzzSelect(); - setEditMode(!getEditMode()); - printValue(); -} - - -void SetTimeScreen::onEncoder(long lastPosition, long newPosition) -{ - if (getEditMode()) - { - buzzSelect(); - - if (newPosition > lastPosition) - ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; - else if (ExposureTime > 0) - ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; - - printValue(); - } - else - BaseMenuScreen::onEncoder(lastPosition, newPosition); -} - - -void SetTimeScreen::onTick() -{ -} - +#include "time.h" + +/* + LiquidCrystal* display = getDisplay(); + display->setCursor(0, 1); + + String time = FormatTime(ExposureTime); + uint8_t offset = (LCDWidth - time.length()) / 2; + + for (uint8_t space = 0; space < offset; space++) + display->print(' '); + + display->print(time); + offset += time.length(); + + if (getEditMode()) + { + display->write(LCDCharUpDown); + offset++; + } + + for (uint8_t space = offset; space < LCDWidth; space++) + display->print(' '); + + + + + + if (newPosition > lastPosition) + ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; + else if (ExposureTime > 0) + ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; +*/ + +char* TimeMenuItem::getTitle() +{ + return NULL; +} + + +char* TimeMenuItem::getValue() +{ + return NULL; +} + + +void TimeMenuItem::incValue() +{ +} + + +void TimeMenuItem::decValue() +{ +} \ No newline at end of file diff --git a/src/menu/time.h b/src/menu/time.h new file mode 100644 index 0000000..39823ef --- /dev/null +++ b/src/menu/time.h @@ -0,0 +1,20 @@ +#ifndef __timemenuitem +#define __timemenuitem + +#include "screen/menu.h" + +class TimeMenuItem : public MenuItem +{ + public: + TimeMenuItem() : MenuItem() { } + + char* getTitle(); + char* getValue(); + + bool editable() { return true; } + + void incValue(); + void decValue(); +}; + +#endif \ No newline at end of file diff --git a/src/ScreenManager.cpp b/src/screen.cpp similarity index 84% rename from src/ScreenManager.cpp rename to src/screen.cpp index 287e2b5..f578089 100644 --- a/src/ScreenManager.cpp +++ b/src/screen.cpp @@ -1,5 +1,5 @@ -#include "ScreenManager.h" -#include "Config.h" +#include "screen.h" +#include "config.h" ScreenManager* BaseScreen::getScreenManager() diff --git a/src/ScreenManager.h b/src/screen.h similarity index 96% rename from src/ScreenManager.h rename to src/screen.h index f1c4b85..e76621b 100644 --- a/src/ScreenManager.h +++ b/src/screen.h @@ -1,9 +1,8 @@ -#ifndef __ScreenManager -#define __ScreenManager +#ifndef __screen +#define __screen #include - class ScreenManager; diff --git a/src/Screen/CountdownScreen.cpp b/src/screen/countdown.cpp similarity index 57% rename from src/Screen/CountdownScreen.cpp rename to src/screen/countdown.cpp index 2d4a2cc..6d0a3a0 100644 --- a/src/Screen/CountdownScreen.cpp +++ b/src/screen/countdown.cpp @@ -1,28 +1,27 @@ -#include "CountdownScreen.h" -#include "Screen/SetTimeScreen.h" -#include "ExposureTimer.h" -#include "Config.h" -#include "Buzzer.h" +#include "countdown.h" +#include "screen/menu.h" +#include "display.h" +#include "state.h" +#include "config.h" +#include "buzzer.h" void CountdownScreen::printRemainingTime() { - getDisplay()->setCursor(0, 1); - String time = FormatTime(ExposureTime - ((getCurrentTime() - ExposureTimerStart) / 1000)); + const char* time = FormatTime(ExposureTime - ((getCurrentTime() - ExposureTimerStart) / 1000)); // TODO blank out, center, etc - getDisplay()->print(time); + LCDPrintLineCentered(getDisplay(), 1, time); } void CountdownScreen::onShow() { - mLastDisplayed = -1; - - getDisplay()->setCursor(0, 0); - getDisplay()->print("Exposing... "); + mLastDisplayed = (uint32_t)-1; + LCDPrintLine(getDisplay(), 0, "Exposing..."); printRemainingTime(); + digitalWrite(PinLED, HIGH); } @@ -36,8 +35,8 @@ void CountdownScreen::onHide() void CountdownScreen::onButton() { // TODO Confirmation? - buzzClick(); - getScreenManager()->show(); + Buzzer::click(); + getScreenManager()->show(); } @@ -49,7 +48,7 @@ void CountdownScreen::onEncoder(long lastPosition, long newPosition) void CountdownScreen::onTick() { - long elapsed = (getCurrentTime() - ExposureTimerStart) / 1000; + uint32_t elapsed = (getCurrentTime() - ExposureTimerStart) / 1000; if (elapsed >= ExposureTime) { @@ -59,10 +58,10 @@ void CountdownScreen::onTick() printRemainingTime(); digitalWrite(PinLED, LOW); - buzzCompleted(); + Buzzer::completed(); ExposureTimerStart = 0; - getScreenManager()->show(); + getScreenManager()->show(); } else if (elapsed != mLastDisplayed) { diff --git a/src/Screen/CountdownScreen.h b/src/screen/countdown.h similarity index 79% rename from src/Screen/CountdownScreen.h rename to src/screen/countdown.h index 9927cda..745ccd5 100644 --- a/src/Screen/CountdownScreen.h +++ b/src/screen/countdown.h @@ -1,7 +1,7 @@ -#ifndef __CountdownScreen -#define __CountdownScreen +#ifndef __countdown +#define __countdown -#include "ScreenManager.h" +#include "screen.h" /* * Countdown screen @@ -10,7 +10,7 @@ class CountdownScreen : public BaseScreen { private: - int mLastDisplayed; + uint32_t mLastDisplayed; protected: void printRemainingTime(); diff --git a/src/screen/menu.cpp b/src/screen/menu.cpp new file mode 100644 index 0000000..5a4c47f --- /dev/null +++ b/src/screen/menu.cpp @@ -0,0 +1,151 @@ +#include "screen/menu.h" +#include "config.h" +#include "buzzer.h" + +#include "menu/time.h" + + +MenuScreen::MenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager) +{ + mCount = 3; + mItems = new MenuItem*[mCount]; + + mItems[0] = new TimeMenuItem(); + mItems[1] = new TimeMenuItem(); + mItems[2] = new TimeMenuItem(); +} + + +MenuScreen::~MenuScreen() +{ + for (uint8_t i = 0; i < mCount; i++) + delete mItems[i]; + + delete[] mItems; +} + + +void MenuScreen::onShow() +{ + printFullUpdate(); +} + + +void MenuScreen::onHide() +{ +} + + +void MenuScreen::printFullUpdate() +{ + printTitle(); + printScrollIndicators(); + printValue(); +} + + +void MenuScreen::printTitle() +{ + LiquidCrystal* display = getDisplay(); + + const char* title = mItems[mSelected]->getTitle(); + uint8_t titleLength = strlen(title); + uint8_t maxWidth = LCDWidth - 2; + + display->setCursor(1, 0); + + if (titleLength >= maxWidth) + { + // Title too long, cut off + char* character = (char*)title; + for (uint8_t i = 0; i < maxWidth; i++) + { + display->write(byte(*character)); + character++; + } + } + else + { + // Center title + uint8_t offset = (maxWidth - titleLength) / 2; + + for (uint8_t i = 0; i < offset; i++) + display->write(' '); + + display->print(title); + offset += titleLength; + + while (offset < LCDWidth - 2) + { + display->print(' '); + offset++; + } + } +} + + +void MenuScreen::printScrollIndicators() +{ + LiquidCrystal* display = getDisplay(); + + display->setCursor(0, 0); + if (mSelected > 0) + display->write(mEditing ? LCDCharArrowLeftHollow : LCDCharArrowLeft); + else + display->write(' '); + + display->setCursor(LCDWidth - 1, 0); + if (mSelected < mCount - 1) + display->write(mEditing ? LCDCharArrowRightHollow : LCDCharArrowRight); + else + display->write(' '); +} + + +void MenuScreen::printValue() +{ + LiquidCrystal* display = getDisplay(); + + display->setCursor(0, 1); + for (uint8_t x = 0; x < LCDWidth; x++) + display->write(' '); +} + + + +void MenuScreen::onButton() +{ +} + + +void MenuScreen::onEncoder(long lastPosition, long newPosition) +{ + if (!mEditing) + { + if (newPosition > lastPosition) + { + if (mSelected < mCount - 1) + { + Buzzer::select(); + mSelected++; + + printFullUpdate(); + } + } + else + { + if (mSelected > 0) + { + Buzzer::select(); + mSelected--; + + printFullUpdate(); + } + } + } +} + + +void MenuScreen::onTick() +{ +} diff --git a/src/screen/menu.h b/src/screen/menu.h new file mode 100644 index 0000000..aa6ac32 --- /dev/null +++ b/src/screen/menu.h @@ -0,0 +1,51 @@ +#ifndef __menuscreen +#define __menuscreen + +#include "screen.h" + +class MenuItem +{ + public: + virtual ~MenuItem() { } + + virtual char* getTitle() = 0; + virtual char* getValue() { return NULL; } + + virtual bool editable() { return false; } + + // Editable = true + virtual void incValue() { } + virtual void decValue() { } + + // Editable = false + virtual void execute(ScreenManager* screenManager) { } +}; + +class MenuScreen : public BaseScreen +{ + private: + uint8_t mCount; + MenuItem** mItems; + uint8_t mSelected = 0; + bool mEditing = false; + + protected: + void printFullUpdate(); + + void printTitle(); + void printScrollIndicators(); + void printValue(); + + public: + MenuScreen(ScreenManager* screenManager); + ~MenuScreen(); + + void onShow(); + void onHide(); + + void onButton(); + void onEncoder(long lastPosition, long newPosition); + void onTick(); +}; + +#endif \ No newline at end of file diff --git a/src/state.cpp b/src/state.cpp new file mode 100644 index 0000000..2e68493 --- /dev/null +++ b/src/state.cpp @@ -0,0 +1,34 @@ +#include "state.h" +#include "config.h" +#include + +uint32_t ExposureTime = DefaultExposureTime; +uint8_t ExposureIntensity = DefaultExposureIntensity; +uint32_t ExposureTimerStart = 0; + + +void LoadSettings() +{ + uint16_t offset = 0; + EEPROM.get(offset, ExposureTime); + offset += sizeof(ExposureTime); + + EEPROM.get(offset, ExposureIntensity); +} + + +void SaveSettings() +{ + uint16_t offset = 0; + EEPROM.put(offset, ExposureTime); + offset += sizeof(ExposureTime); + + EEPROM.put(offset, ExposureIntensity); +} + + +void StartExposureTimer(unsigned long currentTime) +{ + SaveSettings(); + ExposureTimerStart = currentTime; +} \ No newline at end of file diff --git a/src/state.h b/src/state.h new file mode 100644 index 0000000..787a152 --- /dev/null +++ b/src/state.h @@ -0,0 +1,17 @@ +#ifndef __state +#define __state + +#include + +extern uint32_t ExposureTime; +extern uint8_t ExposureIntensity; + +extern uint32_t ExposureTimerStart; + + +void LoadSettings(); +void SaveSettings(); + +void StartExposureTimer(unsigned long currentTime); + +#endif From 4551744a7cda049bc70fa38dfd76fd199135ddb2 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Thu, 7 Dec 2017 17:32:59 +0100 Subject: [PATCH 6/9] More jolly refactoring --- src/display.cpp | 38 ++++++++++++++++++++++++++++++++++++-- src/menu/intensity.cpp | 16 ++++++++++++---- src/menu/intensity.h | 4 ++-- src/menu/time.cpp | 6 +++--- src/menu/time.h | 4 ++-- src/screen/countdown.cpp | 23 ++++++++++------------- src/screen/menu.cpp | 37 ++----------------------------------- src/screen/menu.h | 4 ++-- src/state.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/state.h | 9 ++++++--- 10 files changed, 112 insertions(+), 66 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index b059947..bf10138 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -2,15 +2,49 @@ #include "config.h" -void LCDPrintLine(LiquidCrystal* display, uint8_t y, char* value, uint8_t margin) +void LCDPrintLine(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin) { } -void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, char* value, uint8_t margin) +void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin) { +/* + const char* title = mItems[mSelected]->getTitle(); + uint8_t titleLength = strlen(title); + uint8_t maxWidth = LCDWidth - 2; + display->setCursor(1, 0); + + if (titleLength >= maxWidth) + { + // Title too long, cut off + char* character = (char*)title; + for (uint8_t i = 0; i < maxWidth; i++) + { + display->write(byte(*character)); + character++; + } + } + else + { + // Center title + uint8_t offset = (maxWidth - titleLength) / 2; + + for (uint8_t i = 0; i < offset; i++) + display->write(' '); + + display->print(title); + offset += titleLength; + + while (offset < LCDWidth - 2) + { + display->print(' '); + offset++; + } + } +*/ } diff --git a/src/menu/intensity.cpp b/src/menu/intensity.cpp index 9dbab6e..6fb26f9 100644 --- a/src/menu/intensity.cpp +++ b/src/menu/intensity.cpp @@ -1,4 +1,5 @@ #include "intensity.h" +#include "state.h" /* LiquidCrystal* display = getDisplay(); @@ -24,15 +25,22 @@ */ -char* IntensityMenuItem::getTitle() +const char* IntensityMenuItem::getTitle() { - return NULL; + return "Intensity"; } -char* IntensityMenuItem::getValue() +const char* IntensityMenuItem::getValue() { - return NULL; + char value[5]; + itoa(GetExposureIntensity(), value, 10); + + uint8_t length = strlen(value); + value[length] = '%'; + value[length + 1] = 0; + + return value; } diff --git a/src/menu/intensity.h b/src/menu/intensity.h index a6b7522..f133794 100644 --- a/src/menu/intensity.h +++ b/src/menu/intensity.h @@ -8,8 +8,8 @@ class IntensityMenuItem : public MenuItem public: IntensityMenuItem() : MenuItem() { } - char* getTitle(); - char* getValue(); + const char* getTitle(); + const char* getValue(); bool editable() { return true; } diff --git a/src/menu/time.cpp b/src/menu/time.cpp index d1dba89..47de1fc 100644 --- a/src/menu/time.cpp +++ b/src/menu/time.cpp @@ -32,13 +32,13 @@ ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; */ -char* TimeMenuItem::getTitle() +const char* TimeMenuItem::getTitle() { - return NULL; + return "Time"; } -char* TimeMenuItem::getValue() +const char* TimeMenuItem::getValue() { return NULL; } diff --git a/src/menu/time.h b/src/menu/time.h index 39823ef..9f46bc0 100644 --- a/src/menu/time.h +++ b/src/menu/time.h @@ -8,8 +8,8 @@ class TimeMenuItem : public MenuItem public: TimeMenuItem() : MenuItem() { } - char* getTitle(); - char* getValue(); + const char* getTitle(); + const char* getValue(); bool editable() { return true; } diff --git a/src/screen/countdown.cpp b/src/screen/countdown.cpp index 6d0a3a0..e51e834 100644 --- a/src/screen/countdown.cpp +++ b/src/screen/countdown.cpp @@ -8,18 +8,15 @@ void CountdownScreen::printRemainingTime() { - const char* time = FormatTime(ExposureTime - ((getCurrentTime() - ExposureTimerStart) / 1000)); - - // TODO blank out, center, etc - LCDPrintLineCentered(getDisplay(), 1, time); + LCDPrintLineCentered(getDisplay(), 1, FormatTime(mLastDisplayed)); } void CountdownScreen::onShow() { - mLastDisplayed = (uint32_t)-1; - LCDPrintLine(getDisplay(), 0, "Exposing..."); + + mLastDisplayed = GetExposureTimeRemaining(getCurrentTime()) / 1000; printRemainingTime(); digitalWrite(PinLED, HIGH); @@ -48,25 +45,25 @@ void CountdownScreen::onEncoder(long lastPosition, long newPosition) void CountdownScreen::onTick() { - uint32_t elapsed = (getCurrentTime() - ExposureTimerStart) / 1000; + uint32_t remaining = GetExposureTimeRemaining(getCurrentTime()) / 1000; - if (elapsed >= ExposureTime) + if (remaining == 0) { - getDisplay()->setCursor(0, 0); - getDisplay()->print("Done! "); + mLastDisplayed = 0; + LCDPrintLine(getDisplay(), 0, "Done!"); printRemainingTime(); digitalWrite(PinLED, LOW); Buzzer::completed(); - ExposureTimerStart = 0; + ResetExposureTimer(); getScreenManager()->show(); } - else if (elapsed != mLastDisplayed) + else if (remaining != mLastDisplayed) { + mLastDisplayed = remaining; printRemainingTime(); - mLastDisplayed = elapsed; } } diff --git a/src/screen/menu.cpp b/src/screen/menu.cpp index 5a4c47f..e6b7b4f 100644 --- a/src/screen/menu.cpp +++ b/src/screen/menu.cpp @@ -1,6 +1,7 @@ #include "screen/menu.h" #include "config.h" #include "buzzer.h" +#include "display.h" #include "menu/time.h" @@ -46,41 +47,7 @@ void MenuScreen::printFullUpdate() void MenuScreen::printTitle() { - LiquidCrystal* display = getDisplay(); - - const char* title = mItems[mSelected]->getTitle(); - uint8_t titleLength = strlen(title); - uint8_t maxWidth = LCDWidth - 2; - - display->setCursor(1, 0); - - if (titleLength >= maxWidth) - { - // Title too long, cut off - char* character = (char*)title; - for (uint8_t i = 0; i < maxWidth; i++) - { - display->write(byte(*character)); - character++; - } - } - else - { - // Center title - uint8_t offset = (maxWidth - titleLength) / 2; - - for (uint8_t i = 0; i < offset; i++) - display->write(' '); - - display->print(title); - offset += titleLength; - - while (offset < LCDWidth - 2) - { - display->print(' '); - offset++; - } - } + LCDPrintLineCentered(getDisplay(), 0, mItems[mSelected]->getTitle(), 1); } diff --git a/src/screen/menu.h b/src/screen/menu.h index aa6ac32..6e4ad64 100644 --- a/src/screen/menu.h +++ b/src/screen/menu.h @@ -8,8 +8,8 @@ class MenuItem public: virtual ~MenuItem() { } - virtual char* getTitle() = 0; - virtual char* getValue() { return NULL; } + virtual const char* getTitle() = 0; + virtual const char* getValue() { return NULL; } virtual bool editable() { return false; } diff --git a/src/state.cpp b/src/state.cpp index 2e68493..24ed24f 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -7,6 +7,30 @@ uint8_t ExposureIntensity = DefaultExposureIntensity; uint32_t ExposureTimerStart = 0; +uint32_t GetExposureTime() +{ + return ExposureTime; +} + + +void SetExposureTime(uint32_t value) +{ + ExposureTime = value; +} + + +uint8_t GetExposureIntensity() +{ + return ExposureIntensity; +} + + +void SetExposureIntensity(uint8_t value) +{ + ExposureIntensity = (value <= 100) ? value : 100; +} + + void LoadSettings() { uint16_t offset = 0; @@ -31,4 +55,17 @@ void StartExposureTimer(unsigned long currentTime) { SaveSettings(); ExposureTimerStart = currentTime; +} + + +void ResetExposureTimer() +{ + ExposureTimerStart = 0; +} + + +uint32_t GetExposureTimeRemaining(unsigned long currentTime) +{ + uint32_t elapsed = (currentTime - ExposureTimerStart); + return elapsed <= ExposureTime ? ExposureTime - elapsed : 0; } \ No newline at end of file diff --git a/src/state.h b/src/state.h index 787a152..6856305 100644 --- a/src/state.h +++ b/src/state.h @@ -3,15 +3,18 @@ #include -extern uint32_t ExposureTime; -extern uint8_t ExposureIntensity; +uint32_t GetExposureTime(); +void SetExposureTime(uint32_t value); -extern uint32_t ExposureTimerStart; +uint8_t GetExposureIntensity(); +void SetExposureIntensity(uint8_t value); void LoadSettings(); void SaveSettings(); void StartExposureTimer(unsigned long currentTime); +void ResetExposureTimer(); +uint32_t GetExposureTimeRemaining(unsigned long currentTime); #endif From 2e1a17d60a71ae78868625bb545aebe83380a86b Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Thu, 7 Dec 2017 23:43:24 +0100 Subject: [PATCH 7/9] Fixed menu and editing --- src/Config.h | 37 +++++----- src/display.cpp | 156 +++++++++++++++++++++++++++++++++-------- src/display.h | 7 +- src/menu/intensity.cpp | 51 +++++--------- src/menu/start.cpp | 39 +++++++++++ src/menu/start.h | 19 +++++ src/menu/time.cpp | 54 ++++++-------- src/screen.h | 2 +- src/screen/menu.cpp | 59 ++++++++++++++-- src/state.cpp | 25 +++++-- src/state.h | 8 +-- 11 files changed, 321 insertions(+), 136 deletions(-) create mode 100644 src/menu/start.cpp create mode 100644 src/menu/start.h diff --git a/src/Config.h b/src/Config.h index 2b45816..8552536 100644 --- a/src/Config.h +++ b/src/Config.h @@ -3,27 +3,26 @@ #include -const int PinLCDRS = 7; -const int PinLCDEN = 8; -const int PinLCDDB4 = 9; -const int PinLCDDB5 = 10; -const int PinLCDDB6 = 11; -const int PinLCDDB7 = 12; -const int PinEncoderClock = 2; -const int PinEncoderData = 3; -const int PinButton = 4; -const int PinBuzzer = 5; -const int PinLED = 6; +const uint8_t PinLCDRS = 7; +const uint8_t PinLCDEN = 8; +const uint8_t PinLCDDB4 = 9; +const uint8_t PinLCDDB5 = 10; +const uint8_t PinLCDDB6 = 11; +const uint8_t PinLCDDB7 = 12; +const uint8_t PinEncoderClock = 2; +const uint8_t PinEncoderData = 3; +const uint8_t PinButton = 4; +const uint8_t PinBuzzer = 5; +const uint8_t PinLED = 6; -const int LCDWidth = 16; -const int LCDHeight = 2; +const uint8_t LCDWidth = 16; +const uint8_t LCDHeight = 2; -const int EncoderSensitivity = 4; -const int SmallStep = 1; -const int LargeStepTreshold = 60; -const int LargeStep = 10; - -const int MenuTimeout = 2000; +const uint8_t EncoderSensitivity = 4; +const uint8_t SmallStep = 1; +const uint8_t LargeStepTreshold = 60; +const uint8_t LargeStep = 10; +const uint8_t IntensityStep = 1; const uint32_t DefaultExposureTime = 60; diff --git a/src/display.cpp b/src/display.cpp index bf10138..a677338 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -4,54 +4,150 @@ void LCDPrintLine(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin) { + display->setCursor(margin, y); + uint8_t width = LCDWidth - (2 * margin); + + if (value != NULL) + { + uint8_t length = strlen(value); + + if (length >= width) + { + char* character = (char*)value; + for (uint8_t i = 0; i < width; i++) + { + display->write(byte(*character)); + character++; + } + } + else + { + display->print(value); + width -= length; + + while (width > 0) + { + display->write(' '); + width--; + } + } + } + else + { + for (uint8_t i = 0; i < width; i++) + display->write(' '); + } } void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin) { -/* - const char* title = mItems[mSelected]->getTitle(); - uint8_t titleLength = strlen(title); - uint8_t maxWidth = LCDWidth - 2; + display->setCursor(margin, y); - display->setCursor(1, 0); + uint8_t width = LCDWidth - (2 * margin); - if (titleLength >= maxWidth) + if (value != NULL) { - // Title too long, cut off - char* character = (char*)title; - for (uint8_t i = 0; i < maxWidth; i++) + uint8_t length = strlen(value); + + if (length >= width) { - display->write(byte(*character)); - character++; + char* character = (char*)value; + for (uint8_t i = 0; i < width; i++) + { + display->write(byte(*character)); + character++; + } + } + else + { + uint8_t offset = (width - length) / 2; + width -= offset; + + for (uint8_t i = 0; i < offset; i++) + display->write(' '); + + display->print(value); + width -= length; + + while (width > 0) + { + display->write(' '); + width--; + } } } else { - // Center title - uint8_t offset = (maxWidth - titleLength) / 2; - - for (uint8_t i = 0; i < offset; i++) + for (uint8_t i = 0; i < width; i++) display->write(' '); - - display->print(title); - offset += titleLength; - - while (offset < LCDWidth - 2) - { - display->print(' '); - offset++; - } } -*/ } -const char* FormatTime(unsigned int time) +const char* UniqueString(const char* value) { - String minutes = String(time / 60); - String seconds = String(time % 60); + char* result = new char[strlen(value) + 1]; + return strcpy(result, value); +} - return (minutes + ':' + (seconds.length() == 1 ? '0' + seconds : seconds)).c_str(); -} \ No newline at end of file + +#define ASCII0 0x30 + + +const char* FormatTime(uint16_t time) +{ + uint16_t minutes = time / 60; + uint8_t seconds = time % 60; + + char* value = new char[9]; + itoa(minutes, value, 10); + + uint8_t length = strlen(value); + value[length] = ':'; length++; + + value[length] = (seconds / 10) + ASCII0; length++; + value[length] = (seconds % 10) + ASCII0; length++; + value[length] = 0; + + return value; +} + + +const char* FormatPercentage(uint8_t percentage) +{ + char* value = new char[6]; + + + itoa(percentage, value, 10); + + uint8_t length = strlen(value); + value[length] = '%'; + value[length + 1] = 0; + + return value; +} + + +const char* FormatPercentageFixedWidth(uint8_t percentage) +{ + char* value = new char[5]; + + if (percentage > 99) + { + value[0] = '1'; + value[1] = '0'; + } + else + { + value[0] = ' '; + value[1] = percentage > 9 ? (percentage / 10) + ASCII0 : ' '; + } + + value[2] = (percentage % 10) + ASCII0; + value[3] = '%'; + value[4] = 0; + + return value; +} diff --git a/src/display.h b/src/display.h index 993a01a..ca07d92 100644 --- a/src/display.h +++ b/src/display.h @@ -4,10 +4,13 @@ #include #include - void LCDPrintLine(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin = 0); void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin = 0); -const char* FormatTime(unsigned int time); +const char* UniqueString(const char* value); + +const char* FormatTime(uint16_t time); +const char* FormatPercentage(uint8_t percentage); +const char* FormatPercentageFixedWidth(uint8_t percentage); #endif \ No newline at end of file diff --git a/src/menu/intensity.cpp b/src/menu/intensity.cpp index 6fb26f9..3a57c7b 100644 --- a/src/menu/intensity.cpp +++ b/src/menu/intensity.cpp @@ -1,54 +1,41 @@ #include "intensity.h" +#include "config.h" #include "state.h" +#include "display.h" +#include "buzzer.h" -/* - LiquidCrystal* display = getDisplay(); - display->setCursor(0, 1); - - String intensity = "100%"; - uint8_t offset = (LCDWidth - intensity.length()) / 2; - - for (uint8_t space = 0; space < offset; space++) - display->print(' '); - - display->print(intensity); - offset += intensity.length(); - - if (getEditMode()) - { - display->write(LCDCharUpDown); - offset++; - } - - for (uint8_t space = offset; space < LCDWidth; space++) - display->print(' '); - -*/ const char* IntensityMenuItem::getTitle() { - return "Intensity"; + return UniqueString("Intensity"); } const char* IntensityMenuItem::getValue() { - char value[5]; - itoa(GetExposureIntensity(), value, 10); - - uint8_t length = strlen(value); - value[length] = '%'; - value[length + 1] = 0; - - return value; + return FormatPercentageFixedWidth(GetExposureIntensity()); } void IntensityMenuItem::incValue() { + uint16_t exposureIntensity = GetExposureIntensity(); + + if (exposureIntensity < 100) + { + SetExposureIntensity(exposureIntensity + IntensityStep); + Buzzer::select(); + } } void IntensityMenuItem::decValue() { + uint16_t exposureIntensity = GetExposureIntensity(); + + if (exposureIntensity > IntensityStep) + { + SetExposureIntensity(exposureIntensity - IntensityStep); + Buzzer::select(); + } } \ No newline at end of file diff --git a/src/menu/start.cpp b/src/menu/start.cpp new file mode 100644 index 0000000..d7893a9 --- /dev/null +++ b/src/menu/start.cpp @@ -0,0 +1,39 @@ +#include "start.h" +#include "state.h" +#include "display.h" + +const char* StartMenuItem::getTitle() +{ + return UniqueString("Start"); +} + + +const char* StartMenuItem::getValue() +{ + const char* time = FormatTime(GetExposureTime()); + const char* intensity = FormatPercentage(GetExposureIntensity()); + + uint8_t timeLength = strlen(time); + uint8_t intensityLength = strlen(intensity); + + char* value = new char[timeLength + 3 + intensityLength + 1]; + + strcpy(value, time); + delete[] time; + + uint8_t offset = timeLength; + + value[offset] = ' '; offset++; + value[offset] = '@'; offset++; + value[offset] = ' '; offset++; + + strcpy(value + offset, intensity); + delete[] intensity; + + return value; +} + + +void StartMenuItem::execute() +{ +} diff --git a/src/menu/start.h b/src/menu/start.h new file mode 100644 index 0000000..036aced --- /dev/null +++ b/src/menu/start.h @@ -0,0 +1,19 @@ +#ifndef __startmenuitem +#define __startmenuitem + +#include "screen/menu.h" + +class StartMenuItem : public MenuItem +{ + public: + StartMenuItem() : MenuItem() { } + + const char* getTitle(); + const char* getValue(); + + bool editable() { return false; } + + void execute(); +}; + +#endif \ No newline at end of file diff --git a/src/menu/time.cpp b/src/menu/time.cpp index 47de1fc..ad6640e 100644 --- a/src/menu/time.cpp +++ b/src/menu/time.cpp @@ -1,54 +1,40 @@ #include "time.h" - -/* - LiquidCrystal* display = getDisplay(); - display->setCursor(0, 1); - - String time = FormatTime(ExposureTime); - uint8_t offset = (LCDWidth - time.length()) / 2; - - for (uint8_t space = 0; space < offset; space++) - display->print(' '); - - display->print(time); - offset += time.length(); - - if (getEditMode()) - { - display->write(LCDCharUpDown); - offset++; - } - - for (uint8_t space = offset; space < LCDWidth; space++) - display->print(' '); - - - - - - if (newPosition > lastPosition) - ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep; - else if (ExposureTime > 0) - ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep; -*/ +#include "config.h" +#include "state.h" +#include "display.h" +#include "buzzer.h" const char* TimeMenuItem::getTitle() { - return "Time"; + return UniqueString("Time"); } const char* TimeMenuItem::getValue() { - return NULL; + return FormatTime(GetExposureTime()); } void TimeMenuItem::incValue() { + uint16_t exposureTime = GetExposureTime(); + + if (exposureTime < (uint16_t)-1) + { + SetExposureTime(exposureTime + (exposureTime >= LargeStepTreshold ? LargeStep : SmallStep)); + Buzzer::select(); + } } void TimeMenuItem::decValue() { + uint16_t exposureTime = GetExposureTime(); + + if (exposureTime > SmallStep) + { + SetExposureTime(exposureTime - (exposureTime > LargeStepTreshold ? LargeStep : SmallStep)); + Buzzer::select(); + } } \ No newline at end of file diff --git a/src/screen.h b/src/screen.h index e76621b..d06ec54 100644 --- a/src/screen.h +++ b/src/screen.h @@ -72,7 +72,7 @@ class ScreenManager if (mCurrent != NULL) { mCurrent->onHide(); - delete(mCurrent); + delete mCurrent; } mCurrent = new T(this); diff --git a/src/screen/menu.cpp b/src/screen/menu.cpp index e6b7b4f..80f7c97 100644 --- a/src/screen/menu.cpp +++ b/src/screen/menu.cpp @@ -3,7 +3,9 @@ #include "buzzer.h" #include "display.h" +#include "menu/start.h" #include "menu/time.h" +#include "menu/intensity.h" MenuScreen::MenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager) @@ -11,9 +13,9 @@ MenuScreen::MenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager) mCount = 3; mItems = new MenuItem*[mCount]; - mItems[0] = new TimeMenuItem(); + mItems[0] = new StartMenuItem(); mItems[1] = new TimeMenuItem(); - mItems[2] = new TimeMenuItem(); + mItems[2] = new IntensityMenuItem(); } @@ -47,7 +49,11 @@ void MenuScreen::printFullUpdate() void MenuScreen::printTitle() { - LCDPrintLineCentered(getDisplay(), 0, mItems[mSelected]->getTitle(), 1); + const char* title = mItems[mSelected]->getTitle(); + LCDPrintLineCentered(getDisplay(), 0, title, 1); + + if (title != NULL) + delete[] title; } @@ -73,21 +79,60 @@ void MenuScreen::printValue() { LiquidCrystal* display = getDisplay(); - display->setCursor(0, 1); - for (uint8_t x = 0; x < LCDWidth; x++) - display->write(' '); + const char* value = mItems[mSelected]->getValue(); + + if (mEditing && value != NULL) + { + uint8_t valueLength = strlen(value); + char* editingValue = new char[valueLength + 5]; + + editingValue[0] = ' '; + editingValue[1] = ' '; + strcpy(editingValue + 2, value); + editingValue[valueLength + 2] = ' '; + editingValue[valueLength + 3] = LCDCharUpDown; + editingValue[valueLength + 4] = 0; + + LCDPrintLineCentered(display, 1, editingValue); + + delete[] editingValue; + } + else + LCDPrintLineCentered(display, 1, value); + + if (value != NULL) + delete[] value; } void MenuScreen::onButton() { + if (mItems[mSelected]->editable()) + { + mEditing = !mEditing; + printScrollIndicators(); + printValue(); + } + else + { + mItems[mSelected]->execute(getScreenManager()); + } } void MenuScreen::onEncoder(long lastPosition, long newPosition) { - if (!mEditing) + if (mEditing) + { + if (newPosition > lastPosition) + mItems[mSelected]->incValue(); + else + mItems[mSelected]->decValue(); + + printValue(); + } + else { if (newPosition > lastPosition) { diff --git a/src/state.cpp b/src/state.cpp index 24ed24f..e0f4bb6 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -2,20 +2,23 @@ #include "config.h" #include -uint32_t ExposureTime = DefaultExposureTime; +uint16_t ExposureTime = DefaultExposureTime; uint8_t ExposureIntensity = DefaultExposureIntensity; uint32_t ExposureTimerStart = 0; -uint32_t GetExposureTime() +uint16_t GetExposureTime() { return ExposureTime; } -void SetExposureTime(uint32_t value) +void SetExposureTime(uint16_t value) { - ExposureTime = value; + if (value < SmallStep) + ExposureTime = SmallStep; + else + ExposureTime = value; } @@ -27,7 +30,12 @@ uint8_t GetExposureIntensity() void SetExposureIntensity(uint8_t value) { - ExposureIntensity = (value <= 100) ? value : 100; + if (value > 100) + ExposureIntensity = 100; + else if (value < IntensityStep) + ExposureIntensity = IntensityStep; + else + ExposureIntensity = value; } @@ -35,9 +43,12 @@ void LoadSettings() { uint16_t offset = 0; EEPROM.get(offset, ExposureTime); + SetExposureTime(ExposureTime); + offset += sizeof(ExposureTime); EEPROM.get(offset, ExposureIntensity); + SetExposureIntensity(ExposureIntensity); } @@ -51,7 +62,7 @@ void SaveSettings() } -void StartExposureTimer(unsigned long currentTime) +void StartExposureTimer(uint32_t currentTime) { SaveSettings(); ExposureTimerStart = currentTime; @@ -64,7 +75,7 @@ void ResetExposureTimer() } -uint32_t GetExposureTimeRemaining(unsigned long currentTime) +uint16_t GetExposureTimeRemaining(uint32_t currentTime) { uint32_t elapsed = (currentTime - ExposureTimerStart); return elapsed <= ExposureTime ? ExposureTime - elapsed : 0; diff --git a/src/state.h b/src/state.h index 6856305..4d1a0b8 100644 --- a/src/state.h +++ b/src/state.h @@ -3,8 +3,8 @@ #include -uint32_t GetExposureTime(); -void SetExposureTime(uint32_t value); +uint16_t GetExposureTime(); +void SetExposureTime(uint16_t value); uint8_t GetExposureIntensity(); void SetExposureIntensity(uint8_t value); @@ -13,8 +13,8 @@ void SetExposureIntensity(uint8_t value); void LoadSettings(); void SaveSettings(); -void StartExposureTimer(unsigned long currentTime); +void StartExposureTimer(uint32_t currentTime); void ResetExposureTimer(); -uint32_t GetExposureTimeRemaining(unsigned long currentTime); +uint16_t GetExposureTimeRemaining(uint32_t currentTime); #endif From 1cdb3e476aeee67a9a46a2250ce25bcb820fc2c6 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Fri, 8 Dec 2017 11:08:53 +0100 Subject: [PATCH 8/9] Fixed start --- src/menu/start.cpp | 4 +++- src/menu/start.h | 2 +- src/screen/countdown.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/menu/start.cpp b/src/menu/start.cpp index d7893a9..a2b8e13 100644 --- a/src/menu/start.cpp +++ b/src/menu/start.cpp @@ -1,6 +1,7 @@ #include "start.h" #include "state.h" #include "display.h" +#include "screen/countdown.h" const char* StartMenuItem::getTitle() { @@ -34,6 +35,7 @@ const char* StartMenuItem::getValue() } -void StartMenuItem::execute() +void StartMenuItem::execute(ScreenManager* screenManager) { + screenManager->show(); } diff --git a/src/menu/start.h b/src/menu/start.h index 036aced..9fea889 100644 --- a/src/menu/start.h +++ b/src/menu/start.h @@ -13,7 +13,7 @@ class StartMenuItem : public MenuItem bool editable() { return false; } - void execute(); + void execute(ScreenManager* screenManager); }; #endif \ No newline at end of file diff --git a/src/screen/countdown.cpp b/src/screen/countdown.cpp index e51e834..5d8546b 100644 --- a/src/screen/countdown.cpp +++ b/src/screen/countdown.cpp @@ -14,7 +14,7 @@ void CountdownScreen::printRemainingTime() void CountdownScreen::onShow() { - LCDPrintLine(getDisplay(), 0, "Exposing..."); + LCDPrintLineCentered(getDisplay(), 0, "Exposing..."); mLastDisplayed = GetExposureTimeRemaining(getCurrentTime()) / 1000; printRemainingTime(); From 0be4b62da9163a2e222b9ae8ed179310e6256e63 Mon Sep 17 00:00:00 2001 From: Mark van Renswoude Date: Fri, 8 Dec 2017 22:32:04 +0100 Subject: [PATCH 9/9] Fixed countdown timer Added sound settings Changed edit arrows to indicate for min/max values --- src/Buzzer.cpp | 19 +++++++++----- src/Config.cpp | 20 ++++++++++++++ src/Config.h | 7 ++++- src/main.cpp | 17 +++++++----- src/menu/intensity.cpp | 30 ++++++++++----------- src/menu/intensity.h | 6 +++-- src/menu/sound.cpp | 56 ++++++++++++++++++++++++++++++++++++++++ src/menu/sound.h | 22 ++++++++++++++++ src/menu/start.cpp | 3 ++- src/menu/start.h | 2 +- src/menu/time.cpp | 30 +++++++++++---------- src/menu/time.h | 6 +++-- src/screen.cpp | 2 +- src/screen.h | 10 +++---- src/screen/countdown.cpp | 19 ++++++++++---- src/screen/countdown.h | 2 +- src/screen/menu.cpp | 44 ++++++++++++++++++++++++++----- src/screen/menu.h | 10 ++++--- src/state.cpp | 27 +++++++++++++++++-- src/state.h | 14 ++++++++++ 20 files changed, 274 insertions(+), 72 deletions(-) create mode 100644 src/menu/sound.cpp create mode 100644 src/menu/sound.h diff --git a/src/Buzzer.cpp b/src/Buzzer.cpp index e930d27..59441e3 100644 --- a/src/Buzzer.cpp +++ b/src/Buzzer.cpp @@ -1,6 +1,7 @@ #include "buzzer.h" #include #include "config.h" +#include "state.h" void Buzzer::playNote(uint16_t frequency, uint16_t duration) @@ -13,28 +14,34 @@ void Buzzer::playNote(uint16_t frequency, uint16_t duration) void Buzzer::startup() { - playNote(1000, 50); + if (GetBuzzer() == BuzzerSetting::CompletedButtonStartup) + playNote(1000, 50); } void Buzzer::select() { - playNote(1000, 1); + if (GetBuzzer() <= BuzzerSetting::CompletedButton) + playNote(1000, 1); } void Buzzer::click() { - playNote(1000, 25); + if (GetBuzzer() <= BuzzerSetting::CompletedButton) + playNote(1000, 25); } void Buzzer::completed() { - for (int i = 0; i < 3; i++) + if (GetBuzzer() <= BuzzerSetting::Completed) { - playNote(1000, 250); - delay(500); + for (int i = 0; i < 3; i++) + { + playNote(1000, 250); + delay(500); + } } } diff --git a/src/Config.cpp b/src/Config.cpp index f4a54ba..8ab1b4a 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -49,3 +49,23 @@ uint8_t LCDCharUpDownMap[8] = { B00100, B00000, }; + +uint8_t LCDCharUpMap[8] = { + B00000, + B00100, + B01110, + B00000, + B00000, + B00000, + B00000, +}; + +uint8_t LCDCharDownMap[8] = { + B00000, + B00000, + B00000, + B00000, + B01110, + B00100, + B00000, +}; diff --git a/src/Config.h b/src/Config.h index 8552536..864e056 100644 --- a/src/Config.h +++ b/src/Config.h @@ -15,6 +15,7 @@ const uint8_t PinButton = 4; const uint8_t PinBuzzer = 5; const uint8_t PinLED = 6; +// Note: an LCD size of at least 16x2 is assumed for all text to fit const uint8_t LCDWidth = 16; const uint8_t LCDHeight = 2; @@ -22,7 +23,7 @@ const uint8_t EncoderSensitivity = 4; const uint8_t SmallStep = 1; const uint8_t LargeStepTreshold = 60; const uint8_t LargeStep = 10; -const uint8_t IntensityStep = 1; +const uint8_t IntensityStep = 5; const uint32_t DefaultExposureTime = 60; @@ -33,11 +34,15 @@ const uint8_t LCDCharArrowLeft = 1; const uint8_t LCDCharArrowRightHollow = 2; const uint8_t LCDCharArrowLeftHollow = 3; const uint8_t LCDCharUpDown = 4; +const uint8_t LCDCharUp = 5; +const uint8_t LCDCharDown = 6; extern uint8_t LCDCharArrowRightMap[8]; extern uint8_t LCDCharArrowLeftMap[8]; extern uint8_t LCDCharArrowRightHollowMap[8]; extern uint8_t LCDCharArrowLeftHollowMap[8]; extern uint8_t LCDCharUpDownMap[8]; +extern uint8_t LCDCharUpMap[8]; +extern uint8_t LCDCharDownMap[8]; #endif diff --git a/src/main.cpp b/src/main.cpp index 83df5ca..cdf68ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ LiquidCrystal lcd(PinLCDRS, PinLCDEN, PinLCDDB4, PinLCDDB5, PinLCDDB6, PinLCDDB7 #ifndef ResetEEPROM ScreenManager* screenManager; -unsigned long currentTime; +uint32_t currentTime; Encoder encoder(PinEncoderData, PinEncoderClock); Bounce button = Bounce(); @@ -41,6 +41,8 @@ void setup() lcd.createChar(LCDCharArrowRightHollow, LCDCharArrowRightHollowMap); lcd.createChar(LCDCharArrowLeftHollow, LCDCharArrowLeftHollowMap); lcd.createChar(LCDCharUpDown, LCDCharUpDownMap); + lcd.createChar(LCDCharUp, LCDCharUpMap); + lcd.createChar(LCDCharDown, LCDCharDownMap); lcd.begin(LCDWidth, LCDHeight); screenManager = new ScreenManager(&lcd, ¤tTime); @@ -50,7 +52,7 @@ void setup() } -long lastPosition = 0; +int32_t lastPosition = 0; bool isPressed = false; @@ -59,7 +61,7 @@ void loop() currentTime = millis(); button.update(); - long newPosition = encoder.read(); + int32_t newPosition = encoder.read(); if (abs(newPosition - lastPosition) >= EncoderSensitivity) { screenManager->getCurrent()->onEncoder(lastPosition, newPosition); @@ -82,18 +84,21 @@ void loop() #else +#include + void setup() { pinMode(PinBuzzer, OUTPUT); lcd.begin(LCDWidth, LCDHeight); - for (int i = 0 ; i < EEPROM.length() ; i++) + for (uint16_t i = 0 ; i < EEPROM.length() ; i++) { EEPROM.update(i, 0); } - ExposureTime = DefaultExposureTime; - ExposureIntensity = DefaultExposureIntensity; + SetExposureTime(DefaultExposureTime); + SetExposureIntensity(DefaultExposureIntensity); + SetBuzzer(BuzzerSetting::CompletedButtonStartup); SaveSettings(); lcd.setCursor(0, 0); diff --git a/src/menu/intensity.cpp b/src/menu/intensity.cpp index 3a57c7b..224c823 100644 --- a/src/menu/intensity.cpp +++ b/src/menu/intensity.cpp @@ -17,25 +17,25 @@ const char* IntensityMenuItem::getValue() } -void IntensityMenuItem::incValue() +bool IntensityMenuItem::canIncrement() { - uint16_t exposureIntensity = GetExposureIntensity(); - - if (exposureIntensity < 100) - { - SetExposureIntensity(exposureIntensity + IntensityStep); - Buzzer::select(); - } + return GetExposureIntensity() < 100; } -void IntensityMenuItem::decValue() +bool IntensityMenuItem::canDecrement() { - uint16_t exposureIntensity = GetExposureIntensity(); + return GetExposureIntensity() > IntensityStep; +} - if (exposureIntensity > IntensityStep) - { - SetExposureIntensity(exposureIntensity - IntensityStep); - Buzzer::select(); - } + +void IntensityMenuItem::incrementValue() +{ + SetExposureIntensity(GetExposureIntensity() + IntensityStep); +} + + +void IntensityMenuItem::decrementValue() +{ + SetExposureIntensity(GetExposureIntensity() - IntensityStep); } \ No newline at end of file diff --git a/src/menu/intensity.h b/src/menu/intensity.h index f133794..132d73b 100644 --- a/src/menu/intensity.h +++ b/src/menu/intensity.h @@ -13,8 +13,10 @@ class IntensityMenuItem : public MenuItem bool editable() { return true; } - void incValue(); - void decValue(); + bool canIncrement(); + bool canDecrement(); + void incrementValue(); + void decrementValue(); }; #endif \ No newline at end of file diff --git a/src/menu/sound.cpp b/src/menu/sound.cpp new file mode 100644 index 0000000..83f4262 --- /dev/null +++ b/src/menu/sound.cpp @@ -0,0 +1,56 @@ +#include "sound.h" +#include "config.h" +#include "state.h" +#include "display.h" +#include "buzzer.h" + + +const char* SoundMenuItem::getTitle() +{ + return UniqueString("Sound"); +} + + +const char* SoundMenuItem::getValue() +{ + switch (GetBuzzer()) + { + case BuzzerSetting::CompletedButtonStartup: + return UniqueString("All"); + + case BuzzerSetting::CompletedButton: + return UniqueString("Alarm/button"); + + case BuzzerSetting::Completed: + return UniqueString("Alarm only"); + + case BuzzerSetting::None: + return UniqueString("None"); + } + + return NULL; +} + + +bool SoundMenuItem::canIncrement() +{ + return GetBuzzer() > BuzzerSetting::First; +} + + +bool SoundMenuItem::canDecrement() +{ + return GetBuzzer() < BuzzerSetting::Last; +} + + +void SoundMenuItem::incrementValue() +{ + SetBuzzer((BuzzerSetting)((uint8_t)GetBuzzer() - 1)); +} + + +void SoundMenuItem::decrementValue() +{ + SetBuzzer((BuzzerSetting)((uint8_t)GetBuzzer() + 1)); +} \ No newline at end of file diff --git a/src/menu/sound.h b/src/menu/sound.h new file mode 100644 index 0000000..65b1203 --- /dev/null +++ b/src/menu/sound.h @@ -0,0 +1,22 @@ +#ifndef __soundmenuitem +#define __soundmenuitem + +#include "screen/menu.h" + +class SoundMenuItem : public MenuItem +{ + public: + SoundMenuItem() : MenuItem() { } + + const char* getTitle(); + const char* getValue(); + + bool editable() { return true; } + + bool canIncrement(); + bool canDecrement(); + void incrementValue(); + void decrementValue(); +}; + +#endif \ No newline at end of file diff --git a/src/menu/start.cpp b/src/menu/start.cpp index a2b8e13..6c038ec 100644 --- a/src/menu/start.cpp +++ b/src/menu/start.cpp @@ -35,7 +35,8 @@ const char* StartMenuItem::getValue() } -void StartMenuItem::execute(ScreenManager* screenManager) +void StartMenuItem::execute(ScreenManager* screenManager, uint32_t currentTime) { + StartExposureTimer(currentTime); screenManager->show(); } diff --git a/src/menu/start.h b/src/menu/start.h index 9fea889..7b5a6c6 100644 --- a/src/menu/start.h +++ b/src/menu/start.h @@ -13,7 +13,7 @@ class StartMenuItem : public MenuItem bool editable() { return false; } - void execute(ScreenManager* screenManager); + void execute(ScreenManager* screenManager, uint32_t currentTime); }; #endif \ No newline at end of file diff --git a/src/menu/time.cpp b/src/menu/time.cpp index ad6640e..6fd0c8b 100644 --- a/src/menu/time.cpp +++ b/src/menu/time.cpp @@ -16,25 +16,27 @@ const char* TimeMenuItem::getValue() } -void TimeMenuItem::incValue() +bool TimeMenuItem::canIncrement() { - uint16_t exposureTime = GetExposureTime(); - - if (exposureTime < (uint16_t)-1) - { - SetExposureTime(exposureTime + (exposureTime >= LargeStepTreshold ? LargeStep : SmallStep)); - Buzzer::select(); - } + return GetExposureTime() < (uint16_t)-1; } -void TimeMenuItem::decValue() +bool TimeMenuItem::canDecrement() +{ + return GetExposureTime() > SmallStep; +} + + +void TimeMenuItem::incrementValue() { uint16_t exposureTime = GetExposureTime(); + SetExposureTime(exposureTime + (exposureTime >= LargeStepTreshold ? LargeStep : SmallStep)); +} - if (exposureTime > SmallStep) - { - SetExposureTime(exposureTime - (exposureTime > LargeStepTreshold ? LargeStep : SmallStep)); - Buzzer::select(); - } + +void TimeMenuItem::decrementValue() +{ + uint16_t exposureTime = GetExposureTime(); + SetExposureTime(exposureTime - (exposureTime > LargeStepTreshold ? LargeStep : SmallStep)); } \ No newline at end of file diff --git a/src/menu/time.h b/src/menu/time.h index 9f46bc0..265bf5e 100644 --- a/src/menu/time.h +++ b/src/menu/time.h @@ -13,8 +13,10 @@ class TimeMenuItem : public MenuItem bool editable() { return true; } - void incValue(); - void decValue(); + bool canIncrement(); + bool canDecrement(); + void incrementValue(); + void decrementValue(); }; #endif \ No newline at end of file diff --git a/src/screen.cpp b/src/screen.cpp index f578089..9014894 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -7,7 +7,7 @@ ScreenManager* BaseScreen::getScreenManager() return mScreenManager; } -unsigned long BaseScreen::getCurrentTime() +uint32_t BaseScreen::getCurrentTime() { return mScreenManager->getCurrentTime(); } diff --git a/src/screen.h b/src/screen.h index d06ec54..921b85b 100644 --- a/src/screen.h +++ b/src/screen.h @@ -13,7 +13,7 @@ class BaseScreen protected: ScreenManager* getScreenManager(); - unsigned long getCurrentTime(); + uint32_t getCurrentTime(); LiquidCrystal* getDisplay(); public: @@ -28,7 +28,7 @@ class BaseScreen virtual void onHide() = 0; virtual void onButton() = 0; - virtual void onEncoder(long lastPosition, long newPosition) = 0; + virtual void onEncoder(int32_t lastPosition, int32_t newPosition) = 0; virtual void onTick() = 0; }; @@ -38,12 +38,12 @@ class ScreenManager { private: LiquidCrystal* mDisplay; - unsigned long* mCurrentTime; + uint32_t* mCurrentTime; BaseScreen* mCurrent = NULL; public: - ScreenManager(LiquidCrystal* display, unsigned long* currentTime) + ScreenManager(LiquidCrystal* display, uint32_t* currentTime) { mDisplay = display; mCurrentTime = currentTime; @@ -56,7 +56,7 @@ class ScreenManager } - inline unsigned long getCurrentTime() + inline uint32_t getCurrentTime() { return *mCurrentTime; } diff --git a/src/screen/countdown.cpp b/src/screen/countdown.cpp index 5d8546b..5e6ef18 100644 --- a/src/screen/countdown.cpp +++ b/src/screen/countdown.cpp @@ -6,6 +6,12 @@ #include "buzzer.h" +inline uint32_t intDivCeil(uint32_t x, uint32_t y) +{ + return x / y + (x % y != 0); +} + + void CountdownScreen::printRemainingTime() { LCDPrintLineCentered(getDisplay(), 1, FormatTime(mLastDisplayed)); @@ -16,10 +22,12 @@ void CountdownScreen::onShow() { LCDPrintLineCentered(getDisplay(), 0, "Exposing..."); - mLastDisplayed = GetExposureTimeRemaining(getCurrentTime()) / 1000; + uint32_t remaining = GetExposureTimeRemaining(getCurrentTime()); + mLastDisplayed = intDivCeil(remaining, 1000); + printRemainingTime(); - digitalWrite(PinLED, HIGH); + analogWrite(PinLED, map(GetExposureIntensity(), 0, 100, 0, 255)); } @@ -37,7 +45,7 @@ void CountdownScreen::onButton() } -void CountdownScreen::onEncoder(long lastPosition, long newPosition) +void CountdownScreen::onEncoder(int32_t lastPosition, int32_t newPosition) { // TODO Allow adding / removing time? } @@ -45,13 +53,14 @@ void CountdownScreen::onEncoder(long lastPosition, long newPosition) void CountdownScreen::onTick() { - uint32_t remaining = GetExposureTimeRemaining(getCurrentTime()) / 1000; + uint32_t remaining = GetExposureTimeRemaining(getCurrentTime()); + remaining = intDivCeil(remaining, 1000); if (remaining == 0) { mLastDisplayed = 0; - LCDPrintLine(getDisplay(), 0, "Done!"); + LCDPrintLineCentered(getDisplay(), 0, "Done!"); printRemainingTime(); digitalWrite(PinLED, LOW); diff --git a/src/screen/countdown.h b/src/screen/countdown.h index 745ccd5..82e68f1 100644 --- a/src/screen/countdown.h +++ b/src/screen/countdown.h @@ -22,7 +22,7 @@ class CountdownScreen : public BaseScreen void onHide(); void onButton(); - void onEncoder(long lastPosition, long newPosition); + void onEncoder(int32_t lastPosition, int32_t newPosition); void onTick(); }; diff --git a/src/screen/menu.cpp b/src/screen/menu.cpp index 80f7c97..10052ff 100644 --- a/src/screen/menu.cpp +++ b/src/screen/menu.cpp @@ -2,20 +2,23 @@ #include "config.h" #include "buzzer.h" #include "display.h" +#include "state.h" #include "menu/start.h" #include "menu/time.h" #include "menu/intensity.h" +#include "menu/sound.h" MenuScreen::MenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { - mCount = 3; + mCount = 4; mItems = new MenuItem*[mCount]; mItems[0] = new StartMenuItem(); mItems[1] = new TimeMenuItem(); mItems[2] = new IntensityMenuItem(); + mItems[3] = new SoundMenuItem(); } @@ -90,7 +93,19 @@ void MenuScreen::printValue() editingValue[1] = ' '; strcpy(editingValue + 2, value); editingValue[valueLength + 2] = ' '; - editingValue[valueLength + 3] = LCDCharUpDown; + + bool canIncrement = mItems[mSelected]->canIncrement(); + bool canDecrement = mItems[mSelected]->canDecrement(); + + if (canIncrement && canDecrement) + editingValue[valueLength + 3] = LCDCharUpDown; + else if (canIncrement) + editingValue[valueLength + 3] = LCDCharUp; + else if (canDecrement) + editingValue[valueLength + 3] = LCDCharDown; + else + editingValue[valueLength + 3] = ' '; + editingValue[valueLength + 4] = 0; LCDPrintLineCentered(display, 1, editingValue); @@ -110,25 +125,42 @@ void MenuScreen::onButton() { if (mItems[mSelected]->editable()) { + Buzzer::select(); + + if (mEditing) + SaveSettings(); + mEditing = !mEditing; printScrollIndicators(); printValue(); } else { - mItems[mSelected]->execute(getScreenManager()); + mItems[mSelected]->execute(getScreenManager(), getCurrentTime()); } } -void MenuScreen::onEncoder(long lastPosition, long newPosition) +void MenuScreen::onEncoder(int32_t lastPosition, int32_t newPosition) { if (mEditing) { if (newPosition > lastPosition) - mItems[mSelected]->incValue(); + { + if (mItems[mSelected]->canIncrement()) + { + mItems[mSelected]->incrementValue(); + Buzzer::select(); + } + } else - mItems[mSelected]->decValue(); + { + if (mItems[mSelected]->canDecrement()) + { + mItems[mSelected]->decrementValue(); + Buzzer::select(); + } + } printValue(); } diff --git a/src/screen/menu.h b/src/screen/menu.h index 6e4ad64..da7f004 100644 --- a/src/screen/menu.h +++ b/src/screen/menu.h @@ -14,11 +14,13 @@ class MenuItem virtual bool editable() { return false; } // Editable = true - virtual void incValue() { } - virtual void decValue() { } + virtual bool canIncrement() { return true; } + virtual bool canDecrement() { return true; } + virtual void incrementValue() { } + virtual void decrementValue() { } // Editable = false - virtual void execute(ScreenManager* screenManager) { } + virtual void execute(ScreenManager* screenManager, uint32_t currentTime) { } }; class MenuScreen : public BaseScreen @@ -44,7 +46,7 @@ class MenuScreen : public BaseScreen void onHide(); void onButton(); - void onEncoder(long lastPosition, long newPosition); + void onEncoder(int32_t lastPosition, int32_t newPosition); void onTick(); }; diff --git a/src/state.cpp b/src/state.cpp index e0f4bb6..08372e6 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -5,6 +5,7 @@ uint16_t ExposureTime = DefaultExposureTime; uint8_t ExposureIntensity = DefaultExposureIntensity; uint32_t ExposureTimerStart = 0; +BuzzerSetting Buzzer = BuzzerSetting::CompletedButtonStartup; uint16_t GetExposureTime() @@ -39,6 +40,18 @@ void SetExposureIntensity(uint8_t value) } +BuzzerSetting GetBuzzer() +{ + return Buzzer; +} + + +void SetBuzzer(BuzzerSetting value) +{ + Buzzer = value; +} + + void LoadSettings() { uint16_t offset = 0; @@ -49,6 +62,12 @@ void LoadSettings() EEPROM.get(offset, ExposureIntensity); SetExposureIntensity(ExposureIntensity); + + offset += sizeof(ExposureIntensity); + + EEPROM.get(offset, Buzzer); + if (Buzzer < BuzzerSetting::First || Buzzer > BuzzerSetting::Last) + Buzzer = BuzzerSetting::CompletedButtonStartup; } @@ -59,12 +78,14 @@ void SaveSettings() offset += sizeof(ExposureTime); EEPROM.put(offset, ExposureIntensity); + offset += sizeof(ExposureIntensity); + + EEPROM.put(offset, (uint8_t)Buzzer); } void StartExposureTimer(uint32_t currentTime) { - SaveSettings(); ExposureTimerStart = currentTime; } @@ -78,5 +99,7 @@ void ResetExposureTimer() uint16_t GetExposureTimeRemaining(uint32_t currentTime) { uint32_t elapsed = (currentTime - ExposureTimerStart); - return elapsed <= ExposureTime ? ExposureTime - elapsed : 0; + uint32_t exposureTimeMs = ExposureTime * 1000; + + return elapsed <= exposureTimeMs ? exposureTimeMs - elapsed : 0; } \ No newline at end of file diff --git a/src/state.h b/src/state.h index 4d1a0b8..0b35c4f 100644 --- a/src/state.h +++ b/src/state.h @@ -3,12 +3,26 @@ #include +enum BuzzerSetting +{ + CompletedButtonStartup = 0, + CompletedButton = 1, + Completed = 2, + None = 3, + + First = CompletedButtonStartup, + Last = None +}; + uint16_t GetExposureTime(); void SetExposureTime(uint16_t value); uint8_t GetExposureIntensity(); void SetExposureIntensity(uint8_t value); +BuzzerSetting GetBuzzer(); +void SetBuzzer(BuzzerSetting value); + void LoadSettings(); void SaveSettings();