아두이노에서 푸쉬버튼 스위치의 long press와 short press를 구분하기 위해서는 스위치가 눌린 시간을 기록해 놓은 다음 눌린 스위치가 떨어질 때 스위치가 눌려있던 기간을 계산해 특정 시간보다 짧으면 short press, 길면 long press로 판단 해 주면 된다.
이번 실험을 위해 연결한 회로이다. 13번 핀에 시스템이 동작하는지 확인하기 위한 heartbeat LED를 연결 해 주고 4번 핀에 푸쉬버튼 스위치를 연결해 주었다. 4번 핀의 pinMode로 INPUT_PULLUP을 사용할 것이기 때문에 추가로 저항을 연결할 필요는 없다.
#define SW 4
#define RELEASED 0
#define SHORT_PRESS 1
#define LONG_PRESS 2
#define SW_THRESHOLD 500
#define HB_LED 13
void setup() {
pinMode(HB_LED, OUTPUT);
pinMode(SW, INPUT_PULLUP);
Serial.begin(115200);
}
void loop() {
static boolean hbLedStat = LOW;
static unsigned long last;
int swState = readSw();
if (SHORT_PRESS == swState) {
Serial.println("SWITCH SHORT PRESSED");
} else if (LONG_PRESS == swState) {
Serial.println("SWITCH LONG PRESSED");
}
if ((millis()-last) >= 500) {
digitalWrite(HB_LED, hbLedStat);
hbLedStat = !hbLedStat;
last = millis();
}
}
int readSw()
{
static boolean prev = HIGH;
static unsigned long last, pressed;
boolean curr;
if ((millis()-last) >= 10) {
curr = digitalRead(SW);
if ((HIGH==prev)&&(LOW==curr)) {
pressed = millis();
prev = LOW;
} else if ((LOW==prev)&&(HIGH==curr)) {
prev = HIGH;
if ((millis()-pressed) > SW_THRESHOLD) {
return LONG_PRESS;
} else {
return SHORT_PRESS;
}
}
last = millis();
}
return RELEASED;
}
코드는 위와 같다. 프로그램이 실행되면 heartbeat LED는 1초 간격으로 계속 깜빡이고 스위치를 눌렀다 떼면 누르고 있던 시간 길이에 따라 short press, long press를 판정해 시리얼 포트로 결과를 출력해 준다.
2017년 5월 9일 화요일
아두이노 실습] Push button 스위치로 FND 카운트 증가/감소
2개의 push button으로 FND의 숫자 카운트를 up/down 시키는 실습
회로도...여기서는 Common Anode 타입의 FND를 사용
브레드보드 연결도
4번핀에 연결된 스위치로 숫자 카운트를 up, 5번핀에 연결된 스위치로 숫자 카운트를 down하는 스케치
#define FND_A 13
#define FND_B 12
#define FND_C 11
#define FND_D 10
#define FND_E 9
#define FND_F 8
#define FND_G 7
#define FND_DP 6
#define UP 4
#define DN 5
#define dW digitalWrite
#define ON LOW
#define OFF HIGH
int gCnt = 0;
void setup() {
for (int i=6;i<14;i++) pinMode(i, OUTPUT);
pinMode(UP, INPUT_PULLUP);
pinMode(DN, INPUT_PULLUP);
}
void loop() {
readUpSw(); // UP 스위치 처리
readDnSw(); // DOWN 스위치 처리
dispFnd(gCnt);
}
void dispFnd(int val)
{
static int prevVal = -1;
if (prevVal != val) { // FND에 표시할 값이 바뀐 경우에만 표시를 변경
switch (val) {
case 0:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, ON); dW(FND_G, OFF);
break;
case 1:
dW(FND_A, OFF); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, OFF); dW(FND_E, OFF); dW(FND_F, OFF); dW(FND_G, OFF);
break;
case 2:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, OFF); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, OFF); dW(FND_G, ON);
break;
case 3:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, OFF); dW(FND_F, OFF); dW(FND_G, ON);
break;
case 4:
dW(FND_A, OFF); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, OFF); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, ON);
break;
case 5:
dW(FND_A, ON); dW(FND_B, OFF); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, ON);
break;
case 6:
dW(FND_A, ON); dW(FND_B, OFF); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, ON); dW(FND_G, ON);
break;
case 7:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, OFF); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, OFF);
break;
case 8:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, ON); dW(FND_G, ON);
break;
case 9:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, ON);
break;
}
prevVal = val;
}
}
boolean readUpSw()
{
static boolean prev = HIGH;
static unsigned long last;
boolean curr;
if ((millis()-last)>10) {
curr = digitalRead(UP);
if ((HIGH==prev)&&(LOW==curr)) { // UP SW가 눌린 시점
gCnt = (gCnt+1)%10;
}
prev = curr;
last = millis();
}
}
boolean readDnSw()
{
static boolean prev = HIGH;
static unsigned long last;
boolean curr;
if ((millis()-last)>10) {
curr = digitalRead(DN);
if ((HIGH==prev)&&(LOW==curr)) { // DOWN SW가 눌린 시점
gCnt = gCnt-1;
if (-1 == gCnt) gCnt = 9;
}
prev = curr;
last = millis();
}
}
회로도...여기서는 Common Anode 타입의 FND를 사용
브레드보드 연결도
4번핀에 연결된 스위치로 숫자 카운트를 up, 5번핀에 연결된 스위치로 숫자 카운트를 down하는 스케치
#define FND_A 13
#define FND_B 12
#define FND_C 11
#define FND_D 10
#define FND_E 9
#define FND_F 8
#define FND_G 7
#define FND_DP 6
#define UP 4
#define DN 5
#define dW digitalWrite
#define ON LOW
#define OFF HIGH
int gCnt = 0;
void setup() {
for (int i=6;i<14;i++) pinMode(i, OUTPUT);
pinMode(UP, INPUT_PULLUP);
pinMode(DN, INPUT_PULLUP);
}
void loop() {
readUpSw(); // UP 스위치 처리
readDnSw(); // DOWN 스위치 처리
dispFnd(gCnt);
}
void dispFnd(int val)
{
static int prevVal = -1;
if (prevVal != val) { // FND에 표시할 값이 바뀐 경우에만 표시를 변경
switch (val) {
case 0:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, ON); dW(FND_G, OFF);
break;
case 1:
dW(FND_A, OFF); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, OFF); dW(FND_E, OFF); dW(FND_F, OFF); dW(FND_G, OFF);
break;
case 2:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, OFF); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, OFF); dW(FND_G, ON);
break;
case 3:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, OFF); dW(FND_F, OFF); dW(FND_G, ON);
break;
case 4:
dW(FND_A, OFF); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, OFF); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, ON);
break;
case 5:
dW(FND_A, ON); dW(FND_B, OFF); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, ON);
break;
case 6:
dW(FND_A, ON); dW(FND_B, OFF); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, ON); dW(FND_G, ON);
break;
case 7:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, OFF); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, OFF);
break;
case 8:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, ON); dW(FND_F, ON); dW(FND_G, ON);
break;
case 9:
dW(FND_A, ON); dW(FND_B, ON); dW(FND_C, ON); dW(FND_D, ON); dW(FND_E, OFF); dW(FND_F, ON); dW(FND_G, ON);
break;
}
prevVal = val;
}
}
boolean readUpSw()
{
static boolean prev = HIGH;
static unsigned long last;
boolean curr;
if ((millis()-last)>10) {
curr = digitalRead(UP);
if ((HIGH==prev)&&(LOW==curr)) { // UP SW가 눌린 시점
gCnt = (gCnt+1)%10;
}
prev = curr;
last = millis();
}
}
boolean readDnSw()
{
static boolean prev = HIGH;
static unsigned long last;
boolean curr;
if ((millis()-last)>10) {
curr = digitalRead(DN);
if ((HIGH==prev)&&(LOW==curr)) { // DOWN SW가 눌린 시점
gCnt = gCnt-1;
if (-1 == gCnt) gCnt = 9;
}
prev = curr;
last = millis();
}
}
Labels:
아두이노,
아두이노 실습,
arduino,
Debouncing,
FND,
push button
피드 구독하기:
글 (Atom)



