Skip to content

Instantly share code, notes, and snippets.

@minoki
Created December 17, 2020 06:53
Show Gist options
  • Save minoki/11c304920f22a6d21488cabde3b0ef3c to your computer and use it in GitHub Desktop.
Save minoki/11c304920f22a6d21488cabde3b0ef3c to your computer and use it in GitHub Desktop.
M5Stackで作るタイマーリモコン
#include <M5Stack.h>
#include <utility/M5Timer.h>
const int SHUTTER_PIN = 12;
const int FOCUS_PIN = 5;
const int LEVER_UP = 13;
const int LEVER_PUSH = 0;
const int LEVER_DOWN = 34;
Button LeverUp(LEVER_UP, true, 10);
Button LeverPush(LEVER_PUSH, true, 10);
Button LeverDown(LEVER_DOWN, true, 10);
bool changed = true;
// LCD: 320x240
const uint8_t TEXT_SIZE = 3;
const int16_t LINE_HEIGHT = TEXT_SIZE * 8;
const int16_t CHAR_WIDTH = TEXT_SIZE * 6;
enum Selection {
SEL_DELAY = 0,
SEL_LONG,
SEL_INTERVAL,
SEL_REPEAT,
SEL_MAX = SEL_REPEAT
} selection = SEL_DELAY;
bool valueSelected = false;
int delayValue = 0;
int longValue = 1;
int intervalValue = 1;
int repeatValue = 1;
M5Timer timer;
bool isTimerRunning = false;
bool isLocked = false;
bool isShutterPressed = false;
int timerId = -1;
int count = 0;
void setup() {
M5.begin();
M5.Power.begin();
pinMode(SHUTTER_PIN, OUTPUT);
pinMode(FOCUS_PIN, OUTPUT);
M5.Lcd.setTextSize(TEXT_SIZE);
}
void stopShutter()
{
digitalWrite(SHUTTER_PIN, LOW);
digitalWrite(FOCUS_PIN, LOW);
isShutterPressed = false;
if (repeatValue == 0 || count < repeatValue) {
int delta = intervalValue - longValue;
timerId = timer.setTimeout(delta <= 0 ? 1 : (long)delta * 1000L, startShutter);
} else {
timerId = -1;
isTimerRunning = false;
}
changed = true;
}
void startShutter()
{
++count;
changed = true;
digitalWrite(FOCUS_PIN, HIGH);
digitalWrite(SHUTTER_PIN, HIGH);
isShutterPressed = true;
timerId = timer.setTimeout(longValue == 0 ? 1 : (long)longValue * 1000L, stopShutter);
}
void loop() {
timer.run();
M5.update();
LeverUp.read();
LeverPush.read();
LeverDown.read();
if (LeverPush.wasPressed()) {
valueSelected = !valueSelected;
changed = true;
}
if (LeverUp.wasPressed()) {
if (valueSelected) {
switch (selection) {
case SEL_DELAY:
delayValue += 1;
break;
case SEL_LONG:
longValue += 1;
break;
case SEL_INTERVAL:
intervalValue += 1;
break;
case SEL_REPEAT:
repeatValue += 1;
break;
}
changed = true;
} else {
if (selection > 0) {
selection = (Selection)(selection - 1);
changed = true;
}
}
} else if (LeverDown.wasPressed()) {
if (valueSelected) {
switch (selection) {
case SEL_DELAY:
if (delayValue > 0) {
delayValue -= 1;
}
break;
case SEL_LONG:
if (longValue > 0) {
longValue -= 1;
}
break;
case SEL_INTERVAL:
if (intervalValue > 0) {
intervalValue -= 1;
}
break;
case SEL_REPEAT:
if (intervalValue > 0) {
repeatValue -= 1;
}
break;
}
changed = true;
} else {
if (selection < SEL_MAX) {
selection = (Selection)(selection + 1);
changed = true;
}
}
}
if (M5.BtnA.wasPressed() || M5.BtnA.wasReleased() || M5.BtnB.wasPressed() || M5.BtnB.wasReleased() || M5.BtnC.wasPressed() || M5.BtnC.wasReleased()) {
changed = true;
}
if (changed) {
M5.Lcd.setTextColor(TFT_RED);
M5.Lcd.fillScreen(TFT_BLACK);
// M5.Lcd.fillRect(0, 0, CHAR_WIDTH * 8, LINE_HEIGHT * 4, TFT_DARKGREY);
M5.Lcd.setCursor(0, 0);
if (selection == SEL_DELAY && !valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
M5.Lcd.print("DELAY");
M5.Lcd.setCursor(CHAR_WIDTH * 9, LINE_HEIGHT * 0);
if (selection == SEL_DELAY && valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
M5.Lcd.printf("%d s", delayValue);
M5.Lcd.println();
if (selection == SEL_LONG && !valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
M5.Lcd.print("LONG");
M5.Lcd.setCursor(CHAR_WIDTH * 9, LINE_HEIGHT * 1);
if (selection == SEL_LONG && valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
M5.Lcd.printf("%d s", longValue); // or inf
M5.Lcd.println();
if (selection == SEL_INTERVAL && !valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
M5.Lcd.print("INTERVAL");
M5.Lcd.setCursor(CHAR_WIDTH * 9, LINE_HEIGHT * 2);
if (selection == SEL_INTERVAL && valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
M5.Lcd.printf("%d s", intervalValue);
M5.Lcd.println();
if (selection == SEL_REPEAT && !valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
M5.Lcd.print("REPEAT");
M5.Lcd.setCursor(CHAR_WIDTH * 9, LINE_HEIGHT * 3);
if (selection == SEL_REPEAT && valueSelected) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
if (repeatValue == 0) {
M5.Lcd.println("INF");
} else {
M5.Lcd.println(repeatValue);
}
M5.Lcd.setCursor(60 - 5 * CHAR_WIDTH / 2, 240 - LINE_HEIGHT);
if (M5.BtnA.isPressed()) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
if (!isTimerRunning) {
M5.Lcd.print("START");
} else {
M5.Lcd.print("STOP");
}
M5.Lcd.setCursor(160 - CHAR_WIDTH / 2, 240 - LINE_HEIGHT);
if (M5.BtnB.isPressed() || isShutterPressed) {
M5.Lcd.fillCircle(160, 240 - LINE_HEIGHT, (int32_t)(LINE_HEIGHT * 0.8), TFT_RED);
} else {
M5.Lcd.drawCircle(160, 240 - LINE_HEIGHT, (int32_t)(LINE_HEIGHT * 0.8), TFT_RED);
}
M5.Lcd.setCursor(260 - (isLocked ? 6 : 4) * CHAR_WIDTH / 2, 240 - LINE_HEIGHT);
if (M5.BtnC.isPressed()) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_RED);
} else {
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
}
if (isLocked) {
M5.Lcd.print("UNLOCK");
} else {
M5.Lcd.print("LOCK");
}
changed = false;
}
if (M5.BtnA.wasReleased()) {
if (isTimerRunning) {
timer.deleteTimer(timerId);
timerId = -1;
isTimerRunning = false;
changed = true;
isShutterPressed = false;
digitalWrite(SHUTTER_PIN, LOW);
digitalWrite(FOCUS_PIN, LOW);
} else {
count = 0;
isTimerRunning = true;
timerId = timer.setTimeout((long)delayValue * 1000L, startShutter);
changed = true;
}
}
if (M5.BtnB.wasPressed()) {
isShutterPressed = true;
digitalWrite(FOCUS_PIN, HIGH);
digitalWrite(SHUTTER_PIN, HIGH);
} else if (M5.BtnB.wasReleased() && !isLocked) {
isShutterPressed = false;
digitalWrite(SHUTTER_PIN, LOW);
digitalWrite(FOCUS_PIN, LOW);
changed = true;
}
if (M5.BtnC.wasPressed()) {
if (isLocked) {
if (M5.BtnB.isReleased()) {
isShutterPressed = false;
digitalWrite(SHUTTER_PIN, LOW);
digitalWrite(FOCUS_PIN, LOW);
}
isLocked = false;
} else {
if (M5.BtnB.isReleased()) {
isShutterPressed = true;
digitalWrite(FOCUS_PIN, HIGH);
digitalWrite(SHUTTER_PIN, HIGH);
}
isLocked = true;
}
changed = true;
}
delayMicroseconds(10);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment