Last active
November 27, 2015 14:51
-
-
Save falcon8823/fee7eb99fb64ac511bd8 to your computer and use it in GitHub Desktop.
タイマーレリーズのプログラム http://blog.falconsrv.net/articles/558
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <LiquidCrystal.h> | |
#define RS 12 | |
#define ENABLE 11 | |
#define DB4 10 | |
#define DB5 7 | |
#define DB6 9 | |
#define DB7 8 | |
#define SW_ESC 19 | |
#define SW_SET 18 | |
#define SW_DOWN 17 | |
#define SW_UP 16 | |
#define HALF 2 | |
#define FULL 3 | |
LiquidCrystal lcd(RS, ENABLE, DB4, DB5, DB6, DB7); | |
typedef enum { | |
M_NORMAL, | |
M_TIMER | |
} E_MODE; | |
E_MODE mode = M_NORMAL; | |
char* MODE_STRING[] = { | |
"Normal ", | |
"Timer " | |
}; | |
typedef enum { | |
M_INTERVAL, | |
M_REPEAT, | |
M_EXPOSURE, | |
M_START | |
} E_TIMER_MENU; | |
E_TIMER_MENU t_menu = M_INTERVAL; | |
char *TIMER_MENU_STRING[] = { | |
"Interval", | |
"Repeat ", | |
"Exposure", | |
"Start " | |
}; | |
void (*TIMER_MENU_FUNC[])() = { | |
IntervalSetting, | |
RepeatSetting, | |
ExposureSetting, | |
TimerMode | |
}; | |
typedef union { | |
unsigned int array[3]; | |
volatile struct { | |
unsigned int interval; | |
unsigned int repeat; | |
unsigned int exposure; | |
} data; | |
} TIMER_SETTING; | |
TIMER_SETTING t_setting = {3, 1, 1}; | |
TIMER_SETTING t_current; | |
void (*currentFunc)() = ModeSelectMenu; | |
unsigned long next; | |
byte expose; | |
void setup() { | |
pinMode(SW_ESC, INPUT); | |
pinMode(SW_SET, INPUT); | |
pinMode(SW_DOWN, INPUT); | |
pinMode(SW_UP, INPUT); | |
pinMode(HALF, OUTPUT); | |
pinMode(FULL, OUTPUT); | |
Serial.begin(9600); | |
lcd.begin(8, 2); | |
} | |
void loop() { | |
currentFunc(); | |
} | |
byte pushedButton() { | |
byte sw_state = B00000000; | |
if(!digitalRead(SW_ESC)) { | |
while(!digitalRead(SW_ESC)) delay(10); | |
bitSet(sw_state, 0); | |
} else if(!digitalRead(SW_SET)) { | |
while(!digitalRead(SW_SET)) delay(10); | |
bitSet(sw_state, 1); | |
} else if(!digitalRead(SW_DOWN)) { | |
while(!digitalRead(SW_DOWN)) delay(10); | |
bitSet(sw_state, 2); | |
} else if(!digitalRead(SW_UP)) { | |
while(!digitalRead(SW_UP)) delay(10); | |
bitSet(sw_state, 3); | |
} | |
return sw_state; | |
} | |
// モードセレクト画面 | |
void ModeSelectMenu() { | |
lcd.setCursor(0, 0); | |
lcd.print("Mode "); | |
lcd.setCursor(0, 1); | |
lcd.print(MODE_STRING[mode]); | |
byte button = pushedButton(); | |
switch(button) { | |
case 2: // SET | |
// 遷移 | |
if(mode == M_NORMAL) { | |
currentFunc = NormalMode; | |
lcd.clear(); | |
} else if(mode == M_TIMER) { | |
currentFunc = TimerSettingMenu; | |
lcd.clear(); | |
} | |
break; | |
// 2つしかないので同じ動き | |
case 4: // DOWN | |
case 8: // UP | |
mode = (E_MODE)(((byte)mode + 1) % 2); | |
break; | |
} | |
} | |
// 通常レリーズモード | |
void NormalMode() { | |
lcd.setCursor(0, 0); | |
lcd.print("Normal"); | |
digitalWrite(HALF, digitalRead(SW_DOWN) ? LOW : HIGH); | |
digitalWrite(FULL, digitalRead(SW_UP) ? LOW : HIGH); | |
if(!digitalRead(SW_ESC)) { | |
currentFunc = ModeSelectMenu; | |
digitalWrite(HALF, LOW); | |
digitalWrite(FULL, LOW); | |
} | |
} | |
void TimerSettingMenu() { | |
lcd.setCursor(0, 0); | |
lcd.print(TIMER_MENU_STRING[t_menu]); | |
lcd.setCursor(0, 1); | |
if(t_menu < 3) { | |
lcd.print(t_setting.array[t_menu]); | |
lcd.print(" "); | |
} else { | |
lcd.print(" "); | |
} | |
byte button = pushedButton(); | |
switch(button) { | |
case 1: // ESC | |
currentFunc = ModeSelectMenu; | |
break; | |
case 2: // SET | |
// 遷移 | |
currentFunc = TIMER_MENU_FUNC[t_menu]; | |
if(t_menu == M_START) { | |
t_current = t_setting; | |
next = expose = 0; | |
} | |
break; | |
case 4: // DOWN | |
t_menu = (E_TIMER_MENU)(t_menu == 0 ? 3 : t_menu - 1); | |
break; | |
case 8: // UP | |
t_menu = (E_TIMER_MENU)((t_menu + 1) % 4); | |
break; | |
} | |
} | |
void IntervalSetting() { | |
if(!digitalRead(SW_ESC)) { | |
while(!digitalRead(SW_ESC)) delay(10); | |
currentFunc = TimerSettingMenu; | |
} | |
if(!digitalRead(SW_DOWN)) { | |
if(t_setting.data.interval > 3) { | |
t_setting.data.interval--; | |
byte count = 0; | |
while(!digitalRead(SW_DOWN)) { | |
// 長押しで高速に | |
if(count > 20) { | |
if(t_setting.data.interval > 3) | |
t_setting.data.interval--; | |
} else { | |
count++; | |
} | |
lcd.setCursor(0, 1); | |
lcd.print(t_setting.data.interval); | |
lcd.print(" "); | |
delay(50); | |
} | |
} | |
} | |
if(!digitalRead(SW_UP)) { | |
if(t_setting.data.interval < 18000) { | |
t_setting.data.interval++; | |
byte count = 0; | |
while(!digitalRead(SW_UP)) { | |
// 長押しで高速に | |
if(count > 20) { | |
if(t_setting.data.interval < 18000) | |
t_setting.data.interval++; | |
} else { | |
count++; | |
} | |
lcd.setCursor(0, 1); | |
lcd.print(t_setting.data.interval); | |
lcd.print(" "); | |
delay(50); | |
} | |
} | |
} | |
} | |
void RepeatSetting() { | |
if(!digitalRead(SW_ESC)) { | |
while(!digitalRead(SW_ESC)) delay(10); | |
currentFunc = TimerSettingMenu; | |
} | |
if(!digitalRead(SW_DOWN)) { | |
if(t_setting.data.repeat > 1) { | |
t_setting.data.repeat--; | |
byte count = 0; | |
while(!digitalRead(SW_DOWN)) { | |
// 長押しで高速に | |
if(count > 20) { | |
if(t_setting.data.repeat > 1) | |
t_setting.data.repeat--; | |
} else { | |
count++; | |
} | |
lcd.setCursor(0, 1); | |
lcd.print(t_setting.data.repeat); | |
lcd.print(" "); | |
delay(50); | |
} | |
} | |
} | |
if(!digitalRead(SW_UP)) { | |
if(t_setting.data.repeat < 500) { | |
t_setting.data.repeat++; | |
byte count = 0; | |
while(!digitalRead(SW_UP)) { | |
// 長押しで高速に | |
if(count > 20) { | |
if(t_setting.data.repeat < 500) | |
t_setting.data.repeat++; | |
} else { | |
count++; | |
} | |
lcd.setCursor(0, 1); | |
lcd.print(t_setting.data.repeat); | |
lcd.print(" "); | |
delay(50); | |
} | |
} | |
} | |
} | |
void ExposureSetting() { | |
if(!digitalRead(SW_ESC)) { | |
while(!digitalRead(SW_ESC)) delay(10); | |
currentFunc = TimerSettingMenu; | |
} | |
if(!digitalRead(SW_DOWN)) { | |
if(t_setting.data.exposure > 1) { | |
t_setting.data.exposure--; | |
byte count = 0; | |
while(!digitalRead(SW_DOWN)) { | |
// 長押しで高速に | |
if(count > 20) { | |
if(t_setting.data.exposure > 1) | |
t_setting.data.exposure--; | |
} else { | |
count++; | |
} | |
lcd.setCursor(0, 1); | |
lcd.print(t_setting.data.exposure); | |
lcd.print(" "); | |
delay(50); | |
} | |
} | |
} | |
if(!digitalRead(SW_UP)) { | |
if(t_setting.data.exposure < 18000) { | |
t_setting.data.exposure++; | |
byte count = 0; | |
while(!digitalRead(SW_UP)) { | |
// 長押しで高速に | |
if(count > 20) { | |
if(t_setting.data.exposure < 18000) | |
t_setting.data.exposure++; | |
} else { | |
count++; | |
} | |
lcd.setCursor(0, 1); | |
lcd.print(t_setting.data.exposure); | |
lcd.print(" "); | |
delay(50); | |
} | |
} | |
} | |
} | |
void TimerMode() { | |
unsigned long current; | |
current = millis(); | |
if(!digitalRead(SW_ESC)) { | |
while(!digitalRead(SW_ESC)) delay(10); | |
currentFunc = TimerSettingMenu; | |
digitalWrite(FULL, LOW); | |
} | |
if(t_current.data.repeat > 0 || expose) { | |
if(expose && current > next) { | |
expose = 0; | |
t_current.data.repeat--; | |
next = current + t_setting.data.interval * 1000; | |
} else if(!expose && current > next) { | |
expose = 1; | |
next = current + t_setting.data.exposure * 1000 + 150; | |
} | |
digitalWrite(FULL, expose ? HIGH : LOW); | |
lcd.setCursor(0, 0); | |
lcd.print(t_current.data.repeat); | |
lcd.print(" "); | |
lcd.setCursor(0, 1); | |
lcd.print((next - current) / 1000); | |
lcd.print(" "); | |
} else { | |
currentFunc = TimerSettingMenu; | |
digitalWrite(FULL, LOW); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment