ESP32에 자체 풀업저항이 달려있던가 확신이 없어서 저항까지 연결했었는데, 인터럽트에 대해 알아보면서 자체 저항도 달려있다는 걸 알게 되어 그냥 바로 연결했다.
btn | esp32 pin |
---|---|
go1 | gnd |
go2 | gpio18 |
back1 | gnd |
back2 | gpio19 |
원래는 버튼을 누를 때마다 인터럽트를 발생시켜서 mqtt 송신을 하려고 시도해봤지만, 다른 버튼과 인터럽트가 충돌해서 결국 thread로 press/release 상태를 측정했다.
cmd_button_check()
: 커스텀 객체가 아닌, 기본 Thread
객체를 만들어서 interval 마다 주기적으로 실행할 함수를 정의했다. COMMAND_XXX
는 값이 바뀌지 않는 한 mqtt 송신을 한 번만 보내도록 하기 위해 만든 bool 변수로 volatile
키워드를 추가해 과하게 똑똑한 컴파일러의 방해(!)를 차단했다.command_all_false()
를 통해 함수 하나를 호출하면서 상태 bool 값을 모두 false로 만들고, 입력된 커맨드에 따라 하나씩 수정하는 식으로 재사용했다. #define GO_BUTTON 18 // the number of the go button pin
#define BACK_BUTTON 19 // the number of the back button pin
// ... EspMQTTClient 코드
// ... mpu6050 값을 읽을 스레드 클래스 관련 코드
// ... mqtt 송신용 tx() 함수
// ...
// 한 번만 보내기 위한 flg 변수
volatile bool COMMAND_GO = false,
COMMAND_BACK = false,
COMMAND_STOP = false,
COMMAND_LEFT_MIN = false,
COMMAND_LEFT_MAX = false,
COMMAND_RIGHT_MIN = false,
COMMAND_RIGHT_MAX = false,
COMMAND_MID = false;
void command_all_false(void) {
COMMAND_GO = false;
COMMAND_BACK = false;
COMMAND_STOP = false;
}
// 스레드가 설정된 interval에 맞춰 주기적으로 실행할 함수
void cmd_button_check(void) {
if (digitalRead(GO_BUTTON) == LOW && !COMMAND_GO) {
// Serial.println("go");
tx(CMD_TOPIC, "go");
command_all_false();
COMMAND_GO = true;
} else if (digitalRead(BACK_BUTTON) == LOW && !COMMAND_BACK) {
// Serial.println("back");
tx(CMD_TOPIC, "back");
command_all_false();
COMMAND_BACK = true;
} else if (digitalRead(GO_BUTTON) == HIGH && digitalRead(BACK_BUTTON) == HIGH && !COMMAND_STOP) {
// Serial.println("stop");
tx(CMD_TOPIC, "stop");
command_all_false();
COMMAND_STOP = true;
}
}
loop
에서 controller.run()
을 해주면 등록된 스레드 객체가 모두 start/run 된다.// create thread
Thread cmd_th = Thread()
// ... thread controller 관련 코드
void setup(void) {
// ... serial monitor begin
// ... mqtt client enable
// command (go/back) button
pinMode(GO_BUTTON, INPUT_PULLUP);
pinMode(BACK_BUTTON, INPUT_PULLUP);
// callback thread func
cmd_th.onRun(cmd_button_check);
cmd_th.setInterval(50);
// ... mpu thread add to thread controller
// cmd thread add to thread controller
controller.add(&cmd_th);
// ... mpu init code
}