Skip to content

Instantly share code, notes, and snippets.

@falcon8823
Last active November 27, 2015 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save falcon8823/fee7eb99fb64ac511bd8 to your computer and use it in GitHub Desktop.
Save falcon8823/fee7eb99fb64ac511bd8 to your computer and use it in GitHub Desktop.
タイマーレリーズのプログラム http://blog.falconsrv.net/articles/558
#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