아두이노 드론 만들기 #2


아두이노로 드론 만들기 #1을 포스팅하고 벌써 2주가 흘렀다.
사실은 #1을 쓴 그 주 주말에 이미 실내에서 프로펠러 달고 테스트하다가 한번 식겁한 상황을 겪고 어찌어찌 드론
프레임을 만드느라 많은 시간을 보냈으며 지난 주말(7얼 15일)에 1차 야외 테스트를 진행하여 처참하게 실패를
하였다.


따라서 오늘의 포스팅은 전적으로 실패담이 될 것이다. 즐겁게 보아주시길…ㅠ.ㅠ


겁없이 뎀볐다가…


모터를 돌리는데 성공한 바로 그날, 욕심이 생겼다. 기왕 모터가 돌아간 김에 프로펠러를 붙여보고 싶은 유혹을
뿌리칠 수 없었다. 그래도 안전장치는 해야겠기에 가능한한 날아오르면서 궤도를 이탈하지 않도록 한다고 한 것이
영상에 보이는 상태이다.


몸통에서 4방향으로 평행하도록 나무젓가락을 꽂고(4족보행 로봇 때나 이번에 진행하는 드론 때나 이놈에 나무젓가락
없었으면 어떻게 작업을 했을까? 나무 젓가락으로 기술 진보를 이루는 나는 Homo Chopstickus?) 그 사이에 고정된
막대(이건 빨래 건조대에서 뽑았다…-.-)를 꽂아 틀어지지 않게 하려고 했는데…빨래 건조대에서 빠지는 파이프가 2개
밖에 없어서 4방향 모두 설치하지를 못했다…ㅠ.ㅠ


결국 좌우 2방향만 파이프를 걸고 내쪽으로 뻗은 나무젓가락을 잡아서 어떻게 제어를 해보려고 했지만 영상에서 보는 
것과 같이 이게 이정도로 제어될 수준이 아니었다. 괜히 고수들이 프로펠러 조심하라는 게 아니었다. 만일 저 아직 모양도
제대로 갖추지 못한 드론 같지도 않은 드론이 내 얼굴로 튀어왔다면…생각만해도 아찔하다…ㅠ.ㅠ

 


가장 어려운 것? 프레임 만들기


아두이노로 뭔가를 만들 때 가장 어려운 부분이 무엇일까? 사람마다 생각이 다르겠지만 나의 경우에는 바로 물리적인
‘프레임’을 만드는 것이었다. 이미 이전에 4족보행 로봇을 만들때 3T 규격의 하드보드지를 잘라 로봇의 프레임을
만들었을 때도 커터로 그 두꺼운 종이를 자르는게 어찌나 힘이 들었는지…그마저도 그렇게 손목에 관절염 걸릴 듯이
열심히 잘라대도 자르고 난 결과물은 왜 그리 비뚤어지는지…ㅠ.ㅠ


머리가 나쁘면 손발이 고생한다는 말이 있는데 사실 그 역도 성립한다. 손이 똥손이면 머리가 고통에 몸부림친다…ㅠ.ㅠ
생각대로만 만들어지면 참 좋으련만 자르거나 붙이거나 뚫거나 할 것 없이 똥손이 하는 일은 무조건 비뚤어진다.
그렇게 만들어진 결과물은 항상 기우뚱 할수밖에 없다. 피사의 사탑은 역사적 가치라도 있겠으나 내가 만든 이 비뚤어진
몹쓸 것은 그냥 쓰레기일 뿐이다…ㅠ.ㅠ


그래서 가급적이면 내가 별도로 손을 대지 않아도 그 자체로 사용 가능한 재료들을 주로 찾게 된다. 그마저도 로봇을
만들 때는 워낙 서보모터 토크가 좋기에 무게에 대해 크게 신경을 안썼는데 드론은 공중을 나는 장치이다보니 무게가
무척이나 신경이 쓰인다.


물론 일반적인 드론을 만든다면 기존 프레임을 구입해서 할 수도 있지만 앞서 말했듯이 나는 프로펠러 하나로 움직이는
드론을 만들려고 하는 것이다보니 기성품을 구매할 수가 없다. 오롯이 내가 스스로 만들어야 하는 것이다. 역시나
3D 프린터를 질러야 한다는 내 마음 깊은 곳의 외침이 힘을 갖는 순간이 아닐 수 없다. 그러나 그저 꿈일뿐…ㅠ.ㅠ


아무튼 3D 프린터가 인류의 기술 발전을 무지막지하게 단축시킬 것이라는데 몰표를 줄 수 밖에 없는 상황이다.


간단한 제작 과정


먼저 양해를 구할 것은 일단 제작이 시작되면 귀차니즘에 의해 일일히 사진을 찍어두지 않는다. 어차피 실패작에 대한
이야기이므로 그냥 그런가보다 하고 넘어가면 되시겠다.


앞서 말한 바와 같이 가능하면 노가다를 줄이기 위해 내가 별도로 손을 대지 않고 바로 사용 가능한 재로를 구하게 된다.
처음 눈독을 들인 것은 알루미늄 캔이었는데 그대로 사용하기는 어려워 포기를 했다. 그러다 눈에 들어온 것이 있었으니
바로 아래 사잔과 같은 쁘띠첼 껍데기였다(이거 PPL 아닌가? 광고비 청구해야 하나?).


억지로 구겨넣으니 아두이노 나노도 들어가고 옆을 조금 자르니 ESC도 가로질러 끼울 수 있고 카본 파이프를 대충 십자
형태로 가로지르니 얼추 모양새가 괜찮았다. 그렇게 만들어진 것의 원형이 글 맨 앞의 영상에 보여지는 모습이다.


이후 방향타를 움직이기 위한 서보모터와 서보모터 구동을 위해 사용한 서보 컨트롤러 보드, 그리고 서보 모터에 전원을
공급해줄 9V 추가 배터리와 추가 배터리의 전압을 5V로 떨어뜨려줄 강압기(빵판용 전원 보드) 등등 상당히 많은 부품
들을 추가 장착하게 되었는데. 최종 모습은 대략 다음과 같다.



쁘띠첼 껍데기가 모양도 그렇고 꽤 괜찮았는데 아쉬운 점은 칼집을 잘못내면 잘 찢어진다는 점과 워낙 약해서 쉽게 
찌그러진다는 것이었다. 예를 들어 모터를 나사로 고정하는데 조금 세게 돌리면 이놈에 껍데기가 사정없이 찌그러져
모터의 수평이 안맞게 되는 것이다.


어쨌든 처음 테스트의 영상만을 기준으로 생각할 때 이정도만 되어도 일단 뜨지 않을까 하는 막연한 기대로 테스트를
시작했다.


1차 시도 : 움직이는 척이라도 해볼래…-.-?


우선 영상을 보자…-.-



어처구니 없게도 꼼짝을 안한다…ㅠ.ㅠ 원래는 8인치 프로펠러를 썼다가 꼼짝을 안하길래 추력이 부족한가 싶어
10인치 프로펠러로 바꿨다. 그런데 프로펠러 보호 가드라고 붙여놓은 저 검은색 폼보드 직경이 아슬아슬해서 결국
프로펠러가 폼보드를 갈아먹고 말았다…ㅠ.ㅠ


처음에는 아주 단순하게 무게 탓이라고 생각했다. 정말 꼼짝을 안했으니…
하지만 사용한 모터에 대한 data sheet는 아니지만 동급의 A2212 13T 1000kv 모터에 대한 data sheet를 보면
내가 구성한 환경에서 최대 802g은 띄울 수 있어야 한다. 물론 프로펠러 사이즈가 약간 틀리긴 하지만 실제 드론의
무게도 400g이 채 못되는 무게이니 꼼짝도 못한다는 것은 말이 안된다.




그래서 다른 쪽으로 고민을 해보다가 떠오른 생각이 몸통이 너무 넓은 것이 아닌가 하는 것이었다. 게다가 현재 몸통의
형태가 나팔꽃을 뒤집어놓은 형상이라 프로펠러가 돌면서 발생시킨 바람이 옆으로 분산되면서 양력을 약하게 만든 것이
아닌가 하는 생각을 하게 되었다.


그래서 몸통 주변으로 덕지덕지 올려놓았던 면적이 넓은 보드들을 모두 모터 축과 수평행한 위치로 옮겼다. 그렇게 해서
가능한한 바람이 저항을 받지 않도록 슬림하게 만들었는데 그 형태가 바로 아래에 보이는 이미지 형태이다(사실 아래 
이미지는 시험 비행에 실패한 후의 모습이다).



2차 시도 : 그렇다고 움직이는 척만 하냐…ㅠ.ㅠ


역시 우선 영상부터 보자…



1차 시도 실패 후 2차 시도를 하기까지 1주일이 걸렸다. 누누히 이야기 하지만 일단 프레임에 손이가기 시작하면 노다가도
그런 노가다가 없다. 사정이 이렇다보니 일단 프레임을 고쳐야 하는 경우 쉽게 손이 가지 않는다. 아 3D 프린터여…ㅠ.ㅠ


그래도 프레임(이라기 보다는 부품의 배치)을 고친 후 뭔가 반응이 있었다. 자빠져서 구르고 엉망이 되었지만 일단 움직인
것이다. 하지만 역시 걸음마 하려고 한 발 띄었다가 바로 비틀거리며 넘어지는 갓난 아기 같은 모습은 영 불만이다.
이번에는 무엇이 잘못되었을까?


우선 생각난 것은 처음 자세가 균형이 맞지 않았다는 것이다. 기울어진 자세에서 출발을 하려니 제대로 떠오르지 못하고
기울어지면서 넘어지고 말았다는 생각…틀린 생각은 아니었지만 이게 다가 아니라는 점을 곧 깨닫게 되었다.


3차 시도 : 어뢰 만드는 줄…-.-


오늘의 마지막이자 하일라이트 영상이다. 얼른 확인하고 싶어 퇴근 후 오밤중에 동네 공원가서 테스트했다…-.-
그렇다보니 영상이 상당히 시커멓다. 화면 밝기 최대로 하고 보시길…



아래 이미지는 실패 후 처참한 모습이다.



지난 번 2차 시도에서의 실패 원인을 수평 문제로 생각했기에 프레임을 다시 만들었다. 이번에는 애들 공작용 하드스틱을
이용해서 최대한 수평이 맞도록…하고 싶었으나 역시나 손이 똥손이라…ㅠ.ㅠ 그래도 최대한 노력했다. 그렇게 나온 것이
아래 사진과 같은 모습니다. 일단 아직 서보모터는 달기 전으로 무게는 대략 348g이다.



그러나 테스트 결과는 앞의 동영상과 같았다(그래도 1, 2차에 비하면 이게 어딘가…ㅠ.ㅠ).
그리고 이 동영상을 보고 근본적인 문제를 찾아냈다. 아니 찾아냈다고 추측하고 있다.


애초에 프로펠러 하나짜리 드론을 만든다고 했을 때 물리학과를 나온 회사 동료 한명이 그게 가능하냐고 물었다.
바로 회전체가 있어 회전을 하는 경우 그 힘을 상쇄하기 위해 몸통은 반대쪽으로 회전하게 된다는 것, 쉽게 말해
작용과 반작용, 역 토크라고 하는 것 때문이다. 이미 아는 사람들은 다 알지만 헬리콥터가 정상적으로 움직일 수 있는 것은 
테일로터라든지 같은 축에 서로 반대로 회전하는 2개의 프로펠러를 쓴다든지 하는 방식으로 이 힘을 상쇄시키기 때문이다. 


그런데 그런 장치 없이 드론을 만들겠다고 하니 의문을 가질 법 하다. 그런데 이상한 것은 내가 유튜브에서 구한 자료
동영상에 나오는 프로펠러 하나짜리 드론들은 어째서인지 그런 장치가 보이질 않는 것이다. 그래서 아예 그런 부분을
고려하지 않았다(나중에 네이버 카페와 페북의 아두이노 사용자 모임을 통해 그 비밀을 알게 되었지만…).


나의 결론은 이렇다.
프로펠러가 회전하면서 몸통에는 역회전이 걸리고 드론이 제대로 뜨기도 전에 몸통이 반대로 회전을 하면서 드론을
지지하고 있던 다리가 지면에 걸려 자세가 기울어지면서 결국 중심을 잃고 넘어졌다는 것이다. 그렇다면 나는 이
역 토크(반작용)을 상쇄시킬 방법을 찾아야 하는 것이다.


앞서 언급한 것처럼 몇몇 커뮤니티의 도움과 구글링을 통해 최초에 방향타의 초기 위치를 지면과 수직으로 놓지 않고
몸통이 프로펠러와 같은 방향으로 돌도록 세팅하는 것으로 진행을 해보려 한다. 다음 포스팅은 이 작업의 결과가 될
것이다.


정리

애초에 문돌이로서 이런 작업을 한다는 것 자체가 어려운 일이기는 하지만 그 가운데서도 역시 어려운 것은 하드웨어적인
부분, 물리적인 힘이 작용하는 부분을 해결하는 것이다. 로봇을 만들 때고 드론을 만들 때고 무게와 힘이 적절한 위치에
적절한 강도로 작용하게 한다는 것이 결코 쉽지 않은 작업이다. 사실 소프트웨어적인 부분은 프로펠러 하나짜리라 그런지
별로 할 것이 없다. 조종기 코드 180라인 정도 드론쪽 코드 130라인 정도로 꽤 단순한 코드다.


아직까지 변변한 지식도 특별한 손재주도 없는 상태에서 오로지 직관과 시행착오만을 가지고 작업을 진행하다보니 그
결과 역시 보잘것 없는 상태다. 


일단 재도전을 위해 3T, 5T짜리 스티로폼 보드를 잔뜩 주문을 해놓았다. 또 얼마나 시간을 잡아먹을지는 모르겠지만
우선 이 재료들로 작업을 진행해보고 만일 영 안되겠다 싶으면 없는 재주이지만 간단하게나마 모델링을 해서 무료로
3D 프린팅이 가능한 곳(광화문쪽에 있는 국립현대미술관에서 가능하다고 한다)에서 출력해서 도전을 해봐야겠다.


확실히 걷는 것(로봇)보다 나는 것(드론)이 상당히 어렵다…ㅠ.ㅠ 제대로 띄울 수 있을지는 모르겠지만…
아무튼 다음 포스팅은 스티로폼 보드 도착 후 또 얼마간의 시간이 흘러야 할 것 같다.
그 때까지 무더위 잘 견뎌내시길…^^;





블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


아두이노 드론 만들기 #1


지난 포스팅에서 잠시 언급했지만 정말 BLDC 모터 돌리는데만 꼬박 1주일이 걸렸다. 중간에 잠깐 되는 듯하다가
변속기(이하 ESC) 2개만 태워먹고 결국은 실패했다. 괜한 도전을 시작했나 싶었으나 그래도 인생 짬밥이 있는데
하다보면 수가 나겠거니 하고 계속 시도하다가 결국은 모터를 구동하는데 성공했다.


오늘 포스팅은 간단하게 BLDC 모터를 구동하는 과정을 정리해보도록 하겠다. 
사실상의 주된 내용은 아두이노의 Servo 라이브러리에 대한 설명이니 이 부분이 필요없는 분들은 그냥
맨 마지막 동영상이나 보시고 넘어가시라~


간단한 기초 지식 설명


이미 아는 사람은 다 알지만 나는 문돌이의 입장에서 글을 쓰는만큼 간단하게 기초 지식부터 짚고 넘어가겠다.
하지만 나보다 더 잘 설명하는 글들이 많으니 그냥 링크로 대신한다(결코 귀차니즘의 발로가 아니라고는 말 못하겠다…). 
개인적으로 가장 설명이 잘 되어있다고 생각되는 블로그들을 위주로 링크한다.


BLDC 모터 : http://bit.ly/2uCa078
ESC : http://bit.ly/2sABx7F (혹은 위의 BLDC 설명 블로그에서도 확인 가능)
LiPO 배터리 : http://bit.ly/2tAxSrJ
프로펠러 : http://bit.ly/2uW2eV5


일단 가장 기본적으로 필요한 지식들은 위의 4가지라고 보면 될 것 같다. 문제는 이미 조립이 되어있는 완제품이나
아니면 모든 구성품들이 다 갖추어진 조립 Kit를 사는 경우가 아니라면 이 4가지 부품의 궁합을 잘 맞춰서 구매를
해야 하는데 이 과정이 꽤나 성가시고 어렵다. 


특히나 각각의 부품을 검색하다보면 설명한 글마다 부품 제조업체에서 제공하는 data sheet를 보면 사용법을 알 수 
있다고 하는데 웬만한 제품이 중국산이다보니 제대로된 data sheet 찾기가 결코 만만치 않다.


내가 지금 사놓은 부품 중 일부도 모터와 프로펠러는 짝이 맞는데 ESC와 배터리가 맞지 않아 추가로 구매해야 하는
상황이다. 무려 4세트나 되는데…ㅠ.ㅠ


아무튼 직접 제작을 목표로 하시는 분들은 위 내용들을 잘 숙지하셔서 불필요한 낭비를 줄이도록 하시길 빈다.


아두이노 RF 통신하기


사실 조종기도 따로 사고 싶었으나 조종기와 수신기 가격이 결코 만만치가 않았다. 게다가 그런 것을 사다 집에 들여
놓으면 분명 집사람의 반발이 있을 것 같아 도무지 살 엄두가 나질 않았다.


그래서 대안으로 선택한 것이 아두이노의 조이스틱 모듈과 nRF24L01 트랜시버의 무선 통신을 이용하여 
조종기를 만들기로 했다. 이 부분도 불필요하게 글의 길이가 길어지는 것을 막기 위해 링크로 대신한다.


아두이노 조이스틱 모듈 사용 : http://bit.ly/2uVzwn2
nRF24L01을 이용한 무선 통신 : http://bit.ly/2sRbmhh


이 과정에서는 주의할 점이 조이스틱 모듈이 원점이 제대로 안잡힌다는 문제다. 낱개로 파는 조이스틱 모듈과 두 개가
하나의 기판에 붙은 것 2종류의 조이스틱 모듈을 사용해보았는데 두 종류 모두 센터값 512에서 멈춰있지 않고 계속
1~2 정도의 오차가 생기면서 값이 지속적으로 변하였다. 내가 불량품을 산 것인지 대체로 이정도는 허용 범위인 것인지
모르겠다.


관련 스케치 코드는 다음 포스팅에서 공개하도록 하겠다.


ESC 캘리브레이션하기


바로 이 작업에서 1주일의 시간과 2개의 ESC가 날아갔다…ㅠ.ㅠ
ESC에 대해 설명한 글들에서도 자세한 정보들은 data sheet를 참조하라는데 data sheet 찾는 것도 만만치 않고
또 찾아도 내용 파악이 쉽지 않다…-.-


ESC 캘리브레이션이란 간단히 말하면 조종기의 최솟값/최댓값과 ESC의 최솟값/최댓값을 mapping 시켜주는
과정이다. 다음 블로그에서 조금 자세히 알아볼 수 있을 것이다.


ESC 캘리브레이션이란? : http://ivivaldi.blog.me/220917752795


하지만 처음 실패의 이유는 곰곰히 생각해보면 개발자로서 참 부끄러운 일이기도 하다.
흔히 뭔가 준비가 안되어있는 사람들에게 하는 말이 ‘군인이 전쟁터에 총도 안들고 나간다’는 것이다.
군인에게 가장 필요한 도구가 ‘총’인 것과 같이 개발자에게 가장 필요한 도구는 API다.
군인이 전쟁터에서 훌륭히 싸우기 위해 평소에도 총에 기름칠을 하고 정비를 하듯이 개발자도 자유자재로 원하는 
기능을 만들어내기 위해서는 적재적소에 올바른 API를 적용할 줄 알아야 한다. 비록 평소에 달달 외우지는 못할지언정
어떤 API를 쓸 상황이 되면 그 API에 어떤 속성들이나 함수들이 있으며 그 사용법은 어떻게 되는지를 한 번쯤은
살펴보고 사용을 해야 할 것이다.


나의 실패는 바로 이 과정이 없었기 때문이다.
아래 코드는 최초로 찾은 아두이노를 통해 ESC를 캘리브레이션 하는 코드이다.

#include <Servo.h>

Servo esc_b; 
Servo esc_r; 

int black = 180; //모터로 들어가는 초기값은 180. 즉 최대값.
int red = 180;

void setup() {

  Serial.begin(9600);
  esc_b.attach(6, 1000, 2000); //내가 실수한 부분!!!
  esc_r.attach(7, 1000, 2000); 

  Serial.setTimeout(50); 
  esc_b.write(180);
  esc_r.write(180);
}

void loop() {

  esc_b.write(black); 
  esc_r.write(red);

  Serial.print(black);
  Serial.print('\t');

  Serial.print(red);
  Serial.println('\t');
}

void serialEvent()
{
  while (Serial.available()) {
    black = Serial.parseInt();
    red = Serial.parseInt();
  }
}



물론 이 코드를 그대로 쓰지는 않았다. 우선 다행스러워보이는 것은 BLDC 모터를 제어하는데도 Servo 라이브러리를
사용한다는 것이다. Servo라이브러리라면 작년에 4족보행 로봇 만들 때 지겹게 써오던 라이브러리가 아닌가?


하지만…난 Servo 라이브러리를 반쪽만 알고 있었다…


Servo 라이브러리 살펴보기


Servo 라이브러리는 PWM을 통해 모터를 제어하기 위한 라이브러리이다.



이 Servo 라이브러리의 출력함수에는 2가지가 있다. 바로 write()와 writeMicroseconds()이다.
두 함수 모두 int 값을 파라미터로 받지만 그 범위가 틀리다. 다음은 각 함수의 특징이다.


  1. write(int value) : value의 범위는 0 ~180이다. value는 각도를 의미한다. 90을 중심으로 90보다 작은 값과 90보다 큰 값은 서로 반대 방향으로 움직인다. 내부적으로 writeMicroseconds함수를 호출한다.
  2. writeMicroseconds(int value) : value의 일반적인 범위는 1000 ~ 2000이나 모터 제조사에 따라 700 ~ 2300까지도 설정 가능하다. 모터가 움직이지 않을 때까지 최댓값을 늘릴 수 있으나 모터가 움직이지 않음에도 지나치게 값을 올릴 경우 높은 전류가 흘러 위험하다.


볼드 처리한 문구에 주목을 해야 한다. 우선 write함수는 내부적으로 writeMicroseconds를 호출하게 되어있다.
하지만 두 함수는 각각의 범위가 있고 그 범위가 서로 다르다. 때문에 write함수에서 writeMicroseconds함수를
호출할 때는 map함수를 통해 write에서 사용하는 범위인 0 ~ 180의 값을 writeMicroseconds에서 사용하는
범위의 값으로 변환하여 호출을 한다. 그런데 이 때 단순히 0 ~ 180을 1000 ~ 2000으로 변환하지 않는다.
즉, map(value, 0, 180, 1000, 2000)으로 호출하지 않는다는 말이다. 바로 다음과 같이 호출한다.

value = map(value, 0, 180, SERVO_MIN(),  SERVO_MAX());


이것이 어떤 의미일까? 차근 차근 알아보자.
우선 Servo 라이브러리에는 MIN_PULSE_WIDTH와 MAX_PULSE_WIDTH라는 2개의 상수가 정의되어있다.
MIN_PULSE_WIDTH는 544라는 값을 가지고 있고 MAX_PULSE_WIDTH는 2400이라는 값을 가지고 있다.


또한 Servo 라이브러리에는 SERVO_MIN()와 SERVO_MAX()라는 매크로 함수가 정의되어 있는데 각각 다음과 
같다.

#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4)  // minimum value in uS for this servo
#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4)  // maximum value in uS for this servo


마지막으로 우리가 Servo 라이브러리를 사용하기 위해서는 attach() 함수를 통해 모터가 연결된 PIN을 이용하게 
되는데 이 attach 함수는 2개의 함수가 오버로딩 되어있다. 다음과 같다.

uint8_t Servo::attach(int pin)
uint8_t Servo::attach(int pin, int min, int max)



그런데 이 처음의 파라미터 하나짜리 attach 함수도 내부적으로는 파라미터 3개짜리 attach 함수를 호출하도록 되어있다.
즉, uint8_t Servo::attach(int pin)함수의 전체 모습은 다음과 같다.

uint8_t Servo::attach(int pin)
{
  return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
}


그리고 파라미터 3개짜리 attach 함수에서는 두 번째와 세 번째 파라미터를 다음과 같이 this->min과 this->max에
할당한다.

this->min  = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS
this->max  = (MAX_PULSE_WIDTH - max)/4;


위 내용을 참고할 수 있도록 Servo 라이브러리 소스 코드와 아두이노 공식 사이트의 레퍼런스 페이지를 링크한다.



Servo 라이브러리 소스코드 : http://bit.ly/2tZ4kGh
아두이노 레퍼런스 페이지 : http://bit.ly/1NjpZI0


나의 실수


앞서도 말했듯이 나는 검색을 통해 아두이노로 ESC 캘리브레이션을 하는 소스를 찾았고 그 것을 그대로 쓰지 않고
수정을 했다. 수정한 코드는 다음과 같다. 몰론 이 코드는 잘못된 코드다…-.-

#include <Servo.h>

Servo esc; 

int max = 180; //모터로 들어가는 초기값은 180. 즉 최대값.

void setup() {

  Serial.begin(9600);
  esc_b.attach(9); //내가 실수한 부분!!! attach 함수의 두 번째와 세 번째 파라미터의 의미를 몰랐다.

  Serial.setTimeout(50); 
  esc.write(180);
}

void loop() {

  esc.write(max); 

  Serial.print(max);
  Serial.print('\t');
}

void serialEvent()
{
  // 이 시점에서 시리얼 모니터를 통해 0을 입력한다.
  while (Serial.available()) {
    max = Serial.parseInt();
  }
}


만약 이 코드대로라면 한 번 계산을 해보자. attach(int pin) 함수를 사용한 경우 write함수에서 writeMicroseconds를 호출할 때 값이 어떻게 매핑될까? 순서대로 살펴보자.


  1. attach(9) 호출
  2. attach(9, 544, 2400) 호출
  3. this->min과 this->max에는 모두 0이 할당됨
  4. esc.write(180) 호출
  5. 내부적으로 val = map(180, 0, 180, 544, 2400)을 통해 값을 매핑한 후 writeMicroseconds(val) 호출


이렇게 되면 결국 최댓값은 2400이 설정되고 만일 모터가 최댓값 2000까지 설정된 모터라면 앞서 본 것과 같이
높은 전류가 흐르게 되어 위험한 상황이 될 수도 있는 것이다. 이후로도 유사한 맥락의 실수를 몇처례 더 한 후 결국
ESC 2개를 태워먹고 말았다.


드디어 모터를 돌리다!


결국 진행 단계에서는 확실하게 원인을 찾지 못하였고 2300kv급의 레이싱 드론용 모터로 테스트 하던 것을 1000kv
모터로 시도하여 성공하게 되었다. 아마도 1000kv 모터는 2400 이상의 신호에도 견디도록 제작된 것 같다.
하지만 역시 안전한 구동을 위해서는 파라미터 3개짜리 attach 함수를 이용하여 최솟값과 최댓값을 명시적으로 지정해
주는 것이 바람지할 것으로 생각된다.


아래 동영상은 모터 구동 성공 동영상이다. 




모터가 어찌나 세게 도는지 혼자서 날아가는 줄 알았다…-.-
프로펠러 붙이면 어찌될지 자못 기대가 된다.


정리


결정적으로는 모터의 허용 값을 몰랐던 것이 원인이겠으나 역시나 Servo 라이브러리의 함수들을 좀 더 제대로
알고 썼더라면 조금 더 일찍 성공에 다다르지 않았을까 하는 생각이 든다.

시작이 반이라고…이제 모터 돌렸으니 프로펠러만 달면 붕붕 날아다닐까?
다음 포스팅에서는 진짜 그런지 한 번 확인해보도록 하겠다^^






블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


아두이노 드론 만들기 : Prologue


뭔가 촉이 왔다!
그래서 혹시나 하고 지난 블로그를 되돌아 봤더니…역시나…
아두이노 4족보행 로봇 만들기를 처음 포스팅 한 것이 2016년 6월 20일이었다.
이건 뭐…지킬박사와 하이드씨도 아니고, 늑대인간도 아니고…여름만 되면 공돌이로 변신하고자 하는 욕구가 넘치는
돌연변이 문돌이라고나 할까…-.-


그 때 첫 문장이 이러했다.


이제 막 걸음마를 뗐는데…
벌써 수퍼맨이 되어 날아가려고 한다고나 할까… 

[아두이노] 아두이노 4족보행 로봇 만들기 ~ 1


그랬다. 그 때는 정말 아무 것도 모른 채로 하룻강이지 범 무서운 줄 모르고 무작정 덤볐던 것 같다^^
그러면 지금은? 일단 걷는 것은 해봤으니 진짜로 날아볼 수 있을까?


솔직히 말하면 그리 자신은 없다. 아두이노라는 공통점이 있을 뿐 사용하는 모터도 다르고 모터가 다르니 구동하는
방식도 다르고, 게다가…내가 만들려는 것이 보통 볼 수 있는 프로펠러가 4개나 6개 달린 그런 드론이 아니라 단지
프로펠러 1개로 날아가는 흔히 싱글콥터라고 불리는 형태의 것이라 더더욱 쉽지 않을 것 같다.


상상은 자유~


사실 처음에는 기왕 해보는 거 남이 하지 않은 걸 해보자 하고 프로펠러 하나짜리 드론을 생각했는데 역시나 내가
생각한 것은 이미 지구인의 절반은 생각한 것이라…벌써 그런 시도들을 잔뜩 하고 있었다. 하지만 그게 끝이 아니므로
그냥 도전하기로 했다.


이미 사람들이 만든 싱글콥터들

http://www.techholic.co.kr/news/articleView.html?idxno=6677

https://youtu.be/pF0uLnMoQZA?list=PLbfJADDuNxBd8rud9H4eLfhcK113_XTJB


굳이 싱글콥터를 만들기로 한 이유는? 모터 하나 살 돈밖에 없어서…는 아니고…^^;

최초의 발상은 영화 ‘프로메테우스’로부터 왔다. 프로메테우스에 보면 외계 행성에 도착한 지구인들이 엔지니어의
기지를 탐사할 때 한 과학자가 2대의 공모양 드론을 날린다. 그 드론들은 레이저를 쏘면서 동굴(기지) 내부를 스캔하고
스캔한 데이터는 모선에 입체 영상으로 재구성된다. 바로 그 드론을 만들어보고 싶었다.




하지만 현시창이라던가…
내가 뭔수로 그런걸 만드나…ㅠ.ㅠ
그래도 흉내나 내보려고 했으나 처음부터 막힌 것이 3D 프린터가 없는 상태에서 공 모양의 껍데기를 만들 재간이
없는 것이다. 결국 애초의 목표는 포기를 하고 대신에 프로펠러 1개로 움직이는 녀석으로 바람의 영향을 받지 않는
좁은 공간을 탐색할 수 있는 드론을 한 번 만들어보자고 생각했다.


되든 말든 상상은 할 수 있는거니까.


벋뜨 그러나...내 머리 속에는 왼쪽의 아이언맨이 있으나 내가 손에 쥘 아이언맨은 오른쪽이 아닐까 싶은 불안감이…-.-



준비 작업


까~이꺼! 드론 뭐 별거 있나? 모터 좀 사다가 배터리 연결하고 아두이노 연결해서 프로펠러 막 돌리면 붕붕 거리면서
날아다니…기는 개뿔…모터 돌리는데만 일주일이 걸렸다…ㅠ.ㅠ 일단 모터를 돌리는 과정은 다음 포스팅에서 자세히
다루기로 하고 오늘은 무엇무엇을 준비했나 보자.


이제부터 나오는 용어들은 드론으로 검색하면 모두 자세히 알 수 있는 내용이므로 별다른 설명 없이 지나가겠다.


우선은 무조건 소형화를 목표로 하여 가장 작은 재료들을 모았다. 아무래도 드론 하면 핵심 부품이 모터이므로
모터를 검색했다. 그리고는 주로 미니 드론에 쓰이는 코어리스(coreless) 모터를 발견하고는 아무생각없이 모터와
짝이 맞는 프로펠러와 함께 덜컥 구입을 했다.


하지만 이 모터는 한개로 드론을 만들 수 있는 추력(쉽게 말해 들어올릴 수 있는 힘)이 나오질 않았다.
기본적으로 모터 외에도 배터리와 플라잉 컨트롤러(비행을 제어하는 보드. 나는 아두이노를 사용하기로 한 것이다) 등이
더 붙어야 하는데 거기까지는 어떻게 될까 했더니 아두이노를 구동하기 위해 따로 배터리를 달거나 혹은 전원을 분배
할 수 있는 장치가 더 필요했던 것이다. 결국 이 모터는 아래와 같은 요상한 물건을 하나 만들어놓고는 일단 고이 
보관하기로 했다.



그리고 곧 브러쉬리스(Brushless) 모터 + ESC + 프로펠러 세트인 제품을 하나 샀는데 이놈은 프로펠러 길이가
10인치(약 26Cm)인 놈이라서 다시 레이싱 드론용으로 모터와 프로펠러 5인치(약 12Cm)짜리를 따로 구입했다. 
이번에는 혹시 잘 안되면 일반적인 드론을 만들어보고자 4세트를 샀다. 


더이상의 자세한 내용은 생략하고 기본적으로 필요한 구성품을 보면 다음과 같다.


  1. 아두이노 나노2개 : 하나는 조종기용, 하나는 드론용
  2. nRF24L01 트랜시버 2개 : 역시 하나는 조종기용, 하나는 드론용
  3. 브러쉬리스 모터 1개
  4. 전자 변속기(ESC) 1개
  5. 프로펠러 2개 (정방향 1개, 역방향 1개) : 모터와 변속기 프로펠러는 세트 상품
  6. 조종기용 조이스틱 한 개 (조이스틱 2개가 붙어있는 모델)
  7. 리튬 폴리머 배터리 11.1v 550mAh 30C 2개 (한 개는 2호기 만들면 쓸 것)
  8. 리튬 폴리머 충전기 1 개


일단 여기까지가 기본적으로 모터를 구동시키는데 필요한 부품들이다. 최종 완성을 위해서는 방향타에 쓰일
서보모터와 몇가지 센서들이 더 필요하게 될 것이다. 물론 외장도 만들어야 하고…


정리


사실 아직 만들던 4족보행 로봇도 완성시키지 못한 상태다.
언제나 느끼는 바이지만 나는 프로토타입형 인간이다. 실제 회사 업무를 할 때도 초기 작업은 빠르고 정확하게
잘 하는 편인데 프로젝트가 궤도에 오른 후에는 엄청 게을러진다…-.-


아마도 이 드론 프로젝트도 일단 날고나면 뒷방으로 밀려날지도…^^;


하지만 나의 큰 그림상에서는 이 드론 만들기도 로봇 만들기에 연장선 상에 있으니 조만간 통합 작업이 이루어질
것이다. 그 과정에서 꼭 필요한 것이 3D 프린터인데…언제나 살 수 있을까…ㅠ.ㅠ 서울 시내에 무료로 사용할 수
있는 곳도 있다니 우선은 그쪽을 이용해보는 것도 방법이긴 하겠다.


암튼 이번 포스팅은 이만 줄이고 다음 포스팅에서는 브러쉬리스 모터 구동과 ESC 설정에 대해 알아보도록 하겠다.






블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


아두이노 가지고 놀기 - 아이와 함께 하는 무드등 만들기~


사실 지난 주 페이스북에서 친구가 다음과 같은 링크를 공유했다.

https://www.facebook.com/NTDTVKorea/videos/1390641794308544/


음료 디스펜서라나? 사실 디스펜서라는 이름조차 처음 들어봤다…-.- 난척좀 하느라 바로 댓글에 ‘하나 만들어주랴?’
라고 올렸는데 정작 친구들보다 우리 집 애들이 만들어 달라고 난리다…ㅠ.ㅠ 그래서 이번 주말에 만드려고 계획을
세우고 잇었는데 정작 주말이 되니 너무 귀찮다…ㅠ.ㅠ


사실 예전에 로봇 만들 때 혹시나 필요하지 않을까 하고 에어 펌프 모터와 에어 실린더를 잔뜩 사놨다가 묵히고 있던
차라 잘됐다 싶기도 했는데 막상 프레임 만들 생각을 하니 로봇 만들 때 하드보드지에 칼질하던 트라우마가 떠올라
도저히 엄두가 나지 않았다. 그래서 그냥 애들한테는 에어 펌프모터를 이용하여 병속의 물을 밖으로 내보내는 것만
보여주고 말았다. 게다가 이거 한 번 해보자고 잘 마시지도 않는 청량음료를 3병이나 살 수는 없지 않은가?


일단 동영상에서도 나오지만 구조는 매우 단순하다. 에어 펌프 모터, 푸시 버튼, 배터리 그리고 생수병 하나와 에어 
호스만 있으면 된다. 가장 힘든 작업이라면 생수 병 뚜껑에 구멍을 뚫는 작업인데 생수 병 뚜껑은 워낙 얇아서 송곳
만으로도 쉽게 뚫린다.


기본적인 연결 상태는 다음과 같다.



귀차니즘으로 제작 과정은 담지 못했고 동작 영상만 링크한다.



아이와 함께 만드는 무드등


아이와 함께 했다고는 하지만 아이가 한 일은 등 갓에 해당하는 종이 접기 공 뿐이다…^^;; 원래 나리 꽃도 접어서 등 
갓으로 사용하려고 했는데 큰아이 휴대폰이 망가져 A/S 받으로 왔다 갔다 하고 결국은 회생 불능이라 새 폰 사러
또 왔다 갔다 하다보니 주말에 시간이 빠듯했다.


게다가 아두이노 나노가 Mac Sierra 버전에서 말썽을 일으켜서 삽질도 좀 하고, 오랜만에 아두이노를 만졌더니
그 단순한 LED를 켜는 것도 버벅댔다.


이렇게 완성한 모습은 다음 이미지와 같다.




연결은 매우 단순하다. Frizing으로 그린 스케치는 다음과 같다. PWM을 사용하기 위해 3, 5, 6, 9, 10번 핀을
연결했고 330Ω 저항을 통해 LED의 +극을 연결했다. 당연히 -극은 GND로 연결…PWM을 사용한 이유는 아날로그
출력을 통해 LED가 서서히 밝아졌다가 서서히 어두워지는 효과를 주기 위해서다.



가장 어려웠던 부분은 5개의 LED를 랜덤하게 켜고 끄는 것인데 loop함수 자체가 loop 기능을 한다는 것의 쉽게
적응이 되지 않는다. 일단 어찌 저찌 구현은 해보았는데 뭔가 조금 어설퍼서 손을 봐야 할 것 같다.


CDS_TEST.ino



최종 작동은 아래 동영상과 같다. 이렇게 찍고 보니 차라리 작동 안하는 상태가 더 예뻐보인다…ㅠ.ㅠ




정리


아주 단순한 작업이었지만 아이들이 관심을 가져주니 더 재미있었던 것 같다. 아직은 어려서 많은 것을 시키기는 
어렵지만 조금 더 크면 같이 한 번 해봐야겠다.


그리고 사실 무드등 같은 경우 급히 만드느라 저정도 선에서 마무리 했지만 머리 속에서 많은 디자인들이 떠오른다.
나중에는 목공예나 금속 세공으로 프레임을 만들어 제대로 된 제품을 만들어보고 싶은 욕심도 든다. 언젠가 퇴직을
하고 나면 작은 공방 하나 만들어서 이런 소품들 만들면서 보내는 것도 꽤 즐거운 인생일 것이라는 생각이 든다.


이번 주는 공부할 것을 제대로 하지는 못했지만 오랜만에 처음 아두이노 공부하던 때로 돌아가 즐겁게 보낸 것으로
만족한다…^^






블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


진짜를 만들어보자 - 4. RTC 모듈 연결과 LCD 출력


지난 시간에는 ESP8266 (ESP-01) 모듈과 ITEAD STUDIO의 4.3인치 LCD를 이용하여 인터넷으로부터
날씨 정보를 가져와 출력하는 작업을 해보았다. 비록 LCD 연결이 어렵기는 했지만 전체적으로 동작하는 데는
큰 문제가 없었다. 다만 하고자 했던 내용 중에 제대로 진행하지 못한 것이 인터넷을 이용하여 BMP 이미지를
불러온 후 LCD에 출력하는 부분인데 Wi-Fi 센서에서 이미지를 가져오는 방법을 잘 모르겠다…ㅠ.ㅠ


그리고 불만스러운 것이 openweathermap API가 보내주는 날씨 정보가 영 형편이 없다. 어느 순간부터
최고 기온과 최저 기온이 계속 동일하게 받아진다…-.-


아무튼 이번에는 날씨 정보 아래 큰 여백에 시계를 표시할 계획이었으나 별도의 아두이노와 LCD를 이용하여
시계를 따로 구현하기로 했다. 어차피 LCD 크기가 작기 때문에 2개의 LCD를 이용할 계획이었고 지난 번에
밝힌 목표에서 아두이노간의 통신을 통해 정보를 넘기는 작업도 진행을 해야 하기에 그냥 따로 구현하는 쪽이
좋을 것 같다고 판단했다.


시작 하자마자 난관…ㅠ.ㅠ

지난 번 4.3인치와 3.2인치 LCD를 같은 ITEAD STUDIO것으로 구매를 했다. 그리고 Wi-Fi 연결을 통해
날씨 정보를 보여주는 작업에 4.3인치를 사용했다. 같은 회사 제품이 핀 배열도 동일하기 때문에 이번 작업은
누워서 떡먹기라고 지레 짐작을 했건만…이상하게 지난 번과 동일하게 아두이노 메가와 LCD를 직접 연결을
했는데도 불구하고 백라이트의 하얀 불빛만 보이고 예제 코드들이 하나도 동작을 하지 않았다. 우선 확인한
것은 4.3인치와 3.2인치가 사용하는 컨트롤러 칩이 다르다는 것. UTFT 라이브러리는 LCD 초기화 시 컨트
롤러 모델을 지정한 상수를 첫 번째 파라미터로 받기 때문에 이 값을 수정해가면서 열심히 시도를 해보았으나
아무리 해도 도대체가 반응이 없었다. 판매처에 문의를 해보고 가이드 해주는 대로 따라했는데도 역시 증상은
동일하였다. 일단 제품 불량으로 잠정 결론 짓고 더 이전에 구매한 waveshare제의 2.8인치 LCD를 사용
하기로 했다.

2.8" 쉴드 형태다.2.8" 화면 출력3.2" 아무래도 불량...ㅠ.ㅠ


지난 글에서 말했듯이 waveshare의 2.8인치 LCD는 쉴드 형태로 아두이노를 덮어버리면 다른 핀들을
사용하기가 상당히 답답해진다. 그래서 일단 바로 아두이노에 결합하지 않고 점퍼 케이블을 이용하여 연결
하기로 했다. 이 쉴드는 아두이노 우노에 맞춰져 있기에 아두이노도 우노를 사용하기로 했다. 이전의 ITEAD
제품보다 사용하는 핀 수가 적기는 하지만 아두이노 우노를 사용하니 사실상 남는 핀이 거의 없었다. 다행이
사용할 RTC 모듈은 A4(SDA)와 A5(SCL)에 연결하면 되기에 문제될 것이 없었다.


어찌되었건 이렇게 연결하고 나니 지난 번과 다름없이 심란한 모습이 되었다…-.-



RTC 모듈 사용하기

이번에 사용한 RTC 모듈은 PCF8563이라는 모듈로 앞서 말한대로 SDA와 SCL로 통신하고 전원은 3.3V를
사용하는 녀석이다. 사용하는 핀이라고는 4개밖에 없어 달리 연결도는 올리지 않는다. 아두이노 메가라면
같은 이름끼리 (SDA -> SDA, SCL -> SCL, GND -> GND, VCC -> 3.3V)로 연결하면 되고 우노인 경우
SDA -> A4, SCL -> A5로 연결하면 된다. 이 모듈은 배터리가 포함된 모듈이며 아래 이미지의 모듈 하단에
보이는 점퍼를 그림상의 왼쪽에 꽂으면 아두이노의 전원만을, 오른쪽에 꽂으면 전원이 안들어올 시 포함된
배터리를 이용하여 계속 작동하게 된다.


라이브러리는 아래 링크에서 다운로드 받았다.

https://bitbucket.org/orbitalair/arduino_rtc_pcf8563/downloads


사용법을 알기 위해 검색을 해봤더니 이 모듈을 사용한 케이스가 전무하다시피 했다. 나중에 알고보니 이녀석
다른 모듈에 비해 가격이 비쌌다. 난 왜 하필 이 비싼 걸 산걸까…ㅠ.ㅠ 그러고보니 이 모듈도 이번에 사용한
LCD와 같이 waveshare 로고가 찍혀 있다.


아무튼 라이브러리는 잘 작동을 하였고 직관적인 API로 사용하기도 어렵지 않았다. 다만 완성된 시계에 문제가
좀 있는데 이 문제가 모듈 탓인지 다른 문제인지 모르겠다.


그리고 또 난관…ㅠ.ㅠ

사실 지금까지 개발일을 해오면서 시계도 꽤 많이 만들어봤다. 웹용으로도 만들어보고 아이폰용으로도 만들어
보고…하지만 그 때는 시간만 받아와서 변수에 넣고 출력만 하면 되었다. 물론 지금도 그 과정에는 크게 다름이
없다. 다만 지금은 LCD까지도 처리를 해주어야 한다는 것을 간과했다. 예전에 했던 방식으로 그냥 했더니…
아래 사진과 같이 앞서 출력된 내용 위에 다음에 출력된 내용이 겹쳐지면서 알아볼 수 없는 형체가 표시되었다.


그랬다…일단 데이터를 출력한 후 같은 자리에 다음 데이터를 출력하기 위해서는 앞서 출력된 내용을 지운 후
출력을 해줘야 했던 것이다. 기존의 개발은 화면에서 어떻게 처리해줄 것인가는 전혀 신경을 안써도 되었지만
아두이노는 그렇지 않았던 것이다.
(아무래도 이 부분은 추가 확인이 필요할 것 같다. 지난 번 날씨 표시 구현 시에는

별다른 추가 작업 없이 그냥 화면에 출력만 해주어도 문제가 없었는데...아마도 라이브러리 차이가 아닐런지...)


방법은 알았으나 이 방법을 어떻게 구현해야 할지가 또 난관이었다. 일단 기본적으로 이 LCD 라이브러리에는
lcd_clear_screen라는 화면을 특정 색깔로 채우는 함수가 있다. 일단 이 함수를 사용해보기로 하였으나
문제가 있었는데…1초마다 화면 전체가 껌뻑거리는 것이었다. 아무리 대충만드는 시계이지만 이건 아니다 싶다.


결국 이 함수와 동일한 기능을 하지만 특정 범위만 처리하는 lcd_clear_partscreen라는 함수를 별도로
만들었고 다행히 잘 작동하였다. 아무래도 waveshare와 나는 궁합이 별로 안맞는 것 같다…-.-


lcd_clear_partscreen 소스 코드

void lcd_clear_partscreen(uint16_t hwColor, uint32_t l, uint32_t t, uint32_t w, uint32_t h)  
	{
		uint32_t i, wCount = w;
		wCount *= h;
		
		lcd_set_cursor(l, t);
		lcd_write_byte(0x22, LCD_CMD);
		
		__LCD_DC_SET();
		__LCD_CS_CLR();
		for (i = 0; i < wCount; i ++) {
			__LCD_WRITE_BYTE(hwColor >> 8);
			__LCD_WRITE_BYTE(hwColor & 0xFF);
		}
		__LCD_CS_SET();
	}


사실 전체적인 소스가 뭔 내용인지는 잘 모르겠지만 직관적으로(좋은 말로 직관이고 그냥 대충 찍어서…) LCD
의 가로 해상도가 들어가는 wCount와 전체 해상도에 해당하는 wCount \*= h에 각각 필요한 폭과 넓이를
파라미터로 전달 받고 최초 위치를 지정하는 lcd_set_cursor(l, t);에도 역시 값을 파라미터로 전달 받도록
수정하여 각 영역(시간, 분, 초, 년도, 월, 일)이 갱신될 때 그 영역만 지웠다가 다시 출력하도록 구현하였다.


그래서 일단 아래 동영상과 같이 디지털 시계가 하나 완성되었다.


끝나지 않은 난관

그런데 위의 동영상을 보면 알겠지만 간혹가다가 2초가 튀어버린다. 처음에는 1초 체크를 delay(1000)으로
했었는데 이 때는 거의 10초에 한 번은 2초를 건너 뛰었다. 즉, 1, 2, 3, 4, 6, 7, 8, 9, 0 이런 식으로… 그래서
이번에는 millis() 함수를 이용하여 1초를 측정하여 처리했는데 이렇게 하니 좀 나아지긴 했지만 그래도 1분에
한 번꼴로 2초를 건너 뛴다. 모듈의 문제인지 로직의 문제인지 아직 해결을 못하고 있다.


그리고 시간과 날짜의 출력 라인 제일 앞에 불필요한 점이 찍히는 문제도 해결이 필요하다.


다음 진행 계획

지난 글에서 언급 했듯이 이제 날씨 표시와 시간 표시를 각각의 아두이노와 LCD를 이용하여 만들었으니 다음에는
지난 시간에 만든 Wi-Fi를 통해 날씨를 가져오는 아두이노 쪽에서 시계를 표시하는 아두이노쪽으로 정보를 보내서
날씨와 시간이 한 화면에 출력되도록 구현을 해봐야겠다.


또 어떤 난관이 기다리고 있을지 자못 기대되는 바이다…-.-


아두이노 디지털 시계 최종 소스

https://github.com/mazdah/ArduinoSamples/tree/master/smart_mirror_code3

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


진짜를 만들어보자 - 3. LCD 연결 및 Wi-Fi를 통한 날씨 정보 가져오기


우선 지난 포스팅에 언급한 waveshare사의 LCD 라이브러리에서 똑바로 선 형태의 폰트를 출력할 수
있도록 수정한 함수를 올린다.


//display a char at the specified position on lcd.
void TFT::lcd_display_char2(uint16_t hwXpos, //specify x position.
 uint16_t hwYpos, //specify y position.
 uint8_t chChr,   //a char is display.
 uint8_t chSize,  //specify the size of the char
 uint16_t hwColor) //specify the color of the char
{      	
	uint8_t i, j, chTemp;
	uint16_t hwXpos0 = hwXpos, hwColorVal = 0;

	if (hwXpos >= LCD_WIDTH || hwYpos >= LCD_HEIGHT) {
		return;
	}

	int width = 8;  // 폰트의 가로 폭
	if (SEGMENT18_XXL == chSize) { 
		width = 16;
	} else if (DOTMATRIX_M_SLASH == chSize) {
		width = 8;
	}

	hwColorVal = hwColor;
   
	for (i = 0; i < chSize; i ++) {     	
		if (SEGMENT18_XXL == chSize) { 
			chTemp = pgm_read_byte(&segment18_XXL[chChr - 0x20][i]);

			if (i != 0 && (i % 4) == 0) {
				hwYpos ++;
			}
		} else if (DOTMATRIX_M_SLASH == chSize) { 
			chTemp = pgm_read_byte(&DotMatrix_M_Slash[chChr - 0x20][i]);

			if (i != 0 && (i % 2) == 0) {
				hwYpos ++;
			}
		}

		for (j = 0; j < width; j ++) {
			if (chTemp & 0x80) {
				lcd_draw_point(hwXpos, hwYpos, hwColorVal);
			}
			chTemp <<= 1;
			hwXpos ++;

			if (hwXpos > hwXpos0 + (width * 2 - 1)) {
				hwXpos = hwXpos0;
			}
		}  	 
	} 
}


특별히 수정할 내용은 없으나 폰트의 크기에 따라 width를 조정해야 한다.


LCD와 Wi-Fi 센서 연결


일단 지난 번 waveshare LCD에 UTFT 폰트를 쓸수 있도록 손을 써뒀지만 두 가지 문제가 있었다.
첫 번째는 화면 크기가 작다는 것. 2.8인치의 크기인데 내가 가진 하프 미러의 가장 작은 사이즈가
A4지 절반 크기라서 2.8인치로는 폰트 크기를 크게할 경우 보여줄 수 있는 정보가 얼마 없었다.
다음은 정말 중요한 이유로 이 LCD가 쉴드 형태로 LCD를 장착할 경우 아두이노에서 사용 가능한
포트가 남지 않는다는 것이다. 뭐 아두이노 메가를 사용하면 되겠지만 이 제품은 호환 기종에 메가가
빠져있어서 메가에서는 장착해서 바로 사용을 못한다. 아마도 라이브러리에서 설정을 조금 변경하면
될 것 같지만 이게 아니더라도 할일이 태산인데…-.-


그래서 화면 크기도 좀 키우고 할 겸 이번엔 ITEAD STUDIO라는 곳에서 나온 4.3인치와 3.2인치
LCD를 구매했다. UTFT 라이브러리를 사용하는 놈이라 폰트 사용도 쉬운 장점이 있었다.




그런데 이놈도 제대로 사용을 하기 위해서는 별도의 쉴드를 사용해야 했다. 더군다나 이놈이 사용하는
쉴드는 아두이노 메가에서도 여분의 포트를 남기지 않고 모두 덮어버린다…ㅠ.ㅠ (포장은 모두 깔끔해서
좋다~)




이렇게 되면 큰 문제가 생긴다. 라즈베리파이의 경우 Wi-Fi, 이더넷, USB 등등 그 자체로 하나의 PC
와 같기 때문에 별도로 연결시켜줄 것이 없으나 아두이노는 본체가 달랑 컨트롤러 하나이기에 Wi-Fi
모듈도 붙여줘야 하고, 시계를 표현하기 위해 시계 모듈도 따로 붙여줘야 하고 그밖에 기능을 추가
하고자 할 때마다 센서 모듈을 별도로 연결해야 하기에 포트가 모자라면 심각한 제약이 발생하는 것이다.


그렇기 때문에 일단 쉴드를 사용하지 않고 LCD를 직접 아두이노 메가에 연결할 수 있는 방법을 찾아야 했다.
데이터 시트를 자세히 보면 아마도 방법이 있겠지만 문돌이 지식이야 뻔한 것이고 게다가 데이터 시트가 

모두 영어로 되어있는지라 일단은 구글에서 검색을 해야 했다. 그리고 다행히 아래 링크된 사이트를 찾아

무사히 연결을 할 수있었다. 물론 연결을 하고 난 뒤의 모양새는 조금 심란하다…ㅠ.ㅠ


LCD 연결 참고 사이트 : https://forum.arduino.cc/index.php?topic=101029.0




일단 위 이미지에서 보듯이 총 40개의 핀이 있고 이 중에 사용하지 않는 핀을 7개정도 빼면 33개 그리고
SD카드나 터치스크린 기능을 사용하지 않을 것이면 여기서 또 10개정도는 더 포트를 절약할 수 있다.
나는 SD카드를 제외한 나머지 핀들을 모두 연결하였다.


그리고 다행히도 정상적으로 작동을 하였다.


다음은 출력에 필요한 정보를 가져오기 위해 Wi-Fi 센서를 연결하였다. 이 부분은 워낙 자료가 많으니
생략을 한다. LCD와 Wi-Fi 모두 아두이노로부터 전기를 공급받아야 하기에 3.3V포트와 GND 포트는
빵판을 이용하여 공유하였다(LCD와 Wi-Fi 모두 3.3V를 필요로 한다).


Wi-Fi 모듈 역시 정상 작동 확인 완료!!!


openweathermap API 호출


하드웨어 준비는 마무리 되었으니 이제 인터넷에서 정보를 가져와서 LCD에 출력해주면 된다.
말은 참 쉽다…-.- 일단 Wi-Fi 센서의 경우 일전에 인터넷을 통해 LED 점등 테스트를 하다가 실패한
적이 있다. 아마도 스케치 코드라든가 센서 연결등의 문제라기보다는 공유기를 통해 Wi-Fi 센서로
연결하는데 문제가 있었던 듯하다. 하지만 이번에는 공유기를 통해 외부 웹사이트를 호출하는 것이므로
아마도 쉽게 될 것이라고 생각했다.


우선은 AT 명령어를 이용하여 외부 인터넷에 접속하고 응답을 확인하는 것은 무난히 성공을 하였다.
하지만 AT 명령어를 직접 사용하는 것보다는 뭔가 쉽게 접근 가능한 라이브러리가 있을 것으로 생각
되었다. 그런데 검색을 해봐도 대부분이 Wi-Fi 쉴드 사용을 기준으로 SoftwareSerial을 이용하는
라이브러리밖에 없었다. 나는 아두이노 메가를 사용 중이었고 Wi-Fi 센서는 Serial3에 연결을 해서
이 상태로 사용할 수 있는 라이브러리가 필요했다. 검색 끝에 드디어 아래의 라이브러리를 찾았다.


ESP8266 라이브러리 : https://github.com/itead/ITEADLIB_Arduino_WeeESP8266


사용법도 그리 어렵지 않아 쉽게 코드를 짜고 인터넷 접속 확인을 할 수 있었다.


다음은 어디서 어떤 정보를 가져올 것인가를 선택해야 했다. 우선은 가장 만만한 날씨 정보를 가져오기로
했다. 처음에는 기상청의 오픈 API를 이용하려고 생각했으나 가입이 필요하고 가입하는 과정에서 내가
사용하는 MAC에서는 뭔가 제대로 진행되지 않는 부분이 있었다. 도대체 언제까지 윈도우와 IE에 발목을
잡혀있어야 하는 것인지…-.-


그래서 가입과 사용에 별다른 제약이 없는 openweathermap이라는 서비스를 이용하기로 하였다.
아직은 제작 진행 중이니 이정도면 테스트하기에는 충분하다고 판단되었다. 가입하고 APP ID를 받아
API 호출을 테스트 해보았다. 아래와 같이 날씨 정보를 잘 받아왔다^^


{{“coord":{"lon":126.98,"lat":37.57},"weather":[{"id":721,"main":"Haze","description":"haze","icon":"50d"},{"id":701,"main":"Mist","description":"mist","icon":"50d"}],"base":"stations","main":{"temp":2.43,"pressure":1012,"humidity":74,"temp_min":1,"temp_max":3},"visibility":10000,"wind":{"speed":2.1,"deg":250},"clouds":{"all":90},"dt":1486282800,"sys":{"type":1,"id":8519,"message":0.0111,"country":"KR","sunrise":1486247522,"sunset":1486285237},"id":1835848,"name":"Seoul","cod":200}


다음은 이렇게 JSON으로 받아온 정보를 보기 좋게 LCD에 출력을 하는 일이 남았다.
JAVA라면 순식간에 해치울텐데…이거 스케치에서는 어떻게 해야 하나…ㅠ.ㅠ
하지만 역시 세상에는 많은 천사들이 있다. 열심히 구글을 검색한 결과 역시 아래와 같은 라이브러리를
찾아냈고 아주 쉽게 처리할 수 있었다.


ArduinoJson 라이브러리 : https://github.com/bblanchon/ArduinoJson


그리고 비록 아직은 뭔가 모자라지만 아래와 같이 정보를 출력할 수 있게 되었다.



첩첩 산중…


사실 처음 아두이노로 스마트 미러를 만들어보고자 생각했을 때는 라즈베리파이로 만든 스마트 미러 정도는
만들어보려고 시작을 했다. 심지어는 음성 인식까지…하지만 아두이노가 얼마나 low level의 하드웨어인지
제대로 인식을 못하고 있었던 듯하다. 하드웨어 연결, 인터넷 연결, 입력과 출력…하나 하나가 모두 엄청나게
손이 많이 가는 작업들이었다. 개발자 입장에서 말하자면 java로 짤 코드를 어셈블리로 짜고 있는 느낌이랄까
…-.- 게다가 아직은 폰트를 영문폰트밖에 구하지 못해서 한글 표현이 또 걱정이다.


그래도 우여곡절 끝에 인터넷에서 날씨 정보를 가져와서 LCD에 출력하는 기능까지 구현을 했다. 아직도 
갈 길이 멀지만 일단 칼을 뽑았으니 무라도 잘라보련다.



전체적인 계획은 아두이노 메가 2대를 이용하여 한 대에는 날씨와 날짜 및 시간 정보를 보여주고 다른
한 대를 통해서는 뉴스라든지 현재 내가 개발중이 ToDo 서비스로부터 할 일 정보를 가져와서 보여줄
예정이다. 물론 각각의 아두이노에서 별도로 Wi-Fi를 통해 정보를 가져오는 것은 뭔가 비효율적이라
생각되어 첫 번째 아두이노에서 모든 정보를 가져오고 아두이노간의 시리얼 통신을 통해 다른 한 대로
정보를 넘겨 처리할 생각이다. 과연 얼마나 잘 진행될 수 있을지 자못 궁금하다…-.-


다음 시간에는 시계 모듈을 이용하여 오늘 보여준 날씨 정보 하단에 날짜와 시간을 출력해보고자 한다.
또 얼마나 시간이 걸릴지… 진행되는 내용의 소스코드는 아래 링크에 공유한다. 나는 나쁜 개발자라
주석같은 거 없당~^^


소스코드 : https://github.com/mazdah/ArduinoSamples

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


진짜를 만들어보자 - 2. LCD 폰트 살펴보기


지난 글에서 밝혔듯이 아두이노를 이용하여 TFT LCD에 문자열을 출력하는 방식은 꽤나 
생소했다. 그냥 일반적인 웹 시스템이나 모바일 애플리케이션을 개발할 때는 그냥 폰트 파일
하나 가져다 놓고(물론 폰트 파일의 구조가 어떻게 생겼는지는 알 필요도 없다. 그냥 폰트
이름만 알면 되지) 이름과 size만 지정해서 사용하면 그만이었는데…


아무튼 새로운 지식의 장벽 앞에 조금 막막했다.


닥글링? (닥치고 구글링?)


우선 ‘아두이노’, ‘LCD’, ‘폰트’, ‘TFT LCD’ 등등의 검색어로 구글링을 해보았다. 물론 네이버
검색도…역시나 검색의 바다에는 쓸만한 정보들이 차고 넘친다. 먼저 내가 참조한 사이트들의
링크를 공유한다.


사실 대부분의 내용들이 자세히 살펴보지 않으면 상세한 부분까지 알기 힘든 수준이었다.
특히나 나같은 문돌이들은 일단 수학적인 개념이 들어가면 멘붕 상태에서 이리저리 헤매기
일쑤고…-.- 그래도 그나마 그림으로 표현한 내용들은 어느 정도 이해를 할 수 있었다.


폰트의 구조 - 장인의 한 땀…


일단 위에 링크된 곳들을 돌아다니면서 LCD 화면에 폰트가 어떤식으로 표시되는지는 대략
알 수가 있었다.


LCD상의 하나의 점(pixel)을 하나의 bit로 표시하고 그 점들의 그룹을 한 문자의 영역(이
영역이 바로 폰트의 사이즈라고 보면 되겠다. 8 X 12, 8 X 16, 16 X 22 등)으로 삼고
그 영역 내에서 문자의 형태를 bit값 1로 채워나가는 것이다. (첫 번째 링크의 3. Bitmap
font(비트맵 폰트)의 구조 참조)


그래서 일단 waveshare에서 제공하는 라이브러리에 포함된 font.c 파일에 있는 배열 중
하나에서 ‘A’라고 주석된 배열을 한 번 풀어보기로 했다. 배열의 요소들은 16진수로 표현
되어있으니 이걸 다시 2진수로 만들어보았다.


원본 배열 : 0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40
2진수로 변환한 배열 : 00000000,01000000,00000111,11000000,00111001,00000000,
00001111,00000000,00000001,11000000,00000000,01000000


그리고 이렇게 2진수로 변환한 배열을 2개(2byte)씩 잘라 세로로 배치를 해보았다.
그랬더니 아래와 같은 모양이 되었다(블로그에 사용된 폰트가 가변폭이라서 이미지로 첨부
하였다).




오호~!!! 뭔가 보이는가? 조금 더 알아보기 쉽게 0울 모두 지워보자





마치 그냥 암호처럼 보이던 배열이 이렇게 풀어놓고 보니 어렴풋이 문자의 형상이 나타난다. 
이렇게 풀어놓은 것 중에 1로 표시된 것들이 LCD상에서 빛을 내며 문자로 출력되는 것이다. 
비트맵 폰트라는 것이 이렇게 모눈종이같은 영역에 한땀한땀 정성들여 만들어진다는 것을 
처음 알았다…ㅠ.ㅠ


끝이 아니네?


아하~! 일단 폰트의 구조를 알았으니 응용하면 되겠구나.
하지만 나에게는 장인정신이 없으니 한땀한땀 폰트를 만들 수는 없는 일!
대충 비슷한 폰트 크기 큰걸루다가 구해서 쓰면 내가 산 LCD에도 큰 폰트를 출력할 수 있겠네~


그리고 다시 폰트를 찾기 위해 구글링…그러다가 아래의 사이트를 찾았다. 


굉장히 친절한 사이트였다. LCD 모듈도 파는 것 같고 다양한 LCD 라이브러리도 있고 중요한 
것은 이미지 파일로 폰트 파일을 만들어주기도 하고 아예 그렇게 만들어진 폰트를 다운로드 할
수도 있다. 그것도 모양과 크기도 다양하게!


오호 횡재다~ 하고 다양한 폰트를 다운로드 받었으나…웬걸…내가 가진 폰트는 2차원 배열로
구성되어있는데 다운로드 받은 폰트파일은 1차원 배열이네? 게다가 처음 한 줄은 뭔가 byte
수도 모자라고…




다행히 라인별로 아스키 문자가 주석으로 붙어 있어서 각 라인을 하나의 배열로 만들어 2차원
배열로 만들면 되겠다는 것을 쉽게 알 수 있었다. 나중에 알았지만 처음 4바이트는 폰트의
크기와 종류를 나타내는 값이었다. 그래서 일단 폰트 파일을 다음과 같이 수정했다.




자~ 이제 준비는 끝났고 출력만 해보면 되겠다~물론 라이브러리에서 상수 지정하고 새로
지정한 상수 선택시 추가한 폰트를 표시하도록 몇가지 수정을 거쳤다. 그리고 기운차게
스케치의 업로드 버튼을 클릭!!!


악!!! 이거 왜이래!!!




폰트가 나오기는 나왔는데 이게 영 상태가 병맛이다. 옆으로 누워있는데다가 가운데는 홍해가
갈라지듯 갈라져있고 게다가 이게 시계방향으로 돌려도 문자의 좌우가 뒤집힌 것이 분명한…
이게 아예 글자도 아닌 것 같이 찍혔으면 아예 뭔가 크게 잘못되었구나 하고 처음부터 차근차근
다시 해볼텐데…뭔가 글자인 것 분명한데 돌아가고 뒤집히고 한 모양이다보니 괜히 이리저리
머리를 쓰게 만든다…ㅠ.ㅠ for문을 고쳐볼까? 배열에서 요소들의 순서를 바꿔볼까?
아는가? 뭔가 조금만 손대면 될 것 같은데 어디를 손대야 할 지 모를 때 엄습하는 그 답답함…ㅠ.ㅠ


상투적인 것이 가장 확실하다!


사실 이 문제 해결을 위해 하루를 꼬박 보냈다. for문도 수차례 고쳐보았고, 배열 요소의 순서도
여러번 바꿔보았다. 하지만 도무지 답이 나오지 않았다. 결국 처음 폰트에 대해 이해할 때 했듯
배열을 분해해보기로 했다. 짜잔~ 분해했더니 아래 그림과 같이 거대한 문자가 하나 나왔다.
이거 나름 상당한 노가다다…-.- (로봇을 만들 때도 그렇고 이 것도 그렇고…분명 뭔가 지식 산업
에 대한 과제를 하는 듯한데 왜이리 육체노동을 하는 느낌이지…ㅠ.ㅠ???)




일단 풀어는 놨는데…뭔가 이상하다. 물론 크기가 엄청 큰 것도 있지만 그 것 말고도 뭔가
이상하다…waveshare에 포함된 폰트는 풀어헤쳐놓으니 대가리를 왼쪽으로 향하고 누운
모양이었는데 이 UTFT 폰트는 정상적인 형태로 똑바로 서있는 것이다!


라이브러리에 포함된 출력 함수가 옆으로 누운 폰트를 화면상에 똑바로 보이도록 처리해주는
함수였으니 똑바로 선 폰트가 이상하게 출력되는 것은 당연한 일인 것이다. 함수를 좀
분석해보려 하니 짧은 함수이지만 shift 연산도 있고 또 16진수 bit 연산도 있고…간만에
보니 뒷골 땡기는 연산들이 좀 있어서 일단 그림으로 이해해보기로 하였다.



                



그림을 보니 A와 D를 축으로 회전한 모양이다. 그러고보니 UTFT 폰트가 이상하게 나왔던
모양과도 딱 들어맞는다. 결국 함수를 고치는 수밖에는 답이 없어보였다. 그나마 다행인 것은
사용하려는 폰트가 똑바로 선 형태의 폰트이다보니 좌표때문에 머리아플 일은 없다는 것이다.
그냥 순서대로 x좌표를 이동하면서 출력하다가 폰트 사이즈에 따라 적절한 시점에 y좌표를
증가시켜주기만 하면 된다.


그리고 드디어~!




waveshare 라이브러리에서 UTFT의 다양한 폰트를 사용할 수 있게 된 것이다…ㅠ.ㅠ
(그럼에도 불구하고 마지막 Cyan 색상의 가장 큰 폰트는 뭔가 폰트 이미지하고 모양이
맞지 않는다…-.-)


아직도 남아있는 숙제들


다행히 사용하고자 하는 폰트가 똑바로 선 형태라 쉽게 함수를 만들어 사용할 수 있게
되었다. 하지만 아직 숙제가 있다. 바로 화면 회전에 따라 가로모드 세로모드에서 모두
자유자재로 정상적인 형태의 폰트를 보여주는 것! 그리고 가장 중요한 한글의 처리!!!


이와 관련된 자료도 위에 링크한 사이트에 많은 설명이 있지만 좌표 예기만 들어도
머리가 지끈거린다…ㅠ.ㅠ 일단 머리아픈 일은 여기까지 마무리 하고 새로 주문한
LCD들이 UTFT 라이브러리를 지원한다고 하니 조금은 편하게 작업을 좀 해보자…ㅠ.ㅠ


다음 과제는 Wi-Fi 센서를 통해 웹 서버로부터 날씨나 시간 데이터를 가져와서 예쁘게
뿌려주는 것이다!


수정한 라이브러리를 공유드리고 싶은데 라이센스 정보를 확인 못해서 일단 확인 후
별다른 제약이 없으면 UTFT 폰트를 사용할 수 있도록 수정한 라이브러리를 공유하도록
하겠습니다.

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


진짜를 만들어보자 - 1. LCD에 문자 출력하기


지난 번 “2시간만에 스마트 미러 만들기”를 보시고 실소를 금치 못한 분들이 많이 계실 것이다.
그렇다! 그것은 완벽한 개사기…라기보다는 ‘훼이크’라고 애교스럽게 표현하기로 하겠다…^^;;;


그러면 그렇게 훼이크로 점철된 인생을 살 것이냐? (조금 비약이 심한가…-.-)


그럴 수는 없다. 그래서 이제 진짜를 만들어보려고 한다.
오늘부터는 진짜 스마트 미러 만들기가 시작된다!


아두이노의 제약


우선 시작을 하면서 왜 스마트 미러를 만들 때 라즈베리파이를 이용하는지 제대로 깨달았다.
한마디로 말해서 자바로 프로그램을 짤 것이냐 조금 과장해서 어셈블리로 프로그램을 짤 것이냐의
차이 정도 될 것 같다.


라즈베리파이는 그 자체로 한 대의 컴퓨터다. 즉, PC에 설치할 수 있는 운영체제가 거의 온전한
모습으로 라즈베리파이에 설치 될 수 있는 것이다. 그 말은 화면(LCD)에 문자를 표현하는데 아무런
제약이 없다는 것이다. 물론 이미지도 마찬가지…게다가 다양한 폰트를 자유자재로 이용할 수 있다.
음성이나 모션 인식 등 특별한 기능의 구현이 아니라면 단지 화면에 데이터를 출력해주는 것은
일도 아니라는 것이다.


그런데 아두이노는…ㅠ.ㅠ
그야말로 알파벳 ‘A’ 하나 출력하는데도 이탈리아 장인 정신을 가득 담아 한땀한땀 보여주어야 한다.
물론 모든 LCD 제품들이 라이브러리를 제공해주기 때문에 함수 하나 호출하면 가볍게 출력해
주기는 하지만 폰트 종류, 화면 방향 등 고려해야 할 사항이 다르고 폰트조차도 구성 방식이 달라
라이브러리 별로 사용 가능한 폰트가 따로 있다(물론 얼마든지 수정하여 사용 가능하고 이번 글의
주요 내용이 바로 그것이다).


얼마전 아이들 풍선 껌 종이에 적힌 내용을 보니 이런 글이 적혀있었다.


“집을 나서자 마자 집에 돌아가고 싶어졌다”


그렇다…스마트 미러 만들기를 시작하자 마자 아무 것도 하고싶지 않아졌다…ㅠ.ㅠ


준비물


일단 화면에 정보를 뿌려주는 것이 1차 목표이기에 별다른 준비물은 없다. 아두이노 우노(호환)와
2.8” 크기의 LCD 하나가 전부이다.




헝그리 스마트 미러 제작이 목표이기에 LCD는 크기 대비 가장 싼 녀석으로 골랐다. 메X솔X션에서
2.8”를 23,100원에 그리고 혹시나 해서 2.2”를 11,000에 구매했다. 2.8” 제품은 waveshare라는
브랜드의 제품이었다.


waveshare 제품 페이지 : http://www.waveshare.com/wiki/2.8inch_TFT_Touch_Shield

waveshare 2.8" TFT LCD shield



그리고 아시는 분은 아시겠지만 컵라면이 하나 따라왔다. 스마트미러 만드는 데 쓰라고 보내주신 
것은 아니겠기에 맛있게 먹어줬다(이자리를 빌어 사장님께 감사드립니다^^;).


그런데 준비물을 준비하는데서부터 난감한 미래가 예견되었다. 2.8” LCD는 쉴드 타입인데 이걸
아두이노 우노에 장착하고 나면 남는 핀이 없다…


이런게 찰떡 궁합?



나중에 Wi-Fi 센서도 연결하고 모션 센서나 기타 등등의 센서들을 연결을 해야 할텐데…급한대로
메가에다 장착을 했더니 장착은 잘 되는데 작동을 안한다. 아마도 핀 배열이 안맞는 것이 있나보다. 
일단 이 문제는 나중에 해결하고 우선은 LCD를 통해 문자를 출력하는 것 부터 시작하기로 했다.


참고로 2.8” 크기도 작은 것 같고 이 제품의 라이브러리도 좀 빈약한 것 같아서 아XX팩X리에서
추가로 4.3”와 3.2” 제품을 각각 하나씩 더 구매했다. 헝그리가 목표인데…-.-


또 하나의 장벽


일단 메X솔X션의 제품 페이지에 있는 링크를 찾아가 라이브러리를 다운로드 받고 스케치를 실행해
보았다. 라이브러리를 스케치에 추가하고 샘플 코드를 열어보았다. 그리고 실행!
오~잘된다 잘돼!!!


기본 예제 출력



스마트 미러를 위해 배경색은 검게 문자는 흰색으로도 한 번 출력해보고


색상만 변경~



역시 잘된다!


이제 글자 크기를 좀 키워보자!
어…그런데…폰트가…
일단 출력 함수에 파라미터로 폰트 사이즈를 넘기도록 되어있는데 이 폰트 사이즈가 단 2개만
상수로 정해져 있었다. 그러니까 기본적으로는 2종류 크기의 폰트밖에 사용할 수 없게 되어
있었던 것이다…-.- 아무리봐도 스마트 미러에 사용하기에는 폰트가 너무 작은데…


그런데다가 늘 워드 프로그램에서 간단하게 폰트를 선택해서 쓰기만 하다보니 도대체 이 LCD
에서는 폰트를 어떻게 사용하는지 감이 안잡히는 것이다.


아무래도 라이브러리를 까보는 것 밖에는 답이 없을 것 같았다. 그리고 다행히 라이브러리 소스
안에서 font.c라는 파일을 하나 찾았다. 올타꾸나!하고 파일을 열었는데???
이건 뭔가요??? 1byte Hex값이 잔뜩 적힌 2차원 배열 2개가 다소곳하게 코딩되어 있는데…
얜 어떻게 쓰는건가…


암혼가...ㅠ.ㅠ???



17년 개발자 짬밥으로 1바이트 아스키 문자 95개에 대해 각각 12바이트로 표현을 하고 있는
것 같기는 한데…이게 어떻게 화면에 표시가 되는 것인지 도통…ㅠ.ㅠ


어쩔 수 없이 다시 구글링을 시작…
그리고…신세계를 보게 되었다!


글이 길어져 다음 포스팅에 계속합니다. 다음 포스팅에는 LCD에서 폰트 구조와 사용법에 대해
간단하게 알아보겠습니다.

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^


2시간만에 스마트 미러 만들기!!! (반전주의…^^)


도전 과제를 찾자!!!


4족보행 로봇도 슬슬 마무리가 되어가고…다음엔 뭘 만들어볼까 고민을 하던 차에 뜬금없이
라즈베리파이로 관심이 가기 시작했다. 당연히 이것저것 검색을 하던 차에 눈에 들어온 것이
있었으니…


바로 스마트 미러!


사실 나도 작년 초엔가? 구글 개발자가 만들었다는 스마트 미러 사진을 보고는 꽤 흥미있게
생각을 하고 있던 차였다. 게다가 최근 생산성 카테고리에 해당하는 모바일 앱을 포함한 
웹 서비스 하나를 구현 중인데 생산성 카테고리이다 보니 이 서비스에 연계하여 항상 서비스를
모니터링할 수 있는 장치를 아두이노를 이용해 개발하고 싶었다. 그런데 여기에 스마트 미러가
딱이다 싶은 것이다!


다만 스마트 미러가 아무나 만들 수 없는 꽤나 고도의 기술이 필요한 것으로 생각했다. 
거울을 디스플레이로 이용하려니 거울 뒤에 아주 얇은 디스플레이 장치를 붙여야 할 거라고 
지레 생각한 것이다.


그런데 의외로 꽤나 많은 라즈베리파이 유저들이 스마트 미러를 만들고 있었다. 과장 조금
보태면 마치 아두이노에서 LED 켜듯이…-.-


그러다가 드디어 그 비밀의 열쇠를 발견하게 되었으니…바로 Two Way Mirror 다른 말로
하프 미러(Half Mirror)라고 하는 유리였다. 쉽게 말해 빛의 일부는 반사하고 일부는 투과
시키는 유리다. 그 뒷면에 검은색 배경을 깔면 바로 거울이 된다.(이하 하프 미러)


아하~이거였구나. 많은 메이커들의 스마트 미러 제작기를 보니 바로 이 하프 미러 혹은
일반 유리를 하프 미러처럼 만들어주는 필름을 이용하여 그 뒤에 안쓰는 모니터의 LCD
판넬을 붙여 스마트 미러를 만들고 있는 것이었다. 그리고 스마트 미러에 보여줄 컨텐츠는
라즈베리파이의 PC에 준하는 강력하고 다양한 기능을 통해 쉽게 보여줄 수 있었다. 마치
지하철의 안내 모니터처럼…


그래 바로 이거다! 라고 결정을 하자마자 거의 유일하다시피 소매로 하프 미러를 구매할
수 있는 곳을 찾아 바로 A4 사이즈의 하프 미러 3장 (그 중 2장은 다시 절반으로 재단)을
주문하였다.


그리고…


오늘 드디어 그 유리가 도착했다!!!


나라고 못할소냐!


일단 내가 목표한 것은 무식하게 큰 스마트 미러가 아니라 책상에 놓고 사용할 수 있는 아담한
스마트 미러였다. 그리고 비용도 최소한으로 줄일 수 있는…


라즈베리파이의 경우 이미 보드만도 5만원돈이 나가고 집에 남아도는 모니터가 없는 사람은
라즈베리파이용 LCD라도 사야 할텐데 그 가격 역시 만만치가 않았다. 게다가 사이즈가 커지면
당연히 하프 미러 또는 필름에도 비용이 추가될 것이고…


암튼 여차저차해서 난 이렇게 탁상용으로 만들었다.




탁상용이다보니 요로코롬 가로로 돌릴 수도 있다.




난 이 작업을 단 2시간만에 끝내버렸다. 나의 주체할 수 없는 천재성으로!!!


보드에 센서를 연결하고 Wi-Fi 모듈로 웹을 통해 날씨정보와 시간을 받아와서 LCD에
값을 뿌려주고 하드웨어를 하프 미러 뒤쪽에 잘 배치하…기는 개뿔…-.-


여기가 반전입니다…-.-


사건의 진상은 이렇다…




계획까지는 모두 사실이다. 그리고 실제로 진행도 할 예정이고…
그런데 ‘저럼함’에 방점을 찍다보니 한 가지 아이디어가 떠올랐다.
바로 스마트폰을 이용하여 간이 스마트 미러를 만들면 어떨까 하는 생각…
말하자면 스마트 미러형 거치대라고나 할까?


그리고 바로 작업을 시작했고 앞서 말한대로 2시간의 뻘짓 끝에 프로토타입을 완성했다.
내 예상보다 꽤 그럴듯했다…^^


사실 내 주변에 기념품이나 사은품 제작이나 판매하는 사람이 있으면 아이디어를
제공하고 밥이나 한끼 얻어먹으려 했는데 아직 부족한 부분도 있고 해서 그냥 이렇게
공개를 한다…^^;;;


부족한 부분이란 일단 폰을 넣고 꺼내기가 불편하고 전화가 오거나 혹은 폰으로 다른
앱을 실행시키고자 할 때 폰을 꺼냈다가 다시 집어넣고 해야 한다는 것이다.
무엇보다도 계속 켜져있는 경우 충전을 하고 있는 상태에서도 배터리 눈금이 점점
줄어갔다. 물론 이러한 문제점들은 조금만 생각하면 다 해결이 가능한 것이라서
조만간 어느 오픈 마켓에서 보게 될지도 모르겠다…^^;;


그리고 요고 요렇게 스마트폰 거치 안할 때는 뒤에 판떼기로 막아서 그냥 거울로 쓰면 된다^^



진짜는 과연 만들 수 있을까…-.-


일단 아두이노로 만들 계획이고 이미 2.8인치와 2.2인치 LCD를 주문을 한 상태다.
그런데 이정도 사이즈 LCD는 핀을 너무 많이 소모해서 아두이노 보드 하나에 LCD
하나밖에는 연결을 못할 것 같고…보여주고자 하는 정보는 많고…게다가 LCD 아직
한번도 안써봤는데…복잡한 정보들을 어떻게 예쁘게 보여줄 수 있을지…
게다가 글의 서두에서도 말했듯이 대부분의 중요한 정보는 내가 개발 중인 웹 서비스에서
가져오게 될 것인데 그런 정보들을 어떻게 파싱하고 LCD에 보여주어야 하는지 아직은
감이 잡히질 않는다.


비록 비용은 아낄 수 있지만 고생은 몇배로 더 해야 할 것 같다.


암튼 또 당분간은 심심치 않게 생겼다^^

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^



좌충우돌 로봇 만들기 Season II - 5 : Epilogue


이것저것 벌여놓은 일이 많다보니 한동안 로봇에 손을 못댔습니다.
그러던 중 다행히 12월 29, 30일 휴가를 얻어 여유가 생기면서 개선하기로 생각했던 부분에
대해 드디어 손을 좀 댔습니다.


원래 마지막 포스팅에서 문제로 지적한 모터 성능을 테스트 해보고 모터쪽으로 개선 방향을
맞춰보려고 했습니다. 하지만 그 동안의 문제점에 대해 최종적으로 내린 결론은 배터리나 
모터의 성능 문제가 아니라 확실히 로봇의 설계가 잘못되었다는 것이었습니다. 그래서 몇가지 
조정 작업을 거쳤습니다. 로봇 만들기 Season II는 이 조정작업에 대한 이야기로 마무리 
하려고 합니다.


그동안 페이스북이나 제 블로그를 통해 조언을 주신 많은 분들께 감사 인사 드립니다.
소프트웨어적으로도 아직 완성된 것이 아니라 조만간 다시 준비해서 Season III으로
찾아뵙겠습니다~^^



다시 한 번 다이어트…


지난 포스팅(Season II - 4 : 원래 약골이었네…-.-) 이후 실제로 서보모터 3개 정도를
추가로 구매해서 간단한 실험을 해보기는 하였다. 비슷한 성능의 다른 제품 3개를 가지고
테스트를 한 결과 현재 내가 가진 배터리와 모터로도 충분한 성능을 낼 수 있다는 것을
확인하였다. 기본적으로 포함된 서보 혼에 바로 연결할 경우 3Kg 무게의 가방을 쉽게
들어올릴 수 있었으며 약 10Cm정도의 팔을 추가로 연결한 상태에서도 그 절반정도의
성능을 보여주었다. 결국 SEW MK I 의 전체 무게가 2Kg 남짓이니 그 무게를 

견디지 못할 배터리나 모터는 아니라는 결론을 내릴 수 있다.


그래서 다시 한 번 로봇의 구조를 바꿔보기로 했다. 크게 바뀌는 것은 없고 가능한한
다리의 길이를 줄이고자 시도했다. 그리고 기존 대비 약 6Cm 정도 길이를 줄였다.
비교를 위해 상세하게 찍은 사진이 없어 쉽게 구분이 가진 않지만 아래 사진의 왼쪽이 
기존 형태이고 오른쪽이 개선된 형태이다.


내가 조립이 쉽도록 모듈화를 해서 만든 것도 아니고…하드보드를 목공풀로 붙여가며
만든 것이다보니 이미 만들어진 것을 뜯어고친다는 것이 이만저만 힘든일이 아니다…ㅠ.ㅠ
가장 어려웠던 것은 재조립 과정에서 모터 위치가 바뀌는 바람에 스케치에서 각도 조정을
일일이 다시 해줘야 했다는 것이다. 빨리 스케치 소스도 라이브러리화를 해야 하는데…
이 과정에서 모터 하나가 타버렸다…ㅠ.ㅠ 다행히 앞서 말한 모터 테스트를 위해 구입한
모터 중에 같은 모델이 있어 바로 교체가 가능했기에 망정이지 안그랬으면 또 주문하고
받을 때 까지 기다리다가 시간을 까먹을뻔 했다.
그래도 생각보다 깔끔하게 작업은 완료되었다. 하지만…


어째서인지 여전히 나아진 부분이 없다…기존과 마찬가지로 비리비리 하다…ㅠ.ㅠ


방향전환


답답한 심정으로 이것저것 테스트를 해보다가 이상한 점을 하나 발견을 했다.
처음 구동을 시작해서 가만히 서있을 대는 진동과 소음이 심하고 자꾸 가라앉는 모습이
보이는데 위로 일어서는 동작에서는 오히려 소음도 거의 없고 매우 안정적인 모습을
보여주었다. 여기서 다시 한 번 모터나 배터리가 힘이 없는 것은 아니라는 것이 증명
되었다. 그랬더라면 로봇을 위로 들어올리는 동작이 쉽지 않았을테니까


그리고 제자리에 서있는 동작이나 걷는 동작에서 다리 관절들이 자꾸 몸에서 바깥쪽으로
밀려나가는 모습이 보였다. 그래서 ‘힘’의 문제에서 ‘구조’의 문제로 그리고 ‘구조’의 
문제에서 ‘각도’의 문제로 최종 가닥을 잡았다.


우선 제작 자체에 문제가 있었다. 두꺼운 하드보드를 일일이 손으로 잘라 외형을 만들다 보니
정밀도가 매우 떨어진다. 아무래 자로 재서 똑같은 모양으로 도면을 그렸다고 하더라도
커터로 자르다보면 오차가 안생길 수 없다. 게다가 두께가 3mm나 되다보니 절단면이 수직이
되는 경우가 거의 없다. 이런 문제들을 무시하고 대충 모양을 만들다보니 얼핏 봐서는 동일해
보이는 다리들이 서로 모양과 위치가 어긋나는 것이다. 그 중에 가장 중요한 것이 ‘각도’이다.
스케치에서 동일한 값을 주어도 실제 형태를 보면 미묘하게 각도가 다르게 서있다. 또한 내가 
예상한 각도와 실제 서있는 형태를 맞추기가 왜 그리 어려운지…바로 이런 것들이 수작업의 한계다. 


아래 그림에서 보면 내가 수학이나 공학적 지식이 전무하다보니 논리적으로 설명할 수는 없지만
그래도 인생의 경험으로 A, B 중 어느쪽이 더 안정적으로 서있을 수 있는지는 쉽게 알 수 있다.
나는 B의 형태를 원하는데 정도의 차이는 있지만 자꾸 A의 형태가 되어버린다…ㅠ.ㅠ





세상은 넓고 방법은 많다.


일단 이렇게 문제를 규정하고 나니 사실 당장에 할 수 있는 것이 없어보였다. 그저 3D 프린터에
대한 생각만 간절해질 뿐…-.-


그러던 차에 또 한가지 생각이 떠올랐다. 문제가 뭐가 되었든 힘이 없으면 뭔가로 보완을 해주면
될 것이 아닌가? 우리가 다리를 다치면 목발을 집듯이…그래서 스프링을 이용해서 자세를 유지하면
어떨까 하고 생각해보았다. 하여간 이놈에 잔대가리란~ 부랴부랴 스프링을 주문하고 적당하게
잘라서(자르다가 손목 나가는 줄 알았다…ㅠ.ㅠ) 아래 사진과 같이 연결을 해주었다.


오~이래놓으니 성능상 이점 뿐만 아니라 외관상으로도 뭔가 있어보이네…^^;;


일단 이렇게 스프링을 장착하니 가만히 서있는 자세에서도 확실히 소음과 진동이 줄었다. 스프링의
탄성이 모터의 힘을 보완해주는 것이다. 그리고 아주 만족스럽진 않지만 움직임도 좀 더 안정적으로
보인다.


일단 그 동안의 문제는 해결을 한 것 같다. 하지만 역시 편법은 편법일뿐 근본적인 해결은 될 수 없다.
편법은 문제를 해결할 수는 있지만 그만큼의 비용과 수고를 지불해야 한다. 로봇 만들기 초반에도
잠시 언급했지만 내가 취미로 하고있으니 감수할 만한 내용이지 상업용으로 무언가를 만드는데 이렇다면
당장 일터에서 잘리겠지…-.-


그리고 다음을 위해…


아무튼 이렇게 해서 일단 SEW MK I은 마무리를 하게 되었다. 표면적으로는 어느 정도 문제를
해결한 것 같으나 역시나 근본적인 문제를 해결하지 못했다는 것이 못내 아쉽다.



얼마전 올해 2017년 계획을 포스팅을 했는데 아무래도 거기에 3D 프린터 구매를 추가해야 할 것 
같다. 그리고 좀 더 정밀한 설계를 바탕으로 SEW MK II를 제작해봐야겠다.


시간이 나는대로 SEW MK I의 나머지 동작에 대한 스케치를 마무리하고 한 번 정도는 더 포스팅을
할 지는 모르겠으나 일단 여기서 MK I 개발은 마무리 하려고 한다.


그리고 얼마전 로봇에 FPV 기능을 구현해보고자 계획을 세웠었는데 FPV쪽은 아두이노로 자작할
만한 내용이 거의 없는데다가 관련 모듈 값들이 비싸서 일단 보류 하기로 했다.


그럼 더 나은 MK II를 위하여!

블로그 이미지

마즈다

이미 마흔을 넘어섰지만 아직도 꿈을 좇고 있습니다. 그래서 그 꿈에 다가가기 위한 단편들을 하나 둘 씩 모아가고 있지요. 이 곳에 그 단편들이 모일 겁니다...^^