Code cleanup

Ongoing refactoring... it compiles, but that's about it
This commit is contained in:
Mark van Renswoude 2017-12-07 16:49:57 +01:00
parent 70dfde8562
commit 5efc605d1d
28 changed files with 550 additions and 600 deletions

View File

@ -1,53 +1,50 @@
#include "Buzzer.h"
#include "buzzer.h"
#include <Arduino.h>
#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);
}
}
}

View File

@ -1,10 +1,19 @@
#ifndef __Buzzer
#define __Buzzer
#ifndef __buzzer
#define __buzzer
void buzzStartup();
void buzzSelect();
void buzzClick();
void buzzCompleted();
void buzzMemoryCleared();
#include <Arduino.h>
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

View File

@ -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,

View File

@ -1,43 +1,44 @@
#ifndef __Config
#define __Config
#include "Arduino.h"
#include <Arduino.h>
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

View File

@ -1,26 +0,0 @@
#include "ExposureTimer.h"
#include <EEPROM.h>
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);
}

View File

@ -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

View File

@ -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();
}
}
}
}

View File

@ -1,41 +0,0 @@
#ifndef __BaseMenuScreen
#define __BaseMenuScreen
#include <stdbool.h>
#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

View File

@ -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<SetTimeScreen>();
}
void IntensityScreen::gotoNext()
{
buzzSelect();
getScreenManager()->show<StartScreen>();
}
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()
{
}

View File

@ -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

View File

@ -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

View File

@ -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<IntensityScreen>();
}
void StartScreen::onHide()
{
}
void StartScreen::onButton()
{
buzzSelect();
//setEditMode(!getEditMode());
}
void StartScreen::onTick()
{
}

View File

@ -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

23
src/display.cpp Normal file
View File

@ -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();
}

13
src/display.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef __display
#define __display
#include <Arduino.h>
#include <LiquidCrystal.h>
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

View File

@ -2,20 +2,20 @@
#include <Bounce2.h>
#include <Encoder.h>
#include <LiquidCrystal.h>
#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, &currentTime);
screenManager->show<SetTimeScreen>();
screenManager->show<MenuScreen>();
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

46
src/menu/intensity.cpp Normal file
View File

@ -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()
{
}

20
src/menu/intensity.h Normal file
View File

@ -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

View File

@ -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<IntensityScreen>();
}
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()
{
}

20
src/menu/time.h Normal file
View File

@ -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

View File

@ -1,5 +1,5 @@
#include "ScreenManager.h"
#include "Config.h"
#include "screen.h"
#include "config.h"
ScreenManager* BaseScreen::getScreenManager()

View File

@ -1,9 +1,8 @@
#ifndef __ScreenManager
#define __ScreenManager
#ifndef __screen
#define __screen
#include <LiquidCrystal.h>
class ScreenManager;

View File

@ -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<SetTimeScreen>();
Buzzer::click();
getScreenManager()->show<MenuScreen>();
}
@ -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<SetTimeScreen>();
getScreenManager()->show<MenuScreen>();
}
else if (elapsed != mLastDisplayed)
{

View File

@ -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();

151
src/screen/menu.cpp Normal file
View File

@ -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()
{
}

51
src/screen/menu.h Normal file
View File

@ -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

34
src/state.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "state.h"
#include "config.h"
#include <EEPROM.h>
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;
}

17
src/state.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __state
#define __state
#include <Arduino.h>
extern uint32_t ExposureTime;
extern uint8_t ExposureIntensity;
extern uint32_t ExposureTimerStart;
void LoadSettings();
void SaveSettings();
void StartExposureTimer(unsigned long currentTime);
#endif