반응형

먼저 이전에 만들었던 타이머 부터 살펴보자.

기본적인 타이머는 구현이 되었으나 원하는 시간을 설정하기 위해서는 코드를 수정하여야 했다.

여기에 가변저항을 추가하여 타이머 시간을 코드수정없이 바꾸어보자


https://developmentdiary.tistory.com/564


여기서 가변저항을 추가하고 코드를 추가해보았다.

3번 눌렀을때 시간 수정모드로 들어가는 부분을 추가로 구현하였다.


동작방식

1번 누를시 시작,정지

2번 누를시 초기화 후 정지

3번 누를시 가변저항을 이용하여 시간조절 완료되면 버튼을 한번 더 눌러 저장



회로도




코드


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
//스레드 라이브러리 추가 및 기본
//https://answerofgod.tistory.com/654
 
#include <Arduino_FreeRTOS.h>
#include <TM1637Display.h> // Tm1637 module
 
// TM1637 Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3
TM1637Display display(CLK, DIO);
int speakerpin = 12//스피커가 연결된 디지털핀 설정
int sw=4;//스위치핀 설정
int resiPin = 0;//가변저항 핀설정
int states=0;
int counts=0;
char turnon='0';
char check='1';
 
 
 
unsigned long cnt=0;//버튼눌리는 시간간의 거리
 
 
const uint8_t SEG_DONE[] = {
  SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,           // d
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
  SEG_C | SEG_E | SEG_G,                           // n
  SEG_A | SEG_D | SEG_E | SEG_F | SEG_G            // E
  };
 
 
// time calc
#define numberOfSeconds(_time_) ((_time_ / 1000) % 60)
#define numberOfMinutes(_time_) ((_time_ / 1000/ 60)
// hold time selected in ms.
unsigned long timeLimit = 3000000;// 1000*60*50 = 50분
int timer=0;
 
 
 
void setup() {
 Serial.begin(9600);
 
  //display setup
  display.setBrightness(0);    // LED 밝기조정   0~6
  //display.setBrightness(0x0c);
  display.showNumberDecEx(00x40true);    //64
  pinMode(sw, INPUT);
 
  xTaskCreate(  vTask1,   /* Pointer to the function that implements the task. */
    "Task 1"/* Text name for the task.  This is to facilitate debugging only. */
    200,    /* Stack depth - most small microcontrollers will use much less stack than this. */
    NULL,   /* We are not using the task parameter. */
    1,      /* This task will run at priority 1. */
    NULL );   /* We are not using the task handle. */
 
  /* Create the other task in exactly the same way. */
  xTaskCreate( vTask2, "Task 2"200NULL1NULL );
 
 
  vTaskStartScheduler();
 
  for( ;; );
//  return 0;
}
/*-----------------------------------------------------------*/
 
void vTask1( void *pvParameters )
{
  /* As per most tasks, this task is implemented in an infinite loop. */
  for( ;; )
  {
    for (long i = 0; i <= timeLimit; i=i+1000)   // data type을 long 으로
    {
 
 
      if(check=='3'){//3번누를시 시간조절
        i=0;
        //가변저항에 맞게 timeLimit설정
        long a=long(analogRead(resiPin))*6000;
        timeLimit=a;
        int minutes = numberOfMinutes(timeLimit);
        display.showNumberDecEx(00true,2,2) ;
        display.showNumberDecEx(minutes, (0x80 >> 1), false20) ;  // turn on colon    원본은  0x80 >> 3 인데 콜론이 on 되지 않아 0x80 >> 1 로 변경
        timeLimit=minutes*60000;
        //설정후 정지상태
        turnon='0';
        continue;
      }
    // To display the countdown in mm:ss format, separate the parts
      if(check=='2'){//두번누를시 초기화
        i=0;
        int seconds = numberOfSeconds(i);
        int minutes = numberOfMinutes(i);
        display.showNumberDecEx(seconds, 0true,2,2) ;
        display.showNumberDecEx(minutes, (0x80 >> 1), false20) ;  // turn on colon    원본은  0x80 >> 3 인데 콜론이 on 되지 않아 0x80 >> 1 로 변경
        //초기화 설정 후 정지상태로 대기
        turnon='0';
        check='1';
        //continue;
      }
     while(turnon=='0'&&check=='1'){  //일시정지//
        delay(100);
     }
    
     //showNumberDecEx(표시할번호,도트,선행제로,설정할 자릿수,위치 최하위 숫자(0-맨왼쪽 ,3맨오른쪽)); 
    //https://sminghub.github.io/Sming/api/classTM1637Display.html#a37c8b71de1418f1b545782b722d7277a
    /*도트
    0.000 (0b10000000)
    00.00 (0b01000000)
    000.0 (0b00100000)
    0.0.0.0 (0b11100000) 콜론 만있는 디스플레이의 경우 :
    00:00 (0b01000000) 점과 콜론 콜론이있는 디스플레이의 경우 :
    0.0 : 0.0 (0b11100000)
     * 
     */
    int seconds = numberOfSeconds(i);//시간표시
    int minutes = numberOfMinutes(i); 
    display.showNumberDecEx(seconds, 0true,2,2) ;
    // Display the minutes in the first two places, with colon
    display.showNumberDecEx(minutes, (0x80 >> 1), false20) ;  // turn on colon    원본은  0x80 >> 3 인데 콜론이 on 되지 않아 0x80 >> 1 로 변경
    delay(950);//동작시간이 50정도 소요되서 1000-50=950
      
  }
 
   if(check!='3'){
    display.setSegments(SEG_DONE);//시간다됬을시 done표시
    tone(speakerpin, 500,3000);//3초동안 부저울림(핀,소리음,소리지속시간)
    delay(2000);
    //종료후 정지상태로 대기
    turnon='0';
    check='1';
   }
 
 
  }
}
/*-----------------------------------------------------------*/
 
void vTask2( void *pvParameters )
{
 
  /* As per most tasks, this task is implemented in an infinite loop. */
  for( ;; )
  {
    if (digitalRead(sw) && counts==0 && cnt==0)//디지털핀에서 신호를 받았을때 
  {
    cnt=millis();//현재시간
    counts++;//누른횟수
  }
  else if (millis() > cnt+500 && cnt>0)//0.5초안에 버튼을 누르지 않고 1번이상 눌럿을때
  {
    states=counts;//누른횟수 저장
    counts=0;//카운트 초기화
    cnt=0;
  }
  else if (digitalRead(sw) && millis() > cnt+300)//0.2초안에 한번더 눌리면 이건 조절이 필요할수도 있다.
  {
    cnt=millis();//시간초기화
    counts++;//카운트증가
 
    if (counts >= 3)
    {
      counts=3;//3번이상이면 카운트3
    }
  }
 
   switch (states)
  {
    case 0:
    break;
    case 1:
     if (turnon=='0'){
      turnon='1';
     }else{
      turnon='0';
     }
     check='1';
     states=0;
    break;
    case 2:
     check='2';     
     turnon='0';//초기화
     states=0;
    break;
    case 3:
     check='3';
    break;
  }
 
  }
}
 
 
  /*------------------------------------------------------------*/
 
void loop() {}

cs



#가변저항

간단히 analogRead(연결아날로그핀) 함수를 통해 얻을수 있다.

레지스터 모듈의 저항값은 0~1023까지이다.

모듈마다 조금씩 다른거같다. 필자의 경우 700까지밖에 돌아가지 않았다.

가변저항이 일정하게 유지되지는 않아서 초단위의 타이머는 힘들거같다.


#피에조 부저를 이용한연주

알림소리가 너무 단조롭다면 알림을 바꿔보는것도 좋을거 같다.

코드는 따로 올리지 않겠지만 원하는 음악을 찾아보는것도 좋을거 같다.

https://m.blog.naver.com/PostView.nhn?blogId=gu04005&logNo=221127412642&proxyReferer=https:%2F%2Fwww.google.com%2F

이렇게 MIDI파일을 아두이노 코드로 담을수도 있다. 해보면 썩 좋은 소리가 나지는 않지만 알아들을 수 있을정도는 나오는거 같다.


pitches.h 파일

pitches.h



해당 파일은 음계를 표시해놓은 파일로 프로젝트 폴더 안에 넣으면 된다.


위 사이트에서 알려주었듯이 midi파일에서 키값을 추출한후 코드를 한줄로 만드는 것은 notepad++를 이용하여 ctrl+h를 통해 \r\n 을 찾은후 모두 바꾸기를 누르면 쉽게 가능하다.


더 구현해 보고 싶은것이 생기면 추가할 생각이다 . 끝!






반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기