본문 바로가기
Hardware/MCU(Arduino,ESP8266)

Nextion LCD만으로 Time Timer MOD(타이머) 만들기

by lovey25 2020. 1. 13.
반응형

이번 포스팅은 아두이노 카테고리에 있지만 아두이노가 필요없는 주제입니다. 만능 LCD인 Nextion display(이하 Nextion)만을 가지고 구글 타이머로 유명한 Timetimer 흉내내기 프로젝트 입니다.

먼저 Time Timer MOD라는 제품은 이제 워낙 유명해져서 많이들 알고 계실텐데요. 아래 링크에서 확인 하실 수 있듯이 남은 시간을 눈에 잘 보이게 한 타이머 입니다.

 

Time Timer MOD®

The Time Timer MOD® is a 60-minute visual timer that has the style and durability of the Time Timer PLUS® in a size that's portable and easy to use anywhere—from your office desk to the kitchen counter. The MOD features a removable, silicone cover that off

www.timetimer.com

이 타이머는 남아있는 시간을 명확하게 시각화 해 주기때문에 회의시간이나 개인적으로 집중도 있게 업무를 해야 할 때 옆에 두고 사용하면 업무 효율을 높일 수 있는 아이템으로 구글에서 회의시간에 사용한다고 해서 저도 관심을 갖게된 아이템인데요. 기능이랄게 별게 없습니다. 그냥 1시간짜리 타이머 입니다. 가운데 있는 버튼을 돌려서 시간을 세팅하고나면 설정시간후에 알람이 울리는 방식이죠. 주방에 있는 타이머와 다를바 없죠.

그런데 디자인도 깔끔하고 왠지 이런게 하나 있으면 나도 업무에 더 잘 집중할 수 있을거 같고 그런 느낌이 들어서 하나 마련하려고 봤더니 가격이.. ㅎㄷㄷ. 주방용 타이머 1만원도 안되는 가격이면 살수 있는데 이런거 하나 샀다가는 혼날게 뻔합니다. 그래서 Nextion을 이용해 봤습니다.

타이머 UI 만들기

최종적으로 완성된 UI모습입니다.

가운데 원에 붉은색으로 남은 시간을 표현하고 중심에는 타이머가 가고 있는지를 표시하기 위해서 0.1초 단위로 줄어들 숫자를 배치했습니다. 그리고 원 아래는 남아있는 시간을 표시할 시:분:초 숫자를 배치했습니다.

오른쪽에 있는 수직 슬라이드는 타이머 시간을 설정하는 용도인데 왼쪽은 시간으로 0~3을 설정하고 오른쪽은 분으로 0~60까지를 설정합니다. 그래서 최대 4시간 타이머를 설정할 수 있도록 했습니다.

가운데 남은 시간을 표시할 붉은색 파이차트를 구현하기위해서 이런 노가다가 필요했습니다. Nextion 디자이너에 게이지라는 위젯이 있긴하지만 바늘하나만 덩그러니 있는 모양이라 최대한 Time Timer를 흉내내려면 이렇게 별도로 이미지를 준비해야 했습니다.

원이 비워지는 모양을 60단계로 나누어서 각 단계별로 60장의 별도 이미지를 만들어서 등록했습니다. 그리고 로직에서 해당하는 시간이되면 그림을 변경하는 방식으로 사용했습니다.

여기서 주의할점이 하나 있는데요. 내가 사용하는 Nextion의 저장공간이 얼마나 되는지 미리 확인을 하고 작업을 해야 합니다. 제가 사용하는 모델은 Basic모델로 플래시 매모리 용량이 4MB입니다. 지정된 플래시용량 안에 모든 UI를 포함시켜야 하기때문에 무작정 많은 그림을 넣을수도 무작정 큰 그림을 사용할 수도 없습니다. Nextion에 그림을 집어넣게되면 이미지 타입에 상관없이 변환이되어서 크기에 따라 용량이 소모되는것 같습니다. 그래서 저의 경우 다른 이미지가 이미 소모하고 있는 공간이 있어서 약 2.6MB를 이 타이머를 위해서 사용할 수 있는 상황이었고 각 이미지별로 42.6KB가 할당되는 셈인데 이정도 크기면 Nextion에서는 약 147x147 픽셀의 이미지를 사용할 수 있는 용량이었습니다.

첨에 이것도 모르고 원이 커야 잘 보일테니까 화면 꽉차도록 UI를 만들었고 용량이 15MB가 넘는 바람에 60장의 그림을 다시 만드는 삽질을 했었습니다.

UI 용량이 메모리를 초과했을 때 업데이트 에러 메시지

타이머 로직 만들기

타이머를  동작하는 로직은  슬라이더로 타이머를 세팅하면 세팅된 시간이  줄어드는 매 1초마다 한번씩 남은시간에  맞게 화면표시를 갱신하고 잔여시간이 "0"이되면 화면 깜빡임으로 종료를 알리는 순서로 만들었습니다.

먼저 슬라이더를 이용해서 타이머 시간을  설정합니다. 시간  슬라이더와 분 슬라이더를 이용하여 시간을 세팅하는데 슬라이더에서 터치 릴리즈가 되면 시간과 분을 조합하여  타이머 설정시간을  초로 환산합니다. 그리고 환산된 초시간을  별도의 변수에 저장합니다. 그리고 Nextion 자체 타이머를 동작시킵니다. 이 부분은 슬라이더 각각의 "touch release" 에 다음과  같이  스크립트를 집어넣었습니다.

//설정 시간을 초로 계산해서 va0에 저장
va0.val=0
sys2=0
n0.val=h1.val
n0.val*=3600
n1.val=h0.val
n1.val*=60
va0.val+=n1.val
va0.val+=n0.val
sys2=va0.val//설정시간을 저장하는 변수
//타이머 시작!!
tm0.en=1
dim=30

다음으로 Nextion  내부  타이머에  추가한 스크립트 입니다. 타이머 화면에서 가장 짭은 단위로  변경되는 부분은 잔여시간을 표시하는  파이차트  중심에 있는 숫자로  0.1초의 시간흐름을 표시합니다. 그래서 추가한 Nextion 자체 타이머의 트리거링 간격을 100ms으로 설정합니다. (중간에 여러가지 계산 및 화면표시등으로 인해서 소요되는 연산딜레이 때문에 실제 트리거링 간격은 이보다 더 짧아져야합니다. 따라서 정확한 시간을 표현하기 위해서는 트리거링 간격에 캘리브레이션 작업이 필요합니다.)

이제 매 0.1초마다 수행하는 로직을 간단히 말씀드릴께요. 0.1초를 9번은 그냥 보내고 10번째 0.1초가 되면 앞에서 설정시간을 초로 변환하여 저장했던 변수에서 1을 빼서 다시 같은 변수에 저장을 합니다. 그리고 잔여초를 가지고 역으로 잔여 시간:분:초를 환산하여 파이차트의 채워지는 정도 그리고 슬라이드의 위치 및 숫자표시를 갱신합니다. 

만약 잔여시간이 0으로 지정한 시간이 모두 흐르게 되면 0.1초 간격으로 화면의 밝기를 줄였다 키웠다 하면서 반짝이는 효과가 나타나도록 했습니다.

잔여시간을 표시하는 파이차트는 설정 시간에 따라 해상도를 조절하여 무조건 설정된 시간이 100%가 되도록 만들었습니다. 오전 근무시간 4시간 오후근무시간 4시간을 표현하기 위해서 타이머 설정 최대시간을 4시간으로 만들었기 때문에 60개의 눈금만 있는 파이차트에서 1개의 눈금을 설정시간에 따라서 달라지도록 만들었습니다. (그래서 반대로 60분 이하의 설정시간에서는 그래프가 너무 듬성듬성해지는 문제가 있어서 이는 나중에 수정할 생각입니다.)

if(n3.val==0)
{
  //1초가 흘렀으면
  n3.val=9//0.1초단위를 다시 9로 리셋하고
  va0.val--//잔여타이머시간에서 1초 빼기
  
  //va0 시간을 시분초로 분리
  n2.val=va0.val
  n2.val%=60//초
  n1.val=va0.val
  n1.val%=3600
  n1.val/=60//분
  n0.val=va0.val
  sys0=n1.val
  sys0*=60
  n0.val-=sys0
  n0.val/=3600//시
  
  //진행된 시간에 맞게 슬라이드 조정
  h1.val=n0.val
  h0.val=n1.val
  
  //slider refresh
  ref 2
  ref 6
  //잔여시간을 파이차트로 표시
  sys0=3600
  sys1=sys2//설정시간(초)
  sys1/=60//설정시간(분)
  sys0/=sys1
  sys1=va0.val//남은시간(초)
  sys1/=60//남은시간(분)
  sys1*=sys0
  sys1/=60
  sys0=63
  sys0-=sys1//해당 단계의 차트 ID
  p0.pic=sys0//차트그림 변경
  ref 8
}else
{
  n3.val--//0.1초 진행
}
// 타이머 종료시
// 화면을 깜빡임
if(va0.val==0)
{
  for(sys0=0;sys0<=30;sys0++)
  {
    p0.pic=3
    dim=90
    delay=100
    p0.pic=63
    dim=30
    delay=100
  }
  tm0.en=0//타이머 끄기
}

결과

일단 디자인적인 측면에서 저의 센스 부족은 눈감아 주시길 바랍니다. 시간의 시각화라는 측면에서 원본의 Time timer와는 비교할 수 없는 수준이지만 일단 구현이 되었다는 데 의의를 두려합니다. ^^

마무리

Nextion LCD라는 제품이 정말 물건이란 생각을 다시금 하게 되었습니다. 간단하긴 하지만 이렇게 그래픽이 들어간 작업을 쉽게 할수 있게 해주면서 부가적인 MCU도 필요없으니까요. 

이번 프로젝트로 알게된 Nextion 스크립트의 특징 몇가지 남기고 마무리 하겠습니다.

제가 올려둔 소스를 보시면 Nextion 스크립트를 처음 접하신 분들은 단순한 가감승제 연산을 외 이렇게 불필요한 단계를 많이 거쳐서 했는지 의아해 하실 수 있는데요. Nextion은 일반적인 수학연산기호를 인식하지 않습니다. 다시말해서 x=3+a*2 와 같은 명령을 이해하지 못합니다. 그래서 계산의 순서대로 a*2를 먼저해서 a에 저장하고 a값을 x로 복사한 후에 마지막으로 x에 3을 더하는 식으로 절차를 여러번 거쳐서 계산을 진행해야 합니다. 그리고 Nextion은 실수형 변수를 지원하지 않아서 소수점이 있는 계산을 할 수 없습니다.

그리고 공백문자는 하나의 표현식으로 사용되기 때문에 구문내부에 띄어쓰기를 해서 명령어를 보기좋게 표시하는데 제약이 있습니다. x=1 이라고 써야하는데 x = 1 이라고 사용하면 안된다는거죠. 

Nextion 문서를 꼼꼼히 읽어봤으면 좋았을테지만 그런 성격이 못된터라 대충 이렇게 하면 되겠지 하면서 컴파일이 안되는 오류와 결과값이 이상해지는 오류를 격으면서 한참을 삽질하고서야 알아낸 사실들이었습니다. ㅡ.,ㅡ

마지막으로 자체적으로 임시버퍼로 사용할 수 있는 내장 변수가 3개 있습니다. sys0, sys1, sys2 라는 이름으로 사전 정의된 변수를 사용할 수 있습니다.

 

끝!

반응형

댓글