[아두이노] 시간(시/분/초) 변환
[아두이노] 시간(시/분/초) 변환
- 온라인 가상시뮬레이터 : https://www.tinkercad.com
- 참고 :
[아두이노] 시간 millis()함수로 읽은 숫자 쪼개기
[아두이노] 시간 millis()함수로 시간 카운트 - 공개회로도 :
https://www.tinkercad.com/things/eyAI1iP1V3R (초 변환)
https://www.tinkercad.com/things/l0EI3eJgoHR (시간 분리)
https://www.tinkercad.com/things/esLSzgrWHWG (시간 변환)
오늘은 시간 변환을 실험을 하겠습니다. 초를 입력하여 시/분/초로 변환하는 실험과 문자열 시/분/초를 입력하여 시간, 분, 초로 분리해내는 실험을 하겟습니다 이 원리를 기반으로 시/분/초를 초로 변환시키 후 변환 시킨 초를 기준으로 시/분/초로 다시 원상 복구하여 시간 변환 코딩이 정상적으로 이루어지는지 실험 하겠습니다.
이제 본격적으로 실험을 해볼까요.
1. 초를 시/분/초로 변환
- 공개회로도 : https://www.tinkercad.com/things/eyAI1iP1V3R (초 변환)
초를 시/분/초로 변환식 :
readTime = 입력Sec;
sec = 전체수 % 60;
min = (전체수/60)%60;
hour = (전체수/(60x60)%24;
day = (전체수/(60x60x24)%365;
...
1분 = 60초
1시간 = 60x60초
1day = 60x60x24초
시리얼모니터에서 초를 입력하면,
1 2 3 | if (Serial.available()){ unsigned long readTime = Serial.parseInt(); } |
아두이노에서 parseInt()로 간단히 읽는다. 총 15자리 수까지 입력받을 수 있다.
계산은,
1 2 3 | sec = readTime% 60 ; min = (readTime/ 60 )% 60 ; hour = (readTime/( 60 * 60 ))% 24 ; |
시/분/초만 출력하게 하기 위해서는 위 코딩과 같이 표현하시면 됩니다. 참고로, 24시간 이상이면 day까지 구하면 좋지만 그냥 day은 무시하고 시계처럼 시/분/초만 출력합니다.
[소스]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | int hour, min, sec; void setup() { Serial.begin( 9600 ); } void loop() { //초 입력 if (Serial.available()){ unsigned long readTime = Serial.parseInt(); sec = readTime% 60 ; min = (readTime/ 60 )% 60 ; hour = (readTime/( 60 * 60 ))% 24 ; Serial.print(hour); Serial.print( " : " ); Serial.print(min); Serial.print( " : " ); Serial.println(sec); } } |
[결과]
2. 시/분/초 문자열에서 시간 분리
- 사전학습 : [아두이노] Serial 통신 때 String 사용
- 공개회로도 : https://www.tinkercad.com/things/l0EI3eJgoHR (시간 분리)
입력 => "시:분:초"
위와같이 시/분/초로 입력 받는 다면 어떻게 표현 할까요. 위에 사전학습에서 String에 대해 사전학습을 미리 해 주세요.
시간 문자열을 분리해 내는 방법을 간단히 복습해 봅시다.
String inString = "10:11:22"
위 문자열을 "시:분:초"를 어떻게 분리해 낼까요. 시/분/초의 문자열을 나누는 기호가 ':'입니다. 즉, ':'의 위치를 알고 있으면 이 위치를 기준으로 시/분/초를 읽으면 됩니다.
1 2 3 | int index1 = inString.indexOf( ':' ); int index2 = inString.indexOf( ':' ,index1+ 1 ); int index3 = inString.length(); |
- indexOf(':') : ':'의 기호가 있는 위치
- index(':',검색시작위치) : 검색시작위치부터 ':'의 기호가 있는 위치
이렇게 index들을 구하면 즉, 문자열에서 수자를 읽을 마지막 위치값을 지정할 수 있습니다.
"10:11:22"
index1 = 2
index2 = 5
index3 = 8
index3이 7이 아니고 8인 이유는 문자열은 마지막 끝을 나타내는 문자기호가 포함되어 있기 때문에 index가 8입니다.
이제 위치값을 알았으니깐 시/분/초를 구해 볼까요.
1 2 3 | hour = inString.substring( 0 , index1).toInt(); min = inString.substring(index1+ 1 ,index2).toInt(); sec = inString.substring(index2+ 1 ,index3).toInt(); |
- substring(시작위치,마지막위치) : 특정부분문자열 추출
- toInt() : 문자열을 정수형으로 변환
inString.substring(0, index1).toInt();
위 명령은 전체문자열에서 특정부분문자열을 추출하고 그 추출된 문자열을 정수형으로 변환시킨다는 명령입니다. hour, min, sec를 이 명령으로 시/분/초를 구할 수 있게 됩니다.
정확히 시/분/초가 분리되었는지 살펴 볼까요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | void setup() { Serial.begin( 9600 ); } void loop() { // 시:분:초 입력 if (Serial.available()){ String inString = Serial.readStringUntil( '\n' ); int index1 = inString.indexOf( ':' ); int index2 = inString.indexOf( ':' ,index1+ 1 ); int index3 = inString.length(); int hour = inString.substring( 0 , index1).toInt(); int min = inString.substring(index1+ 1 ,index2).toInt(); int sec = inString.substring(index2+ 1 ,index3).toInt(); Serial.print(hour); Serial.print( " : " ); Serial.print(min); Serial.print( " : " ); Serial.println(sec); } } |
[결과]
위 그림처럼 시/분/초를 입력한 문자열이 제대로 분리되어 정확히 시/분/초가 출력 됩니다.
3. 시/분/초 입력값을 초 변환 후 다시 시/분/초 변환
- 공개회로도 : https://www.tinkercad.com/things/esLSzgrWHWG (시간 변환)
이번에는 시/분/초를 입력 받은 후에 그 값을 초로 변환 시킵니다. 그리고 그 초 값을 다시 시/분/초로 변환하여 결과를 살펴보겠습니다. 시간 변환을 잘 이루어지는 살펴보기 위한 실험입니다.
시/분/초를 입력받은 문자열을 초로 변환하기 위해서는 다음과 같습니다.
totalSec = 시*3600 + 분*60 + 초;
시간 문자열을 읽어서 hour, min, sec 값을 분리 해내고 초로 변환하면 다음과 같이 코딩을 하면 되겠죠.
1 2 3 4 5 6 7 8 9 10 11 12 | if (Serial.available()){ String inString = Serial.readStringUntil( '\n' ); int index1 = inString.indexOf( ':' ); int index2 = inString.indexOf( ':' ,index1+ 1 ); int index3 = inString.length(); hour = inString.substring( 0 , index1).toInt(); min = inString.substring(index1+ 1 ,index2).toInt(); sec = inString.substring(index2+ 1 ,index3).toInt(); readTime = ( long )hour* 3600 +min* 60 +sec; } |
위 코딩 식의 의해서 readTime 총 sec 값을 저장하게 됩니다.
다시, readTime 시/분/초 변환을 시켜서 계산 상 아무런 문제가 없는지 확인해 봅시다.
1 2 3 4 | readTime = ( long )hour* 3600 +min* 60 +sec; sec = readTime% 60 ; min = (readTime/ 60 )% 60 ; hour = (readTime/( 60 * 60 ))% 24 ; |
이렇게 다시 hour, min, sec 구하여 이 값이 시리얼모니터로 출력시키면 확인이 가능해 집니다.
[소스]
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 | unsigned long readTime; int hour, min, sec; void setup() { Serial.begin( 9600 ); } void loop() { if (Serial.available()){ String inString = Serial.readStringUntil( '\n' ); int index1 = inString.indexOf( ':' ); int index2 = inString.indexOf( ':' ,index1+ 1 ); int index3 = inString.length(); hour = inString.substring( 0 , index1).toInt(); min = inString.substring(index1+ 1 ,index2).toInt(); sec = inString.substring(index2+ 1 ,index3).toInt(); readTime = ( long )hour* 3600 +min* 60 +sec; Serial.print( "Total Sec : " ); Serial.println(readTime); sec = readTime% 60 ; min = (readTime/ 60 )% 60 ; hour = (readTime/( 60 * 60 ))% 24 ; Serial.print(hour); Serial.print( " : " ); Serial.print(min); Serial.print( " : " ); Serial.println(sec); } } |
[결과]
위 결과를 보면 "11:22:33" 시간이 입력되면 시간에 대한 초 변환 값 '40953'값이 나왔고 이 값을 다시 시/분/초로 변환하면 "11:22:33" 시간이 나옵니다. 시간 변환이 깔끔하게 되었네요.
마무리
오늘은 시간에 대한 코딩 트레이닝을 하였습니다. 아두이노에서 시간를 다룰 줄 알면 시간에 관한 다양한 표현을 할 수 있습니다. 오늘 배운 원리를 이해하시면 아두이노 시계를 만들 수 있습니다. 아두이노에 전원을 공급하고 현재 시간값을 입력하여 millis()함수를 이용하면 아두이노 시계를 만들 수 있습니다.
지난 시간에는 millis()함수로 시간값을 분리하고 카운트하는 방법을 살펴보았으며 오늘은 시간 변환을 살펴보았습니다. 한번 지끔까지 배운 원리를 종합하여 아두이노 시계를 만들어 보세요.
'IOT > 아두이노' 카테고리의 다른 글
[아두이노] 2-Digit 7-Segment Display (0) | 2019.06.13 |
---|---|
[아두이노] 시간 millis() 함수로 시계 코딩 (0) | 2019.06.07 |
[아두이노] 시간 millis()함수로 시간 카운트 (0) | 2019.06.05 |
[아두이노] 시간 millis()함수로 읽은 숫자 쪼개기 (0) | 2019.06.04 |
[아두이노] 온도센서를 이용한 경보 온도계 다른 접근 (0) | 2019.06.03 |