[아두이노] 시간(시/분/초) 변환

IOT/아두이노|2019. 6. 6. 09:00

[아두이노] 시간(시/분/초) 변환



오늘은 시간 변환을 실험을 하겠습니다. 초를 입력하여 시/분/초로 변환하는 실험과 문자열 시/분/초를 입력하여 시간, 분, 초로 분리해내는 실험을 하겟습니다 이 원리를 기반으로 시/분/초를 초로 변환시키 후 변환 시킨 초를 기준으로 시/분/초로 다시 원상 복구하여 시간 변환 코딩이 정상적으로 이루어지는지 실험 하겠습니다.


이제 본격적으로 실험을 해볼까요.

1. 초를 시/분/초로 변환



초를 시/분/초로 변환식 :

readTime = 입력Sec;

sec = 전체수 % 60;
min = (전체수/60)%60;
hour = (전체수/(60x60)%24;
day = (전체수/(60x60x24)%365;
...


1분 = 60초
1시간 = 60x60초
1day = 60x60x24초


시리얼모니터에서 초를 입력하면,

  if(Serial.available()){
    unsigned long readTime = Serial.parseInt();    
  }

아두이노에서 parseInt()로 간단히 읽는다. 총 15자리 수까지 입력받을 수 있다.

계산은,

    sec = readTime%60;
    min = (readTime/60)%60;
    hour = (readTime/(60*60))%24;       

시/분/초만 출력하게 하기 위해서는 위 코딩과 같이 표현하시면 됩니다. 참고로, 24시간 이상이면 day까지 구하면 좋지만 그냥 day은 무시하고 시계처럼 시/분/초만 출력합니다.

[소스]

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. 시/분/초 문자열에서 시간 분리



입력 => "시:분:초"

위와같이 시/분/초로 입력 받는 다면 어떻게 표현 할까요. 위에 사전학습에서 String에 대해 사전학습을 미리 해 주세요.

시간 문자열을 분리해 내는 방법을 간단히 복습해 봅시다.

String inString = "10:11:22"

위 문자열을 "시:분:초"를 어떻게 분리해 낼까요. 시/분/초의 문자열을 나누는 기호가 ':'입니다. 즉, ':'의 위치를 알고 있으면 이 위치를 기준으로 시/분/초를 읽으면 됩니다.

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입니다.

이제 위치값을 알았으니깐 시/분/초를 구해 볼까요.

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를 이 명령으로 시/분/초를 구할 수 있게 됩니다.

정확히 시/분/초가 분리되었는지 살펴 볼까요.

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. 시/분/초 입력값을 초 변환 후 다시 시/분/초 변환



이번에는 시/분/초를 입력 받은 후에 그 값을 초로 변환 시킵니다. 그리고 그 초 값을 다시 시/분/초로 변환하여 결과를 살펴보겠습니다. 시간 변환을 잘 이루어지는 살펴보기 위한 실험입니다.

시/분/초를 입력받은 문자열을 초로 변환하기 위해서는 다음과 같습니다.

totalSec = 시*3600 + 분*60 + 초;

시간 문자열을 읽어서 hour, min, sec 값을 분리 해내고 초로 변환하면 다음과 같이 코딩을 하면 되겠죠.

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 시/분/초 변환을 시켜서 계산 상 아무런 문제가 없는지 확인해 봅시다.

readTime = (long)hour*3600+min*60+sec;
sec = readTime%60;
min = (readTime/60)%60;
hour = (readTime/(60*60))%24;  

이렇게 다시 hour, min, sec 구하여 이 값이 시리얼모니터로 출력시키면 확인이 가능해 집니다.

[소스]

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()함수로 시간값을 분리하고 카운트하는 방법을 살펴보았으며 오늘은 시간 변환을 살펴보았습니다. 한번 지끔까지 배운 원리를 종합하여 아두이노 시계를 만들어 보세요.

댓글()