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