Compare commits
10 Commits
20c25767bd
...
47cb78f6c6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47cb78f6c6 | ||
|
|
914b1d6588 | ||
|
|
fbb3fa4a13 | ||
|
|
8c15a865ee | ||
|
|
ffa1564a45 | ||
|
|
0ff9bdd0d2 | ||
|
|
2bbfeb8940 | ||
|
|
11b4909f39 | ||
|
|
031a19b107 | ||
|
|
7861a6d207 |
21
Defines.h
21
Defines.h
@@ -13,12 +13,27 @@
|
||||
#define PIN_DISPLAY_CLK 7
|
||||
#define PIN_DISPLAY_DIO 8
|
||||
|
||||
#define PIN_LED_DATA 5
|
||||
#define PIN_LED_LATCH 4
|
||||
#define PIN_LED_CLOCK 3
|
||||
#define PIN_LED_SHIFT_REGISTER_DATA 5
|
||||
#define PIN_LED_SHIFT_REGISTER_LATCH 4
|
||||
#define PIN_LED_SHIFT_REGISTER_CLOCK 3
|
||||
|
||||
#define REGISTER_SIZE 2
|
||||
|
||||
#define LONG_CLICK_TIME_MS 500
|
||||
|
||||
#define BTN_UP_SHORT_CLICKED 1
|
||||
#define BTN_DOWN_SHORT_CLICKED -1
|
||||
#define BTN_DOWN_UP_NO_SHORT_CLICKED 0
|
||||
|
||||
#define BTN_UP_HOLDED 1
|
||||
#define BTN_DOWN_HOLDED -1
|
||||
#define BTN_DOWN_UP_NOT_HOLDED 0
|
||||
|
||||
#define LED_MAX_DISTANCE 1312
|
||||
#define LED_DISTANCE_ARRAY LedDistances [MAX_LED_INDEX + 1] = { 0.0, 0.013, 0.029, 0.049, 0.073, 0.101, 0.135, 0.176, 0.225, 0.285, 0.356, 0.442, 0.546, 0.670, 0.820, 1.0 }
|
||||
|
||||
#define MAX_SWITCH_TIME 15000
|
||||
#define MIN_SWITCH_TIME 500
|
||||
#define DEFAULT_SWITCH_TIME 5000
|
||||
|
||||
#endif
|
||||
50
DisplayDefines.h
Normal file
50
DisplayDefines.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef EYE_TRAINER_DISPLAYDEFINES
|
||||
#define EYE_TRAINER_DISPLAYDEFINES 0
|
||||
|
||||
#include <TM1637Display.h>
|
||||
|
||||
//SEG_A - Up
|
||||
//SEG_B..SEG_F - Clockwise
|
||||
//SEG_G - middle
|
||||
|
||||
#define NONE 0
|
||||
#define A SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G
|
||||
#define B SEG_F | SEG_C | SEG_D | SEG_E | SEG_G
|
||||
#define C SEG_A | SEG_F | SEG_E | SEG_D
|
||||
#define D SEG_B | SEG_C | SEG_D | SEG_E | SEG_G
|
||||
#define E SEG_A | SEG_D | SEG_E | SEG_F | SEG_G
|
||||
#define F SEG_A | SEG_F | SEG_G | SEG_E
|
||||
#define G SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G
|
||||
#define H SEG_F | SEG_C | SEG_E | SEG_G
|
||||
#define I SEG_B | SEG_C
|
||||
#define J SEG_B | SEG_C | SEG_D
|
||||
#define K SEG_A
|
||||
#define L SEG_F | SEG_E | SEG_D
|
||||
#define M SEG_C | SEG_G | SEG_E
|
||||
#define N SEG_C | SEG_G | SEG_E
|
||||
#define O SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F
|
||||
#define P SEG_A | SEG_B | SEG_G | SEG_F | SEG_E
|
||||
#define Q SEG_A | SEG_B | SEG_C | SEG_G | SEG_F
|
||||
#define R SEG_E | SEG_G
|
||||
#define S SEG_A | SEG_F | SEG_G | SEG_C | SEG_D
|
||||
#define T SEG_F | SEG_E | SEG_D | SEG_G
|
||||
#define U SEG_C | SEG_D | SEG_E
|
||||
#define V SEG_C | SEG_D | SEG_E | SEG_F | SEG_B
|
||||
#define W SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G
|
||||
#define X SEG_B | SEG_C | SEG_E | SEG_F | SEG_G
|
||||
#define Y SEG_F | SEG_G | SEG_B | SEG_C
|
||||
#define Z SEG_A | SEG_B | SEG_G | SEG_E | SEG_D
|
||||
|
||||
#define WORD(a, b, c, d) (const uint8_t[]) {a, b, c, d}
|
||||
|
||||
#define WORD_DONE WORD( D, O, N, E )
|
||||
#define WORD_RUN WORD( R, U, N, NONE )
|
||||
#define WORD_MODE WORD( R, M, O, D )
|
||||
#define WORD_TIME_SWITCH WORD( T, I, M, E )
|
||||
#define WORD_TIME_MODE WORD( T, M, O, D )
|
||||
#define WORD_BRIGHTNESS WORD( B, R, G, H )
|
||||
#define WORD_TEST WORD( T, E, S, T )
|
||||
#define WORD_ WORD( SEG_G, SEG_G, SEG_G, SEG_G )
|
||||
|
||||
|
||||
#endif
|
||||
172
DisplayHelper.h
172
DisplayHelper.h
@@ -5,6 +5,7 @@
|
||||
#include "Defines.h"
|
||||
#include "Settings.h"
|
||||
#include "Enums.h"
|
||||
#include "DisplayDefines.h"
|
||||
|
||||
class DisplayHelper
|
||||
{
|
||||
@@ -13,71 +14,11 @@ class DisplayHelper
|
||||
|
||||
public:
|
||||
DisplayHelper() { }
|
||||
|
||||
DisplayHelper(Settings* _Settings)
|
||||
{
|
||||
m_Settings = _Settings;
|
||||
}
|
||||
|
||||
static const uint8_t NONE = 0;
|
||||
static const uint8_t A = SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G;
|
||||
static const uint8_t B = SEG_F | SEG_C | SEG_D | SEG_E | SEG_G;
|
||||
static const uint8_t C = SEG_A | SEG_F | SEG_E | SEG_D;
|
||||
static const uint8_t D = SEG_B | SEG_C | SEG_D | SEG_E | SEG_G;
|
||||
static const uint8_t E = SEG_A | SEG_D | SEG_E | SEG_F | SEG_G;
|
||||
static const uint8_t F = SEG_A | SEG_F | SEG_G | SEG_E;
|
||||
static const uint8_t G = SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G;
|
||||
static const uint8_t H = SEG_F | SEG_C | SEG_E | SEG_G;
|
||||
static const uint8_t I = SEG_B | SEG_C;
|
||||
static const uint8_t J = SEG_B | SEG_C | SEG_D;
|
||||
static const uint8_t K = SEG_A;
|
||||
static const uint8_t L = SEG_F | SEG_E | SEG_D;
|
||||
static const uint8_t M = SEG_C | SEG_G | SEG_E;
|
||||
static const uint8_t N = SEG_C | SEG_G | SEG_E;
|
||||
static const uint8_t O = SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F;
|
||||
static const uint8_t P = SEG_A | SEG_B | SEG_G | SEG_F | SEG_E;
|
||||
static const uint8_t Q = SEG_G;
|
||||
static const uint8_t R = SEG_E | SEG_G;
|
||||
static const uint8_t S = SEG_A | SEG_F | SEG_G | SEG_C | SEG_D;
|
||||
static const uint8_t T = SEG_F | SEG_E | SEG_D | SEG_G;
|
||||
static const uint8_t U = SEG_C | SEG_D | SEG_E;
|
||||
static const uint8_t V = SEG_C | SEG_D | SEG_E | SEG_F | SEG_B;
|
||||
static const uint8_t W = SEG_D;
|
||||
static const uint8_t X = SEG_B | SEG_C | SEG_E | SEG_F | SEG_G;
|
||||
static const uint8_t Y = SEG_F | SEG_G | SEG_B | SEG_C;
|
||||
static const uint8_t Z = SEG_A | SEG_B | SEG_G | SEG_E | SEG_D;
|
||||
|
||||
void setup()
|
||||
{
|
||||
display.setBrightness(0x0f);
|
||||
}
|
||||
|
||||
void buttonsTest()
|
||||
{
|
||||
bool btnMainState = digitalRead(PIN_BTN_MAIN);
|
||||
bool btnUpState = digitalRead(PIN_BTN_UP);
|
||||
bool btnDownState = digitalRead(PIN_BTN_DOWN);
|
||||
int numChanged = currentTestNum;
|
||||
|
||||
if(btnMainState == HIGH)
|
||||
{
|
||||
numChanged = 0;
|
||||
}
|
||||
else if (btnUpState == HIGH)
|
||||
{
|
||||
numChanged++;
|
||||
}
|
||||
else if (btnDownState == HIGH)
|
||||
{
|
||||
numChanged--;
|
||||
}
|
||||
|
||||
if(numChanged != currentTestNum)
|
||||
{
|
||||
currentTestNum = numChanged;
|
||||
display.clear();
|
||||
display.showNumberDec(currentTestNum, false);
|
||||
}
|
||||
m_DrawTitle = true;
|
||||
}
|
||||
|
||||
void runTest()
|
||||
@@ -187,106 +128,113 @@ public:
|
||||
display.setSegments(WORD_DONE);
|
||||
}
|
||||
|
||||
void DrawRunInfo(bool _Title, bool _Run)
|
||||
void UpdateModeDisplay(bool _RunnerActive, DeviceMode _DeviceMode)
|
||||
{
|
||||
if(_Title)
|
||||
switch(_DeviceMode)
|
||||
{
|
||||
case DeviceMode::RUN: DrawRunInfo(_RunnerActive); break;
|
||||
case DeviceMode::SETTINGS_MODE: DrawSettingsRunModeInfo(); break;
|
||||
case DeviceMode::SETTINGS_BRIGHTNESS: DrawSettingsBrightnessInfo(); break;
|
||||
case DeviceMode::SETTINGS_TIME_SWITCH: DrawSettingsTimeSwitchInfo(); break;
|
||||
case DeviceMode::SETTINGS_TIME_MODE: DrawSettingsTimeModeInfo(); break;
|
||||
case DeviceMode::TEST: DrawTestInfo(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawRunInfo(bool _Run)
|
||||
{
|
||||
if(m_DrawTitle)
|
||||
{
|
||||
display.setSegments(WORD_RUN);
|
||||
}
|
||||
else if(_Run)
|
||||
{
|
||||
uint8_t forward[4] = {P, L, A, NONE};
|
||||
display.setSegments(forward);
|
||||
display.setSegments(WORD(P, L, A, Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t forward[4] = {P, A, U, S};
|
||||
display.setSegments(forward);
|
||||
display.setSegments(WORD(P, A, U, S));
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSettingsRunModeInfo(bool _Title, RunMode _RunMode)
|
||||
void DrawSettingsRunModeInfo()
|
||||
{
|
||||
if(_Title)
|
||||
if(m_DrawTitle)
|
||||
{
|
||||
display.setSegments(WORD_MODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(_RunMode)
|
||||
switch(Settings::getInstance().RunModeState)
|
||||
{
|
||||
case RunMode::FORWARD: display.setSegments((const uint8_t[]) {F, W, R, D}); break;
|
||||
case RunMode::BACKWARD: display.setSegments((const uint8_t[]) {B, A, C, K}); break;
|
||||
case RunMode::BOTH: display.setSegments((const uint8_t[]) {B, O, T, H}); break;
|
||||
case RunMode::RANDOM: display.setSegments((const uint8_t[]) {R, N, D, NONE}); break;
|
||||
case RunMode::FORWARD: display.setSegments(WORD(F, R, W, D )); break;
|
||||
case RunMode::BACKWARD: display.setSegments(WORD(B, A, C, D )); break;
|
||||
case RunMode::PING_PONG: display.setSegments(WORD(P, I, N, G )); break;
|
||||
case RunMode::RANDOM: display.setSegments(WORD(R, N, D, NONE)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSettingsTimeInfo(bool _Title, int _SwitchTime)
|
||||
void DrawSettingsTimeSwitchInfo()
|
||||
{
|
||||
if(_Title)
|
||||
if(m_DrawTitle)
|
||||
{
|
||||
display.setSegments(WORD_TIME);
|
||||
display.setSegments(WORD_TIME_SWITCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.showNumberDec(_SwitchTime, false);
|
||||
display.showNumberDec(Settings::getInstance().getDisplaySwitchTime(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSettingsTimeModeInfo()
|
||||
{
|
||||
if(m_DrawTitle)
|
||||
{
|
||||
display.setSegments(WORD_TIME_MODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(Settings::getInstance().TimeModeState)
|
||||
{
|
||||
case TimeMode::CONST: display.setSegments(WORD(C, N, S, T )); break;
|
||||
case TimeMode::MANUAL: display.setSegments(WORD(M, A, N, L )); break;
|
||||
case TimeMode::DECREASING: display.setSegments(WORD(D, E, C, R )); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSettingsBrightnessInfo(bool _Title, int _Brightness)
|
||||
void DrawSettingsBrightnessInfo()
|
||||
{
|
||||
if(_Title)
|
||||
if(m_DrawTitle)
|
||||
{
|
||||
display.setSegments(WORD_BRIGHTNESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
display.showNumberDec(_Brightness, false);
|
||||
display.showNumberDec(Settings::getInstance().Brightness, false);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTestInfo(bool _Title)
|
||||
void DrawTestInfo()
|
||||
{
|
||||
display.setSegments(WORD_TEST);
|
||||
}
|
||||
|
||||
//DOES NOT WORK!
|
||||
// uint8_t* encodeNumber(uint8_t _Num)
|
||||
// {
|
||||
// uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
|
||||
// // data[3] = display.encodeDigit(_Num % 10);
|
||||
// // _Num = _Num / 10;
|
||||
// // data[2] = display.encodeDigit(_Num % 10);
|
||||
// // _Num = _Num / 10;
|
||||
// // data[1] = display.encodeDigit(_Num % 10);
|
||||
// // _Num = _Num / 10;
|
||||
// // data[0] = display.encodeDigit(_Num % 10);
|
||||
void setDrawTitle(bool _Value)
|
||||
{
|
||||
m_DrawTitle = _Value;
|
||||
}
|
||||
|
||||
// data[3] = display.encodeDigit(1);
|
||||
// data[2] = display.encodeDigit(2);
|
||||
// data[1] = display.encodeDigit(3);
|
||||
// data[0] = display.encodeDigit(4);
|
||||
// return data;
|
||||
// }
|
||||
void getDrawTitle()
|
||||
{
|
||||
return m_DrawTitle;
|
||||
}
|
||||
|
||||
private:
|
||||
TM1637Display display = TM1637Display::TM1637Display(PIN_DISPLAY_CLK, PIN_DISPLAY_DIO);
|
||||
Settings* m_Settings;
|
||||
int currentTestNum = 0;
|
||||
|
||||
//seg A = upper ground
|
||||
//seg B = upper right
|
||||
//seg C = lower right
|
||||
|
||||
uint8_t WORD_DONE[4] = { D, O, N, E };
|
||||
uint8_t WORD_RUN[4] = { R, U, N, NONE };
|
||||
uint8_t WORD_MODE[4] = { M, O, D, E };
|
||||
uint8_t WORD_TIME[4] = { T, I, M, E };
|
||||
uint8_t WORD_BRIGHTNESS[4] = { B, R, G, H };
|
||||
uint8_t WORD_TEST[4] = { T, E, S, T };
|
||||
uint8_t WORD_[4] = { SEG_G, SEG_G, SEG_G, SEG_G };
|
||||
bool m_DrawTitle = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
7
Enums.h
7
Enums.h
@@ -6,7 +6,8 @@ enum DeviceMode
|
||||
RUN = 0,
|
||||
SETTINGS_MODE,
|
||||
SETTINGS_BRIGHTNESS,
|
||||
SETTINGS_TIME,
|
||||
SETTINGS_TIME_SWITCH,
|
||||
SETTINGS_TIME_MODE,
|
||||
TEST
|
||||
};
|
||||
|
||||
@@ -14,7 +15,7 @@ enum RunMode
|
||||
{
|
||||
FORWARD = 0,
|
||||
BACKWARD = 1,
|
||||
BOTH = 2,
|
||||
PING_PONG = 2,
|
||||
RANDOM = 3
|
||||
};
|
||||
|
||||
@@ -22,7 +23,7 @@ enum TimeMode
|
||||
{
|
||||
CONST = 0,
|
||||
MANUAL,
|
||||
DECREASING
|
||||
DECREASING // not implemented
|
||||
};
|
||||
|
||||
#endif
|
||||
2559
EyeTrainerLayout.diy
Normal file
2559
EyeTrainerLayout.diy
Normal file
File diff suppressed because it is too large
Load Diff
211
EyeTrainerMain.h
211
EyeTrainerMain.h
@@ -4,27 +4,11 @@
|
||||
#include "LEDRunner.h"
|
||||
#include "InputHelper.h"
|
||||
#include "Enums.h"
|
||||
#include "WrapHelper.h"
|
||||
|
||||
class EyeTrainerMain
|
||||
{
|
||||
public:
|
||||
//==============================================================
|
||||
//state
|
||||
//==============================================================
|
||||
|
||||
enum DeviceMode m_deviceMode = DeviceMode::RUN;
|
||||
|
||||
Settings m_Settings = Settings();
|
||||
LEDRunner m_LEDRunner = LEDRunner(&m_Settings);
|
||||
DisplayHelper m_DisplayHelper = DisplayHelper(&m_Settings);
|
||||
InputHelper m_InputHelper = InputHelper();
|
||||
bool m_DrawTitle = true;
|
||||
unsigned long m_PrevTime = 0;
|
||||
|
||||
//==============================================================
|
||||
//end of state
|
||||
//==============================================================
|
||||
|
||||
EyeTrainerMain() { }
|
||||
|
||||
void setup()
|
||||
@@ -33,26 +17,32 @@ public:
|
||||
m_LEDRunner.setup();
|
||||
m_DisplayHelper.setup();
|
||||
m_InputHelper.setup();
|
||||
UpdateModeDisplay();
|
||||
updateModeDisplay();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
bool inputEvent = m_InputHelper.readInputs(millis());
|
||||
|
||||
switch(m_deviceMode)
|
||||
|
||||
if(inputEvent)
|
||||
{
|
||||
case DeviceMode::RUN: ProcessRun(); break;
|
||||
case DeviceMode::SETTINGS_MODE: ProcessSettingsRunMode(); break;
|
||||
case DeviceMode::SETTINGS_TIME: ProcessSwitchTime(); break;
|
||||
case DeviceMode::SETTINGS_BRIGHTNESS: ProcessBrightness(); break;
|
||||
case DeviceMode::TEST: ProcessTest(); break;
|
||||
processChangeMode();
|
||||
int upDownButtonsShortClickState = m_InputHelper.getUpDownButtonsShortClicked();
|
||||
int upDownButtonsHoldState = m_InputHelper.getUpDownButtonsHold();
|
||||
switch(m_deviceMode)
|
||||
{
|
||||
case DeviceMode::RUN: processRun(upDownButtonsShortClickState, upDownButtonsHoldState); break;
|
||||
case DeviceMode::SETTINGS_MODE: processSettingsRunMode(upDownButtonsShortClickState, upDownButtonsHoldState); break;
|
||||
case DeviceMode::SETTINGS_TIME_SWITCH: processSwitchTime(upDownButtonsShortClickState, upDownButtonsHoldState); break;
|
||||
case DeviceMode::SETTINGS_BRIGHTNESS: processBrightness(upDownButtonsShortClickState, upDownButtonsHoldState); break;
|
||||
case DeviceMode::SETTINGS_TIME_MODE: processTimeMode(upDownButtonsShortClickState, upDownButtonsHoldState); break;
|
||||
case DeviceMode::TEST: processTest(upDownButtonsShortClickState, upDownButtonsHoldState); break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long deltaTime = millis() - m_PrevTime;
|
||||
m_PrevTime = millis();
|
||||
|
||||
m_LEDRunner.update(deltaTime, m_Settings.SwitchTime, m_Settings.m_RunMode, m_Settings.m_TimeMode);
|
||||
unsigned long currentTime = millis();
|
||||
unsigned long deltaTime = currentTime - m_PrevTime;
|
||||
m_PrevTime = currentTime;
|
||||
m_LEDRunner.update(deltaTime);
|
||||
}
|
||||
|
||||
void runTest()
|
||||
@@ -62,154 +52,115 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
enum DeviceMode m_deviceMode = DeviceMode::RUN;
|
||||
|
||||
static const uint8_t BTN_UP_SHORT_CLICKED = 1;
|
||||
static const uint8_t BTN_DOWN_SHORT_CLICKED = -1;
|
||||
static const uint8_t BTN_DOWN_UP_NO_SHORT_CLICKED = 0;
|
||||
LEDRunner m_LEDRunner = LEDRunner();
|
||||
DisplayHelper m_DisplayHelper = DisplayHelper();
|
||||
InputHelper m_InputHelper = InputHelper();
|
||||
unsigned long m_PrevTime = 0;
|
||||
|
||||
int wrapInt(int _Num, int _Max)
|
||||
void updateModeDisplay()
|
||||
{
|
||||
if(_Num < 0)
|
||||
{
|
||||
return (_Max - _Num) % _Max;
|
||||
}
|
||||
if(_Num >= _Max)
|
||||
{
|
||||
return _Num % _Max;
|
||||
}
|
||||
|
||||
return _Num;
|
||||
m_DisplayHelper.UpdateModeDisplay(m_LEDRunner.getRun(), m_deviceMode);
|
||||
}
|
||||
|
||||
int wrapInt(int _Num, int _Min, int _Max)
|
||||
void processChangeMode()
|
||||
{
|
||||
int num = _Num - _Min;
|
||||
int max = _Max - _Min;
|
||||
return wrapInt(num, max) + _Min;
|
||||
}
|
||||
|
||||
void ProcessChangeMode()
|
||||
{
|
||||
bool mainButtonShortClicked = m_InputHelper.getButtonMain().IsNowShortClicked();
|
||||
bool mainButtonShortClicked = m_InputHelper.getButtonMain().isNowShortClicked();
|
||||
if(!mainButtonShortClicked)
|
||||
return;
|
||||
|
||||
m_DrawTitle = true;
|
||||
m_deviceMode = static_cast<DeviceMode>(wrapInt(static_cast<int>(m_deviceMode) + 1, 5));
|
||||
UpdateModeDisplay();
|
||||
m_DisplayHelper.setDrawTitle(true);
|
||||
m_deviceMode = static_cast<DeviceMode>(wrapInt(static_cast<int>(m_deviceMode) + 1, 6));
|
||||
updateModeDisplay();
|
||||
if(m_deviceMode != DeviceMode::RUN)
|
||||
{
|
||||
m_LEDRunner.setRun(false);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateModeDisplay()
|
||||
void processRun(int upDownButtons, int upDownButtonsHold)
|
||||
{
|
||||
switch(m_deviceMode)
|
||||
if(Settings::getInstance().TimeModeState == TimeMode::MANUAL && upDownButtons != BTN_DOWN_UP_NO_SHORT_CLICKED)
|
||||
{
|
||||
case DeviceMode::RUN: m_DisplayHelper.DrawRunInfo(m_DrawTitle, m_LEDRunner.getRun()); break;
|
||||
case DeviceMode::SETTINGS_MODE: m_DisplayHelper.DrawSettingsRunModeInfo(m_DrawTitle, m_Settings.m_RunMode); break;
|
||||
case DeviceMode::SETTINGS_TIME: m_DisplayHelper.DrawSettingsTimeInfo(m_DrawTitle, m_Settings.SwitchTime / 10); break;
|
||||
case DeviceMode::SETTINGS_BRIGHTNESS: m_DisplayHelper.DrawSettingsBrightnessInfo(m_DrawTitle, m_Settings.Brightness); break;
|
||||
case DeviceMode::TEST: m_DisplayHelper.DrawTestInfo(m_DrawTitle); break;
|
||||
}
|
||||
}
|
||||
|
||||
int GetUpDownButtonsShortClicked()
|
||||
{
|
||||
bool upButtonShortClicked = m_InputHelper.getButtonUp().IsNowShortClicked();
|
||||
bool downButtonShortClicked = m_InputHelper.getButtonUp().IsNowShortClicked();
|
||||
if(upButtonShortClicked)
|
||||
return BTN_UP_SHORT_CLICKED;
|
||||
else if(downButtonShortClicked)
|
||||
return BTN_DOWN_SHORT_CLICKED;
|
||||
return BTN_DOWN_UP_NO_SHORT_CLICKED;
|
||||
}
|
||||
|
||||
int GetUpDownButtonsHold()
|
||||
{
|
||||
bool upButtonHold = m_InputHelper.getButtonUp().IsHolded();
|
||||
bool downButtonHold = m_InputHelper.getButtonDown().IsHolded();
|
||||
return (upButtonHold - downButtonHold);
|
||||
}
|
||||
|
||||
void ProcessRun()
|
||||
{
|
||||
ProcessChangeMode();
|
||||
int upDownButtons = GetUpDownButtonsShortClicked();
|
||||
if(upDownButtons == BTN_UP_SHORT_CLICKED)
|
||||
{
|
||||
m_LEDRunner.setRun(true);
|
||||
UpdateModeDisplay();
|
||||
m_LEDRunner.manualUpdate(Settings::getInstance().RunModeState, upDownButtons);
|
||||
}
|
||||
if(upDownButtons == BTN_DOWN_SHORT_CLICKED)
|
||||
else
|
||||
{
|
||||
m_LEDRunner.setRun(false);
|
||||
UpdateModeDisplay();
|
||||
if(upDownButtons == BTN_UP_SHORT_CLICKED)
|
||||
{
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
m_LEDRunner.setRun(true);
|
||||
updateModeDisplay();
|
||||
}
|
||||
if(upDownButtons == BTN_DOWN_SHORT_CLICKED)
|
||||
{
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
m_LEDRunner.setRun(false);
|
||||
updateModeDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessSettingsRunMode()
|
||||
void processSettingsRunMode(int upDownButtons, int upDownButtonsHold)
|
||||
{
|
||||
ProcessChangeMode();
|
||||
int upDownButtons = GetUpDownButtonsShortClicked();
|
||||
if(upDownButtons != BTN_DOWN_UP_NO_SHORT_CLICKED)
|
||||
{
|
||||
m_DrawTitle = false;
|
||||
m_Settings.switchRunMode(upDownButtons);
|
||||
UpdateModeDisplay();
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
Settings::getInstance().switchRunMode(upDownButtons);
|
||||
updateModeDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessSwitchTime()
|
||||
void processSwitchTime(int upDownButtons, int upDownButtonsHold)
|
||||
{
|
||||
ProcessChangeMode();
|
||||
|
||||
int upDownButtons = GetUpDownButtonsShortClicked();
|
||||
int upDownHoldButtons = GetUpDownButtonsHold();
|
||||
if(upDownButtons != BTN_DOWN_UP_NO_SHORT_CLICKED)
|
||||
{
|
||||
m_DrawTitle = false;
|
||||
m_Settings.setSwitchTime(m_Settings.SwitchTime + upDownButtons * 50);
|
||||
UpdateModeDisplay();
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
Settings::getInstance().setSwitchTime(Settings::getInstance().SwitchTime + upDownButtons * 50);
|
||||
updateModeDisplay();
|
||||
}
|
||||
if(upDownHoldButtons != 0)
|
||||
if(upDownButtonsHold != BTN_DOWN_UP_NOT_HOLDED)
|
||||
{
|
||||
m_DrawTitle = false;
|
||||
m_Settings.setSwitchTime(m_Settings.SwitchTime + upDownHoldButtons * 50);
|
||||
UpdateModeDisplay();
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
Settings::getInstance().setSwitchTime(Settings::getInstance().SwitchTime + upDownButtonsHold * 50);
|
||||
updateModeDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessBrightness()
|
||||
void processBrightness(int upDownButtons, int upDownButtonsHold)
|
||||
{
|
||||
ProcessChangeMode();
|
||||
|
||||
int upDownButtons = GetUpDownButtonsShortClicked();
|
||||
int upDownHoldButtons = GetUpDownButtonsHold();
|
||||
if(upDownButtons != BTN_DOWN_UP_NO_SHORT_CLICKED)
|
||||
{
|
||||
m_LEDRunner.setAllHigh();
|
||||
m_DrawTitle = false;
|
||||
m_Settings.setBrightness(m_Settings.Brightness + upDownButtons);
|
||||
m_LEDRunner.updateBrightness(m_Settings.Brightness);
|
||||
UpdateModeDisplay();
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
Settings::getInstance().setBrightness(Settings::getInstance().Brightness + upDownButtons);
|
||||
m_LEDRunner.setBrightness(Settings::getInstance().Brightness);
|
||||
updateModeDisplay();
|
||||
}
|
||||
|
||||
if(upDownHoldButtons != 0)
|
||||
if(upDownButtonsHold != BTN_DOWN_UP_NOT_HOLDED)
|
||||
{
|
||||
m_LEDRunner.setAllHigh();
|
||||
m_DrawTitle = false;
|
||||
m_Settings.setBrightness(m_Settings.Brightness + upDownHoldButtons);
|
||||
m_LEDRunner.updateBrightness(m_Settings.Brightness);
|
||||
UpdateModeDisplay();
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
Settings::getInstance().setBrightness(Settings::getInstance().Brightness + upDownButtonsHold);
|
||||
m_LEDRunner.setBrightness(Settings::getInstance().Brightness);
|
||||
updateModeDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessTest()
|
||||
void processTimeMode(int upDownButtons, int upDownButtonsHold)
|
||||
{
|
||||
if(upDownButtons != BTN_DOWN_UP_NO_SHORT_CLICKED)
|
||||
{
|
||||
m_DisplayHelper.setDrawTitle(false);
|
||||
Settings::getInstance().switchTimeMode(upDownButtons);
|
||||
updateModeDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
void processTest(int upDownButtons, int upDownButtonsHold)
|
||||
{
|
||||
ProcessChangeMode();
|
||||
int upDownButtons = GetUpDownButtonsShortClicked();
|
||||
if(upDownButtons != BTN_DOWN_UP_NO_SHORT_CLICKED)
|
||||
{
|
||||
runTest();
|
||||
|
||||
BIN
GeneralViewBreadBoard.jpg
Normal file
BIN
GeneralViewBreadBoard.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 292 KiB |
@@ -42,11 +42,33 @@ public:
|
||||
return m_DownButton;
|
||||
}
|
||||
|
||||
int getUpDownButtonsShortClicked()
|
||||
{
|
||||
bool upButtonShortClicked = m_UpButton.isNowShortClicked();
|
||||
bool downButtonShortClicked = m_DownButton.isNowShortClicked();
|
||||
if(upButtonShortClicked)
|
||||
return BTN_UP_SHORT_CLICKED;
|
||||
else if(downButtonShortClicked)
|
||||
return BTN_DOWN_SHORT_CLICKED;
|
||||
return BTN_DOWN_UP_NO_SHORT_CLICKED;
|
||||
}
|
||||
|
||||
int getUpDownButtonsHold()
|
||||
{
|
||||
bool upButtonHold = m_UpButton.isHolded();
|
||||
bool downButtonHold = m_DownButton.isHolded();
|
||||
if(upButtonHold)
|
||||
return BTN_UP_HOLDED;
|
||||
else if(downButtonHold)
|
||||
return BTN_DOWN_HOLDED;
|
||||
return BTN_DOWN_UP_NOT_HOLDED;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_InputEvent;
|
||||
|
||||
SimpleButton m_MainButton = SimpleButton(PIN_BTN_MAIN, LONG_CLICK_TIME_MS);
|
||||
SimpleButton m_UpButton = SimpleButton(PIN_BTN_UP, LONG_CLICK_TIME_MS);
|
||||
SimpleButton m_UpButton = SimpleButton(PIN_BTN_UP, LONG_CLICK_TIME_MS);
|
||||
SimpleButton m_DownButton = SimpleButton(PIN_BTN_DOWN, LONG_CLICK_TIME_MS);
|
||||
};
|
||||
|
||||
|
||||
144
LEDRunner.h
144
LEDRunner.h
@@ -1,3 +1,6 @@
|
||||
#ifndef EYE_TRAINER_LEDRUNNER
|
||||
#define EYE_TRAINER_LEDRUNNER 0
|
||||
|
||||
/*
|
||||
ShiftRegister74HC595 - Library for simplified control of 74HC595 shift registers.
|
||||
Developed and maintained by Timo Denk and contributers, since Nov 2014.
|
||||
@@ -7,52 +10,42 @@
|
||||
#include "Defines.h"
|
||||
#include <ShiftRegister74HC595.h>
|
||||
#include "Settings.h"
|
||||
#include "WrapHelper.h"
|
||||
|
||||
class LEDRunner
|
||||
{
|
||||
public:
|
||||
// LEDRunner()
|
||||
// {
|
||||
// }
|
||||
|
||||
LEDRunner(Settings* _Settings)
|
||||
{
|
||||
this->m_Settings = _Settings;
|
||||
}
|
||||
LEDRunner() { }
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(PIN_LED_GND_BUS, OUTPUT);
|
||||
pinMode(PIN_LED_DATA, OUTPUT);
|
||||
pinMode(PIN_LED_CLOCK, OUTPUT);
|
||||
pinMode(PIN_LED_LATCH, OUTPUT);
|
||||
pinMode(PIN_LED_SHIFT_REGISTER_DATA, OUTPUT);
|
||||
pinMode(PIN_LED_SHIFT_REGISTER_CLOCK, OUTPUT);
|
||||
pinMode(PIN_LED_SHIFT_REGISTER_LATCH, OUTPUT);
|
||||
}
|
||||
|
||||
void nextLED(RunMode _RunMode)
|
||||
void manualUpdate(RunMode _RunMode, int _NextLEDIndexIncrement)
|
||||
{
|
||||
switch(_RunMode)
|
||||
{
|
||||
case RunMode::FORWARD: m_CurrentLED = wrapInt(m_CurrentLED + 1, MAX_LED_INDEX + 1); break;
|
||||
case RunMode::BACKWARD: m_CurrentLED = wrapInt(m_CurrentLED - 1, MAX_LED_INDEX + 1); break;
|
||||
//TODO: ADD PING PONG
|
||||
case RunMode::BOTH: m_CurrentLED = wrapInt(m_CurrentLED - 1, MAX_LED_INDEX + 1); break;
|
||||
case RunMode::RANDOM: m_CurrentLED = random(0, MAX_LED_INDEX + 1); break;
|
||||
}
|
||||
nextLED(_RunMode, _NextLEDIndexIncrement);
|
||||
m_LEDs.setAllLow();
|
||||
m_LEDs.set(m_CurrentLED, HIGH);
|
||||
}
|
||||
|
||||
void update(unsigned long _DeltaTime, int _SwitchTime, RunMode _RunMode, TimeMode _TimeMode)
|
||||
void update(unsigned long _DeltaTime)
|
||||
{
|
||||
if(!m_Run)
|
||||
if(!m_Run || Settings::getInstance().TimeModeState == TimeMode::MANUAL)
|
||||
return;
|
||||
|
||||
m_CurrentTime += _DeltaTime;
|
||||
|
||||
if(m_CurrentTime > _SwitchTime)
|
||||
//Settings::getInstance().SwitchTime
|
||||
if(m_CurrentTime > Settings::getInstance().getDistanceCorrectedSwitchTime(m_CurrentLED))
|
||||
{
|
||||
m_CurrentTime = 0;
|
||||
nextLED(_RunMode);
|
||||
sr.setAllLow();
|
||||
sr.set(m_CurrentLED, HIGH);
|
||||
nextLED(Settings::getInstance().RunModeState, 1);
|
||||
m_LEDs.setAllLow();
|
||||
m_LEDs.set(m_CurrentLED, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +54,7 @@ public:
|
||||
m_Run = _Run;
|
||||
}
|
||||
|
||||
void updateBrightness(float _Brightness)
|
||||
void setBrightness(float _Brightness)
|
||||
{
|
||||
analogWrite(PIN_LED_GND_BUS, (MAX_BRIGHTNESS - _Brightness) / MAX_BRIGHTNESS * 255);
|
||||
}
|
||||
@@ -73,10 +66,6 @@ public:
|
||||
|
||||
void runTest()
|
||||
{
|
||||
// // setting all pins at the same time to either HIGH or LOW
|
||||
// sr.setAllHigh(); // set all pins HIGH
|
||||
// delay(500);
|
||||
|
||||
analogWrite(PIN_LED_GND_BUS, 120);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
@@ -87,13 +76,13 @@ public:
|
||||
delay(250); // wait for a second
|
||||
}
|
||||
|
||||
sr.setAllHigh();
|
||||
m_LEDs.setAllHigh();
|
||||
delay(500);
|
||||
sr.setAllLow();
|
||||
m_LEDs.setAllLow();
|
||||
delay(500);
|
||||
sr.setAllHigh();
|
||||
m_LEDs.setAllHigh();
|
||||
delay(500);
|
||||
sr.setAllLow();
|
||||
m_LEDs.setAllLow();
|
||||
delay(500);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
@@ -109,29 +98,29 @@ public:
|
||||
// setting single pins
|
||||
for (int i = 0; i < MAX_LED_INDEX; i++)
|
||||
{
|
||||
sr.set(i, HIGH);
|
||||
m_LEDs.set(i, HIGH);
|
||||
delay(25);
|
||||
sr.set(i, LOW);
|
||||
m_LEDs.set(i, LOW);
|
||||
}
|
||||
// setting single pins
|
||||
// setting single pins
|
||||
for (int i = MAX_LED_INDEX; i > 0; i--)
|
||||
{
|
||||
sr.set(i, HIGH);
|
||||
m_LEDs.set(i, HIGH);
|
||||
delay(25);
|
||||
sr.set(i, LOW);
|
||||
m_LEDs.set(i, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
sr.set(0, HIGH);
|
||||
m_LEDs.set(0, HIGH);
|
||||
delay(50);
|
||||
|
||||
for (int i = 0; i < MAX_LED_INDEX / 2; i++)
|
||||
{
|
||||
sr.set(i, HIGH);
|
||||
sr.set(MAX_LED_INDEX - i, HIGH);
|
||||
m_LEDs.set(i, HIGH);
|
||||
m_LEDs.set(MAX_LED_INDEX - i, HIGH);
|
||||
delay(150);
|
||||
sr.set(i, LOW);
|
||||
sr.set(MAX_LED_INDEX - i, LOW);
|
||||
m_LEDs.set(i, LOW);
|
||||
m_LEDs.set(MAX_LED_INDEX - i, LOW);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,15 +128,15 @@ public:
|
||||
{
|
||||
for (int i = MAX_LED_INDEX / 2; i >= 0; i--)
|
||||
{
|
||||
sr.set(i, HIGH);
|
||||
sr.set(MAX_LED_INDEX - i, HIGH);
|
||||
m_LEDs.set(i, HIGH);
|
||||
m_LEDs.set(MAX_LED_INDEX - i, HIGH);
|
||||
delay(50);
|
||||
sr.set(i, LOW);
|
||||
sr.set(MAX_LED_INDEX - i, LOW);
|
||||
m_LEDs.set(i, LOW);
|
||||
m_LEDs.set(MAX_LED_INDEX - i, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
sr.setAllHigh(); // set all pins HIGH
|
||||
m_LEDs.setAllHigh(); // set all pins HIGH
|
||||
|
||||
for(int i = 10; i > 0; i--)
|
||||
{
|
||||
@@ -160,58 +149,53 @@ public:
|
||||
|
||||
void blink(const uint8_t _LedIndex, unsigned long _Time)
|
||||
{
|
||||
sr.setAllLow();
|
||||
sr.set(_LedIndex, HIGH);
|
||||
m_LEDs.setAllLow();
|
||||
m_LEDs.set(_LedIndex, HIGH);
|
||||
delay(_Time);
|
||||
sr.setAllLow();
|
||||
m_LEDs.setAllLow();
|
||||
}
|
||||
|
||||
void setAndClearOthers(const uint8_t _LedIndex, const uint8_t _Value)
|
||||
{
|
||||
sr.setAllLow();
|
||||
sr.set(_LedIndex, _Value);
|
||||
m_LEDs.setAllLow();
|
||||
m_LEDs.set(_LedIndex, _Value);
|
||||
}
|
||||
|
||||
void set(const uint8_t _LedIndex, const uint8_t _Value)
|
||||
{
|
||||
sr.set(_LedIndex, _Value);
|
||||
m_LEDs.set(_LedIndex, _Value);
|
||||
}
|
||||
|
||||
void setAllHigh()
|
||||
{
|
||||
sr.setAllHigh();
|
||||
m_LEDs.setAllHigh();
|
||||
}
|
||||
|
||||
void setAllLow()
|
||||
{
|
||||
sr.setAllLow();
|
||||
m_LEDs.setAllLow();
|
||||
}
|
||||
|
||||
private:
|
||||
Settings* m_Settings;
|
||||
bool m_Run = false;
|
||||
unsigned long m_CurrentTime = 0;
|
||||
int m_CurrentLED = 0;
|
||||
ShiftRegister74HC595<REGISTER_SIZE> sr = ShiftRegister74HC595<REGISTER_SIZE>::ShiftRegister74HC595(PIN_LED_DATA, PIN_LED_CLOCK, PIN_LED_LATCH);
|
||||
private:
|
||||
bool m_Run = true;
|
||||
unsigned long m_CurrentTime = 0;
|
||||
int m_CurrentLED = 0;
|
||||
int m_CurrentLEDPingPong = 0;
|
||||
ShiftRegister74HC595<REGISTER_SIZE> m_LEDs = ShiftRegister74HC595<REGISTER_SIZE>::ShiftRegister74HC595(PIN_LED_SHIFT_REGISTER_DATA, PIN_LED_SHIFT_REGISTER_CLOCK, PIN_LED_SHIFT_REGISTER_LATCH);
|
||||
|
||||
int wrapInt(int _Num, int _Max)
|
||||
void nextLED(RunMode _RunMode, int _NextLEDIndexIncrement)
|
||||
{
|
||||
if(_Num < 0)
|
||||
switch(_RunMode)
|
||||
{
|
||||
return (_Max - _Num) % _Max;
|
||||
case RunMode::FORWARD: m_CurrentLED = wrapInt(m_CurrentLED + _NextLEDIndexIncrement, MAX_LED_INDEX + 1); break;
|
||||
case RunMode::BACKWARD: m_CurrentLED = wrapInt(m_CurrentLED - _NextLEDIndexIncrement, MAX_LED_INDEX + 1); break;
|
||||
case RunMode::PING_PONG:
|
||||
m_CurrentLEDPingPong = wrapInt(m_CurrentLEDPingPong + _NextLEDIndexIncrement, MAX_LED_INDEX * 2);
|
||||
m_CurrentLED = pingPong(m_CurrentLEDPingPong, MAX_LED_INDEX);
|
||||
break;
|
||||
case RunMode::RANDOM: m_CurrentLED = random(0, MAX_LED_INDEX + 1); break;
|
||||
}
|
||||
if(_Num >= _Max)
|
||||
{
|
||||
return _Num % _Max;
|
||||
}
|
||||
|
||||
return _Num;
|
||||
}
|
||||
|
||||
int wrapInt(int _Num, int _Min, int _Max)
|
||||
{
|
||||
int num = _Num - _Min;
|
||||
int max = _Max - _Min;
|
||||
return wrapInt(num, max) + _Min;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Lis Glitchrain
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
91
LogDistanceCalc.ipynb
Normal file
91
LogDistanceCalc.ipynb
Normal file
File diff suppressed because one or more lines are too long
97
README.md
Normal file
97
README.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Eye Trainer
|
||||
|
||||
## Description
|
||||
|
||||
This is a simple eye trainer which is supposed to reduce muscle stress after focusing on same distance for a long time. The constraction is long stick (1.0-1.5m) with LEDs placed along. LEDs turn on with choosen order after selected switch time is passed. Display helps to control the device.
|
||||
|
||||
## Controls
|
||||
|
||||
**Buttons:**
|
||||
|
||||
1. Main
|
||||
2. Up
|
||||
3. Down
|
||||
|
||||
## Usage
|
||||
|
||||
Device starts in "run" mode. but inactive. Click "Up" button to start with default settings. Click "Down" button to pause. Click "Main" button to switch displayed info. On other screens than "run" press "Up" or "Down" buttons to change settings.
|
||||
|
||||
On "Test" screen any button except "Main" will trigger test sequence to check display and LEDs.
|
||||
|
||||
## Device Settings
|
||||
|
||||
**LEDS order modes (rnod):**
|
||||
|
||||
1. Forward (FrWd)
|
||||
2. Backward (bAC-)
|
||||
3. Ping-Pong (PInG)
|
||||
4. Random (rnd) (default)
|
||||
|
||||
**Brightness (brgh):**
|
||||
|
||||
Number from 25 to 255.
|
||||
|
||||
**Switch Time (time):**
|
||||
|
||||
Number between 25 and 1500 measured in milliseconds x10, i.e. 25 means 250 ms and 1500 means 15000 ms (15 seconds).
|
||||
Default value 300 (3 seconds).
|
||||
|
||||
**Time mode (tmod):**
|
||||
|
||||
1. Constant (CnSt)
|
||||
2. Manusl (nAnL)
|
||||
3. Decremental (dECr) (not implemented)
|
||||
|
||||
## Components Used
|
||||
1. Arduino Nano (ATMega328PB) x1
|
||||
2. ShiftRegister 74HC595N x2
|
||||
3. LED x16
|
||||
4. Resistor 220Ohm x16
|
||||
5. Resistor 10kOhm x3
|
||||
6. Segment Display TM1637 x1
|
||||
7. Tact Button x3
|
||||
8. Solderless breadboards x3
|
||||
9. Wires (a lot)
|
||||
|
||||
## Connection Scheme
|
||||
|
||||
To be added. Hints are in file EyeTrainerLayout.diy (can be opened with DIY Layout Creator).
|
||||
|
||||
### Text description
|
||||
|
||||
**Arduino's BreadBoard:**
|
||||
|
||||
1. Contains Arduino Nano, TM1637 Display, 3 tact buttons with 10kOhm resistors, connectors
|
||||
2. Pins D7, D8 controlls display (see Defines.h)
|
||||
3. Pins D9, D10, D11 receives buttons signals (see Defines.h)
|
||||
4. Pins D3, D4, D5 controlls shift registers (see Defines.h)
|
||||
5. Ping 6 controlls brightness of LEDs (see Defines.h)
|
||||
6. D6, D3, D4, D5, GND and 5V pins are passed to ShiftRegisters' BreadBoard
|
||||
|
||||
**ShiftRegisters' BreadBoard:**
|
||||
|
||||
1. Contains two 74HC595N shift registers, x16 220Ohm resistors and connectors
|
||||
2. Pins Q0..Q7 of both shift registers are used to controll LEDs.
|
||||
3. Two 74HC595N are connected sequentially. Latch, Data and Clock connections to Arduino board are defined in Defines.h
|
||||
|
||||
**IMPORTANT: Arduino's pins are different in EyeTrainer project!**
|
||||
|
||||

|
||||
|
||||
Source: https://blog.timodenk.com/shift-register-arduino-library/
|
||||
|
||||
## General View
|
||||
|
||||

|
||||
|
||||
## Notes
|
||||
|
||||
Python script (LogDistanceCalc.ipynb, Jupyter Notebook) can be used to define distances between LEDs on stick.
|
||||
|
||||
## Known Problems
|
||||
|
||||
1. Sometimes buttons click are not registered or skipped.
|
||||
|
||||
## Possible Improvements
|
||||
|
||||
1. Lighten small printed and high contrast images with white LEDs. Probably it would be easier and healthier to focus eyes on, than watching LEDs directly.
|
||||
75
Settings.h
75
Settings.h
@@ -7,26 +7,40 @@
|
||||
class Settings
|
||||
{
|
||||
public:
|
||||
enum RunMode m_RunMode = RunMode::RANDOM;
|
||||
enum TimeMode m_TimeMode = TimeMode::CONST;
|
||||
int SwitchTime = 3000; //In milliseconds
|
||||
// float Brightness = MAX_BRIGHTNESS;
|
||||
float Brightness = 195;
|
||||
enum RunMode RunModeState = RunMode::PING_PONG;
|
||||
enum TimeMode TimeModeState = TimeMode::CONST;
|
||||
int SwitchTime = DEFAULT_SWITCH_TIME; //In milliseconds
|
||||
float Brightness = MAX_BRIGHTNESS / 2;
|
||||
float LED_DISTANCE_ARRAY;
|
||||
|
||||
Settings()
|
||||
//=======================================
|
||||
//Singleton. AVOID COPY ASSIGNMENTS
|
||||
//=======================================
|
||||
|
||||
static Settings& getInstance()
|
||||
{
|
||||
static Settings instance; // Guaranteed to be destroyed. Instantiated on first use.
|
||||
return instance;
|
||||
}
|
||||
|
||||
Settings() {}
|
||||
Settings(Settings const&) = delete;
|
||||
void operator = (Settings const&) = delete;
|
||||
|
||||
//=======================================
|
||||
//Singleton. AVOID COPY ASSIGNMENTS
|
||||
//=======================================
|
||||
|
||||
void setSwitchTime(int _SwitchTime)
|
||||
{
|
||||
if(_SwitchTime > 15000)
|
||||
if(_SwitchTime > MAX_SWITCH_TIME)
|
||||
{
|
||||
SwitchTime = 15000;
|
||||
SwitchTime = MAX_SWITCH_TIME;
|
||||
return;
|
||||
}
|
||||
if(_SwitchTime < 250)
|
||||
if(_SwitchTime < MIN_SWITCH_TIME)
|
||||
{
|
||||
SwitchTime = 250;
|
||||
SwitchTime = MIN_SWITCH_TIME;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,45 +64,40 @@ public:
|
||||
|
||||
void resetRunMode(RunMode _RunMode)
|
||||
{
|
||||
m_RunMode = RunMode::FORWARD;
|
||||
RunModeState = RunMode::FORWARD;
|
||||
}
|
||||
|
||||
void switchRunMode(int _NextOrBack)
|
||||
void switchRunMode(int _ModeIncrement)
|
||||
{
|
||||
if(m_RunMode == RunMode::FORWARD)
|
||||
{
|
||||
m_RunMode = RunMode::BACKWARD;
|
||||
}
|
||||
else if(m_RunMode == RunMode::BACKWARD)
|
||||
{
|
||||
m_RunMode = RunMode::BOTH;
|
||||
}
|
||||
else if(m_RunMode == RunMode::BOTH)
|
||||
{
|
||||
m_RunMode = RunMode::RANDOM;
|
||||
}
|
||||
else if(m_RunMode == RunMode::RANDOM)
|
||||
{
|
||||
m_RunMode = RunMode::FORWARD;
|
||||
}
|
||||
|
||||
// RunMode newRunMode = static_cast<RunMode>(wrapInt(static_cast<int>(m_RunMode) + _NextOrBack, 4));
|
||||
// m_RunMode = newRunMode;
|
||||
RunModeState = static_cast<RunMode>(wrapInt(static_cast<int>(RunModeState) + _ModeIncrement, 4));
|
||||
}
|
||||
|
||||
void setTimeMode(enum TimeMode _TimeMode)
|
||||
{
|
||||
m_TimeMode = _TimeMode;
|
||||
TimeModeState = _TimeMode;
|
||||
}
|
||||
|
||||
void switchTimeMode(int _ModeIncrement)
|
||||
{
|
||||
TimeModeState = static_cast<TimeMode>(wrapInt(static_cast<int>(TimeModeState) + _ModeIncrement, 3));
|
||||
}
|
||||
|
||||
int getDisplaySwitchTime()
|
||||
{
|
||||
return SwitchTime / 10;
|
||||
}
|
||||
|
||||
int getDistanceCorrectedSwitchTime(int _LedIndex)
|
||||
{
|
||||
return (int) (min(max(SwitchTime * LedDistances[_LedIndex], MIN_SWITCH_TIME), MAX_SWITCH_TIME));
|
||||
}
|
||||
|
||||
private:
|
||||
int wrapInt(int _Num, int _Max)
|
||||
{
|
||||
if(_Num < 0)
|
||||
{
|
||||
return (_Max - _Num) % _Max;
|
||||
return (_Max + _Num % _Max);
|
||||
}
|
||||
if(_Num >= _Max)
|
||||
{
|
||||
|
||||
BIN
ShiftRegisterSequentialConnection.png
Normal file
BIN
ShiftRegisterSequentialConnection.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 341 KiB |
@@ -58,37 +58,37 @@ public:
|
||||
return m_IsNowHolded | (prevState != m_State);
|
||||
}
|
||||
|
||||
bool IsNowClicked()
|
||||
bool isNowClicked()
|
||||
{
|
||||
return m_IsNowClicked;
|
||||
}
|
||||
|
||||
bool IsNowPressed()
|
||||
bool isNowPressed()
|
||||
{
|
||||
return m_IsNowPressed;
|
||||
}
|
||||
|
||||
bool IsNowReleased()
|
||||
bool isNowReleased()
|
||||
{
|
||||
return m_IsNowReleased;
|
||||
}
|
||||
|
||||
bool IsHolded()
|
||||
bool isHolded()
|
||||
{
|
||||
return m_IsNowHolded;
|
||||
}
|
||||
|
||||
bool IsNowLongClicked()
|
||||
bool isNowLongClicked()
|
||||
{
|
||||
return m_IsNowLongClicked;
|
||||
}
|
||||
|
||||
bool IsNowShortClicked()
|
||||
bool isNowShortClicked()
|
||||
{
|
||||
return m_IsNowShortClicked;
|
||||
}
|
||||
|
||||
unsigned long GetPressedTime()
|
||||
unsigned long getPressedTime()
|
||||
{
|
||||
return m_PressedTime;
|
||||
}
|
||||
|
||||
44
WrapHelper.h
Normal file
44
WrapHelper.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef EYE_TRAINER_WRAPHELPER
|
||||
#define EYE_TRAINER_WRAPHELPER 0
|
||||
|
||||
int wrapInt(int _Num, int _Max)
|
||||
{
|
||||
if(_Num < 0)
|
||||
{
|
||||
return (_Max + _Num % _Max);
|
||||
}
|
||||
if(_Num >= _Max)
|
||||
{
|
||||
return _Num % _Max;
|
||||
}
|
||||
|
||||
return _Num;
|
||||
}
|
||||
|
||||
int pingPong(int _Num, int _MaxHalfIndex)
|
||||
{
|
||||
const int maxHalfCount = _MaxHalfIndex + 1;
|
||||
const int maxFullIndex = _MaxHalfIndex * 2;
|
||||
const int maxFullCount = (_MaxHalfIndex + 1) * 2;
|
||||
int numInRange = _Num < 0
|
||||
? _Num % maxFullCount == 0
|
||||
? 0
|
||||
: _Num % maxFullCount + maxFullCount
|
||||
: _Num % maxFullCount;
|
||||
|
||||
if(numInRange > _MaxHalfIndex)
|
||||
{
|
||||
return maxFullIndex - numInRange;
|
||||
}
|
||||
|
||||
return numInRange;
|
||||
}
|
||||
|
||||
int wrapInt(int _Num, int _Min, int _Max)
|
||||
{
|
||||
int num = _Num - _Min;
|
||||
int max = _Max - _Min;
|
||||
return wrapInt(num, max) + _Min;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#include "EyeTrainerMain.h"
|
||||
|
||||
EyeTrainerMain m_EyeTrainerMain;
|
||||
Reference in New Issue
Block a user