본문 바로가기

이론/AVR

무이메이커스_[ arduino] 아두이노 원터치 LED제어(버튼/터치센서 한개로 LED제어)

안녕하세요 헬스케어 제품 개발회사 허니컴의 무이메이커스 입니다.

오늘은 버튼 또는 터치센서 한개로 LED의 on/off, 밝기제어를 해보도록 하겠습니다.

아래 영상에서는 터치센서로 동작하였지만, 버튼으로도 같은 동작이 가능합니다. 같은 코드에 아래있는 회로도중에 버튼이 포함된 회로도로 동작하면 됩니다.

 

< 예상동작 >

1. LED가 꺼져있을 때 버튼을 짧게 누르면 on

LED가 켜있을 때 버튼을 짧게 누르면 off

2. LED가 꺼져있을 때

버튼을 길게 누르면 동작없음

LED가 켜져있을 때

버튼을 길게 누르면 밝기변화 시작

3. 밝기변화 도중에 버튼에서 손을 떼면

그 당시 밝기에서 멈춤

4. 다시 버튼을 길게 누르면 멈췄던 밝기에서

밝기변화 시작

 

 

< 아두이노 원터치 LED제어 회로도

                               - 버튼/터치센서 한개로LED제어 >

1) 터치센서 1개로 LED제어 - on/off , 밝기제어, 밝기유지

 

 

2) 버튼 1개로 LED제어 - on/off , 밝기제어, 밝기유지

 

 

< 아두이노 원터치 LED제어 연결방법 터치센서ver.

                                                      - 버튼/터치센서 한개로LED제어 >

 

아두이노

터치센서

LED

5V

Vcc

GND

GND

- (cathode)

D9

+ (anode)

D2, A2

SIG

 

 

 

< 아두이노 원터치 LED제어 코드

                                     - 버튼/터치센서 한개로LED제어 >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#include<util/delay.h>
 
const int ledpin = 9//led출력핀
 
const int inpin = 16//버튼 입력핀, A2
 
const byte interruptPin = 2;
 
 
 
volatile int count=0// 버튼 눌린 횟수
 
 
 
volatile int state = LOW;  //stores if the switch was high before at all
 
volatile int state_short = LOW;  //storing the button state for short press mode
 
volatile int state_long = LOW;  //storing the button state for long press mode
 
 
 
volatile unsigned long current_high;
 
volatile unsigned long current_low;
 
 
 
static unsigned long startTime = 0//스위치 누를때의 시간 
 
int i=0, f;
 
int bright=0;
 
int longtime=0;
 
 
 
void read_button() //버튼과 버튼사이의 간격이 짧다, 길다를 구분
 
 
  _delay_ms(100);
 
  if(digitalRead(inpin) == HIGH && state == LOW)      //버튼 안눌린 상태
 
  { 
 
    current_high = millis(); //버튼을 에서 손을 뗀시간
 
      state = HIGH;
 
    //return 0;
 
 
 
    if(current_low==0)
 
      state_long=HIGH;
 
  }
 
  
 
   if(digitalRead(inpin) == LOW && state == HIGH)  //버튼 눌린 상태    
 
  { 
 
    current_low = millis();  //버튼을 누른시간
 
    count += 1//버튼 눌린횟수를 count가 가짐
 
    if((current_low - current_high) > 1 && (current_low - current_high) < 300//버튼을 두번 눌렀을 때 버튼간의 간격이 짧다
 
    {
 
      state_short = HIGH;
 
       
 
      state = LOW;
 
    }
 
    else if((current_low - current_high) >= 300//버튼을 두번 눌렀을 때 버튼간의 간격이 길다
 
    {
 
      state_long = HIGH;
 
      state = LOW;
 
    }
 
  }
 
}
 
 
 
long switchTime() //스위치가 눌렸으면 눌린 시간을 리턴함, 눌리지 않았으면 0을 리턴함
 
{
 
  static boolean state_2;                
 
 
 
  if (digitalRead(inpin) != state_2) 
 
  {
 
    state_2 = ! state_2;       
 
     startTime = millis();  
 
  }
 
  if (state_2 == LOW)
 
    return millis() - startTime;   
 
                                   
 
  else
 
    return 0
 
}
 
 
 
void setup() 
 
{
 
  pinMode(ledpin, OUTPUT); 
 
  digitalWrite(ledpin, LOW);
 
  pinMode(inpin, INPUT);
 
  attachInterrupt(digitalPinToInterrupt(interruptPin), read_button, CHANGE);
 
  Serial.begin(9600);
 
}
 
 
 
void loop()
 
 
  int stime = switchTime(); //스위치 눌린시간
 
  
 
//////////////////////////////////////////on, off//////////////////////////////////////////////////////////
 
  if(current_high > 0 && stime<450//짧게 누른 후 버튼을 뗀 순간
 
  { 
 
    if(digitalRead(ledpin)==1//led가 켜져있으면 끄고
 
      digitalWrite(ledpin, LOW);
 
      
 
    else if(digitalRead(ledpin)==0//led가 꺼져 있으면 킨다
 
        digitalWrite(ledpin,HIGH);
 
  }
 
      
 
//////////////////////////////////on,off 끝/////////////////////////////////////////////////////////////////      
 
 
 
//////////////////////////////////밝기변화////////////////////////////////////////////////////////////////////   
 
 
 
  else if(stime >= 450//길게 눌렸을 때 
 
  { 
 
    if( digitalRead(ledpin)==0 )  //불이 꺼져있으면 끈상태유지
 
    {  Serial.println("!!");
 
        i=bright;
 
        if(f!=1//밝기변화가 '최고까지증가~최소까지감소'의 동작이 한번도 없었으면, 불이 꺼져있을때 끈상태를 유지한다
 
          digitalWrite(ledpin, LOW);
 
          
 
 
 
        else if(f==1//밝기변화가 '최고까지증가~최소까지감소'의 동작이 한번이라도 있었으면,led에 불을켜서 아래의 else if문에 해당되게하여 밝기변화를 반복한다
 
          digitalWrite(ledpin, HIGH);
 
    }
 
   
 
    else if(i<=255)  // 길게눌렀는데 i가 255보다 작을 때, 밝기 증가
 
    { 
 
      i++;
 
      analogWrite(ledpin,i);
 
      delay(10);
 
      bright=i; 
 
    }
 
    
 
    else if(i>255 && bright>0// 길게 누르고 밝기증가 끝났을 때, 밝기 감소
 
    { 
 
      bright--;
 
      analogWrite(ledpin,bright);
 
      delay(10);
 
      if(bright==1//밝기가 최소로되면 flag표시를 한다.
 
        f=1;
 
    }
 
 
 
  }
 
  current_high = 0;  //인터럽터가 끝나고나면 버튼 뗀순간의 값초기화
 
  current_low = 0;  //인터럽터가 끝나고나면 버튼 누른순간의 값초기화
 
}
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

 

 

 

 

< 아두이노 원터치 LED제어 코드설명

                                               - 버튼/터치센서 한개로LED제어 >

 

            loop 처음에 호출되는 switchTime()은

            스위치가 눌리지 않았을 때에는 0을 리턴하고,

                                                        스위치가 눌렸을 때에는 눌린 시간을 리턴합니다.

 

 

 

 

버튼을 짧게 누른 시간은 switchTime()에서 리턴된 값인 stime으로 판단합니다.

stime이 450 미만이면 짧게 누른 버튼으로 판단하고, 450이상이면 길게누른 버튼으로 판단합니다.

current_high는 버튼이 눌렸을 때 인터럽트가 호출되어 read_button()이 실행될 때 값을 가지게 됩니다.

current_high는 아두이노가 시작된 후 경과된 시간중에 버튼을 눌렀다가 뗀 순간의 값을 가지고 있습니다.

즉, 위 부분은 버튼을 눌렀다가 뗀 후 버튼누른시간이 짧을때

led가 켜져있으면 끄고, 꺼져있으면 키는 동작을 수행합니다.

 

 

 

 

 

 

 

 

위 부분은 "else if(stime >= 450)" 안에 포함되어 있습니다.

i는 LED에 출력할 밝기를 의미합니다. 0~255중에 숫자가 클 수록 밝은 밝기를 가집니다.

버튼이 길게 눌렸을 때 i의 밝기가 최대밝기가 아니면 밝기를 증가 시킵니다.

그 후 현재밝기는 bright에 저장합니다.

최대밝기가 되었을 때 i의 값은 256이 됩니다.

버튼이 길게 눌렸을 때 led가 최대밝기가 된다면 bright를 감소해 led에 출력합니다.

밝기가 감소될 때에는 bright가 led에 출력되는 숫자 즉, 밝기 입니다.

밝기가 최소로 감소하면 f에 1을 대입하는 방식으로 flag를 표시합니다.

 

 

 

 

 

 

 

버튼을 길게 눌렀을 때

밝기변화가 '최고까지증가~최소까지감소'의 동작이 한번도 없었으면, 불이 꺼져있을때 끈상태를 유지합니다.

버튼을 길게 눌렀을 때

밝기변화가 '최고까지증가~최소까지감소'의 동작이 한번이라도 있었으면, 밝기변화를 반복합니다.

 

 

 

 

 

< 아두이노 원터치 LED제어 영상

                                            - 버튼/터치센서 한개로LED제어 >

 

 

 

 

 

 

 

.....................................................................................................................................................

시제품 제작 문의