Merge branch 'feature/platformio' into develop
This commit is contained in:
commit
3035fd189b
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.sublime-workspace
|
||||||
|
.pioenvs
|
||||||
|
.piolibdeps
|
53
Buzzer.cpp
53
Buzzer.cpp
@ -1,53 +0,0 @@
|
|||||||
#include "Buzzer.h"
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include "Config.h"
|
|
||||||
|
|
||||||
void buzzStartup()
|
|
||||||
{
|
|
||||||
tone(PinBuzzer, 1000);
|
|
||||||
delay(50);
|
|
||||||
noTone(PinBuzzer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void buzzSelect()
|
|
||||||
{
|
|
||||||
tone(PinBuzzer, 1000);
|
|
||||||
delay(1);
|
|
||||||
noTone(PinBuzzer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void buzzClick()
|
|
||||||
{
|
|
||||||
tone(PinBuzzer, 1000);
|
|
||||||
delay(25);
|
|
||||||
noTone(PinBuzzer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void buzzCompleted()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
tone(PinBuzzer, 1000);
|
|
||||||
delay(250);
|
|
||||||
noTone(PinBuzzer);
|
|
||||||
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void buzzMemoryCleared()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
tone(PinBuzzer, 1000);
|
|
||||||
delay(25);
|
|
||||||
noTone(PinBuzzer);
|
|
||||||
|
|
||||||
delay(250);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
10
Buzzer.h
10
Buzzer.h
@ -1,10 +0,0 @@
|
|||||||
#ifndef __Buzzer
|
|
||||||
#define __Buzzer
|
|
||||||
|
|
||||||
void buzzStartup();
|
|
||||||
void buzzSelect();
|
|
||||||
void buzzClick();
|
|
||||||
void buzzCompleted();
|
|
||||||
void buzzMemoryCleared();
|
|
||||||
|
|
||||||
#endif
|
|
12
Config.cpp
12
Config.cpp
@ -1,12 +0,0 @@
|
|||||||
#include "Config.h"
|
|
||||||
|
|
||||||
byte LCDCharArrow[8] = {
|
|
||||||
B00000,
|
|
||||||
B01000,
|
|
||||||
B01100,
|
|
||||||
B01110,
|
|
||||||
B01100,
|
|
||||||
B01000,
|
|
||||||
B00000,
|
|
||||||
};
|
|
||||||
|
|
33
Config.h
33
Config.h
@ -1,33 +0,0 @@
|
|||||||
#ifndef __Config
|
|
||||||
#define __Config
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
extern byte LCDCharArrow[8];
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,18 +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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
#ifndef __ExposureTimer
|
|
||||||
#define __ExposureTimer
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
extern unsigned int ExposureTime;
|
|
||||||
extern unsigned long ExposureTimerStart;
|
|
||||||
|
|
||||||
|
|
||||||
void ResetExposureTime();
|
|
||||||
void StartExposureTimer(unsigned long currentTime);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||||||
#include "ScreenCountdown.h"
|
|
||||||
#include "ScreenSetTime.h"
|
|
||||||
#include "ExposureTimer.h"
|
|
||||||
#include "Config.h"
|
|
||||||
#include "Buzzer.h"
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenCountdown::printRemainingTime()
|
|
||||||
{
|
|
||||||
getDisplay()->setCursor(0, 1);
|
|
||||||
printTime(ExposureTime - ((getCurrentTime() - ExposureTimerStart) / 1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenCountdown::onShow()
|
|
||||||
{
|
|
||||||
mLastDisplayed = -1;
|
|
||||||
|
|
||||||
getDisplay()->setCursor(0, 0);
|
|
||||||
getDisplay()->print("Exposing... ");
|
|
||||||
|
|
||||||
printRemainingTime();
|
|
||||||
digitalWrite(PinLED, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenCountdown::onHide()
|
|
||||||
{
|
|
||||||
digitalWrite(PinLED, LOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenCountdown::onButton()
|
|
||||||
{
|
|
||||||
// TODO Confirmation?
|
|
||||||
buzzClick();
|
|
||||||
getScreenManager()->show<ScreenSetTime>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenCountdown::onEncoder(long lastPosition, long newPosition)
|
|
||||||
{
|
|
||||||
// TODO Allow adding / removing time?
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ScreenCountdown::onTick()
|
|
||||||
{
|
|
||||||
int elapsed = (getCurrentTime() - ExposureTimerStart) / 1000;
|
|
||||||
|
|
||||||
if (elapsed >= ExposureTime)
|
|
||||||
{
|
|
||||||
getDisplay()->setCursor(0, 0);
|
|
||||||
getDisplay()->print("Done! ");
|
|
||||||
|
|
||||||
printRemainingTime();
|
|
||||||
digitalWrite(PinLED, LOW);
|
|
||||||
|
|
||||||
buzzCompleted();
|
|
||||||
|
|
||||||
ExposureTimerStart = 0;
|
|
||||||
getScreenManager()->show<ScreenSetTime>();
|
|
||||||
}
|
|
||||||
else if (elapsed != mLastDisplayed)
|
|
||||||
{
|
|
||||||
printRemainingTime();
|
|
||||||
mLastDisplayed = elapsed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef __ScreenCountdown
|
|
||||||
#define __ScreenCountdown
|
|
||||||
|
|
||||||
#include "ScreenManager.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Countdown screen
|
|
||||||
* Shows the remaining time.
|
|
||||||
*/
|
|
||||||
class ScreenCountdown : public BaseScreen
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int mLastDisplayed;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void printRemainingTime();
|
|
||||||
|
|
||||||
public:
|
|
||||||
ScreenCountdown(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
|
||||||
|
|
||||||
void onShow();
|
|
||||||
void onHide();
|
|
||||||
|
|
||||||
void onButton();
|
|
||||||
void onEncoder(long lastPosition, long newPosition);
|
|
||||||
void onTick();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||||||
#include "ScreenManager.h"
|
|
||||||
#include "Config.h"
|
|
||||||
|
|
||||||
|
|
||||||
ScreenManager* BaseScreen::getScreenManager()
|
|
||||||
{
|
|
||||||
return mScreenManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long BaseScreen::getCurrentTime()
|
|
||||||
{
|
|
||||||
return mScreenManager->getCurrentTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
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(" ");
|
|
||||||
}
|
|
||||||
|
|
100
ScreenMenu.cpp
100
ScreenMenu.cpp
@ -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<ScreenCountdown>();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
ResetExposureTime();
|
|
||||||
getScreenManager()->show<ScreenSetTime>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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<ScreenSetTime>();
|
|
||||||
}
|
|
||||||
|
|
33
ScreenMenu.h
33
ScreenMenu.h
@ -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
|
|
@ -1,52 +0,0 @@
|
|||||||
#include "ScreenSetTime.h"
|
|
||||||
#include "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<ScreenMenu>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
9
UVControl.sublime-project
Normal file
9
UVControl.sublime-project
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"folders":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"path": ".",
|
||||||
|
"file_exclude_patterns": ["*.sublime-project"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
24
platformio.ini
Normal file
24
platformio.ini
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
; 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 = pro16MHzatmega328
|
||||||
|
framework = arduino
|
||||||
|
|
||||||
|
;upload_protocol = stk500v1
|
||||||
|
;upload_flags = -P$UPLOAD_PORT -b$UPLOAD_SPEED
|
||||||
|
;upload_speed = 19200
|
||||||
|
|
||||||
|
board_f_cpu = 16000000L
|
||||||
|
|
||||||
|
lib_deps =
|
||||||
|
Bounce2
|
||||||
|
Encoder
|
57
src/Buzzer.cpp
Normal file
57
src/Buzzer.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "buzzer.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
|
|
||||||
|
void Buzzer::playNote(uint16_t frequency, uint16_t duration)
|
||||||
|
{
|
||||||
|
tone(PinBuzzer, frequency);
|
||||||
|
delay(duration);
|
||||||
|
noTone(PinBuzzer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Buzzer::startup()
|
||||||
|
{
|
||||||
|
if (GetBuzzer() == BuzzerSetting::CompletedButtonStartup)
|
||||||
|
playNote(1000, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Buzzer::select()
|
||||||
|
{
|
||||||
|
if (GetBuzzer() <= BuzzerSetting::CompletedButton)
|
||||||
|
playNote(1000, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Buzzer::click()
|
||||||
|
{
|
||||||
|
if (GetBuzzer() <= BuzzerSetting::CompletedButton)
|
||||||
|
playNote(1000, 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Buzzer::completed()
|
||||||
|
{
|
||||||
|
if (GetBuzzer() <= BuzzerSetting::Completed)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
playNote(1000, 250);
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Buzzer::memoryCleared()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
playNote(1000, 25);
|
||||||
|
delay(250);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
19
src/Buzzer.h
Normal file
19
src/Buzzer.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef __buzzer
|
||||||
|
#define __buzzer
|
||||||
|
|
||||||
|
#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
|
71
src/Config.cpp
Normal file
71
src/Config.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
uint8_t LCDCharArrowRightMap[8] = {
|
||||||
|
B00000,
|
||||||
|
B01000,
|
||||||
|
B01100,
|
||||||
|
B01110,
|
||||||
|
B01100,
|
||||||
|
B01000,
|
||||||
|
B00000,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t LCDCharArrowLeftMap[8] = {
|
||||||
|
B00000,
|
||||||
|
B00100,
|
||||||
|
B01100,
|
||||||
|
B11100,
|
||||||
|
B01100,
|
||||||
|
B00100,
|
||||||
|
B00000,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t LCDCharArrowRightHollowMap[8] = {
|
||||||
|
B00000,
|
||||||
|
B01000,
|
||||||
|
B00100,
|
||||||
|
B00010,
|
||||||
|
B00100,
|
||||||
|
B01000,
|
||||||
|
B00000,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t LCDCharArrowLeftHollowMap[8] = {
|
||||||
|
B00000,
|
||||||
|
B00100,
|
||||||
|
B01000,
|
||||||
|
B10000,
|
||||||
|
B01000,
|
||||||
|
B00100,
|
||||||
|
B00000,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t LCDCharUpDownMap[8] = {
|
||||||
|
B00000,
|
||||||
|
B00100,
|
||||||
|
B01110,
|
||||||
|
B00000,
|
||||||
|
B01110,
|
||||||
|
B00100,
|
||||||
|
B00000,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t LCDCharUpMap[8] = {
|
||||||
|
B00000,
|
||||||
|
B00100,
|
||||||
|
B01110,
|
||||||
|
B00000,
|
||||||
|
B00000,
|
||||||
|
B00000,
|
||||||
|
B00000,
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t LCDCharDownMap[8] = {
|
||||||
|
B00000,
|
||||||
|
B00000,
|
||||||
|
B00000,
|
||||||
|
B00000,
|
||||||
|
B01110,
|
||||||
|
B00100,
|
||||||
|
B00000,
|
||||||
|
};
|
48
src/Config.h
Normal file
48
src/Config.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#ifndef __Config
|
||||||
|
#define __Config
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
const uint8_t EncoderSensitivity = 4;
|
||||||
|
const uint8_t SmallStep = 1;
|
||||||
|
const uint8_t LargeStepTreshold = 60;
|
||||||
|
const uint8_t LargeStep = 10;
|
||||||
|
const uint8_t IntensityStep = 5;
|
||||||
|
|
||||||
|
|
||||||
|
const uint32_t DefaultExposureTime = 60;
|
||||||
|
const uint8_t DefaultExposureIntensity = 100;
|
||||||
|
|
||||||
|
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;
|
||||||
|
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
|
153
src/display.cpp
Normal file
153
src/display.cpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#include "display.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < width; i++)
|
||||||
|
display->write(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* UniqueString(const char* value)
|
||||||
|
{
|
||||||
|
char* result = new char[strlen(value) + 1];
|
||||||
|
return strcpy(result, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
16
src/display.h
Normal file
16
src/display.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#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* UniqueString(const char* value);
|
||||||
|
|
||||||
|
const char* FormatTime(uint16_t time);
|
||||||
|
const char* FormatPercentage(uint8_t percentage);
|
||||||
|
const char* FormatPercentageFixedWidth(uint8_t percentage);
|
||||||
|
|
||||||
|
#endif
|
@ -1,24 +1,24 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
#include <Bounce2.h>
|
#include <Bounce2.h>
|
||||||
#include <Encoder.h>
|
#include <Encoder.h>
|
||||||
#include <LiquidCrystal.h>
|
#include <LiquidCrystal.h>
|
||||||
#include <EEPROM.h>
|
#include "config.h"
|
||||||
#include "Config.h"
|
#include "screen.h"
|
||||||
#include "ScreenManager.h"
|
#include "screen/menu.h"
|
||||||
#include "ScreenSetTime.h"
|
#include "buzzer.h"
|
||||||
#include "Buzzer.h"
|
#include "state.h"
|
||||||
#include "ExposureTimer.h"
|
|
||||||
|
|
||||||
|
|
||||||
LiquidCrystal lcd(PinLCDRS, PinLCDEN, PinLCDDB4, PinLCDDB5, PinLCDDB6, PinLCDDB7);
|
LiquidCrystal lcd(PinLCDRS, PinLCDEN, PinLCDDB4, PinLCDDB5, PinLCDDB6, PinLCDDB7);
|
||||||
|
|
||||||
|
|
||||||
// Before uploading the sketch, upload it once with ClearEEPROM defined to
|
// Before uploading the sketch, upload it once with ResetEEPROM defined to
|
||||||
// zero out the memory.
|
// write the default values to the EEPROM
|
||||||
//#define ClearEEPROM
|
//#define ResetEEPROM
|
||||||
#ifndef ClearEEPROM
|
#ifndef ResetEEPROM
|
||||||
|
|
||||||
ScreenManager* screenManager;
|
ScreenManager* screenManager;
|
||||||
unsigned long currentTime;
|
uint32_t currentTime;
|
||||||
|
|
||||||
Encoder encoder(PinEncoderData, PinEncoderClock);
|
Encoder encoder(PinEncoderData, PinEncoderClock);
|
||||||
Bounce button = Bounce();
|
Bounce button = Bounce();
|
||||||
@ -34,19 +34,25 @@ void setup()
|
|||||||
button.attach(PinButton);
|
button.attach(PinButton);
|
||||||
button.interval(5);
|
button.interval(5);
|
||||||
|
|
||||||
ResetExposureTime();
|
LoadSettings();
|
||||||
|
|
||||||
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.createChar(LCDCharUp, LCDCharUpMap);
|
||||||
|
lcd.createChar(LCDCharDown, LCDCharDownMap);
|
||||||
lcd.begin(LCDWidth, LCDHeight);
|
lcd.begin(LCDWidth, LCDHeight);
|
||||||
|
|
||||||
screenManager = new ScreenManager(&lcd, ¤tTime);
|
screenManager = new ScreenManager(&lcd, ¤tTime);
|
||||||
screenManager->show<ScreenSetTime>();
|
screenManager->show<MenuScreen>();
|
||||||
|
|
||||||
buzzStartup();
|
Buzzer::startup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long lastPosition = 0;
|
int32_t lastPosition = 0;
|
||||||
bool isPressed = false;
|
bool isPressed = false;
|
||||||
|
|
||||||
|
|
||||||
@ -54,11 +60,11 @@ void loop()
|
|||||||
{
|
{
|
||||||
currentTime = millis();
|
currentTime = millis();
|
||||||
button.update();
|
button.update();
|
||||||
|
|
||||||
long newPosition = encoder.read();
|
int32_t newPosition = encoder.read();
|
||||||
if (abs(newPosition - lastPosition) >= EncoderSensitivity)
|
if (abs(newPosition - lastPosition) >= EncoderSensitivity)
|
||||||
{
|
{
|
||||||
screenManager->getCurrent()->onEncoder(lastPosition, newPosition);
|
screenManager->getCurrent()->onEncoder(lastPosition, newPosition);
|
||||||
lastPosition = newPosition;
|
lastPosition = newPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,23 +84,31 @@ void loop()
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
pinMode(PinBuzzer, OUTPUT);
|
pinMode(PinBuzzer, OUTPUT);
|
||||||
lcd.begin(LCDWidth, LCDHeight);
|
lcd.begin(LCDWidth, LCDHeight);
|
||||||
|
|
||||||
for (int i = 0 ; i < EEPROM.length() ; i++)
|
for (uint16_t i = 0 ; i < EEPROM.length() ; i++)
|
||||||
{
|
{
|
||||||
EEPROM.write(i, 0);
|
EEPROM.update(i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetExposureTime(DefaultExposureTime);
|
||||||
|
SetExposureIntensity(DefaultExposureIntensity);
|
||||||
|
SetBuzzer(BuzzerSetting::CompletedButtonStartup);
|
||||||
|
SaveSettings();
|
||||||
|
|
||||||
lcd.setCursor(0, 0);
|
lcd.setCursor(0, 0);
|
||||||
lcd.print("Memory cleared");
|
lcd.print("Memory cleared");
|
||||||
|
|
||||||
buzzMemoryCleared();
|
Buzzer::memoryCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
41
src/menu/intensity.cpp
Normal file
41
src/menu/intensity.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "intensity.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "buzzer.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char* IntensityMenuItem::getTitle()
|
||||||
|
{
|
||||||
|
return UniqueString("Intensity");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* IntensityMenuItem::getValue()
|
||||||
|
{
|
||||||
|
return FormatPercentageFixedWidth(GetExposureIntensity());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IntensityMenuItem::canIncrement()
|
||||||
|
{
|
||||||
|
return GetExposureIntensity() < 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IntensityMenuItem::canDecrement()
|
||||||
|
{
|
||||||
|
return GetExposureIntensity() > IntensityStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IntensityMenuItem::incrementValue()
|
||||||
|
{
|
||||||
|
SetExposureIntensity(GetExposureIntensity() + IntensityStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IntensityMenuItem::decrementValue()
|
||||||
|
{
|
||||||
|
SetExposureIntensity(GetExposureIntensity() - IntensityStep);
|
||||||
|
}
|
22
src/menu/intensity.h
Normal file
22
src/menu/intensity.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef __intensitymenuitem
|
||||||
|
#define __intensitymenuitem
|
||||||
|
|
||||||
|
#include "screen/menu.h"
|
||||||
|
|
||||||
|
class IntensityMenuItem : public MenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IntensityMenuItem() : MenuItem() { }
|
||||||
|
|
||||||
|
const char* getTitle();
|
||||||
|
const char* getValue();
|
||||||
|
|
||||||
|
bool editable() { return true; }
|
||||||
|
|
||||||
|
bool canIncrement();
|
||||||
|
bool canDecrement();
|
||||||
|
void incrementValue();
|
||||||
|
void decrementValue();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
56
src/menu/sound.cpp
Normal file
56
src/menu/sound.cpp
Normal file
@ -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));
|
||||||
|
}
|
22
src/menu/sound.h
Normal file
22
src/menu/sound.h
Normal file
@ -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
|
42
src/menu/start.cpp
Normal file
42
src/menu/start.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "start.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "screen/countdown.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(ScreenManager* screenManager, uint32_t currentTime)
|
||||||
|
{
|
||||||
|
StartExposureTimer(currentTime);
|
||||||
|
screenManager->show<CountdownScreen>();
|
||||||
|
}
|
19
src/menu/start.h
Normal file
19
src/menu/start.h
Normal file
@ -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(ScreenManager* screenManager, uint32_t currentTime);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
42
src/menu/time.cpp
Normal file
42
src/menu/time.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "time.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "buzzer.h"
|
||||||
|
|
||||||
|
const char* TimeMenuItem::getTitle()
|
||||||
|
{
|
||||||
|
return UniqueString("Time");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* TimeMenuItem::getValue()
|
||||||
|
{
|
||||||
|
return FormatTime(GetExposureTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TimeMenuItem::canIncrement()
|
||||||
|
{
|
||||||
|
return GetExposureTime() < (uint16_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TimeMenuItem::canDecrement()
|
||||||
|
{
|
||||||
|
return GetExposureTime() > SmallStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TimeMenuItem::incrementValue()
|
||||||
|
{
|
||||||
|
uint16_t exposureTime = GetExposureTime();
|
||||||
|
SetExposureTime(exposureTime + (exposureTime >= LargeStepTreshold ? LargeStep : SmallStep));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TimeMenuItem::decrementValue()
|
||||||
|
{
|
||||||
|
uint16_t exposureTime = GetExposureTime();
|
||||||
|
SetExposureTime(exposureTime - (exposureTime > LargeStepTreshold ? LargeStep : SmallStep));
|
||||||
|
}
|
22
src/menu/time.h
Normal file
22
src/menu/time.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef __timemenuitem
|
||||||
|
#define __timemenuitem
|
||||||
|
|
||||||
|
#include "screen/menu.h"
|
||||||
|
|
||||||
|
class TimeMenuItem : public MenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TimeMenuItem() : MenuItem() { }
|
||||||
|
|
||||||
|
const char* getTitle();
|
||||||
|
const char* getValue();
|
||||||
|
|
||||||
|
bool editable() { return true; }
|
||||||
|
|
||||||
|
bool canIncrement();
|
||||||
|
bool canDecrement();
|
||||||
|
void incrementValue();
|
||||||
|
void decrementValue();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
19
src/screen.cpp
Normal file
19
src/screen.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "screen.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
ScreenManager* BaseScreen::getScreenManager()
|
||||||
|
{
|
||||||
|
return mScreenManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t BaseScreen::getCurrentTime()
|
||||||
|
{
|
||||||
|
return mScreenManager->getCurrentTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidCrystal* BaseScreen::getDisplay()
|
||||||
|
{
|
||||||
|
return mScreenManager->getDisplay();
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,8 @@
|
|||||||
#ifndef __ScreenManager
|
#ifndef __screen
|
||||||
#define __ScreenManager
|
#define __screen
|
||||||
|
|
||||||
#include <LiquidCrystal.h>
|
#include <LiquidCrystal.h>
|
||||||
|
|
||||||
|
|
||||||
class ScreenManager;
|
class ScreenManager;
|
||||||
|
|
||||||
|
|
||||||
@ -13,24 +12,23 @@ class BaseScreen
|
|||||||
ScreenManager* mScreenManager;
|
ScreenManager* mScreenManager;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScreenManager* getScreenManager();
|
ScreenManager* getScreenManager();
|
||||||
unsigned long getCurrentTime();
|
uint32_t getCurrentTime();
|
||||||
LiquidCrystal* getDisplay();
|
LiquidCrystal* getDisplay();
|
||||||
|
|
||||||
|
|
||||||
void printTime(int value);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BaseScreen(ScreenManager* screenManager)
|
BaseScreen(ScreenManager* screenManager)
|
||||||
{
|
{
|
||||||
mScreenManager = screenManager;
|
mScreenManager = screenManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~BaseScreen() {}
|
||||||
|
|
||||||
virtual void onShow() = 0;
|
virtual void onShow() = 0;
|
||||||
virtual void onHide() = 0;
|
virtual void onHide() = 0;
|
||||||
|
|
||||||
virtual void onButton() = 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;
|
virtual void onTick() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,25 +38,25 @@ class ScreenManager
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
LiquidCrystal* mDisplay;
|
LiquidCrystal* mDisplay;
|
||||||
unsigned long* mCurrentTime;
|
uint32_t* mCurrentTime;
|
||||||
|
|
||||||
BaseScreen* mCurrent = NULL;
|
BaseScreen* mCurrent = NULL;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScreenManager(LiquidCrystal* display, unsigned long* currentTime)
|
ScreenManager(LiquidCrystal* display, uint32_t* currentTime)
|
||||||
{
|
{
|
||||||
mDisplay = display;
|
mDisplay = display;
|
||||||
mCurrentTime = currentTime;
|
mCurrentTime = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline BaseScreen* getCurrent()
|
inline BaseScreen* getCurrent()
|
||||||
{
|
{
|
||||||
return mCurrent;
|
return mCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline unsigned long getCurrentTime()
|
inline uint32_t getCurrentTime()
|
||||||
{
|
{
|
||||||
return *mCurrentTime;
|
return *mCurrentTime;
|
||||||
}
|
}
|
||||||
@ -66,17 +64,17 @@ class ScreenManager
|
|||||||
inline LiquidCrystal* getDisplay()
|
inline LiquidCrystal* getDisplay()
|
||||||
{
|
{
|
||||||
return mDisplay;
|
return mDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T> void ScreenManager::show()
|
template<class T> void show()
|
||||||
{
|
{
|
||||||
if (mCurrent != NULL)
|
if (mCurrent != NULL)
|
||||||
{
|
{
|
||||||
mCurrent->onHide();
|
mCurrent->onHide();
|
||||||
delete(mCurrent);
|
delete mCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrent = new T(this);
|
mCurrent = new T(this);
|
||||||
mCurrent->onShow();
|
mCurrent->onShow();
|
||||||
}
|
}
|
78
src/screen/countdown.cpp
Normal file
78
src/screen/countdown.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "countdown.h"
|
||||||
|
#include "screen/menu.h"
|
||||||
|
#include "display.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "config.h"
|
||||||
|
#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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CountdownScreen::onShow()
|
||||||
|
{
|
||||||
|
LCDPrintLineCentered(getDisplay(), 0, "Exposing...");
|
||||||
|
|
||||||
|
uint32_t remaining = GetExposureTimeRemaining(getCurrentTime());
|
||||||
|
mLastDisplayed = intDivCeil(remaining, 1000);
|
||||||
|
|
||||||
|
printRemainingTime();
|
||||||
|
|
||||||
|
analogWrite(PinLED, map(GetExposureIntensity(), 0, 100, 0, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CountdownScreen::onHide()
|
||||||
|
{
|
||||||
|
digitalWrite(PinLED, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CountdownScreen::onButton()
|
||||||
|
{
|
||||||
|
// TODO Confirmation?
|
||||||
|
Buzzer::click();
|
||||||
|
getScreenManager()->show<MenuScreen>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CountdownScreen::onEncoder(int32_t lastPosition, int32_t newPosition)
|
||||||
|
{
|
||||||
|
// TODO Allow adding / removing time?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CountdownScreen::onTick()
|
||||||
|
{
|
||||||
|
uint32_t remaining = GetExposureTimeRemaining(getCurrentTime());
|
||||||
|
remaining = intDivCeil(remaining, 1000);
|
||||||
|
|
||||||
|
if (remaining == 0)
|
||||||
|
{
|
||||||
|
mLastDisplayed = 0;
|
||||||
|
|
||||||
|
LCDPrintLineCentered(getDisplay(), 0, "Done!");
|
||||||
|
printRemainingTime();
|
||||||
|
digitalWrite(PinLED, LOW);
|
||||||
|
|
||||||
|
Buzzer::completed();
|
||||||
|
|
||||||
|
ResetExposureTimer();
|
||||||
|
getScreenManager()->show<MenuScreen>();
|
||||||
|
}
|
||||||
|
else if (remaining != mLastDisplayed)
|
||||||
|
{
|
||||||
|
mLastDisplayed = remaining;
|
||||||
|
printRemainingTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
29
src/screen/countdown.h
Normal file
29
src/screen/countdown.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __countdown
|
||||||
|
#define __countdown
|
||||||
|
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Countdown screen
|
||||||
|
* Shows the remaining time.
|
||||||
|
*/
|
||||||
|
class CountdownScreen : public BaseScreen
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint32_t mLastDisplayed;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void printRemainingTime();
|
||||||
|
|
||||||
|
public:
|
||||||
|
CountdownScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
||||||
|
|
||||||
|
void onShow();
|
||||||
|
void onHide();
|
||||||
|
|
||||||
|
void onButton();
|
||||||
|
void onEncoder(int32_t lastPosition, int32_t newPosition);
|
||||||
|
void onTick();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
195
src/screen/menu.cpp
Normal file
195
src/screen/menu.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#include "screen/menu.h"
|
||||||
|
#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 = 4;
|
||||||
|
mItems = new MenuItem*[mCount];
|
||||||
|
|
||||||
|
mItems[0] = new StartMenuItem();
|
||||||
|
mItems[1] = new TimeMenuItem();
|
||||||
|
mItems[2] = new IntensityMenuItem();
|
||||||
|
mItems[3] = new SoundMenuItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
const char* title = mItems[mSelected]->getTitle();
|
||||||
|
LCDPrintLineCentered(getDisplay(), 0, title, 1);
|
||||||
|
|
||||||
|
if (title != NULL)
|
||||||
|
delete[] title;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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] = ' ';
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
delete[] editingValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LCDPrintLineCentered(display, 1, value);
|
||||||
|
|
||||||
|
if (value != NULL)
|
||||||
|
delete[] value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MenuScreen::onButton()
|
||||||
|
{
|
||||||
|
if (mItems[mSelected]->editable())
|
||||||
|
{
|
||||||
|
Buzzer::select();
|
||||||
|
|
||||||
|
if (mEditing)
|
||||||
|
SaveSettings();
|
||||||
|
|
||||||
|
mEditing = !mEditing;
|
||||||
|
printScrollIndicators();
|
||||||
|
printValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mItems[mSelected]->execute(getScreenManager(), getCurrentTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MenuScreen::onEncoder(int32_t lastPosition, int32_t newPosition)
|
||||||
|
{
|
||||||
|
if (mEditing)
|
||||||
|
{
|
||||||
|
if (newPosition > lastPosition)
|
||||||
|
{
|
||||||
|
if (mItems[mSelected]->canIncrement())
|
||||||
|
{
|
||||||
|
mItems[mSelected]->incrementValue();
|
||||||
|
Buzzer::select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mItems[mSelected]->canDecrement())
|
||||||
|
{
|
||||||
|
mItems[mSelected]->decrementValue();
|
||||||
|
Buzzer::select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (newPosition > lastPosition)
|
||||||
|
{
|
||||||
|
if (mSelected < mCount - 1)
|
||||||
|
{
|
||||||
|
Buzzer::select();
|
||||||
|
mSelected++;
|
||||||
|
|
||||||
|
printFullUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mSelected > 0)
|
||||||
|
{
|
||||||
|
Buzzer::select();
|
||||||
|
mSelected--;
|
||||||
|
|
||||||
|
printFullUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MenuScreen::onTick()
|
||||||
|
{
|
||||||
|
}
|
53
src/screen/menu.h
Normal file
53
src/screen/menu.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef __menuscreen
|
||||||
|
#define __menuscreen
|
||||||
|
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
class MenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~MenuItem() { }
|
||||||
|
|
||||||
|
virtual const char* getTitle() = 0;
|
||||||
|
virtual const char* getValue() { return NULL; }
|
||||||
|
|
||||||
|
virtual bool editable() { return false; }
|
||||||
|
|
||||||
|
// Editable = true
|
||||||
|
virtual bool canIncrement() { return true; }
|
||||||
|
virtual bool canDecrement() { return true; }
|
||||||
|
virtual void incrementValue() { }
|
||||||
|
virtual void decrementValue() { }
|
||||||
|
|
||||||
|
// Editable = false
|
||||||
|
virtual void execute(ScreenManager* screenManager, uint32_t currentTime) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
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(int32_t lastPosition, int32_t newPosition);
|
||||||
|
void onTick();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
105
src/state.cpp
Normal file
105
src/state.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#include "state.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
|
uint16_t ExposureTime = DefaultExposureTime;
|
||||||
|
uint8_t ExposureIntensity = DefaultExposureIntensity;
|
||||||
|
uint32_t ExposureTimerStart = 0;
|
||||||
|
BuzzerSetting Buzzer = BuzzerSetting::CompletedButtonStartup;
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t GetExposureTime()
|
||||||
|
{
|
||||||
|
return ExposureTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetExposureTime(uint16_t value)
|
||||||
|
{
|
||||||
|
if (value < SmallStep)
|
||||||
|
ExposureTime = SmallStep;
|
||||||
|
else
|
||||||
|
ExposureTime = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t GetExposureIntensity()
|
||||||
|
{
|
||||||
|
return ExposureIntensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetExposureIntensity(uint8_t value)
|
||||||
|
{
|
||||||
|
if (value > 100)
|
||||||
|
ExposureIntensity = 100;
|
||||||
|
else if (value < IntensityStep)
|
||||||
|
ExposureIntensity = IntensityStep;
|
||||||
|
else
|
||||||
|
ExposureIntensity = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BuzzerSetting GetBuzzer()
|
||||||
|
{
|
||||||
|
return Buzzer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetBuzzer(BuzzerSetting value)
|
||||||
|
{
|
||||||
|
Buzzer = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LoadSettings()
|
||||||
|
{
|
||||||
|
uint16_t offset = 0;
|
||||||
|
EEPROM.get(offset, ExposureTime);
|
||||||
|
SetExposureTime(ExposureTime);
|
||||||
|
|
||||||
|
offset += sizeof(ExposureTime);
|
||||||
|
|
||||||
|
EEPROM.get(offset, ExposureIntensity);
|
||||||
|
SetExposureIntensity(ExposureIntensity);
|
||||||
|
|
||||||
|
offset += sizeof(ExposureIntensity);
|
||||||
|
|
||||||
|
EEPROM.get(offset, Buzzer);
|
||||||
|
if (Buzzer < BuzzerSetting::First || Buzzer > BuzzerSetting::Last)
|
||||||
|
Buzzer = BuzzerSetting::CompletedButtonStartup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SaveSettings()
|
||||||
|
{
|
||||||
|
uint16_t offset = 0;
|
||||||
|
EEPROM.put(offset, ExposureTime);
|
||||||
|
offset += sizeof(ExposureTime);
|
||||||
|
|
||||||
|
EEPROM.put(offset, ExposureIntensity);
|
||||||
|
offset += sizeof(ExposureIntensity);
|
||||||
|
|
||||||
|
EEPROM.put(offset, (uint8_t)Buzzer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StartExposureTimer(uint32_t currentTime)
|
||||||
|
{
|
||||||
|
ExposureTimerStart = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ResetExposureTimer()
|
||||||
|
{
|
||||||
|
ExposureTimerStart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t GetExposureTimeRemaining(uint32_t currentTime)
|
||||||
|
{
|
||||||
|
uint32_t elapsed = (currentTime - ExposureTimerStart);
|
||||||
|
uint32_t exposureTimeMs = ExposureTime * 1000;
|
||||||
|
|
||||||
|
return elapsed <= exposureTimeMs ? exposureTimeMs - elapsed : 0;
|
||||||
|
}
|
34
src/state.h
Normal file
34
src/state.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef __state
|
||||||
|
#define __state
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
void StartExposureTimer(uint32_t currentTime);
|
||||||
|
void ResetExposureTimer();
|
||||||
|
uint16_t GetExposureTimeRemaining(uint32_t currentTime);
|
||||||
|
|
||||||
|
#endif
|
1
upload.ps1
Normal file
1
upload.ps1
Normal file
@ -0,0 +1 @@
|
|||||||
|
& platformio run --target upload
|
Loading…
Reference in New Issue
Block a user