Fixed menu and editing

This commit is contained in:
Mark van Renswoude 2017-12-07 23:43:24 +01:00
parent 4551744a7c
commit 2e1a17d60a
11 changed files with 321 additions and 136 deletions

View File

@ -3,27 +3,26 @@
#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 uint8_t PinLCDRS = 7;
const uint8_t PinLCDEN = 8;
const uint8_t PinLCDDB4 = 9;
const uint8_t PinLCDDB5 = 10;
const uint8_t PinLCDDB6 = 11;
const uint8_t PinLCDDB7 = 12;
const uint8_t PinEncoderClock = 2;
const uint8_t PinEncoderData = 3;
const uint8_t PinButton = 4;
const uint8_t PinBuzzer = 5;
const uint8_t PinLED = 6;
const int LCDWidth = 16;
const int LCDHeight = 2;
const uint8_t LCDWidth = 16;
const uint8_t LCDHeight = 2;
const int EncoderSensitivity = 4;
const int SmallStep = 1;
const int LargeStepTreshold = 60;
const int LargeStep = 10;
const int MenuTimeout = 2000;
const uint8_t EncoderSensitivity = 4;
const uint8_t SmallStep = 1;
const uint8_t LargeStepTreshold = 60;
const uint8_t LargeStep = 10;
const uint8_t IntensityStep = 1;
const uint32_t DefaultExposureTime = 60;

View File

@ -4,24 +4,18 @@
void LCDPrintLine(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin)
{
display->setCursor(margin, y);
}
uint8_t width = LCDWidth - (2 * margin);
void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, const char* value, uint8_t margin)
{
/*
const char* title = mItems[mSelected]->getTitle();
uint8_t titleLength = strlen(title);
uint8_t maxWidth = LCDWidth - 2;
display->setCursor(1, 0);
if (titleLength >= maxWidth)
if (value != NULL)
{
// Title too long, cut off
char* character = (char*)title;
for (uint8_t i = 0; i < maxWidth; i++)
uint8_t length = strlen(value);
if (length >= width)
{
char* character = (char*)value;
for (uint8_t i = 0; i < width; i++)
{
display->write(byte(*character));
character++;
@ -29,29 +23,131 @@ void LCDPrintLineCentered(LiquidCrystal* display, uint8_t y, const char* value,
}
else
{
// Center title
uint8_t offset = (maxWidth - titleLength) / 2;
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(title);
offset += titleLength;
display->print(value);
width -= length;
while (offset < LCDWidth - 2)
while (width > 0)
{
display->print(' ');
offset++;
display->write(' ');
width--;
}
}
*/
}
else
{
for (uint8_t i = 0; i < width; i++)
display->write(' ');
}
}
const char* FormatTime(unsigned int time)
const char* UniqueString(const char* value)
{
String minutes = String(time / 60);
String seconds = String(time % 60);
return (minutes + ':' + (seconds.length() == 1 ? '0' + seconds : seconds)).c_str();
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;
}

View File

@ -4,10 +4,13 @@
#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);
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

View File

@ -1,54 +1,41 @@
#include "intensity.h"
#include "config.h"
#include "state.h"
#include "display.h"
#include "buzzer.h"
/*
LiquidCrystal* display = getDisplay();
display->setCursor(0, 1);
String intensity = "100%";
uint8_t offset = (LCDWidth - intensity.length()) / 2;
for (uint8_t space = 0; space < offset; space++)
display->print(' ');
display->print(intensity);
offset += intensity.length();
if (getEditMode())
{
display->write(LCDCharUpDown);
offset++;
}
for (uint8_t space = offset; space < LCDWidth; space++)
display->print(' ');
*/
const char* IntensityMenuItem::getTitle()
{
return "Intensity";
return UniqueString("Intensity");
}
const char* IntensityMenuItem::getValue()
{
char value[5];
itoa(GetExposureIntensity(), value, 10);
uint8_t length = strlen(value);
value[length] = '%';
value[length + 1] = 0;
return value;
return FormatPercentageFixedWidth(GetExposureIntensity());
}
void IntensityMenuItem::incValue()
{
uint16_t exposureIntensity = GetExposureIntensity();
if (exposureIntensity < 100)
{
SetExposureIntensity(exposureIntensity + IntensityStep);
Buzzer::select();
}
}
void IntensityMenuItem::decValue()
{
uint16_t exposureIntensity = GetExposureIntensity();
if (exposureIntensity > IntensityStep)
{
SetExposureIntensity(exposureIntensity - IntensityStep);
Buzzer::select();
}
}

39
src/menu/start.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "start.h"
#include "state.h"
#include "display.h"
const char* StartMenuItem::getTitle()
{
return UniqueString("Start");
}
const char* StartMenuItem::getValue()
{
const char* time = FormatTime(GetExposureTime());
const char* intensity = FormatPercentage(GetExposureIntensity());
uint8_t timeLength = strlen(time);
uint8_t intensityLength = strlen(intensity);
char* value = new char[timeLength + 3 + intensityLength + 1];
strcpy(value, time);
delete[] time;
uint8_t offset = timeLength;
value[offset] = ' '; offset++;
value[offset] = '@'; offset++;
value[offset] = ' '; offset++;
strcpy(value + offset, intensity);
delete[] intensity;
return value;
}
void StartMenuItem::execute()
{
}

19
src/menu/start.h Normal file
View 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();
};
#endif

View File

@ -1,54 +1,40 @@
#include "time.h"
/*
LiquidCrystal* display = getDisplay();
display->setCursor(0, 1);
String time = FormatTime(ExposureTime);
uint8_t offset = (LCDWidth - time.length()) / 2;
for (uint8_t space = 0; space < offset; space++)
display->print(' ');
display->print(time);
offset += time.length();
if (getEditMode())
{
display->write(LCDCharUpDown);
offset++;
}
for (uint8_t space = offset; space < LCDWidth; space++)
display->print(' ');
if (newPosition > lastPosition)
ExposureTime += ExposureTime >= LargeStepTreshold ? LargeStep : SmallStep;
else if (ExposureTime > 0)
ExposureTime -= ExposureTime > LargeStepTreshold ? LargeStep : SmallStep;
*/
#include "config.h"
#include "state.h"
#include "display.h"
#include "buzzer.h"
const char* TimeMenuItem::getTitle()
{
return "Time";
return UniqueString("Time");
}
const char* TimeMenuItem::getValue()
{
return NULL;
return FormatTime(GetExposureTime());
}
void TimeMenuItem::incValue()
{
uint16_t exposureTime = GetExposureTime();
if (exposureTime < (uint16_t)-1)
{
SetExposureTime(exposureTime + (exposureTime >= LargeStepTreshold ? LargeStep : SmallStep));
Buzzer::select();
}
}
void TimeMenuItem::decValue()
{
uint16_t exposureTime = GetExposureTime();
if (exposureTime > SmallStep)
{
SetExposureTime(exposureTime - (exposureTime > LargeStepTreshold ? LargeStep : SmallStep));
Buzzer::select();
}
}

View File

@ -72,7 +72,7 @@ class ScreenManager
if (mCurrent != NULL)
{
mCurrent->onHide();
delete(mCurrent);
delete mCurrent;
}
mCurrent = new T(this);

View File

@ -3,7 +3,9 @@
#include "buzzer.h"
#include "display.h"
#include "menu/start.h"
#include "menu/time.h"
#include "menu/intensity.h"
MenuScreen::MenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager)
@ -11,9 +13,9 @@ MenuScreen::MenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager)
mCount = 3;
mItems = new MenuItem*[mCount];
mItems[0] = new TimeMenuItem();
mItems[0] = new StartMenuItem();
mItems[1] = new TimeMenuItem();
mItems[2] = new TimeMenuItem();
mItems[2] = new IntensityMenuItem();
}
@ -47,7 +49,11 @@ void MenuScreen::printFullUpdate()
void MenuScreen::printTitle()
{
LCDPrintLineCentered(getDisplay(), 0, mItems[mSelected]->getTitle(), 1);
const char* title = mItems[mSelected]->getTitle();
LCDPrintLineCentered(getDisplay(), 0, title, 1);
if (title != NULL)
delete[] title;
}
@ -73,21 +79,60 @@ void MenuScreen::printValue()
{
LiquidCrystal* display = getDisplay();
display->setCursor(0, 1);
for (uint8_t x = 0; x < LCDWidth; x++)
display->write(' ');
const char* value = mItems[mSelected]->getValue();
if (mEditing && value != NULL)
{
uint8_t valueLength = strlen(value);
char* editingValue = new char[valueLength + 5];
editingValue[0] = ' ';
editingValue[1] = ' ';
strcpy(editingValue + 2, value);
editingValue[valueLength + 2] = ' ';
editingValue[valueLength + 3] = LCDCharUpDown;
editingValue[valueLength + 4] = 0;
LCDPrintLineCentered(display, 1, editingValue);
delete[] editingValue;
}
else
LCDPrintLineCentered(display, 1, value);
if (value != NULL)
delete[] value;
}
void MenuScreen::onButton()
{
if (mItems[mSelected]->editable())
{
mEditing = !mEditing;
printScrollIndicators();
printValue();
}
else
{
mItems[mSelected]->execute(getScreenManager());
}
}
void MenuScreen::onEncoder(long lastPosition, long newPosition)
{
if (!mEditing)
if (mEditing)
{
if (newPosition > lastPosition)
mItems[mSelected]->incValue();
else
mItems[mSelected]->decValue();
printValue();
}
else
{
if (newPosition > lastPosition)
{

View File

@ -2,19 +2,22 @@
#include "config.h"
#include <EEPROM.h>
uint32_t ExposureTime = DefaultExposureTime;
uint16_t ExposureTime = DefaultExposureTime;
uint8_t ExposureIntensity = DefaultExposureIntensity;
uint32_t ExposureTimerStart = 0;
uint32_t GetExposureTime()
uint16_t GetExposureTime()
{
return ExposureTime;
}
void SetExposureTime(uint32_t value)
void SetExposureTime(uint16_t value)
{
if (value < SmallStep)
ExposureTime = SmallStep;
else
ExposureTime = value;
}
@ -27,7 +30,12 @@ uint8_t GetExposureIntensity()
void SetExposureIntensity(uint8_t value)
{
ExposureIntensity = (value <= 100) ? value : 100;
if (value > 100)
ExposureIntensity = 100;
else if (value < IntensityStep)
ExposureIntensity = IntensityStep;
else
ExposureIntensity = value;
}
@ -35,9 +43,12 @@ void LoadSettings()
{
uint16_t offset = 0;
EEPROM.get(offset, ExposureTime);
SetExposureTime(ExposureTime);
offset += sizeof(ExposureTime);
EEPROM.get(offset, ExposureIntensity);
SetExposureIntensity(ExposureIntensity);
}
@ -51,7 +62,7 @@ void SaveSettings()
}
void StartExposureTimer(unsigned long currentTime)
void StartExposureTimer(uint32_t currentTime)
{
SaveSettings();
ExposureTimerStart = currentTime;
@ -64,7 +75,7 @@ void ResetExposureTimer()
}
uint32_t GetExposureTimeRemaining(unsigned long currentTime)
uint16_t GetExposureTimeRemaining(uint32_t currentTime)
{
uint32_t elapsed = (currentTime - ExposureTimerStart);
return elapsed <= ExposureTime ? ExposureTime - elapsed : 0;

View File

@ -3,8 +3,8 @@
#include <Arduino.h>
uint32_t GetExposureTime();
void SetExposureTime(uint32_t value);
uint16_t GetExposureTime();
void SetExposureTime(uint16_t value);
uint8_t GetExposureIntensity();
void SetExposureIntensity(uint8_t value);
@ -13,8 +13,8 @@ void SetExposureIntensity(uint8_t value);
void LoadSettings();
void SaveSettings();
void StartExposureTimer(unsigned long currentTime);
void StartExposureTimer(uint32_t currentTime);
void ResetExposureTimer();
uint32_t GetExposureTimeRemaining(unsigned long currentTime);
uint16_t GetExposureTimeRemaining(uint32_t currentTime);
#endif