초보자를 위한 아두이노 코딩 입문-19: 아두이노 코딩 시계 종류와 시리얼 모니터 시계 코딩

codingart(66)
Published in
#kr
Words
923
Reading
5 min
Listen
Play
8y

다음은 아두이노와 웹에서 HTML+자바스크립트 언어를 사용하여 아날로그 시계를 구성하였고 초침은 좀 더 럭셔리하게 보이도록 별도로 분리하여 디자인한 시계 모델로서 아두이노와 스마트폰과 와이파이 통신에 의해 구현한 작품이다. 머지 않아 스팀잇에도 선보일 회가 있을 것이다.

그림_05.png

블로그 독자분들 중에 내용을 어려워하는 분들이 계실 수 있는데 이 시리즈 블로그의 목적이 해보는 데에 있지 단순 읽기용은 아닐 수 있습니다, 그렇다고 어려운 것은 당연 아닙니다, 어렵다고 느껴지시는 분들은 “초보자를 위한 아두이노 코딩 입문- 1 에서 10” 까지 훑어 보시면 되겠습니다. 당연히 눈팅하는 것이 아니라 직접 배선 코딩을 곁들여 재미로 해 보시기 바랍니다.

인류 문명의 역사 시작에는 반드시 시간 계산법과 아울러 해시계 또는 물시계를 비롯한 시계의 발명이 뒤따르고 있다.
까마득한 지구 최초의 문명으로 알려진 수메르 문명에서도 이미 60진법에 근거한 수학이 뒷받침되어 연월일시분을 이미 측량할 수 있었던 것으로 보인다. 메소포타미아 지방에서 발생한 수메르 문명의 영향으로 오늘날까지도 당연하게 60진법을 사용하고 있다.

다음의 사진 YBC 7289는 즉 예일대의 바빌로니아 유물 중 번호 7289 점토판이며 기원전 1800 ∼ 1600 년 경으로 추정된다. 물론 당시에 60 진법을 사용했기 때문에 1에서 59까지에 해당하는 쐐기 문자 점토 판들이 남아 있으며 사진에서는 이런 쐐기 문자 수자를 10진 수로 표현해 두었다.

그림_02.png

이 점토판의 정사각형 도형에서 30은 한 변의 길이이며 1:24;51;10 은 대각선의 길이를 나타냄이 분명하다.

그림_10.png

이 값은 카시오 계산기에서 계산한 그림_11.png값과 소수이하 6자리까지 동일함을 알 수 있다.
그다음으로 42:25:35를 60진법으로 계산해 보면 다음과 같은 결과를 얻을 수 있다.

그림_12.png

마지막으로 수메르 방식으로 대각선 길이를 계산해 보면 그림_13.png가 됨을 알 수 있다. 현대의 계산기 결과와 하등 차이가 없다는 점을 알 수 있다.
현재의 컴퓨터에서 흔히 사용되는 진법 연산은 2진법과 16진법이 포함되어 있다. 16진법 사용은 7 segment ON OFF 코딩에서 그 사용법을 이미 엿보았다.

그림_03.png

하지만 당시의 문명 수준에서 아직 톱니바퀴를 비롯한 시계 메카니즘이 발명되기 전이었기 때문에 해시계 정도가 사용되었을 것이며, 시간, 분까지의 개념을 가졌을 것으로 추정된다.

하지만 오늘 날 시계의 개념은 단순히 명품으로서만이 아니고 네트워크 상에서 돌아가는 코드들 간의 상호 연동을 비롯한 초 단위까지의 정확도도 흔히 요구되고 있다.

다음은 아두이노 코딩을 통해 구현할 수 있는 시계 종류들이다. HTML, Java Script 언어나 앱인벤터 언어와 와이파이 코딩 기법을 습득하게 되면 보다 다채로운 시계 코딩이 가능하다. 초보 단계를 벗어나면 그러한 코딩을 소개할 계획이다.

아래의 0.96인치 OLED 디스플레이를 사용한 시계는 사실 시계 알코리듬 코딩이라기 보다는 I2C lcd 사용법에서처럼 OLED 사용법에 많은 중점을 두고 있다. OLED 시간 디스플레이는 대단히 선명하다.

그림_04.png

아래의 시계는 아두이노 호환 보드인 NodeMCU 보드 와이파이에 의해 PC에서 시간 과 분 데이터를 입력 설정하여 0.96 OLED 디스플레이를 사용하여 출력하는 시계이다. 와이파이가 가능한 NodeMCU 보드의 가격은 10,000 원 이내로서 앞으로 스팀잇 독자들의 흥미로운 코딩 분야가 될 것이다.

그림_01.png

다음은 스마트폰에서 앱인벤터에 의해 구현해본 아날로그 시계이다. 아두이노 금방 학습하고 앱 인벤터로 넘어가면 금새 코딩이 가능하다. 시계가 없어서가 아니라 앱 인벤터 학습을 위한 코딩 연습 작품이다.

그림_06.png

아두이노 시리얼 모니터 시계 코딩

아두이노 우노 보드 모델은 16MHz 크리스탈 칩을 사용하여 Atnel 328CPU 가 필요로 하는 기본적인 클럭 신호를 발생 시켜 공급한다. 따라서 아두이노 우노 CPU에서 시간의 최소 단위를 체크하고 경과 시간을 모니터링 하는 기본 명령들을 제공하고 있다.

그림_07.png

아두이노의 CPU에서 계산 가능한 가장 큰 정수 값은 4바이트 즉 32비트를 사용하여 표현되는 큰 숫자로서 로 주어진다. 근사적으로 42억9천만에 해당한다. 아두이노는 전원이 ON 되면 이 숫자에 해당하는 만큼의 시간을 카운트 할 수 있는 것이다. 이 숫자를 초 단위로 사용하여 아두이노 시계를 코딩하게 되면 이론적으로 장기간 시계를 볼 수 있다는 의미이다.
시간 및 분 단위를 체크하여 시리얼 모니터에 디스플레이해 주는 아두이노 코드를 작성해 보자. 이번 코딩에서 시계의 시간 계산 원리 알고리듬을 학습해 보기 바란다. 이 알고리듬이 앞서 소개핶던 모든 종류의 시계에 고스란히 클론 된다는 점을 유의하자. 그렇지 않을 경우에는 오픈 소스 코드를 단순 업로딩하여 돌려 보도록 해 보자.

이 시리얼 모니터 시계 코딩에서의 준비물은 아두이노 우노 보드면 족하다.

헤더 부분에서 2개의 unsigned long 변수 currentHr 과 CurrentMin의 초기 값을 0으로 설정한다.

setup()에서 Hour & Minute 입력을 요구하도록 시리얼 모니터에 출력한다.
while( Serial,available() == 0) {
}
이 명령은 아두이노와 PC를 연결하는 USB 케이블을 통해 시리얼 통신에 의하여 아두이노의 입력 메모리 버퍼에 데이터가 입력 되었는지 여부를 체크하는 역할을 한다. 여기서 버퍼라 함은 문자나 숫자 1개의 데이터를 의미하는 것이 아니라 한 번에 시리얼 모니터 입력 칸에 입력될 수 있는 한줄 가량의 데이터 양을 뜻한다.
버퍼에 입력된 정보가 있으면 그 값이 0보다 크므로 while( )을 만족하므로 { } 를 수행하고 즉 그 다음 명령문으로 넘어 가게 되는 것이다.

입력 버퍼에 수신된 정보는 parsing 과정 즉 일종의 분석을 거쳐야 한다. parseInt() 명령은 버퍼의 정보를 정수로 꺼내게 된다. 즉 현재 시간 14시 23분을 1423으로 입력했으면 parseInt() 의 결과물은 정수 값 1423에 해당하게 된다. 따라서 100으로 나눈 후 소수 이하 값을 버리고 정수 값을 취하면 14가 되며 바로 이 값을 현재 시간 currentHr 로 둔다.
반면에 hrmin%100 명령은 100으로 나눈 후의 나머지 값을 취하는 명령이다. 즉 23이 현재의 분으로서 currentMin 으로 삼는다. 여기까지 아두이노 시계의 현재 시간 및 분 설정이 완료된다.

그림_08.png

loop()에서 millis() 명령을 사용한다. 이 명령은 아두이노 전원이 ON 이 된 아후 실제 코드가 돌아가기 시작하는 시점으로부터의 경과된 초 값을 측정하여 제공한다. 매번 loop를 돌 경우 경과 시간을 불러 와 시간 분 데이터를 환산하면 된다. loop() 앞부분의 setup()까지의 시간 경과는 1초에 비해 아주 작으므로 무시해도 무방하다.

아울러 시각이 12시 이전이면 AM 그 이후이면 PM 으로 하여 시계의 시간 정보를 출력하도록 하자.

컴파일 업로딩 후 시리얼 모니터를 오픈하여 시간 및 현재 분 데이터를 컴퓨터 화면을 참고하여 입력해 보자.

그림_09.png

//Serial_Monitor_Clock_setting_01

unsigned long currentHr = 0;
unsigned long currentMin = 0;

void setup() {
Serial.begin(9600);
Serial.println("Clock setting data with 0000 in HR & Min");
while( Serial.available() == 0 ) {
}
int hrmin = Serial.parseInt();
currentHr = hrmin/100;
Serial.println(currentHr);
currentMin = hrmin%100;
Serial.println(currentMin);
}

void loop() {

unsigned long currentMillis = millis();
unsigned long hr = currentHr + currentMillis/3600000;
currentMillis = currentMillis%3600000;
unsigned long minute = currentMin + currentMillis/60000;
unsigned long second = currentMillis%60000;
unsigned long sec = second/1000;

if( hr <12 ) {
  Serial.println("AM");
}
else if( hr <24 ) {
  Serial.println("PM");
}
else {
  hr = hr -24;
  Serial.println("AM");
}

if( minute >= 60 ) {
  hr = hr + 1;
  minute = minute - 60;
}
Serial.print((unsigned long)hr);
Serial.print(":");
Serial.print((unsigned long)minute);

}//끝

초보자를 위한 아두이노 코딩 입문-19: 아두이노 코딩 시계 종류와 시리얼 모니터 시계 코딩 | Ecency