<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NTREXGO - 디바이스마트, 엔티렉스 컨텐츠 통합 사이트 &#187; 프로젝트</title>
	<atom:link href="http://www.ntrexgo.com/archives/category/magazine/project/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ntrexgo.com</link>
	<description>엔티렉스, 디바이스마트 컨텐츠 통합 사이트</description>
	<lastBuildDate>Thu, 03 Mar 2022 06:47:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>[64호]레트로디세이(Retrodyssey)</title>
		<link>http://www.ntrexgo.com/archives/39455</link>
		<comments>http://www.ntrexgo.com/archives/39455#comments</comments>
		<pubDate>Mon, 22 Feb 2021 00:00:10 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[64호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[RETRODYSSEY]]></category>
		<category><![CDATA[게임기]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[레트로]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=39455</guid>
		<description><![CDATA[디바이스마트매거진 64호 &#124; Odyssey x86으로 여러 가지를 개발하고 싶어 하는 개발자뿐만 아니라, 콘솔 게임에 대한 추억을 가지고 있는 일반인들도 함께 즐길 수 있도록 레트로디세이를 구성하였다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-555.png" rel="lightbox[39455]"><img class="alignnone size-large wp-image-39500" alt="64 ptb 레트로디세이 (555" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-555-620x192.png" width="620" height="192" /></a></p>
<p><strong>Odyssey 미니PC로 만들어본 DIY 콘솔 게임장치</strong></p>
<p><span style="font-size: x-large;color: #ff6600"><strong>레트로디세이(Retrodyssey)</strong></span></p>
<p>글 | 성균관대학교(IWMYS) 임혁수, 김현목, 허재호, 이형욱</p>
<p>&nbsp;</p>
<p><span style="color: #ff6600"><strong>1. 작품 개요</strong></span><br />
Odyssey x86으로 여러 가지를 개발하고 싶어 하는 개발자뿐만 아니라, 콘솔 게임에 대한 추억을 가지고 있는 일반인들도 함께 즐길 수 있도록 레트로디세이를 구성하였습니다. Window PC에서 개인이 좋아하는 온라인 게임(STEAM)을 콘솔로 플레이할 수 있으며, Window PC와 Arduino GPIO의 결합이라는 Odyssey x86의 장점을 확인할 수 있는 프로젝트입니다.<br />
또한, 외관을 레트로 디자인으로 설계하여 과거에 대한 향수를 느끼며 추억하는 어른과, 뉴트로에 빠진 젊은이들의 흥미를 끌어 낼 수 있도록 디자인했습니다.</p>
<p><span style="color: #ff9900"><strong>1.1. 관련 시장의 성장</strong></span></p>
<p>아지는 현대인들을 위한, Window용 콘솔 장치의 시장성도 성장하리라 예측합니다. 따라서 Odyssey x86 미니 PC로 DIY 콘솔 게임 장치에 대한 사람들의 욕구를 자극하고자 합니다.<br />
“한국콘텐츠진흥원이 발간한 2020 대한민국 게임백서에 따르면 2019년 국내 게임 시장규모는 15조 5,750억 원이다. 이 중 2019년 콘솔 게임 시장 매출은 6,946억 원을 기록했고 점유율은 4.5%다. 2018년 대비 매출액은 1,660억 원 늘었고, 성장률은 31.4%에 달했다. 어마어마한 성장세다.“(동아일보, 2020.12.23, 조광민)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-2.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39462" alt="64 ptb 레트로디세이 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-2.png" width="620" height="293" /></a></p>
<p><span style="color: #ff9900"><strong>1.2. ODYSSEY x86 만의 장점 극대화</strong></span><br />
이 작품은 Window 운영체제와 아두이노를 내장한 오디세이(Odyssey) 보드로 제작되었습니다. 인터넷을 통해 스팀(Steam)을 비롯한 플랫폼에서 게임을 다운로드받아 플레이할 수 있으며, 조이스틱과 8개의 버튼을 개인별 취향에 맞게 설정할 수 있습니다. 이는 Window와 Arduino가 결합된, 오디세이 만의 장점을 극대화한 활용법입니다.</p>
<p><span style="color: #ff6600"><strong>2. 작품 설명</strong></span><br />
이 작품은 1개의 조이스틱과 8개의 버튼으로 구성되어 있습니다. 조이스틱은 마우스와 키보드로 전환되어 사용될 수 있습니다. 8개의 버튼은 각각 키보드 버튼과 매핑(Mapping) 되어 있습니다. 제품과 함께 제공되는 GUI 프로그램을 이용해 매핑된 키보드 버튼을 바꿀 수 있습니다. 자신의 STEAM 최애 게임을 콘솔로 즐겨보세요!<br />
(※ 최애 : 최고로 애정한다. 가장 사랑함)</p>
<p><span style="color: #ff9900"><strong>2.1. 주요 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-1.jpg" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39459" alt="64 ptb 레트로디세이 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-1.jpg" width="620" height="406" /></a></p>
<p><span style="color: #cc99ff"><strong>2.1.1. 레트로 감성의 디자인</strong></span><br />
어릴 적 오락실 게임기와 닌X도의 게임기를 떠올리게 하는 바로 그 디자인입니다. 게임을 즐기지 않더라도 인테리어 용품으로도 인기만점! 이제 하나씩 만드는 과정을 살펴보도록 하겠습니다!</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-2.jpg" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39461" alt="64 ptb 레트로디세이 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-2.jpg" width="620" height="339" /></a></p>
<p><span style="color: #cc99ff"><strong>2.1.2. 조이스틱과 버튼을 키보드와 마우스로 이용</strong></span><br />
조이스틱을 A0와 A1 아날로그 입력으로 설정합니다. 조이스틱의 x축 y축의 가변저항이 기울어짐을 측정해, 아날로그값을 전달합니다. 이 데이터를 기반으로 마우스 움직임 (Mouse.move()) 또는, 키보드 방향키(←↑→↓)를 움직입니다.<br />
또한, 키보드의 경우 (Keyboard.press())를 이용하여, 버튼이 입력되면 키의 입력을 설정합니다. 또한, count 변수를 설정해 키보드를 꾹 누를 때 발생하는 반복 입력의 경우도 대처합니다. 모든 경우가 키보드와 동일하게 작동합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-3.png" rel="lightbox[39455]"><img class="alignnone size-large wp-image-39464" alt="64 ptb 레트로디세이 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-3-546x620.png" width="546" height="620" /></a></p>
<p><span style="color: #cc99ff"><strong>2.1.3. 일반인을 위한 GUI를 이용한 키 매핑</strong></span><br />
게임의 경우 모든 키가 동일하지 않습니다. 그래서 저희 컨트롤러는 여러 게임에 호환하여 적용할 수 있도록 키를 설정합니다. 저희는 코드에 익숙하지 않은 사람들도 쉽게 사용할 수 있도록 Qt creator를 사용해 GUI 인터페이스를 만들었습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-5.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39468" alt="64 ptb 레트로디세이 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-5.png" width="212" height="227" /></a></p>
<p>사용자는 GUI 환경에서 A부터 Z까지 25개의 알파벳과 ‘ESC’, ‘TAB’ 2개 특수키, 총 27개의 키를 게임기 버튼에 할당할 수 있습니다. 사용자는 슬라이드를 사용하거나 직접 해당하는 글자를 타이핑한 후(단, 이때 모든 글자는 대문자로 쓰여야 합니다.) ‘DEVICEMART’ 버튼을 클릭하면 해당 정보를 오디세이 x86으로 시리얼 통신을 통해 보낼 수 있는데 이를 통해 게임기의 키 셋업을 마칠 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-6.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39470" alt="64 ptb 레트로디세이 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-6.png" width="620" height="399" /></a></p>
<p><strong style="color: #ff9900">2.2. 전체 시스템 구성</strong></p>
<p>오디세이에서 Steam 게임을 구동합니다. 그리고 조이스틱과 버튼으로 키의 입력을 받습니다. 키를 변경하고 싶으면 qt 배포판 GUI를 실행하여 키를 커스텀합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-7.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39472" alt="64 ptb 레트로디세이 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-7.png" width="620" height="376" /></a></p>
<p><strong style="color: #ff9900">2.3. 개발 환경(개발 언어, Tool, 사용 시스템 등)</strong></p>
<p>아래는 사용한 부품목록입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-8.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39474" alt="64 ptb 레트로디세이 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-8.png" width="620" height="325" /></a></p>
<p><span style="color: #cc99ff"><strong>2.3.1. Hardware(외관 설계)</strong></span></p>
<p>Autodesk Inventor 2020, Autodesk Fusion 360을 사용했습니다. 하드웨어 설계를 위해 사용합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-9.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39475" alt="64 ptb 레트로디세이 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-9.png" width="620" height="91" /></a></p>
<p><span style="color: #cc99ff"><strong>2.3.2. Hardware(Odyssey x86)</strong></span></p>
<p>Arduino IDE 1.8.1 버전을 사용했습니다. 오디세이 x86으로 windows 운영체제에서 아두이노 IDE를 사용하기 위해서는 초기 세팅 과정을 거쳐야 합니다.<br />
1단계) 파일 &#8211; 환경설정 &#8211; 추가적인 보드매니저 추가하기 아래 URL을 보드매니저에 추가해줍니다. https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json<br />
2단계) 보드 매니저 추가하기. 툴 &#8211; 보드 &#8211; 보드매니저에서 “Seeeduino Zero” 설치<br />
3단계) 보드와 포트를 Seeeduino Zero로 선택해주세요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-10.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39476" alt="64 ptb 레트로디세이 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-10.png" width="620" height="350" /></a></p>
<p><span style="color: #cc99ff"><strong>2.3.3. GUI용 qt 프로그래밍 작성 &#8211; QT creator , C++</strong></span></p>
<p>Qt creator는 GUI 프로그램을 개발할 때 많이 사용되는 프레임워크입니다. 저희는 Qt creator 5.15.2 버전을 사용했습니다. 사용자는 Qt creator를 설치하지 않더라도 저희가 만든 파일중 ‘Retrodyssey_성균관대(IWMYS)/소스코드/qt배포판’ 안에 있는 ‘retrodyssey’ 폴더(또는 압축파일)을 다운로드 받아 손쉽게 GUI 인터페이스를 사용할 수 있습니다.</p>
<p><span style="background-color: #ffffff;color: #3366ff"><strong>  <a title="첨부자료 이동" href="https://blog.naver.com/no1_devicemart/222244126252" target="_blank"><span style="background-color: #ffffff;color: #3366ff">qt 배포판은 디바이스마트 블로그 해당 게시글 첨부자료에서 확인하실 수 있습니다.</span></a>  </strong></span></p>
<p>&nbsp;</p>
<p><strong>2.3.3.1 GUI 환경의 코드를 개인적으로 수정하고 싶은 경우</strong><br />
Qt creator는 https://www.qt.io/ 에서 다운로드 할 수 있습니다. Qt creator을 설치한다면 GUI를 위해 작성한 코드의 세부구조를 개인이 원하는 대로 수정하거나 기능을 추가할 수 있습니다. 아래는 Qt 공식 홈페이지에서 설치파일을 다운받는 과정입니다. 설치파일을 실행하는 경우, Qt creator의 버전만 5.15.2 버전으로 설정해주고 나머지는 디폴트 상태로 설정한 후 다운로드 받으면 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-12.png" rel="lightbox[39455]"><img class="alignnone  wp-image-39478" alt="64 ptb 레트로디세이 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-12-528x620.png" width="620" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-13.png" rel="lightbox[39455]"><img class="alignnone size-large wp-image-39479" alt="64 ptb 레트로디세이 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-13-620x252.png" width="620" height="252" /></a><br />
작성한 코드는 ‘Retrodyssey_성균관대(IWMYS)/소스코드/qt’ 에 들어있는 ‘seedcontroller’ 폴더 안에 들어 있으며 해당 폴더(‘seedcontroller’)를 ‘로컬디스크/Users/사용자명/문서’로 옮기거나 해당 사용자의 qt 파일이 저장되는 경로로 옮기면 코드를 수정할 수 있습니다. 아래는 경로의 예시입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-14.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39480" alt="64 ptb 레트로디세이 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-14.png" width="615" height="161" /></a></p>
<p><strong>  <a title="첨부자료 이동" href="https://blog.naver.com/no1_devicemart/222244126252" target="_blank">qt 배포판은 디바이스마트 블로그 해당 게시글 첨부자료에서 확인하실 수 있습니다.</a>  </strong></p>
<p><strong>2.3.3.2 배포한 GUI 환경을 그대로 사용하고 싶은 경우</strong><br />
만약 가볍게 구현해보고자 하는 사람이라면 저희가 배포한 배포 파일 ‘Retrodyssey_성균관대(IWMYS)/소스코드/qt배포판’ 안에 있는 ‘retrodyssey’ 폴더를 다운로드 받는다면 GUI 인터페이스를 사용할 수 있습니다. ‘retrodyssey’ 폴더 안에는 qt배포판 실행을 위한 여러 라이브러리가 들어 있는데 이들 중 ‘seedcontroller’을 실행하면, 게임 실행을 위한 키 설정을 할 수 있습니다.<br />
게임기 키 설정을 위해서는 우선 오디세이 x86보드에 우선 아두이노 코드가 올라가 있어야 합니다. 아두이노 코드가 보드에 올라가 있다면, 다음으로 오디세이 x86보드와 통신하기 위해, USB 포트 번호를 설정해주어야 합니다. 배포판의 경우, ‘COM8’의 포트와 연결되도록 만들어져 있으므로 다음과 같은 과정을 거쳐 포트명을 ‘COM8’로 바꿔줘야 합니다.</p>
<p>1단계) 장치 관리자에서 아두이노와 연결된 포트를 찾아 선택해줍니다.<br />
2단계) ‘포트 설정’에서 고급 탭을 선택합니다.<br />
3단계) 포트명을 ‘COM8’로 바꿔줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-15.png" rel="lightbox[39455]"><img class="alignnone size-large wp-image-39481" alt="64 ptb 레트로디세이 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-15-620x378.png" width="620" height="378" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-16.png" rel="lightbox[39455]"><img class="alignnone size-large wp-image-39482" alt="64 ptb 레트로디세이 (16)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-16-620x317.png" width="620" height="317" /></a></p>
<p>그렇게 포트설정을 끝냈다면 이후 다운로드 받은 ‘retrodyssey’ 폴더 안의 ‘seedcontroller’ 파일을 실행해 원하는 키보드 정보를 입력하고 ‘DEVICEMART’버튼을 눌러주면 게임기 키 설정을 할 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-26.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39492" alt="64 ptb 레트로디세이 (26)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-26.png" width="620" height="371" /></a></p>
<p><span style="color: #ff6600"><strong>3. 단계별 제작 과정</strong></span><br />
<span style="color: #ff9900"><strong>3.1. 3D 본체 설계</strong></span><br />
모델링을 함에 있어서 게임기의 모습을 부각시키기 위해 노력했습니다. 디자인적 측면에서 버튼과 조이스틱이 둥글다는 공통점을 가지고 있어, 버튼과 조이스틱이 차지하는 부분은 둥근 원으로 디자인하였습니다. 또한 게임기를 떠올릴 때, 강력하게 대비대는 빨간색과 파란색으로 색깔을 입혔으며 메인 프레임의 모든 색상은 이를 부각할 수 있는 하얀색으로 디자인했습니다. 수치와 설계 부분에 있어서는 Inventor를 이용하여 진행했습니다.<br />
부품 구성은 메인 프레임 각각 좌, 우 부분과 조이스틱이 들어가는 부분과 고정시켜주는 부분 마지막으로 버튼 6개를 담을 버튼 프레임으로 구성 되어있습니다. 전체적인 모습은 다음과 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-18.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39484" alt="64 ptb 레트로디세이 (18)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-18.png" width="620" height="515" /></a></p>
<p>조이스틱과 버튼을 설치할 프레임들은 공통적으로 메인프레임에 안정적으로 거치될 수 있는 것을 목표로 했습니다. 그 결과 위아래의 지름을 다르게 하여, 걸칠 수 있게 설계하였습니다.<br />
조이스틱을 담을 파트와 받침 부분은 조이스틱을 움직이는 과정에서 흔들림이 없이 고정되어야 하므로 나사 연결방식을 채택하였습니다. 이는 M1.2 나사를 사용하도록 설계하였고 고정하는 구멍은 총 4개로 설계되었습니다.<br />
오디세이를 담을 메인프레임의 설계는 두 손을 올려 장시간 게임을 함에 있어서 무리가 가지 않도록 높이를 10cm로 설계하였습니다. 이는 버튼과 조이스틱 등을 오디세이와 연결할 때 많은 회로가 메인프레임 내부에서 엉키지 않게 하려는 부분도 고려한 수치입니다.<br />
그보다도 가장 많이 신경을 쓴 부분은 단연 오디세이가 들어가는 부분입니다.<br />
이 제품의 가장 중요한 것은 오디세이입니다. 오디세이가 어떤 식으로도 손상이 가면 안 되기 때문에, 오디세이를 단단하게 고정해줄 나사의 위치를 선정하는 것부터, 발열 해소를 위해 팬이 들어가는 공간을 특히나 신경 써 설계하였습니다. 발열 해소를 하지 못한다면, 기능의 저하와 손상으로 직결되는 부분이니 반드시 고려 해야 했습니다.<br />
그 결과 팬이 바닥과 충분한 거리로 떨어져 있고, 바닥엔 직사각형으로 여러 구멍을 뚫어 설계를 진행하였습니다. 위의 설명의 설계 이미지는 다음과 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-19.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39485" alt="64 ptb 레트로디세이 (19)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-19.png" width="620" height="212" /></a></p>
<p>또한, 메인 윗 파트와 연결하는 부분을 원 지름을 가로질러 설계를 하였는데 이는 M3나사를 사용하도록 설계했습니다. 추가로 메인 프레임에서 HDMI 케이블이나 다른 여러 선들을 연결하기 위한 공간을 설계한 것 또한 볼 수 있습니다. 자세한 사진은 다음과 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-20.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39486" alt="64 ptb 레트로디세이 (20)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-20.png" width="620" height="189" /></a></p>
<p>최종 설계 부품들은 다음과 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-21.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39487" alt="64 ptb 레트로디세이 (21)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-21.png" width="620" height="349" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-22.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39488" alt="64 ptb 레트로디세이 (22)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-22.png" width="620" height="216" /></a></p>
<p>그리고 추가로 Odyssey x86 전용 게임기라는 것을 나타내기 위해, 디바이스마트와 seeed의 로고를 삽입하였습니다. 아래 별표 분에 꽂아주면 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-23.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39489" alt="64 ptb 레트로디세이 (23)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-23.png" width="620" height="216" /></a></p>
<p>그리고 조이스틱 부분도 설계하였습니다. 2가지 모델로 설계하였으나, 일반 조이스틱 모듈을 사용하는 경우, 조이스틱은 추가하지 않는 게 좋습니다. 지렛대의 원리로 인해 힘점이 작용점보다 멀어지게 되어, 조이스틱 특유의 탄성을 느끼기 힘들어집니다. 저희 팀이 시연할 때도 제거하고 플레이하였습니다. 좌측 조이스틱은 M3 규격의 나사로 조립하면 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-3.jpg" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39463" alt="64 ptb 레트로디세이 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-3.jpg" width="620" height="385" /></a></p>
<p><span style="color: #ff9900"><strong>3.2. 조이스틱 및 버튼 회로 연결</strong></span><br />
조이스틱 모듈과 버튼을 오디세이의 GPIO에 연결하여 줍니다. 이때, 버튼은 풀다운 저항을 사용하여, 값이 튀지 않도록 해줍니다. 내부 연결 회로를 제작한 후, 가조립하여 작동여부를 확인합니다. 먼저 아래 회로도에 따라 연결합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-24.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39490" alt="64 ptb 레트로디세이 (24)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-24.png" width="620" height="376" /></a></p>
<p>이후 가조립하여 테스트합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-4.jpg" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39465" alt="64 ptb 레트로디세이 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-4.jpg" width="620" height="559" /></a></p>
<p>아래는 각종 부품 연결상태를 확대한 모습입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-5.jpg" rel="lightbox[39455]"><img class="alignnone  wp-image-39467" alt="64 ptb 레트로디세이 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-5-504x620.jpg" width="620" /></a></p>
<p><span style="color: #ff9900"><strong>3.3. 오디세이 x86 코드 작성</strong></span><br />
우리는 Odyssey의 동작에서 크게 3가지 부분을 고려해야 합니다.<br />
1. qt와의 시리얼통신<br />
2. 조이스틱 조작<br />
3. 버튼 동작</p>
<p>해당 코드와 함께 살펴보겠습니다. 코드는 soo_odyssey.ino와 soo_odyssey_h의 헤더파일로 구성됩니다. 헤더파일에는 주로 하기 기능 구현을 위해 제작한 함수들이 담겨있습니다. 큰 흐름은 soo_odyssey.ino를 보며 확인하시면 됩니다.</p>
<p><span style="color: #cc99ff"><strong>3.3.1. [soo_retrodyssey.ino]</strong></span><br />
키보드 버튼에 연결된 GPIO를 저장합니다. 저는 D2~D9가 버튼으로 동작하고 있습니다. 그리고 key라는 배열에 우리가 버튼을 눌렀을 때, 입력될 키를 보관합니다. Received 배열은 qt와의 시리얼 통신으로 받아올 데이터를 저장합니다. qt는 바꿀 버튼의 ID 1개와, 해당 버튼에 매핑될 ASCII 데이터 2개를 송신합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>//PART0. 변수 선언<br />
#include &#8220;Keyboard.h&#8221;<br />
#include &#8220;Mouse.h&#8221;<br />
#include &#8220;soo_retrodyssey.h&#8221;</p>
<p>// 키보드 GPIO 세팅<br />
const int button1 = 2; //노1<br />
const int button2 = 3; //노2<br />
const int button3 = 4; //노3<br />
const int button4 = 5; //핑1<br />
const int button5 = 6; //핑2<br />
const int button6 = 7; //핑3<br />
const int button7 = 8; //검1<br />
const int button8 = 9; //검2</p>
<p>// 버튼의 중복입력을 방지하는 버퍼로 쓰일 배열입니다.<br />
int button1_state[2] = {0,0};<br />
int button2_state[2] = {0,0};<br />
int button3_state[2] = {0,0};<br />
int button4_state[2] = {0,0};<br />
int button5_state[2] = {0,0};<br />
int button6_state[2] = {0,0};<br />
int button7_state[2] = {0,0};<br />
int button8_state[2] = {0,0};</p>
<p>// ASCII 번호로 누를 키의 정보를 입력합니다. 8개의 버튼에 해당합니다.<br />
int key[8] = {97, 98, 99, 100, 101, 102, 1, 2};//기본세팅 a,b,c,d,e,f,TAB,ESC<br />
int received[24] = {0,};<br />
</div>
아래는 마우스 컨트롤을 위한 변수 선언입니다. 여기서 joystick_judger는 조이스틱을 방향키로 사용할지 마우스로 사용할지 선택할 수 있게 해줍니다. joystick_judger에는 D13에 연결된 스위치의 값이 저장될 겁니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>// 마우스세팅<br />
const int xAxis = A0; // x축 기울기를 읽습니다.<br />
const int yAxis = A1; // y축 기울기를 읽습니다.<br />
// 조이스틱을 마우스로 사용할지, 키보드로 사용할지 판단하는 GPIO입니다.<br />
const int joystick_judger = 13;<br />
bool mouse_or_arrow = false; //true: 마우스, false:화살표<br />
//const int mouseButton = 12; //조이스틱의 버튼을 사용하실 분은 주석을 해제하면 됩니다. 저는 사용하지 않았습니다.<br />
</div>
<p>간단하게 셋업을 진행합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>void setup() {<br />
//디지털핀을 세팅합니다.<br />
pinMode(button1, INPUT);<br />
pinMode(button2, INPUT);<br />
pinMode(button3, INPUT);<br />
pinMode(button4, INPUT);<br />
pinMode(button5, INPUT);<br />
pinMode(button6, INPUT);<br />
pinMode(button7, INPUT);<br />
pinMode(button8, INPUT);<br />
pinMode(joystick_judger, INPUT); //마우스 혹은 화살표</p>
<p>//시리얼과 마우스 키보드를 사용합니다.<br />
Serial.begin(9600);<br />
Mouse.begin();<br />
Keyboard.begin();</p>
<p>//시리얼 통신을 시작합니다.<br />
Serial.begin(9600);<br />
Serial.println(&#8220;setup finished&#8221;);<br />
}</p>
</div>
<p>메인 코드의 시작입니다. qt로부터 수신한 시리얼 데이터를 received 배열에 저장합니다. qt는 키매핑에 대한 데이터(바꿀 키 ID 1개와 매핑할 데이터 2개)를 시리얼로 전송합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>void loop() {<br />
//PART1. 시리얼 통신<br />
//Qt로부터 시리얼 데이터를 수신합니다.<br />
int i =0;<br />
while(Serial.available()&gt; 0){<br />
received[i] = Serial.read();<br />
i++;<br />
}</p>
</div>
<p>이제 키보드를 다룹니다. 첫번째, select_key 함수는 qt에서 받은 데이터를 저장한 received 배열의 데이터를 해석해, key 배열에 저장해 매핑합니다. 두번째, Key_press_once 함수는 중복 키 입력을 방지하는 코드입니다. 이 코드로 인해, 버튼을 꾹 누르면 키보드를 꾹 눌렀을 때와 동일하게 버튼이 작동합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>//PART2. 키보드<br />
//시리얼 데이터를 바탕으로, 키를 매핑하는 함수입니다.<br />
select_key(received, key);<br />
//<br />
//키를 누릅니다.<br />
key_press_once(button1, button1_state, key[0]);//노1<br />
key_press_once(button2, button2_state, key[1]);//노2<br />
key_press_once(button3, button3_state, key[2]);//노3<br />
key_press_once(button4, button4_state, key[3]);//핑1<br />
key_press_once(button5, button5_state, key[4]);//핑2<br />
key_press_once(button6, button6_state, key[5]);//핑3<br />
key_press_once(button7, button7_state, key[6]);//검1<br />
key_press_once(button8, button8_state, key[7]);//검2</p>
</div>
<p>조이스틱의 동작에 관한 코드입니다. joystick_judger로부터 조이스틱을 마우스로 사용할지, 방향키로 사용할지, 판단합니다. arrow_key는 마우스를 키보드 방향키로 사용하기 위해, 제작한 함수입니다. 추가로 딜레이는 조금만 주는 편이 좋습니다. 딜레이를 길게 주면, 키 입력이 무시될 가능성이 큽니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>//PART2. 조이스틱<br />
//조이스틱의 동작여부를 판단합니다.<br />
//D13번 키가 high면 조이스틱이 마우스로 동작, low면 화살표로 동작<br />
if (digitalRead(joystick_judger) == LOW) mouse_or_arrow = false;<br />
if (digitalRead(joystick_judger) == HIGH) mouse_or_arrow = true;</p>
<p>//조이스틱으로 마우스 혹은 키보드 화살표를 제어합니다.<br />
if (mouse_or_arrow) Mouse.move((int)readAxis(A0), (int)-readAxis(A1), 0);<br />
if (!mouse_or_arrow) arrow_key((int)readAxis(A0), (int)-readAxis(A1));</p>
<p>//조이스틱의 버튼을 클릭하는 함수입니다. 사용하지는 않지만 만들어봤습니다.<br />
//mouse_press(mouseButton);</p>
<p>//혹시 눌려져 있는 버튼이 있다면 종료합니다.<br />
Keyboard.releaseAll();<br />
delay(5);<br />
}</p>
</div>
<p><span style="color: #cc99ff"><strong>3.3.2. [soo_retrodyssey.h]</strong></span><br />
조이스틱과 버튼 제어를 위해 직접 제작한 함수입니다. 코드는 살펴보셔도 좋고, 아니면 그 기능만 살펴보셔도 좋습니다. 헤더파일의 함수 기능을 요약해 보았습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-25.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39491" alt="64 ptb 레트로디세이 (25)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-25.png" width="620" height="234" /></a></p>
<p>&nbsp;</p>
<p><strong style="color: #ff9900">3.4. GUI용 qt 프로그래밍 작성</strong></p>
<p>qt creator를 사용하기 위해 총 10개의 함수를 사용하였습니다. 게임기 셋업을 할 때, 슬라이드를 사용하기 위해 8개의 버튼에 해당하는 8개의 ‘on_slidernumber_valueChanged()’를 만들었으며, 슬라이드를 사용하거나 타이핑을 통해 입력한 키보드정보(A ~ Z, 25개의 알파벳과 ESC, TAB 2개의 특수키)를 읽어 아스키코드로 바꿔주는 ‘on_pushButton_clicker()’ 함수와 오디세이x86 보드와 연결된 상태에서 값을 전송해주는 ‘updateButton()’ 함수를 만들었습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-26.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39492" alt="64 ptb 레트로디세이 (26)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-26.png" width="620" height="371" /></a></p>
<p>이후 원하는 키보드를 설정하기 위해 UI환경에서 게임기의 자판 배열에 맞춰 왼쪽의 목록에서 ‘Line Edit’ 위젯과 ‘Vertical Scroll Bar’ 위젯을 사용해 입력 인터페이스를 만듭니다. 이후 키보드 값을 한번에 시리얼 통신으로 전송하기 위해 ‘Push Button’ 버튼을 사용합니다.</p>
<p><span style="color: #ff9900"><strong>3.5. 최종 조립</strong></span><br />
1단계) 밑판 위에 오디세이 보드를 고정시켜줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-6.jpg" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39469" alt="64 ptb 레트로디세이 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-6.jpg" width="620" height="313" /></a></p>
<p>2단계) 회로도에 맞게, 오디세이와 조이스틱 모듈 버튼을 연결합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-27.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39493" alt="64 ptb 레트로디세이 (27)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-27.png" width="620" height="323" /></a></p>
<p>3단계) 밑판의 나사선에 맞춰 윗판을 올린 후 M3 나사로 고정시킵니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-7.jpg" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39471" alt="64 ptb 레트로디세이 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-7.jpg" width="620" height="325" /></a></p>
<p>4단계) 원판(붉은색, 파란색)을 삽입하고, 로고(디바이스마트와 seeed 로고)도 끼워줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-28.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39494" alt="64 ptb 레트로디세이 (28)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-28.png" width="620" height="325" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-8.jpg" rel="lightbox[39455]"><img alt="64 ptb 레트로디세이 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-8.jpg" width="620" height="325" /></a></p>
<p>5단계) 완성된 게임기의 모습입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-29.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39495" alt="64 ptb 레트로디세이 (29)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-29.png" width="620" height="317" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-30.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39496" alt="64 ptb 레트로디세이 (30)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-30.png" width="620" height="320" /></a></p>
<p>그래서 이게 진짜, 되는 거야? 라고 하시는 분들을 위해 작동영상도 준비해봤습니다. 작품 시연은 아래 QR코드로 확인해주세요.</p>
<p><a title="시 연 영 사" href="//youtu.be/atN5hFQRGno" target="_blank"><span style="text-decoration: underline">시연 영상 보러가기</span></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-31.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39497" alt="64 ptb 레트로디세이 (31)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-31.png" width="620" height="385" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-32.png" rel="lightbox[39455]"><img class="alignnone size-full wp-image-39498" alt="64 ptb 레트로디세이 (32)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-32.png" width="620" height="231" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #ff6600"><strong>4. 기타</strong></span><br />
<span style="color: #ff9900"><strong>4.1. 소스코드</strong></span><br />
<span style="color: #cc99ff"><strong>4.1.1. odyssey x86 코드</strong></span><br />
soo_retrodyssey.ino</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>//PART0. 변수 선언<br />
#include &#8220;Keyboard.h&#8221;<br />
#include &#8220;Mouse.h&#8221;<br />
#include &#8220;soo_retrodyssey.h&#8221;</p>
<p>// 키보드 GPIO 세팅<br />
const int button1 = 2; //노1<br />
const int button2 = 3; //노2<br />
const int button3 = 4; //노3<br />
const int button4 = 5; //핑1<br />
const int button5 = 6; //핑2<br />
const int button6 = 7; //핑3<br />
const int button7 = 8; //검1<br />
const int button8 = 9; //검2</p>
<p>// 버튼의 중복입력을 방지하는 버퍼로 쓰일 배열입니다.<br />
int button1_state[2] = {0,0};<br />
int button2_state[2] = {0,0};<br />
int button3_state[2] = {0,0};<br />
int button4_state[2] = {0,0};<br />
int button5_state[2] = {0,0};<br />
int button6_state[2] = {0,0};<br />
int button7_state[2] = {0,0};<br />
int button8_state[2] = {0,0};</p>
<p>// ASCII 번호로 누를 키의 정보를 입력합니다. 8개의 버튼에 해당합니다.<br />
int key[8] = {97, 98, 99, 100, 101, 102, 1, 2};//기본세팅 a,b,c,d,e,f,TAB,ESC<br />
int received[24] = {0,};</p>
<p>// 마우스세팅<br />
const int xAxis = A0; // x축 기울기를 읽습니다.<br />
const int yAxis = A1; // y축 기울기를 읽습니다.<br />
// 조이스틱을 마우스로 사용할지, 키보드로 사용할지 판단하는 GPIO입니다.<br />
const int joystick_judger = 13;<br />
bool mouse_or_arrow = false; //true: 마우스, false:화살표<br />
//const int mouseButton = 12; //조이스틱의 버튼을 사용하실 분은 주석을 해제하면 됩니다. 저는 사용하지 않았습니다.<br />
void setup() {<br />
//디지털핀을 세팅합니다.<br />
pinMode(button1, INPUT);<br />
pinMode(button2, INPUT);<br />
pinMode(button3, INPUT);<br />
pinMode(button4, INPUT);<br />
pinMode(button5, INPUT);<br />
pinMode(button6, INPUT);<br />
pinMode(button7, INPUT);<br />
pinMode(button8, INPUT);<br />
pinMode(joystick_judger, INPUT); //마우스 혹은 화살표</p>
<p>//시리얼과 마우스 키보드를 사용합니다.<br />
Serial.begin(9600);<br />
Mouse.begin();<br />
Keyboard.begin();<br />
//시리얼 통신을 시작합니다.<br />
Serial.begin(9600);<br />
Serial.println(&#8220;setup finished&#8221;);<br />
}</p>
<p>void loop() {<br />
//PART1. 시리얼 통신<br />
//Qt로부터 시리얼 데이터를 수신합니다.<br />
int i =0;<br />
while(Serial.available()&gt; 0){<br />
received[i] = Serial.read();<br />
i++;<br />
}</p>
<p>//PART2. 키보드<br />
//시리얼 데이터를 바탕으로, 키를 매핑하는 함수입니다.<br />
select_key(received, key);<br />
//<br />
//키를 누릅니다.<br />
key_press_once(button1, button1_state, key[0]);//노1<br />
key_press_once(button2, button2_state, key[1]);//노2<br />
key_press_once(button3, button3_state, key[2]);//노3<br />
key_press_once(button4, button4_state, key[3]);//핑1<br />
key_press_once(button5, button5_state, key[4]);//핑2<br />
key_press_once(button6, button6_state, key[5]);//핑3<br />
key_press_once(button7, button7_state, key[6]);//검1<br />
key_press_once(button8, button8_state, key[7]);//검2<br />
//PART2. 조이스틱<br />
//조이스틱의 동작여부를 판단합니다.<br />
//D13번 키가 high면 조이스틱이 마우스로 동작, low면 화살표로 동작<br />
if (digitalRead(joystick_judger) == LOW) mouse_or_arrow = false;<br />
if (digitalRead(joystick_judger) == HIGH) mouse_or_arrow = true;</p>
<p>//조이스틱으로 마우스 혹은 키보드 화살표를 제어합니다.<br />
if (mouse_or_arrow) Mouse.move((int)readAxis(A0), (int)-readAxis(A1), 0);<br />
if (!mouse_or_arrow) arrow_key((int)readAxis(A0), (int)-readAxis(A1));</p>
<p>//조이스틱의 버튼을 클릭하는 함수입니다. 사용하지는 않지만 만들어봤습니다.<br />
//mouse_press(mouseButton);</p>
<p>//혹시 눌려져 있는 버튼이 있다면 종료합니다.<br />
Keyboard.releaseAll();<br />
delay(5);<br />
}<br />
</div>
<p>soo_retrodyssey.h</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>// 중복키 설정입니다.<br />
#define FIRST_KEY_DELAY 5 //첫 키입력후, 둘째 키 입력까지 기다리는 정도입니다.<br />
#define MAX_TOGGLE 8 //중복입력 속도를 조절합니다.</p>
<p>//Qt에서 수신한 내용을 ASCII로 저장합니다.<br />
int special_key(int a, int b){<br />
if((a==50) &amp;&amp;(b==54)){<br />
return 1;<br />
}<br />
if((a==50) &amp;&amp;(b==55)){<br />
return 2;<br />
}<br />
return a+49;<br />
}</p>
<p>//Function for 시리얼통신<br />
void select_key(int button_call[], int button_data[]){<br />
//키매핑하는 함수입니다.<br />
for(int i=0;i&lt;24;i++){<br />
switch(button_call[i]-96){<br />
case 1: button_data[6]=special_key(button_call[i+1],button_call[i+2]); break; //검1<br />
case 2: button_data[7]=special_key(button_call[i+1],button_call[i+2]); break; //검2<br />
case 3: button_data[3]=special_key(button_call[i+1],button_call[i+2]); break; //핑1<br />
case 4: button_data[4]=special_key(button_call[i+1],button_call[i+2]); break; //핑2<br />
case 5: button_data[5]=special_key(button_call[i+1],button_call[i+2]); break; //핑3<br />
case 6: button_data[0]=special_key(button_call[i+1],button_call[i+2]); break; //노1<br />
case 7: button_data[1]=special_key(button_call[i+1],button_call[i+2]); break; //노2<br />
case 8: button_data[2]=special_key(button_call[i+1],button_call[i+2]); break; //노3<br />
}<br />
}<br />
}</p>
<p>//조이스틱의 기울기를 읽고 각 축별 -1, 0 ,1을 반환합니다..<br />
int readAxis(int thisAxis) {<br />
int reading = analogRead(thisAxis);<br />
int range = 8;<br />
reading = map(reading, 0, 1023, 0, range);<br />
int distance = reading &#8211; (range / 2);</p>
<p>if (abs(distance) &lt; (range / 2)) {<br />
distance = 0;<br />
}<br />
return distance;<br />
}</p>
<p>//조이스틱으로 화살표를 동작합니다.<br />
void arrow_key( int x_line, int y_line){<br />
if (x_line &gt; 0) Keyboard.press(KEY_RIGHT_ARROW);<br />
if (x_line &lt; 0) Keyboard.press(KEY_LEFT_ARROW);<br />
if (y_line &lt; 0) Keyboard.press(KEY_UP_ARROW);<br />
if (y_line &gt; 0) Keyboard.press(KEY_DOWN_ARROW);<br />
}</p>
<p>//조이스틱으로 마우스 클릭을 하는 함수입니다. 저는 사용하지 않았습니다.<br />
void mouse_press(int mouse_button){<br />
if (digitalRead(mouse_button) == HIGH) {<br />
if (!Mouse.isPressed(MOUSE_LEFT)) Mouse.press(MOUSE_LEFT);<br />
}<br />
else {<br />
if (Mouse.isPressed(MOUSE_LEFT)) Mouse.release(MOUSE_LEFT);<br />
}<br />
}</p>
<p>//키보드를 누르는 코드입니다.<br />
//버튼이 꾹 눌릴경우에 대한, 중복키 설정을 하는 코드입니다.<br />
void key_press_once(const int key_name, int pre_state[], char data){<br />
if (*pre_state &gt; MAX_TOGGLE){<br />
*pre_state = 0;<br />
}<br />
if (digitalRead(key_name) == LOW){<br />
*pre_state = 0;<br />
pre_state[1] = 0;<br />
}<br />
if ((digitalRead(key_name) == HIGH) &amp;&amp;(*pre_state == 0)){<br />
if ((pre_state[1] == 0) || (pre_state[1] &gt; FIRST_KEY_DELAY )){<br />
if(data==1){<br />
Keyboard.press(KEY_TAB);<br />
}<br />
else if(data==2){<br />
Keyboard.press(KEY_ESC);<br />
}<br />
else{<br />
Keyboard.press(data);<br />
}<br />
}<br />
*pre_state = 1;<br />
pre_state[1] += 1;<br />
}<br />
if ((digitalRead(key_name) == HIGH) &amp;&amp;(*pre_state != 0)){<br />
*pre_state = *pre_state +1;<br />
}<br />
}<br />
</div>
<p><span style="color: #cc99ff"><strong>4.1.2. Qt creator 코드</strong></span></p>
<p>seedcontroller.pro</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>QT += core gui serialport // 아두이노 연결<br />
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets<br />
CONFIG += c++11<br />
SOURCES += \<br />
main.cpp \<br />
dialog.cpp<br />
HEADERS += \<br />
dialog.h<br />
FORMS += \<br />
dialog.ui<br />
qnx: target.path = /tmp/$${TARGET}/bin<br />
else: unix:!android: target.path = /opt/$${TARGET}/bin<br />
!isEmpty(target.path): INSTALLS += target<br />
</div>
<p>dialog.h</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#ifndef DIALOG_H<br />
#define DIALOG_H<br />
#include &lt;QDialog&gt;<br />
#include &lt;QSerialPort&gt; // 시리얼 통신을 위한 라이브러리<br />
#include &lt;QString&gt; // QString 자료형 사용을 위한 라이브러리</p>
<p>QT_BEGIN_NAMESPACE<br />
namespace Ui { class Dialog; }<br />
QT_END_NAMESPACE</p>
<p>class Dialog : public QDialog<br />
{<br />
Q_OBJECT<br />
public:<br />
Dialog(QWidget *parent = nullptr);<br />
~Dialog();<br />
private slots:<br />
void updateButton(QString); //시리얼 통신을 통해 아두이노로 값 전달<br />
void on_pushButton_clicked(); //키보드 정보를 유니코드 값으로 변환<br />
void on_slider1_valueChanged(int value); //게임기에 키보드 정보 할당<br />
void on_slider2_valueChanged(int value);<br />
void on_slider3_valueChanged(int value);<br />
void on_slider4_valueChanged(int value);<br />
void on_slider5_valueChanged(int value);<br />
void on_slider6_valueChanged(int value);<br />
void on_slider7_valueChanged(int value);<br />
void on_slider8_valueChanged(int value);</p>
<p>private:<br />
Ui::Dialog *ui; // UI 사용을 위한 객체 생성<br />
QSerialPort *arduino; // 시리얼 포트 연결을 위한 객체 생성<br />
QString arduino_port_name; // 아두이노 포트 정보를 저장할 변수<br />
bool arduino_is_available; // 아두이노가 연결되었는지 확인하는 변수<br />
};<br />
#endif // DIALOG_H<br />
</div>
<p>dialog.cpp</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include &#8220;dialog.h&#8221;<br />
#include &#8220;ui_dialog.h&#8221;<br />
#include &lt;QSerialPort&gt;<br />
#include &lt;QSerialPortInfo&gt;<br />
#include &lt;QDebug&gt;<br />
#include &lt;QtWidgets&gt;</p>
<p>Dialog::Dialog(QWidget *parent)<br />
: QDialog(parent)<br />
, ui(new Ui::Dialog)<br />
{<br />
ui-&gt;setupUi(this);<br />
arduino_is_available = true;<br />
arduino_port_name = &#8220;COM5&#8243;; // 포트 지정<br />
arduino = new QSerialPort;<br />
if(arduino_is_available)<br />
{<br />
// 아두이노와 시리얼 포트 연결을 위한 설정<br />
arduino-&gt;setPortName(arduino_port_name);<br />
arduino-&gt;open(QSerialPort::WriteOnly);<br />
arduino-&gt;setBaudRate(QSerialPort::Baud9600);<br />
arduino-&gt;setDataBits(QSerialPort::Data8);<br />
arduino-&gt;setParity(QSerialPort::NoParity);<br />
arduino-&gt;setStopBits(QSerialPort::OneStop);<br />
arduino-&gt;setFlowControl(QSerialPort::NoFlowControl);<br />
}<br />
else<br />
{<br />
// 에러 확인<br />
QMessageBox::warning(this, &#8220;Port error&#8221;, &#8220;Cannot connect to Arduino!!!&#8221;);<br />
}<br />
}</p>
<p>Dialog::~Dialog()<br />
{<br />
if (arduino-&gt;isOpen())<br />
{<br />
arduino-&gt;close();<br />
}<br />
delete ui;<br />
}</p>
<p>void Dialog::updateButton(QString command)<br />
{<br />
if(arduino-&gt;isWritable())<br />
{<br />
arduino-&gt;write(command.toStdString().c_str());<br />
}<br />
else<br />
{<br />
qDebug() &lt;&lt; &#8220;Cannot write to serial!&#8221;;<br />
}<br />
}</p>
<p>void Dialog::on_pushButton_clicked()<br />
{<br />
//버튼에 적힌 값을 읽은 후, 그 값이 TAB 이면 26, ESC 이면 27,<br />
//나머지 키보드(알파벳)이면 0 ~ 25의 값을 아두이노로 보낸다.<br />
QString one = ui-&gt;value_label1-&gt;text();<br />
if(one == &#8220;TAB&#8221;)<br />
{<br />
int a = 91;<br />
Dialog::updateButton(QString(&#8220;a%1&#8243;).arg(a-65));<br />
}<br />
else if(one == &#8220;ESC&#8221;)<br />
{<br />
int a = 92;<br />
Dialog::updateButton(QString(&#8220;a%1&#8243;).arg(a-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; one.length(); i++)<br />
{<br />
int one1 = one.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;a%1&#8243;).arg(one1-65));<br />
}<br />
}</p>
<p>QString two = ui-&gt;value_label2-&gt;text();<br />
if(two == &#8220;TAB&#8221;)<br />
{<br />
int b = 91;<br />
Dialog::updateButton(QString(&#8220;b%1&#8243;).arg(b-65));<br />
}<br />
else if(two == &#8220;ESC&#8221;)<br />
{<br />
int b = 92;<br />
Dialog::updateButton(QString(&#8220;b%1&#8243;).arg(b-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; two.length(); i++)<br />
{<br />
int two1 = two.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;b%1&#8243;).arg(two1-65));<br />
}<br />
}<br />
QString three = ui-&gt;value_label3-&gt;text();<br />
if(three == &#8220;TAB&#8221;)<br />
{<br />
int c = 91;<br />
Dialog::updateButton(QString(&#8220;c%1&#8243;).arg(c-65));<br />
}<br />
else if(three == &#8220;ESC&#8221;)<br />
{<br />
int c = 92;<br />
Dialog::updateButton(QString(&#8220;c%1&#8243;).arg(c-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; three.length(); i++)<br />
{<br />
int three1 = three.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;c%1&#8243;).arg(three1-65));<br />
}<br />
}</p>
<p>QString four = ui-&gt;value_label4-&gt;text();<br />
if(four == &#8220;TAB&#8221;)<br />
{<br />
int d = 91;<br />
Dialog::updateButton(QString(&#8220;d%1&#8243;).arg(d-65));<br />
}<br />
else if(four == &#8220;ESC&#8221;)<br />
{<br />
int d = 92;<br />
Dialog::updateButton(QString(&#8220;d%1&#8243;).arg(d-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; four.length(); i++)<br />
{<br />
int four1 = four.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;d%1&#8243;).arg(four1-65));<br />
}<br />
}</p>
<p>QString five = ui-&gt;value_label5-&gt;text();<br />
if(five == &#8220;TAB&#8221;)<br />
{<br />
int e = 91;<br />
Dialog::updateButton(QString(&#8220;e%1&#8243;).arg(e-65));<br />
}<br />
else if(five == &#8220;ESC&#8221;)<br />
{<br />
int e = 92;<br />
Dialog::updateButton(QString(&#8220;e%1&#8243;).arg(e-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; five.length(); i++)<br />
{<br />
int five1 = five.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;e%1&#8243;).arg(five1-65));<br />
}<br />
}</p>
<p>QString six = ui-&gt;value_label6-&gt;text();<br />
if(six == &#8220;TAB&#8221;)<br />
{<br />
int f = 91;<br />
Dialog::updateButton(QString(&#8220;f%1&#8243;).arg(f-65));<br />
}<br />
else if(six == &#8220;ESC&#8221;)<br />
{<br />
int f = 92;<br />
Dialog::updateButton(QString(&#8220;f%1&#8243;).arg(f-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; six.length(); i++)<br />
{<br />
int six1 = six.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;f%1&#8243;).arg(six1-65));<br />
}<br />
}<br />
QString seven = ui-&gt;value_label7-&gt;text();<br />
if(seven == &#8220;TAB&#8221;)<br />
{<br />
int g = 91;<br />
Dialog::updateButton(QString(&#8220;g%1&#8243;).arg(g-65));<br />
}<br />
else if(seven == &#8220;ESC&#8221;)<br />
{<br />
int g = 92;<br />
Dialog::updateButton(QString(&#8220;g%1&#8243;).arg(g-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; seven.length(); i++)<br />
{<br />
int seven1 = seven.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;g%1&#8243;).arg(seven1-65));<br />
}<br />
}</p>
<p>QString eight = ui-&gt;value_label8-&gt;text();<br />
if(eight == &#8220;TAB&#8221;)<br />
{<br />
int h = 91;<br />
Dialog::updateButton(QString(&#8220;h%1&#8243;).arg(h-65));<br />
}<br />
else if(eight == &#8220;ESC&#8221;)<br />
{<br />
int h = 92;<br />
Dialog::updateButton(QString(&#8220;h%1&#8243;).arg(h-65));<br />
}<br />
else<br />
{<br />
for (int i=0; i &lt; eight.length(); i++)<br />
{<br />
int eight1 = eight.at(i).unicode();<br />
Dialog::updateButton(QString(&#8220;h%1&#8243;).arg(eight1-65));<br />
}<br />
}<br />
}</p>
<p>//슬라이드를 움직인 정도(0 ~ 27)를, A ~ Z, TAB, ESC 로 바꿔 QLabelEdit 출력<br />
void Dialog::on_slider1_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label1-&gt;setText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label1-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label1-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}<br />
void Dialog::on_slider2_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label2-&gt;setText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label2-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label2-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}<br />
void Dialog::on_slider3_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label3-&gt;setText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label3-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label3-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}<br />
void Dialog::on_slider4_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label4-&gt;setText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label4-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label4-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}<br />
void Dialog::on_slider5_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label5-&gt;se tText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label5-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label5-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}<br />
void Dialog::on_slider6_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label6-&gt;setText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label6-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label6-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}<br />
void Dialog::on_slider7_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label7-&gt;setText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label7-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label7-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}<br />
void Dialog::on_slider8_valueChanged(int value)<br />
{<br />
int nvalue = value+65;<br />
if (nvalue == 91)<br />
{<br />
ui-&gt;value_label8-&gt;setText(&#8220;TAB&#8221;);<br />
}<br />
else if (nvalue == 92)<br />
{<br />
ui-&gt;value_label8-&gt;setText(&#8220;ESC&#8221;);<br />
}<br />
else<br />
{<br />
ui-&gt;value_label8-&gt;setText(QString(value+65));<br />
qDebug() &lt;&lt; value;<br />
}<br />
}</p>
</div>
<p>main.cpp</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include &#8220;dialog.h&#8221;<br />
#include &lt;QApplication&gt;<br />
#include &lt;QPixmap&gt;</p>
<p>int main(int argc, char *argv[])<br />
{<br />
QApplication a(argc, argv);<br />
Dialog w;<br />
w.setFixedSize(750, 450);<br />
w.setWindowTitle(&#8220;DEVICEMART &amp;&amp; SEED GAME MACHINE SETTING&#8221;);<br />
w.show();<br />
return a.exec();<br />
}</p>
</div>
<p><span style="color: #ff9900"><strong>4.2. 참고문헌</strong></span></p>
<p>https://www.donga.com/news/It/article/all/20201223/104607777/1</p>
<p>&nbsp;</p>
<p><a title="제품 상세 보러가기" href="https://www.devicemart.co.kr/goods/view?no=12527976" target="_blank"><img class="alignnone size-full wp-image-39499" alt="64 ptb 레트로디세이 (33)" src="http://www.ntrexgo.com/wp-content/uploads/2021/02/64-ptb-레트로디세이-33.png" width="620" height="389" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/39455/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[61호]음성으로 제어하는 간접등 만들기</title>
		<link>http://www.ntrexgo.com/archives/38614</link>
		<comments>http://www.ntrexgo.com/archives/38614#comments</comments>
		<pubDate>Wed, 26 Aug 2020 00:00:07 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[제품 리뷰]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[61호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[간접등]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[따라하기]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[무작정]]></category>
		<category><![CDATA[음성인식]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=38614</guid>
		<description><![CDATA[디바이스마트매거진 61호 &#124; 디바이스마트 매거진 구독자분들이 이러한 4차 산업혁명 시대에 빠질 수 없는 사물인터넷, 스마트홈에 대한 개념을 이해하고 생각해볼 수 있는 시간을 갖고, 코로나19로 지친 심신을 원하는 장소의 간접등을 설치하는 과정을 통해 기분을 전환해보는건 어떨까 하여 이번 프로젝트를 소개해드리게 되었습니다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-1.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38908" alt="61 ptb 음성간접등 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-1-620x234.png" width="620" height="234" /></a></p>
<p><span style="background-color: #333399; color: #ffffff;"><strong>  아두이노 DIY 무작정 따라하기 (중·고급편)  </strong></span></p>
<p><span style="font-size: xx-large; color: #333399;"><strong>음성으로 제어하는 간접등 만들기 </strong></span></p>
<p><span style="font-size: small;"><strong>음성인식 모듈을 활용하여 내 목소리로 간접등을 끄고 켜고 스마트한 나만의 공간 만들기!</strong></span></p>
<p style="text-align: right;">글 | 디바이스마트 정대진, 박진아</p>
<p>&nbsp;</p>
<p>스마트 스피커로 집안을 제어하거나, 집안의 전기 사용량, 온·오프 등을 앱으로 관리할 수 있게 만들어주는 사물인터넷, 스마트 홈에 대한 관심이 날로 높아지며 일상생활에 많은 변화를 주고 있습니다.<br />
그렇다면 스마트 홈이란 정확히 무엇일까요? 스마트 홈은 사물인터넷 등을 이용해서 가정 내의 시스템들을 자동/원격으로 조작 가능한 환경을 구축한 것을 의미합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
사물인터넷은 유무형의 객체들이 다양한 방식으로 서로 연결되어 개별 객체들이 제공하지 못했던 새로운 서비스를 제공할 수 있게 됨을 말합니다.<br />
</div>
디바이스마트 매거진 구독자분들이 이러한 4차 산업혁명 시대에 빠질 수 없는 사물인터넷, 스마트홈에 대한 개념을 이해하고 생각해볼 수 있는 시간을 갖고, 코로나19로 지친 심신을 원하는 장소의 간접등을 설치하는 과정을 통해 기분을 전환해보는건 어떨까 하여 이번 프로젝트를 소개해드리게 되었습니다.<br />
저희는 사무실이라는 공간적 제약이 있었기에 이번 프로젝트는 회의실 화이트보드위에 간접등을 설치하고 음성 인식 모듈을 통해 음성으로 불 켜짐과 꺼짐을 제어해 보았습니다. 집에서 따라하실 분은 신발장 하부나, 책상아래, 주요 장식장 등 원하는 위치에 설치해보고 따라하는 시간을 가져보시기 바랍니다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
Tip : LED 스트립 길이가 짧아 확장이 필요하다면 18AWG × 2C, 24AWG × 2C 규격의 전선을 구매 후 납땜하여 사용이 가능합니다. 확장한 전선을 깔끔하게 처리하고 싶으신 경우에는 케이블타이와 케이블타이 마운트를 필요한 수량만큼 구매하여 사용하시길 권장합니다.<br />
</div>
<p><span style="color: #0000ff;"><strong>1. 음성 제어 간접등 만들기에 필요한 제품소개</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-2.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38910" alt="61 ptb 음성간접등 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-2-620x448.png" width="620" height="448" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-3.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38912" alt="61 ptb 음성간접등 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-3-620x444.png" width="620" height="444" /></a></p>
<p>필수 준비물 제품은 각 각 한개씩 사용하였으며, 프로젝트에 사용되는 모든 제품은 디바이스마트에서 구매가 가능하오니 디바이스마트 검색창에 상품번호를 입력해보시기 바랍니다.</p>
<div class="symple-box blue none" style="text-align:left; width:100%;"> 
Tip : LED 스트립 길이가 짧아 확장이 필요하다면 18AWG × 2C, 24AWG × 2C 규격의 전선을 구매 후 납땜하여 사용이 가능합니다. 확장한 전선을 깔끔하게 처리하고 싶으신 경우에는 케이블타이와 케이블타이 마운트를 필요한 수량만큼 구매하여 사용하시길 권장합니다.<br />
</div>
<p><span style="color: #0000ff;"><strong>2. 음성인식 모듈에 명령어 세팅하기</strong></span><br />
가장 먼저 이번 프로젝트에서 제일 중요한 음성인식 모듈에 간접등을 음성으로 끄고, 켤 수 있도록 음성 명령어를 세팅해주도록 하겠습니다.</p>
<p><span style="color: #33cccc;"><strong>2.1. 음성 인식 모듈 연결하기</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-4.png" rel="lightbox[38614]"><img class="alignnone size-full wp-image-38914" alt="61 ptb 음성간접등 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-4.png" width="250" height="219" /></a></p>
<p>이번에 사용한 음성 인식 모듈은 최대 15개의 음성 명령어를 저장할 수 있습니다.<br />
음성 명령은 3개의 그룹으로 나뉘며, 각 5개의 음성 명령이 저장되기에 그룹 별로 음성 명령어를 모듈에 저장 한 후, 사용할 그룹을 선택해야 합니다.<br />
음성인식 모듈을 PC와 연결하기 위해서 위와 같이 USB to TTL 컨버터와 모듈을 연결해야 합니다. 이때 Rx와 Tx가 교차되어 연결해야 합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-5.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38916" alt="61 ptb 음성간접등 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-5-620x154.png" width="620" height="154" /></a><br />
연결 도식표는 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-6.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38918" alt="61 ptb 음성간접등 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-6-620x249.png" width="620" height="249" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-7.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38920" alt="61 ptb 음성간접등 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-7-620x400.png" width="620" height="400" /></a></p>
<p>음성 인식 모듈과 USB to TTL 컨버터를 연결한 후 PC USB포트에 USB to TTL 컨버터를 꽂아주면 PC의 장치관리자에서 포트 번호를 확인 할 수 있습니다. 저희는 포트 번호가 COM22입니다.</p>
<p><span style="color: #33cccc;"><strong>2.2. 음성인식 모듈에 명령어 저장하기</strong></span><br />
음성 인식 모듈의 데이터 시트에서는 PC와의 연결 할 때, AccessPort라는 시리얼 통신 프로그램 사용을 권하고 있지만 다른 시리얼 통신 프로그램을 사용해도 가능합니다. 이 프로젝트에서는 음성 인식 모듈의 데이터 시트에 권장하는 AceesPort라는 프로그램을 사용하며 음성 인식 명령어를 녹음하는 방법에 대해 알려드리겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-8.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38921" alt="61 ptb 음성간접등 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-8-620x400.png" width="620" height="400" /></a></p>
<p>프로그램은 http://www.sudt.com/en/ap/download.htm에서 다운로드 받으실 수 있습니다.<br />
프로그램 다운로드 페이지를 보시면 오른쪽 하단에 있는 AccessPort137.zip을 확인할 수 있습니다. 클릭해서 다운받아준 후, 압축을 해제하면 AccessPort.exe파일이 있습니다. 해당 프로그램을 실행시켜줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-9.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38922" alt="61 ptb 음성간접등 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-9-620x191.png" width="620" height="191" /></a></p>
<p>AccessPort 프로그램을 실행 시킨 후, 왼쪽 상단에 있는 노란색과 초록색의 톱니바퀴 모양의 Configuration 아이콘을 눌러줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-10.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38923" alt="61 ptb 음성간접등 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-10-620x480.png" width="620" height="480" /></a></p>
<p>그럼 Options 창이 뜹니다. 여기서 USB to TTL 컨버터와 연결된 Port 번호를 입력하고, Baud Rate는 9600으로 맞춰줍니다. Send display는 Hex format으로 Receive display는 Char Format으로 설정해준후 OK 버튼을 눌러줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-11.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38924" alt="61 ptb 음성간접등 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-11-620x224.png" width="620" height="224" /></a></p>
<p>이 후 원래창 아래쪽에 Hex 명령어로 ‘AA36’을 Send 버튼을 통해 보내주었을 때, Common Mode라는 답변이 온다면, 제대로 연결된 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-12.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38925" alt="61 ptb 음성간접등 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-12-620x162.png" width="620" height="162" /></a></p>
<p>Hex 명령어로 ‘AA11’을 보내면, 음성 명령어 녹음이 시작됩니다. 음성 인식 모듈의 마이크에 대고 명령어를 녹음해주시면 됩니다. 각 명령의 길이는 최대 1300ms(1.3초)이므로, 짧은 단어로 명령을 넣는게 좋습니다. 녹음을 시작하면, 한 그룹의 5가지 음성 명령 녹음을 끝내기 전까지 녹음 과정을 멈출 수 없는점 유의해 주시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-13.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38926" alt="61 ptb 음성간접등 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-13-620x539.png" width="620" height="539" /></a></p>
<p>START 라는 답변이 오면 명령어를 녹음해주시면 됩니다. No Voice, Different등을 통해 이전 녹음과 다른지, 녹음이 되고 있는지 확인이 가능합니다. Finish one이 나오면 1개의 명령어가 녹음되었다는 뜻입니다. 순차적으로 5개가 모두 녹음 완료되면, Group 1 finish라는 답변이 옵니다.<br />
저희의 경우에는 불켜, 꺼줘, 하나, 둘, 셋 5가지를 녹음한 후 아두이노를 통해 ‘불켜’, ‘꺼줘’ 명령어만 사용하여 간접등을 제어하였습니다. 실제로 하나, 둘, 셋 같은 단어가 인식률이 더 좋았으며 파동을 인식하는 모듈이기에 불켜와 같은 문장을 명령어로 설정할 경우 똑같은 음정으로 명령어를 발음하여야 인식이 더 잘되는점 참고해서 원하는 명령어를 입력해보시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-14.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38927" alt="61 ptb 음성간접등 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-14-620x172.png" width="620" height="172" /></a></p>
<p>이 후 Hex 명령어로 ‘AA21’을 보내주면, Group1 Imported라는 답변이 옵니다. 첫번째 그룹의 5개의 명령어 입력이 끝났습니다.<br />
이 프로그램에서 사용 가능한 명령어 리스트는 아래와 같으며, 이외의 추가적인 명령어는 QR코드에 관련자료 Voice_Recognize_manual.pdf를 참고하시기 바랍니다.<br />
Delete Group 1 &#8211; 0xAA01<br />
Delete Group 2 &#8211; 0xAA02<br />
Delete Group 3 &#8211; 0xAA03<br />
Delete All Groups &#8211; 0xAA04<br />
Record Group 1 &#8211; 0xAA11<br />
Record Group 2 &#8211; 0xAA12<br />
Record Group 3 &#8211; 0xAA13<br />
Import Group 1 &#8211; 0xAA21<br />
Import Group 2 &#8211; 0xAA22<br />
Import Group 3 &#8211; 0xAA23<br />
<span style="color: #ff9900;">Switch Common Mode &#8211; 0xAA36</span><br />
<span style="color: #ff9900;"> Switch Compact Mode &#8211; 0xAA37</span></p>
<p>Common Mode는 음성 명령값을 ‘Result:11’과 같은 ASCII 코드 값으로 전달해 주지만, Compact Mode는 음성 명령값을 ‘11’과 같은 Hex값으로 전달해줍니다.<br />
따라서 처음 PC와 음성 인식 모듈을 연결하여, 음성 명령을 녹음 할 때는 Common Mode(AA36)를 사용하여 녹음하고 이후 아두이노등의 플랫폼에서 사용 할때는 Compact Mode(AA37)로 사용해야 합니다.</p>
<div class="symple-box blue none" style="text-align:left; width:100%;"> 
Tip : 음성 명령어는 녹음할 때 사용자의 목소리 위주로 인식하기 때문에, 다른 사람이 명령어를 넣으면 제대로 작동하지 않을 수 있습니다.<br />
</div>
<p><span style="color: #0000ff;"><strong>3. 하드웨어 구성 하기</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-15.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38928" alt="61 ptb 음성간접등 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-15-594x620.png" width="594" height="620" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-16.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38929" alt="61 ptb 음성간접등 (16)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-16-620x286.png" width="620" height="286" /></a></p>
<p>회로도와 상세연결도식표를 보며 아두이노를 브레드보드, 음성인식 모듈, 릴레이모듈에 연결해줍니다.<br />
저희는 회의실에 실제로 장착하는데 편리하고자 음성 인식 키트를 구매하면 같이 오는 케이스에 구멍을 뚫고 모든 하드웨어를 넣어 정리해주었으나 필수적인 작업은 아닙니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-17.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38930" alt="61 ptb 음성간접등 (17)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-17-620x368.png" width="620" height="368" /></a></p>
<div class="symple-box blue none" style="text-align:left; width:100%;"> 
Tip : 하드웨어 전체를 케이스에 넣게될 경우엔 아두이노에 코딩 작업을 하기 어려워지니 케이스에 넣기 전에 코딩작업을 먼저 진행하시길 권장드립니다.<br />
</div>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-1.jpg" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38907" alt="61 ptb 음성간접등 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-1-620x368.jpg" width="620" height="368" /></a></p>
<p>전선의 경우, LED 스트립 설치 시 전선길이가 부족했기에 안내해드렸던 추가전선과 LED 스트립선을 납땜, 수축튜브를 활용하여 연결해주었습니다.<br />
작업이 완료된 LED 스트립은 항상 불이 켜져있는 상태가 아닌 아두이노에서 신호를 주었을 때만 불이 들어와야 하기 때문에 중간에 릴레이를 거쳐서 DC잭에 연결하여 줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-18.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38931" alt="61 ptb 음성간접등 (18)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-18-620x285.png" width="620" height="285" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-2.jpg" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38909" alt="61 ptb 음성간접등 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-2-620x377.jpg" width="620" height="377" /></a></p>
<p>DC잭에서 출력되는 전압은 아두이노의 VIN핀, GND로 연결하여 아두이노에 전원을 공급해주고, 또한 릴레이를 거쳐 LED스트립에 전원을 공급해 줍니다. LED스트립의 플러스 선(빨간선)은 다이렉트로 DC잭의 플러스 선으로 연결해주고, LED스트립의 마이너스 선(검정선)은 릴레이의 NO(Normal Open)단자에 연결해줍니다. 또 릴레이의 COM(Common)단자에는 DC잭의 마이너스 선으로 연결해주면 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-3.jpg" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38911" alt="61 ptb 음성간접등 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-3-620x364.jpg" width="620" height="364" /></a></p>
<p>전원 어댑터와 연결된 DC 잭을 통해 아두이노와 LED 스트립에 전원을 공급하게 됩니다. 또 릴레이 모듈과 음성 인식 모듈에도 5V를 인가해줘야 하기 때문에 아두이노의 5V 출력 핀에서 브레드 보드를 통해 전원을 나눠서 공급할 수 있게 연결을 해줬습니다.<br />
저희는 전선처리를 더욱 깔끔하게 하기위해 필수사항은 아니나 DC 잭에 연결하는 전선앞을 펜홀단자로 작업 후에 연결하였습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-4.jpg" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38913" alt="61 ptb 음성간접등 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-4-620x467.jpg" width="620" height="467" /></a></p>
<p>완성된 모습은 위와 같습니다. 점퍼선들로 복잡해 보이지만 회로도를 보고 따라서 천천히 작업하다보면 쉽게 하실 수 있습니다.</p>
<p><span style="color: #0000ff;"><strong>4. 아두이노 설치 및 소스코드 업로드하기</strong></span><br />
하드웨어까지 완료되었다면 이제 음성으로 LED 스트립이 잘 제어될 수 있게 코딩작업을 진행해보도록 하겠습니다. 앞서 말씀드렸듯이 작업과정에 따라 하드웨어 구성보다 코딩작업이 먼저 진행되어도 무관함합니다.<br />
<strong></strong></p>
<p><span style="color: #33cccc;"><strong>4.1. 아두이노 통합개발환경(IDE)</strong></span><br />
아두이노 IDE(Integrated Development Environment)는 아두이노 프로그램을 작성하고 컴파일할 수 있는 통합 개발 환경입니다. 아두이노 공식 홈페이지에서 무료로 제공하고 있어서 편리하게 사용할 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-19.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38932" alt="61 ptb 음성간접등 (19)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-19-620x438.png" width="620" height="438" /></a></p>
<p><span style="color: #33cccc;"><strong>4.2. 아두이노 통합개발환경(IDE) 설치</strong></span><br />
아두이노 통합환경은 아두이노 공식 홈페이지(https://www.arduino.cc)에서 다운 받을 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-20.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38933" alt="61 ptb 음성간접등 (20)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-20-620x350.png" width="620" height="350" /></a></p>
<p>아두이노 공식 홈페이지에 접속하신 후 SOFTWARE-DOWNLOADS를 클릭해 주세요. Download the Arduino IDE 부분에서 각자 운영체제의 알맞은 버전의 파일을 선택해서 다운받으시면 됩니다. 제가 다운로드 받을 시점에서 최신 버전은 1.8.13입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-21.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38934" alt="61 ptb 음성간접등 (21)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-21-620x313.png" width="620" height="313" /></a></p>
<p>파일을 선택하시면 아두이노 소프트웨어에 대한 기부를 권하는 창이 뜹니다. 기부를 하지 않으시려면 JUST DOWNLOAD를 클릭하시면 다운로드 됩니다.</p>
<p><span style="color: #33cccc;"><strong>4.3. 아두이노 통합개발환경(IDE) 기본 세팅</strong></span><br />
IDE를 사용하는 방법에 대해 알려드리겠습니다.<br />
IDE 환경에서 아두이노 보드(Board)와 포트(Port)를 맞춰줘야 합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-22.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38935" alt="61 ptb 음성간접등 (22)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-22-620x514.png" width="620" height="514" /></a></p>
<p>보드를 선택하는 방법은 메뉴바 &#8211; 툴 &#8211; 보드 &#8211; Arduino Uno 보드를 선택해 주면 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-23.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38936" alt="61 ptb 음성간접등 (23)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-23-620x514.png" width="620" height="514" /></a></p>
<p>포트 선택하는 방법은 메뉴바 &#8211; 툴 &#8211; 포트에서 아두이노에 해당하는 COM 포트를 선택해 주면 됩니다.</p>
<p><span style="color: #33cccc;"><strong>4.4. 소스코드 업로드하기</strong></span><br />
이번 프로젝트에 사용 할 소스코드 전체는 아래와 같습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>/*<br />
www.devicemart.co.kr<br />
Voice Recognition Module test<br />
*/</p>
<p>#include &lt;SoftwareSerial.h&gt;<br />
SoftwareSerial mySerial(2, 3);<br />
int relay= 7;<br />
byte voice_recogn= 0;</p>
<p>void setup()<br />
{<br />
Serial.begin(9600);<br />
mySerial.begin(9600);<br />
Serial.println(&#8220;wait settings are in progress&#8221;);<br />
pinMode(relay, OUTPUT);<br />
delay(1000);<br />
mySerial.write(0xAA);<br />
mySerial.write(0&#215;37);<br />
delay(1000);<br />
mySerial.write(0xAA);<br />
mySerial.write(0&#215;12);<br />
Serial.println(&#8220;The settings are complete&#8221;);<br />
}</p>
<p>void loop()<br />
{<br />
while(mySerial.available())<br />
{<br />
Serial.println(&#8220;voice input&#8221;);<br />
voice_recogn=mySerial.read();<br />
switch(voice_recogn)<br />
{<br />
case 0&#215;11:<br />
digitalWrite(relay,HIGH);<br />
Serial.println(&#8220;relay turn on&#8221;);<br />
break;</p>
<p>case 0&#215;12:<br />
digitalWrite(relay,LOW);<br />
Serial.println(&#8220;relay turn off&#8221;);<br />
break;</p>
<p>case 0&#215;13:<br />
//<br />
break;</p>
<p>case 0&#215;14:<br />
//<br />
break;</p>
<p>case 0&#215;15:<br />
//<br />
break;</p>
<p>}<br />
}<br />
}<br />
</div>
<p>업로드 하는 방법은 아두이노 IDE 툴에서 보드와 포트가 정확히 선택되었는지 확인하신 후, 위쪽 오른편에 있는 화살표 모양을 클릭해 주시면 업로드가 진행됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-24.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38937" alt="61 ptb 음성간접등 (24)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-24-620x452.png" width="620" height="452" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-25.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38938" alt="61 ptb 음성간접등 (25)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-25-600x620.png" width="600" height="620" /></a></p>
<p>업로드가 완료되면 아래편에 업로드 완료라고 표시가 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-26.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38939" alt="61 ptb 음성간접등 (26)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-26-620x160.png" width="620" height="160" /></a></p>
<p>소스 코드에 대해 설명드리겠습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include &lt;SoftwareSerial.h&gt;<br />
SoftwareSerial mySerial(2, 3);<br />
int relay= 7;<br />
byte voice_recogn= 0;<br />
</div>
<p>음성 인식 모듈과 아두이노를 Serial 통신으로 연결하여 사용하기 위해, 소프트웨어 시리얼 라이브러리를 포함시키고, 디지털 2번핀 3번핀을 각각 Rx핀 Tx핀으로 할당시켜주는 코드입니다. 릴레이를 제어하기 위해 디지털 7번핀에 relay 변수를 선언하고, 음성을 인식하기 위한 변수 voice_recogn를 초기값 0으로 선언해주었습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>void setup()<br />
{<br />
Serial.begin(9600);<br />
mySerial.begin(9600);<br />
Serial.println(&#8220;wait settings are in progress&#8221;);<br />
pinMode(relay, OUTPUT);<br />
delay(1000);<br />
mySerial.write(0xAA);<br />
mySerial.write(0&#215;37);<br />
delay(1000);<br />
mySerial.write(0xAA);<br />
mySerial.write(0&#215;12);<br />
Serial.println(&#8220;The settings are complete&#8221;);<br />
}<br />
</div>
<p>보드에 전원이 들어왔을 때 혹은 리셋 되었을 때 한번만 동작하는 Setup()함수에 작성해야 할 내용입니다. Serial.begin()함수와 mySerial.begin()함수를 9600보오 레이트로 통신 속도로 설정해줍니다. relay 변수를 출력모드로 설정해주고, Serial통신으로 연결된 음성 인식 모듈에 명령어를 넣어 Compact Mode로 설정, Group2에 연결된 명령어를 가져와 줍니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>void loop()<br />
{<br />
while(mySerial.available())<br />
{<br />
Serial.println(&#8220;voice input&#8221;);<br />
voice_recogn=mySerial.read();<br />
switch(voice_recogn)<br />
{<br />
case 0&#215;11:<br />
digitalWrite(relay,HIGH);<br />
Serial.println(&#8220;relay turn on&#8221;);<br />
break;</p>
<p>case 0&#215;12:<br />
digitalWrite(relay,LOW);<br />
Serial.println(&#8220;relay turn off&#8221;);<br />
break;</p>
<p>case 0&#215;13:<br />
//<br />
break;</p>
<p>case 0&#215;14:<br />
//<br />
break;</p>
<p>case 0&#215;15:<br />
//<br />
break;<br />
}<br />
}<br />
}<br />
</div>
<p>loop()함수에 들어가는 내용은 아두이노에 전원이 들어가 있는 한 계속 반복됩니다.<br />
처음 While(mySerial.availble())을 통해 음성 인식 모듈로 음성이 인식되면 voice_recogn변수에 음성 인식 모듈을 통해 읽은 데이터를 저장하고, 저장한 명령어가 맞다면 switch 문을 통해 동작을 제어 할 수 있습니다. 이번 예제에서는 음성 인식 모듈로 릴레이를 on/off만 제어하기 때문에 1번 그룹의 case 0&#215;11(명령어1), case 0&#215;12(명령어2)만 사용하여 릴레이를 on/off하는 동작을 제어하였고, 사용하지 않을 명령어 case 0&#215;13(명령어3), case 0&#215;14(명령어4), case 0&#215;15(명령어5)는 주석처리(//) 하였습니다.</p>
<p><span style="color: #0000ff;"><strong>5. 불키고, 끄고 확인하고 완성하기</strong></span></p>
<p><span style="color: #0000ff;"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-5.jpg" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38915" alt="61 ptb 음성간접등 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-5-620x405.jpg" width="620" height="405" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-6.jpg" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38917" alt="61 ptb 음성간접등 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-6-620x256.jpg" width="620" height="256" /></a></strong></span></p>
<p>하드웨어 구성과 코딩작업이 완료된 후에는 LED 스트립은 필요한 장소에 부착합니다.<br />
LED스트립은 원하는 길이 만큼 컷팅이 가능하며 뒷면이 접착식으로 되어 원하는 장소에 부착이 간편합니다. 설치가 완료되고 나면 전원을 공급한 후 입력한 명령어에 따라 불이 켜지고 꺼짐을 확인해봅니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-7.jpg" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38919" alt="61 ptb 음성간접등 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-7-620x408.jpg" width="620" height="408" /></a></p>
<p>완성된 모습입니다. 회의실 한편이 은은한 조명으로 멋스러워졌습니다.</p>
<p><span style="background-color: #ffff00;"><strong>만일 명령어를 말했을때 불이 들어오지 않는다면?</strong></span></p>
<p><span style="color: #ff6600;"><strong>1. LED 스트립과 릴레이가 제대로 동작하는지 확인해 보세요.</strong></span><br />
음성 인식에 대한 코드는 사용하지 않고, 1초마다 릴레이를 On/Off하는 아래 소스코드를 아두이노에 직접 업로드 해줍니다. 이를 통해 LED가 켜졌다 꺼졌다를 반복하는지를 보며 릴레이와 LED스트립이 제대로 동작하는지 확인할 수 있습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
Box Content<br />
</div>
<p>이 코드를 사용해서 릴레이가 제대로 동작하지 않는다면 배선을 다시 한번 점검해보시거나 모듈의 불량을 의심하여 모듈을 교체해줍니다.</p>
<p><strong><span style="color: #ff6600;">2. 음성인식 모듈이 제대로 작동하는지 확인해 보아야합니다.</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-27.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38940" alt="61 ptb 음성간접등 (27)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-27-510x620.png" width="510" height="620" /></a></p>
<p>아두이노와 연결했을 때 아두이노 시리얼 모니터를 통해 음성인식 모듈에 명령어가 제대로 인식되고 있는지 확인 가능합니다.<br />
아두이노 IDE에서 오른쪽 위에 있는 시리얼 모니터 버튼을 클릭해주세요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-28.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38941" alt="61 ptb 음성간접등 (28)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-28-620x133.png" width="620" height="133" /></a></p>
<p>아두이노에서 음성 인식 모듈에 명령어를 불러오기가 끝나면 위 화면과 같이 ‘The settings are complete’라고 출력이 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-29.png" rel="lightbox[38614]"><img class="alignnone size-large wp-image-38942" alt="61 ptb 음성간접등 (29)" src="http://www.ntrexgo.com/wp-content/uploads/2020/08/61-ptb-음성간접등-29-620x354.png" width="620" height="354" /></a></p>
<p>음성을 인식해 주면 아래와 같이 ‘voice input’이라는 글자가 출력이 되고, 첫번째와 두번째 명령어를 인식하면 ‘relay turn on/off’로 글자가 출력이 됩니다.<br />
모듈이 제대로 작동하는데도 명령어를 인식하지 못한다면 더쉽고 명확한 단어로 명령어를 변경하시거나 녹음한 음정과 똑같은 음정으로 발음해보시기 바랍니다. 모듈이 제대로 작동하지 않는다면 모듈의 불량을 의심하여 모듈을 교체하기시 바랍니다.<br />
자, 이제 모든 과정이 끝났습니다. 구독자 분들이 이번 프로젝트를 함께하며 음성인식 기능과 사물인터넷에 대해 조금이나마 쉽게 생각할 수 있는 기회가 되셨길 바라며 다음에도 더 쉽고 재미난 프로젝트로 찾아뵙도록 하겠습니다!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/38614/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2018 ICT 융합 프로젝트 공모전</title>
		<link>http://www.ntrexgo.com/archives/34806</link>
		<comments>http://www.ntrexgo.com/archives/34806#comments</comments>
		<pubDate>Fri, 09 Feb 2018 04:06:09 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[공지사항 및 뉴스]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=34806</guid>
		<description><![CDATA[(주)엔티렉스/디바이스마트 주최 2018 ICT 융합프로젝트 공모전
접수가 시작되었습니다.]]></description>
				<content:encoded><![CDATA[<p>&nbsp;</p>
<p><img alt="2018 ICT 융합 프로젝트 공모전" src="http://www.devicemart.co.kr/data/temp/264644.jpg" width="600" height="1440" /></p>
<p>&nbsp;</p>
<p><span style="font-size: x-large;"><strong>2018 ICT 융합 프로젝트 공모전 응모요강</strong></span></p>
<p>&nbsp;</p>
<p><strong>1. 참가자격</strong> : 국내•외 대학생, 대학원생 및 일반인</p>
<p><strong>2. 주제</strong> : 전자, 로봇, 기계 분야 중 자유주제</p>
<p><strong>3. 접수기간</strong> : 2018년 2월 1일(목) ~ 3월 31일(토)</p>
<p><strong>4. 시상내역</strong> : 입상작 30편, 총 상금 및 상품 300만원 상당</p>
<p>* 최우수상( 1명)   –     50만원<br />
* 우수상 ( 3명)     – 각  30만원<br />
* 입선 ( 6명)         – 각  10만원<br />
* 참가상 ( 20명)  - 각    5만원</p>
<p>※ 시상 기준에 부합하는 응모작이 없을 경우 시상 내용이 변경될 수 있으며, 상금은 디바이스마트 적립금으로 제공됩니다.</p>
<p>※ 심사 및 평가 : ㈜엔티렉스, 위드로봇 ㈜, ㈜칩센, ㈜펌테크, ㈜뉴티씨<em id="__mceDel"><br />
</em></p>
<p><strong>5. 응모 요령</strong><br />
- 응모 원고 : A4 20매 내외 분량</p>
<p><strong>6. 접수 및 문의처</strong><br />
- 접수 방법 : 이메일 접수(press@ntrex.co.kr)<br />
- 문의처 : TEL. 070-4342-6312 또는 070-7019-1518</p>
<p><strong>7. 주최 및 협찬</strong><br />
- 주최 : ㈜엔티렉스-디바이스마트<br />
- 협찬 : 위드로봇㈜, ㈜칩센, ㈜펌테크, ㈜뉴티씨</p>
<p><em id="__mceDel"> </em></p>
<p><strong>[응모자 유의사항]</strong></p>
<p>응모 자격은 국내외 일반인 및 대학생, 대학원생, 휴학생도 참가 가능합니다.<br />
심사 기준에 적합하지 않을 경우 시상 편수 및 수상 인원이 변경될 수 있습니다.<br />
제출된 원고는 반환되지 않으며, 응모작의 저작권은 응모자와 주최기관에 공동으로 귀속됩니다.<br />
응모된 작품은 순수 창작이어야 하며, 타 공모에 입상한 작품 및 다른 간행물에 발표되지 않은 것이어야 하며, 모방과 표절에 관련하여 저작권, 초상권 등의 문제가 발생할 경우 법적 책임은 응모자에게 있습니다.</p>
<p>위 내용이 발생할 경우 시상 이후라도 시상을 취소하고 상금은 반환하여 합니다.<br />
제작 과정에 관한 모든 사항을 기록하고, 문서화하여 제출하여야 하며, 해당 내용은 디바이스마트 매거진 특집 기획으로 게재됩니다.</p>
<p><strong>[원고 작성 유의 사항]</strong></p>
<p><strong>파일 형식</strong> : DOC, HWP, PDF 중 택 1<br />
<strong>작성 분량</strong> : A4 20매 내외(최대 글자 크기 12 point)<br />
아래의 작성 목록을 기준으로 원고를 작성하여 주시기 바랍니다.</p>
<p>- 작성 목록(최대한 자세하게 기술)<br />
1. 작품 제목<br />
2. 작품 개요<br />
3. 작품 설명<br />
3.1 주요 동작 및 특징<br />
3.2 전체 시스템 구성<br />
3.3 개발 환경(개발 언어, Tool, 사용시스템 등)<br />
4. 단계별 제작 과정<br />
5. 기타(회로도, 소스코드, 참고문헌 등)<br />
4. 필수 입력 항목 : 소속(회사, 학교), 성명, 이메일, 휴대폰번호, 주소<br />
5. 파일 접수시 최종 문서 파일①과 문서 파일①에 첨부된 자료(이미지, 회로도, 소스코드 등)②을 압축하여 총 2개의 파일(①+②)을 접수합니다.<br />
6. 첨부된 이미지는 직접 촬영하거나 제작한 원본 이미지여야 하며, 화면 캡쳐 이미지 및 식별 불가한 이미지를 사용해서는 안됩니다.<br />
7. 이미지 파일 확장자는 jpg, eps, tiff, pdf, png, bmp, 이미지 해상도는 150 ~ 300 DPI 이상으로 작성하시기 바랍니다.</p>
<p>&nbsp;</p>
<p>자세한 사항은 아래 사이트를 참조해주세요.^-^</p>
<p><a href="http://www.devicemart.co.kr/board/view.php?seq=28&amp;table=capstone&amp;page=">http://www.devicemart.co.kr/board/view.php?seq=28&amp;table=capstone&amp;page=</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/34806/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[39호]카멜레온 DIY LED 이야기 ⑤</title>
		<link>http://www.ntrexgo.com/archives/32471</link>
		<comments>http://www.ntrexgo.com/archives/32471#comments</comments>
		<pubDate>Fri, 25 Nov 2016 00:00:16 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[39호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[LED]]></category>
		<category><![CDATA[Projects to build]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=32471</guid>
		<description><![CDATA[디바이스마트 매거진 39호 &#124; 오늘은 좀 더 멋진 프로젝트로 [특별한 크리스마스 트리] 만들기에 도전해 보겠습니다. 사슴도 만들고, 산타도 만들고, 커다랗고 멋진 눈 결정도 만들고… 그리고 이것들을 엮어서 크리스마스 트리를 만든 다음, 스마트폰으로 트리 점등을 해 보는데까지 씽씽 달려보겠습니다. 야호~ 신난다. “흰 눈 사이로 ♬ 썰매를 타고 ♬ GO~ GO~”]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-1.jpg" rel="lightbox[32471]"><img class="alignnone size-large wp-image-32622" alt="39 ptb diyled (1)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-1-620x234.jpg" width="620" height="234" /></a></p>
<p>&nbsp;</p>
<p><span style="font-size: large"><strong>카멜레온 DIY LED 이야기 5</strong></span></p>
<p><strong><span style="font-size: xx-large">LED ART 2 : 특별한 크리스마스 트리</span></strong></p>
<p>&nbsp;</p>
<p style="text-align: right">글 | 신상석 ssshin@jcnet.co.kr</p>
<p style="text-align: right">
<table style="background-color: #e2e2e2;;width: 620px" border="0" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>디바이스마트 매거진 독자 여러분, 안녕하세요. 앞으로 5회에 걸쳐 [카멜레온 DIY LED 이야기]를 진행할 신상석입니다.<br />
이 이야기는 WS2812B라는 컬러 LED를 기반으로 제작된 [카멜레온 DIY LED] 시리즈를 이용하여 생활에 필요한 다양한 형상을 꾸며보고 이것을 다양한 컬러로 디스플레이 해보는 내용입니다. 앞으로 진행할 내용에 대하여 간단히 알아보면 다음과 같습니다. (약간 변경될 수도 있습니다.)<br />
앞으로 즐겁고 유익한 강의가 될 수 있도록 많은 격려와 성원 부탁드립니다.</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>디바이스마트매거진 독자 여러분, 안녕하세요. 반갑습니다.<br />
[카멜레온 DIY LED 이야기] 다섯번째, 어느덧 벌써 마지막 시간이네요.<br />
지난 시간에는 카멜레온 DIY LED(카DL)을 이용하여 [I ♥ U] 모양과 [변색 카멜레온]을 꾸미고 실행시켜 보았습니다. 오늘은 좀 더 멋진 프로젝트로 [특별한 크리스마스 트리] 만들기에 도전해 보겠습니다. 사슴도 만들고, 산타도 만들고, 커다랗고 멋진 눈 결정도 만들고… 그리고 이것들을 엮어서 크리스마스 트리를 만든 다음, 스마트폰으로 트리 점등을 해 보는데까지 씽씽 달려보겠습니다. 야호~ 신난다. “흰 눈 사이로 ♬ 썰매를 타고 ♬ GO~ GO~”</p>
<p><span style="color: #008000"><strong>아이템(ITEM) 모듈</strong></span></p>
<p>지난번 이야기에서 카DL의 기본 구성품 중 4종류의 모듈을 소개한 바 있습니다. BAR 모듈은 직선용, ARC 모듈은 곡선용, DIR 모듈은 방향 전환용, FIGURE 모듈은 기본 도형용으로 소개를 하였지요. 크리스마스 트리를 장식할 여러가지 형상을 만들기 전에, 카DL의 나머지 형상 모듈인 ITEM 모듈을 소개하는 것이 앞으로의 이야기 전개에 편리할 것 같아 이것을 먼저 간단히 살펴보고 가겠습니다. 아이템(ITEM) 모듈은 말 그대로 사람들이 자주 사용할만한 간단한 아이템을 형상화한 모듈입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-2.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32624" alt="39 ptb diyled (2)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-2.jpg" width="620" height="338" /></a></p>
<p>해(링), 달, 별, 작은화살표, 하트, 눈, 큰화살표의 7가지 모듈이 있는데, 이것은 개별 형상을 가지고 있으므로 단독으로도 사용할 수 있고, 다른 모듈과 조합하여 사용할 수도 있습니다. 창조적인 상상력을 동원하면 이 모듈들을 이리저리 엮어서 또 다른 멋진 아이템을 만들어 낼 수도 있겠습니다.</p>
<p><span style="color: #008000"><strong>특별한 크리스마스 트리</strong></span></p>
<p>카DL로 [특별한 크리스마스 트리]를 제작하기로 하였으므로 일단 어떤 모양으로 어떤 크기로 어떤 기능을 갖도록 만들 것인지를 먼저 고민하여 결정한 후 이것을 제작하도록 하겠습니다. 일단 하고 싶은 것을 죽 나열해 보기로 하지요.</p>
<p>· 내 키 정도 되는(1.5m ~ 2m) 크기의 녹색 트리에 장식한다.<br />
· 카DL의 ARC 모듈을 사용하여 물결 모양의 형상을 만들고, 반짝반짝하는 느낌과 물결이 흘러가는 느낌을 주도록 프로그램한다.<br />
· 카DL의 BAR, FIGURE, ITEM 모듈을 적당히 섞어서 사용하여 알록달록하고 다양한 색상이 나타나도록 프로그램한다.<br />
· 손바닥 정도 크기의 크리스마스 상징물을 카DL을 이용하여 5-6개 만들어 배치하고, 각 상징물의 색상과 움직임이 구별되도록 프로그램한다.<br />
· 얼굴정도 크기로 조금 큰 특별 형상을 1개 만들어 중앙에 배치하고, 은은하게 조금씩 변하도록 프로그램한다.<br />
· 스마트폰으로 그룹별로 껐다 켰다 할 수 있게 프로그램한다.</p>
<p>(사실 이것들을 모두 한꺼번에 다 제작한다고 하면 비용이 꽤 많이 듭니다. 실제로는 자신이 해보고 싶은 것만, 마음에 드는 것만 부분적으로 구현하면 되겠습니다. 별 하나만 제작한다고 해도 충분히 특별한 크리스마트 트리가 될 수 있으니까요.)<br />
어느 정도 아우트라인이 갖추어졌으므로 세부적인 것은 하나씩 구현해 가면서 구체화시켜 보겠습니다.</p>
<p><span style="color: #3366ff"><strong>1단계 : 트리 구입 및 약간의 장식 구입</strong></span><br />
기반이 되는 트리가 있어야 실제로 구현하면서 적용해 볼 수 있으므로 트리를 우선 준비하여야 하겠습니다. 방울이나 종, 리본 등 크리스마스 기분을 내기 위한 약간의 장식도 함께 준비해 두면 더 예쁠테니 취향에 따라서 원하는 것을 구입하여 준비합니다.</p>
<p><span style="color: #3366ff"><strong>2단계 : 필요한 형상 설계하기</strong></span><br />
두번째로 할 일은 지난 회에도 언급한 것처럼 형상을 제작하여야 합니다. 트리에 얹혀 있는 형태로 만들면 되므로 필요한 형상을 만들고 이것들을 케이블로 죽 이어가는 형태로 하겠습니다.<br />
기본 형상은 있는 그대로 연결하면 되므로, 크리스마스 기분이 나는 손바닥만한 형상 5-6개와 얼굴만한 큰 형상 1개를 정해서 따로 만들겠습니다. 무엇이 좋을까요? 음… 심사숙고한 끝에…<br />
십자가, 별, 트리, 지팡이, 싼타, 루돌프 이렇게 6가지 형상은 손바닥만한 크기로 만들고, 눈(SNOW) 결정은 얼굴만한 형상으로 조금 크게 구현하는 것으로 하겠습니다.<br />
카DL로 이런 모양을 형상화하여 구현하려면 사실 디자인적인 감각이 약간 필요합니다만, 뭐, 그냥 자신이 원하는대로 만들어도 별 지장은 없습니다. 제 멋에 사는거니까요.</p>
<p>저는 다행히 주변에 디자이너가 있어서 도움을 받아 아래와 같이 형상 설계를 하였습니다.<br />
AUTOCAD 같은 설계도구를 이용하여 만들었기 때문에 상당히 정교하게 제작되었는데, 이런 도구없이 손으로 대강 쓱쓱 그려도 무방합니다.<br />
형상이 마음에 드시나요? 단순하지만 특징을 잘 잡아 잘 표현된 것 같습니다. 저는 매우 만족합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-3.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32626" alt="39 ptb diyled (3)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-3.jpg" width="620" height="396" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-4.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32627" alt="39 ptb diyled (4)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-4.jpg" width="620" height="429" /></a></p>
<p>와우~ [눈(SNOW) 결정] 형상! 이건 거의 예술이네요. FIGURE 모듈(JLED-TRI-6)과 ITEM 모듈(JLED-ARROW-9, JLED-SNOW-12) 그리고 BAR 모듈(JLED-BAR-1, JLED-BAR-2)의 5가지 모듈을 적절히 배치하여 아주 독특하면서도 멋진 [눈(SNOW) 결정]을 구현하였습니다. 이것을 보면 정말 웬만한 형상은 카DL의 기본 모듈로 모두 다 구현이 가능할 것이라는 확신이 듭니다. 이것은 매우~ 매우~ 만족입니다.</p>
<p>참, 지난 번에도 이야기한 것처럼, 이와 같은 형상을 만들 때는 연결성도 고려하면서 모듈을 배치해야 하는 것도 잊지 말아야 할 사항입니다. 나중에 LED에 불이 ON 될 때를 고려하면 나름대로 자신만의 규칙성을 가지고 LED에 불이 들어올 때를 상상하며 연결을 하는 것이 좋습니다.<br />
만들어진 형상을 연결을 표시하여 다시 나타내 보겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-5.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32628" alt="39 ptb diyled (5)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-5.jpg" width="620" height="460" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-6.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32629" alt="39 ptb diyled (6)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-6.jpg" width="620" height="412" /></a></p>
<p>이 중, 십자가 형상은 CON-0 를 이용하여 연결하면 밑판 없이도 연결이 가능할 것 같고, 나머지 형상은 밑판을 대고 카DL을 꽂은 후 뒤에서 CABLE-MM-10이나 CABLE-MM-20과 같은 케이블로 연결하면 될 것 같습니다.</p>
<p>눈결정 형상은 좀 더 복잡한데, 여섯 방향의 메인 직선 형상을 먼저 연결한 다음, 주변의 나머지부분을 연결하는 형태로 된 것을 확인할 수 있습니다. 어쨓거나 자기 자신만의 룰을 이용하여 한 줄로 연결이 되도록 하면 됩니다.<br />
나중에 형상 제작을 위하여 한 가지 팁을 더 말씀드리면 아래와 같이 그림을 그려 놓고 필요한 카DL의 종류와 개수를 적어 놓으면 나중에 모듈을 준비할 때 조금 더 편리할 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-7.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32630" alt="39 ptb diyled (7)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-7.jpg" width="582" height="401" /></a></p>
<p><span style="color: #3366ff"><strong>3단계 : 형상 제작하기</strong></span><br />
자, 이제 설계(디자인)가 완료되었으니 구현할 차례입니다.<br />
모든 카DL을 하나로 모두 연결할 수도 있겠지만 이 경우 전체 LED의 갯수가 너무 많아 제어하기가 어렵기 때문에, 여기서는 4개 그룹으로 나누고 각 그룹마다 아두이노를 하나씩 따로 연결하여 프로그램을 하는 것으로 하겠습니다.</p>
<p><strong>제 1 그룹 연결</strong><br />
ARC 모듈은 기본 형상을 그대로 사용하므로 CON-0 및 CABLE-MM-10 케이블을 이용하여 직접 연결합니다. 최종적으로 만들어진 형상은 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-8.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32631" alt="39 ptb diyled (8)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-8.jpg" width="582" height="318" /></a></p>
<p><strong>제 2 그룹 연결</strong><br />
BAR, FIGURE, ITEM 모듈도 기본 형상을 그대로 사용하므로 CABLE-MM-20 또는 CABLE-MM-10 케이블을 이용하여 직접 연결합니다. 최종적인 형상은 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-9.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32632" alt="39 ptb diyled (9)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-9.jpg" width="587" height="320" /></a></p>
<p><strong>제 3 그룹 연결</strong><br />
제 3그룹은 손바닥만한 형상을 설계하여 만든 모듈인데, 이 중 십자가는 아무런 보조 도구 없이 그냥 CON-0를 이용하여 연결하면 되지만, 나머지 형상은 직접 연결만으로는 형상을 만들 수 없으므로 지난번에 살펴본대로 폼보드(2mm) 등을 밑판으로 하여 카DL을 관통하여 모양을 잡고, 뒤쪽에서 CON-0 커넥터와 CABLE-MM-10 또는 CABLE-MM-20 케이블을 이용하여 고정시키는 방법을 사용하여야 합니다. 참, 조립하기 전에 폼보드의 형상은 칼이나 가위 등을 이용하여 미리 알맞게 잘라놓는 것이 좋습니다. 아래는 트리의 경우 앞면과 뒷면의 조립 형상입니다. 직접 연결되는 부분은 CON-0를 이용하여 연결하고 조금 떨어져 있는 경우는 CABLE-MM-10을 이용하여 연결한 것을 알 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-10.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32633" alt="39 ptb diyled (10)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-10.jpg" width="584" height="350" /></a></p>
<p>조립을 좀 더 편하게 할 수 있는 팁을 하나 더 알려드리지요. 폼보드 위에 설계한(그린) 도안을 붙이고 이 위에 카DL을 하나씩 순서대로 꼽아가면 눈으로 보면서 조립하는 것 보다는 훨씬 편리합니다. 6가지 형상을 모두 조립한 후의 모습은 아래와 같습니다. 십자가 형상은 CON-0만으로도 연결이 가능하여 밑판없이 제작하였고 나머지 5개 형상은 모두 2mm 두께의 폼보드를 이용하여 밑판을 만든 후 제작하였습니다. 최종적인 형상은 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-12.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32635" alt="39 ptb diyled (12)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-12.jpg" width="581" height="336" /></a></p>
<p><strong>제 4 그룹 연결</strong><br />
제 4 그룹에 속하는 것은 오직 눈결정 모듈 1개입니다. 제 3그룹의 6개 형상을 제작한 것과 동일한 방법으로 제작하면 됩니다. 최종적인 형상은 아래와 같습니다.</p>
<p><span style="color: #3366ff"><strong>4 단계 : 아두이노 연결하기</strong></span><br />
이제 만들어진 형상을 제어하기 위하여 아두이노를 연결하도록 하겠습니다. 우리는 스마트폰으로 아두이노를 제어하기로 하였으므로 아두이노에도 무선 모듈을 연결(또는 장착)하여 이를 해결해야 합니다. 스마트폰에서 사용할 수 있는 무선 통신 방식은 와이파이(WIFI)를 이용한 이더넷 통신과 블루투스를 이용한 시리얼 통신이 있는데, 전송하여야 할 데이터의 양이 많지 않으므로 연결하기 쉬운 블루투스 통신 방식을 사용하는 것이 간편하므로 이것을 사용하는 것으로 하겠습니다.</p>
<p>아두이노 UNO를 비롯한 아두이노 모듈은 블루투스 모듈을 내장하고 있지 않으므로 이것을 가능하게 하려면, (1) 블루투스 실드를 장착하여 사용하거나 (2) 블루투스 모듈을 준비하여 케이블로 연결하거나 (3) 아예 블루투스 모듈을 내장한 아두이노를 사용하는 방법이 있습니다. 우리의 경우는 크기와 편의성을 위하여 (3)번 방식을 채택하도록 하며, 여기에 가장 알맞은 아두이노로 JARDUINO-UNO-BTmini(제이씨넷)를 선정합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-13.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32636" alt="39 ptb diyled (13)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-13.jpg" width="579" height="558" /></a></p>
<p>JARDUINO-UNO-BTmini는 아두이노 UNO와 기능이 호환되며, HC-05 블루투스시리얼 모듈을 내장하고 있는 새끼손가락만한 크기의 모듈입니다. 블루투스 포트 선택 스위치는 HC-05 블루투스시리얼 모듈의 TX/RX 연결 포트를 아두이노 내부의 RX(D0)/TX(D1) 핀으로 연결하거나 D4/D7 핀으로 연결하도록 선택하는 스위치인데, 우리는 이것을 D4/D7로 연결되도록 위치시키고, D4/D7 핀을 SoftSerial 포트로 선언해서 사용할 것입니다. 한편, 카DL 그룹의 첫번째 모듈의 I(Data Input) 핀에 연결할 핀은 임의로 D13으로 할당하겠습니다. 장시간 사용을 염두에 둔다면 안정성을 위하여 JLED-START-1을 JARDUINO-UNO-BTmini와 카DL 사이에 삽입하는 것이 좋지만 짧은 시간 사용하는 것이라면 이것을 생략하여도 무방합니다.</p>
<p>크리스마트 트리 제작에 있어 또 하나 고려할 점은 전원 공급 방식입니다. 몇 개 안되는 모듈을 사용할 때는 USB 케이블을 통하여 제공되는 전원(5V, 500mA)이나, 휴대폰 보조배터리로도 사용이 가능하겠지만, 이번과 같이 한 그룹 당 카DL에 사용된 WS2812B의 개수의 최대치가 약 150개 정도 될 것으로 예상되는 경우는 다른 전원 공급 방법을 사용하여야 합니다. 일단, 필요한 전류량을 계산해보겠습니다.</p>
<table style="width: 620px" border="1" cellspacing="0" cellpadding="4">
<tbody>
<tr>
<td style="text-align: center">항목</td>
<td style="text-align: center">필요 전류량</td>
</tr>
<tr>
<td style="text-align: center">WS2812B 1개 (최대)</td>
<td style="text-align: center">60mA</td>
</tr>
<tr>
<td style="text-align: center">WS2812B 150개 (1개 그룹 최대)</td>
<td style="text-align: center">9A (60mA X 150)</td>
</tr>
<tr>
<td style="text-align: center">WS2812B 600개 (4개 그룹 최대)</td>
<td style="text-align: center">36A (9A X 4)</td>
</tr>
<tr>
<td style="text-align: center">WS2812B 600개 (실제 사용 최대)</td>
<td style="text-align: center">18A (최대치의 1/2 가정)</td>
</tr>
</tbody>
</table>
<p>이론적인 최대값은 WS2812B의 모든 R, G, B LED가 켜져 있는 상태를 가정한 경우이므로 실제 사용 최대값은 약 1/2 정도로 설정하여도 충분하리라 생각됩니다. 이 경우 전원 공급은 최대 10A짜리 파워서플라이 2개를 사용하여 2그룹씩 제공하여야 할 것 같네요. 물론 4개의 JARDUINO-UNO-BTmini에도 전류를 공급하여야 하는데 이것은 큰 전류량이 아니므로 이것은 한 쪽 파워서플라이에서 함께 공급하면 되겠습니다.</p>
<p>눈결정 그룹에 연결된 모습만 간단하게 나타내면 아래와 같으며, 다른 그룹도 같은 방법으로 연결할 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-14.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32637" alt="39 ptb diyled (14)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-14.jpg" width="596" height="390" /></a></p>
<p><span style="color: #3366ff"><strong>5 단계 : 아두이노 스케치 프로그램하기</strong></span><br />
하드웨어는 모두 완성되었으므로, 이제는 스케치 프로그램을 작성할 시간입니다. 그동안 배운 라이브러리를 이용하여 자신이 원하는 대로 프로그램을 작성하면 되겠습니다. 모든 그룹에 대한 프로그램를 제시하는 것은 양도 너무 많으므로 가장 핵심이 되는 형상인 눈결정에 대한 스케치 프로그램만 살펴보도록 합니다.<br />
스케치 프로그램의 큰 줄기는 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-2.png" rel="lightbox[32471]"><img class="alignnone  wp-image-32625" alt="39 ptb diyled (2)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-2.png" width="500" /></a></p>
<p>· 블루투스 신호(TX/RX)는 아두이노 D4/D7 핀에 연결되어 있으므로 이것을 SoftwareSerial로 선언하고 처리한다.<br />
· 블루투스 앱을 이용하여 휴대폰으로부터의 [켜짐] 또는 [꺼짐] 명령을 받아, [켜짐] 명령이 오면 LED 동작을 실행하고, [꺼짐] 명령이 오면 LED를 모두 끈다. 따로 명령이 오지 않으면 현재 상태를 지속한다.<br />
· 눈결정 모양은 총 157개의 LED로 구성되는데, 이것을 크게 3부분으로 나누어 프로그램한다. 즉, 처음 108번째까지는 눈(SNOW) 형상의 MAIN 부분으로, 109번째부터 133번째까지는 SUB1 부분으로,</p>
<p>나머지는 SUB2 부분으로 나누어 처리한다.</p>
<p>· 단조로움을 피하기 위해 컬러 및 컬러 변화 시간을 결정할 때 random( ) 함수를 가능한 많이 이용한다.<br />
· 카DL은 밝기가 상당히 밝으므로 눈으로 쳐다 보았을 때 눈이 많이 부시지 않는 정도의 밝기로 처리한다.<br />
· 각 부분의 컬러는 아래의 기준으로 결정한다.<br />
· MAIN : 청색과 녹색의 비중을 강하게 하고, 빨강의 비중은 약하게 함<br />
· SUB1 : 청색과 녹색의 비중을 조금 강하게 하고, 빨강의 비중은 조금 약하게 함<br />
· SUB2 : 청색과 녹색, 빨강 비중을 똑같이 함<br />
· 모든 LED의 컬러가 흰색이 되는 경우와 각 LED의 컬러가 알록달록하도록 하는 경우도 구현한다.</p>
<p>이를 바탕으로 구현한 알고리즘은 아래와 같습니다.<br />
자, 이제 스케치 프로그램을 작성해 보겠습니다. 알고리즘을 보면서 차근차근 구현하면 되겠습니다. 아래를 보시지요.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
#include &lt;Adafruit_NeoPixel.h&gt;<br />
#include &lt;SoftwareSerial.h&gt;</p>
<p>#define CDL 13 // 아두이노(JARDUINO-UNO-BTmini) 연결 핀 = D13<br />
#define NUMPIXELS 157 // 눈결정에 사용된 카DL LED의 총 개수<br />
#define SNOW_NUM1 108 // 눈결정 MAIN 골격에 사용된 마지막 LED 번호<br />
#define SNOW_NUM2 133 // 눈결정 SUB1에 사용된 마지막 LED 번호<br />
#define SNOW_NUM3 157 // 눈결정 SUB2에 사용된 마지막 LED 번호<br />
#define BT_RX 4 // 블루투스가 연결된 RX핀 번호 (소프트시리얼로 연결)<br />
#define BT_TX 7 // 블루투스가 연결된 TX핀 번호 (소프트시리얼로 연결)<br />
#define CMD_ON ‘1’ // 휴대폰에서의 카DL 켜기(ON) 명령어<br />
#define CMD_OFF ‘0’ // 휴대폰에서의 카DL 끄기(OFF) 명령어</p>
<p>int mode=CMD_ON; // 시작은 카DL이 켜진 상태</p>
<p>SoftwareSerial btSerial=SoftwareSerial(BT_RX, BT_TX); // 블루투스 시리얼 핀 할당<br />
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, CDL, NEO_GRB + NEO_KHZ800); // 눈결정 구성 = (개수, 핀번호, 기타)</p>
<p>void setup()<br />
{<br />
pinMode(CDL,OUTPUT);<br />
btSerial.begin(115200); // 115200 baud (JARDUINO-UNO-BTmin 기본 셋팅<br />
pixels.begin(); //<br />
randomSeed(analogRead(0)); // 랜덤 초기값 설정<br />
for(uint8_t i = 0; i&lt;=NUMPIXELS; i++)<br />
pixels.setPixelColor(i,pixels.Color(0,0,0)); // 모든 카DL 꺼진 상태에서 시작<br />
pixels.show();<br />
delay(300);<br />
}</p>
<p>void loop()<br />
{<br />
uint8_t r, g, b, command, dummy;<br />
int i;</p>
<p>if (btSerial.available()) // 휴대폰에서의 명령 검사<br />
{ // 휴대폰의 입력이 있으면<br />
command = btSerial.read(); // 값을 저장하고,<br />
while (btSerial.available()) // 기타 다른 입력이 혹시 있으면<br />
dummy = btSerial.read(); // 모두 버림<br />
if (command == CMD_ON) // [켜기] 명령어면<br />
mode = CMD_ON; // [켜기] 모드 세팅<br />
else if (command == CMD_OFF) // [끄기] 명령어면<br />
mode = CMD_OFF; // [끄기] 모드 세팅<br />
else ; // 그 외의 명령어이면 무시!<br />
}<br />
if (mode == CMD_ON) // [켜기] 모드이면<br />
{<br />
r = random(0,16); // 눈결정의 MAIN은 r, g, b를 약한 불빛으로 랜덤하게<br />
g = random(32,64); // 단, 청색과 녹색이 많이 강하도록<br />
b = random(32,64);<br />
for(i = 0; i&lt;=SNOW_NUM1; i++)<br />
pixels.setPixelColor(i,pixels.Color(r,g,b));<br />
pixels.show();<br />
delay(random(100,1000)); // 지속 시간도 0.1초~1초로 랜덤하게</p>
<p>r = random(0,64); // 눈결정의 SUB1은 r, g, b를 약한 불빛으로 랜덤하게<br />
g = random(32,64); // 단, 청색과 녹색이 조금 강하도록<br />
b = random(32,64);<br />
for(i=SNOW_NUM1+1; i&lt;=SNOW_NUM2; i++)<br />
pixels.setPixelColor(i,pixels.Color(r,g,b));<br />
pixels.show();<br />
delay(random(100,1000)); // 지속 시간도 0.1초~1초로 랜덤하게</p>
<p>r = random(0,64); // 눈결정의 SUB2는 r, g, b를 약한 불빛으로 랜덤하게<br />
g = random(0,64); // 단, 모든 색상 가능<br />
b = random(0,64);<br />
for(i=SNOW_NUM2+1; i&lt;=SNOW_NUM3; i++)<br />
pixels.setPixelColor(i,pixels.Color(r,g,b));<br />
pixels.show();<br />
delay(random(100,1000)); // 지속 시간도 0.1초~1초로 랜덤하게</p>
<p>g = b = random(32,128); r = g/2; // (빨강은 광량을 줄여서 처리하여야 비슷하게 됨)<br />
for(i=0; i&lt;=NUMPIXELS; i++)<br />
pixels.setPixelColor(i,pixels.Color(r,g,b));<br />
pixels.show();<br />
delay(random(100,1000)); // 지속 시간도 0.1초~1초로 랜덤하게</p>
<p>for(i=0; i&lt;=NUMPIXELS; i++) // 눈결정의 LED 각각을 모두 랜덤한 다른 색상으로<br />
{<br />
r = random(0,64);<br />
g = random(0,64);<br />
b = random(0,64);<br />
pixels.setPixelColor(i,pixels.Color(r,g,b));<br />
}<br />
pixels.show();<br />
delay(random(100,1000)); // 지속 시간도 0.1초~1초로 랜덤하게<br />
}<br />
else // [끄기] 모드이면<br />
{<br />
for(i = 0; i&lt;=NUMPIXELS; i++) // 모든 LED를 OFF<br />
pixels.setPixelColor(i,pixels.Color(0,0,0));<br />
pixels.show();<br />
delay(1000);<br />
}<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
</div>
<p>카DL의 색상이나 켜져있는 시간 등을 결정할 때 random() 함수를 많이 사용한 이유는 임의성을 주어 실행시 나타나는 패턴이 단조롭지 않게 하기 위함입니다.</p>
<p><span style="color: #3366ff"><strong>6 단계 : 업로드하고 실행시키기</strong></span><br />
이제 프로그램까지 준비가 되었으니 업로드하고 실행시켜 보겠습니다.<br />
JARDUINO-UNO-BTmini는 아두이노 UNO 호환이므로 업로드시 스케치 프로그램의 [보드] 선택 항목을 ‘UNO’로 선택하면 되고 나머지 업로드 방법은 일반적인 아두이노와 동일합니다. 자, 그러면 가볼까요? GO~<br />
결과가 어찌 되었을까요?</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-15.jpg" rel="lightbox[32471]"><img class="alignnone size-full wp-image-32638" alt="39 ptb diyled (15)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-15.jpg" width="583" height="608" /></a></p>
<p>오우~ FANTASTIC!!! 너무나 아름답습니다.<br />
그동안 한 번도 보지 못했던 환상적인 컬러의 율동입니다.<br />
계속 바라봐도 질리지 않는… 북극에서 오로라를 보는 것과 같은 감흥(?)이…</p>
<p><span style="color: #3366ff"><strong>7 단계 : 트리에 장식하여 크리스마스트리 점등하기</strong></span><br />
나머지 3개 그룹에 대한 스케치 프로그램에 대한 제작 과정과 프로그램 소개는 생략하도록 하겠습니다. 각 그룹마다 다르게 구성된 카DL의 특징이 살아나도록 개별 스케치 프로그램을 작성하면 되는데, 예를 들어, 싼타나 지팡이 형상의 경우는 모자, 리본 장식 등의 형상마다 특징적인 색상을 갖도록 한다든지, ARC로 구성된 그룹의 모듈에 대하여는 물결이 흘러가는 듯이 컬러와 움직임을 구현하는 등이 그 예입니다. (실제로도 그렇게 구현했습니다.)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-16.jpg" rel="lightbox[32471]"><img class="alignnone  wp-image-32639" alt="39 ptb diyled (16)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-16.jpg" width="500" /></a></p>
<p>이렇게 모든 그룹에 대한 형상 제작과 스케치 프로그램 실행을 개별적으로 확인하였으므로, 이젠 드디어 전체 크리스마스트리를 완성할 시간이 되었습니다. 합동 공연의 모습은 어떨라나요?<br />
아래와 같이 꾸며 놓고… 점등해 보면… 짜잔~!</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-17.jpg" rel="lightbox[32471]"><img class="alignnone  wp-image-32640" alt="39 ptb diyled (17)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-17.jpg" width="500" /></a></p>
<p>아, 실제로 보면 컬러의 율동이 너무너무 환상적인데 사진으로는 이 느낌을 나타낼 길이 없네요.<br />
어쨌거나 성공입니다!</p>
<p><span style="color: #3366ff"><strong>8 단계 : 스마트폰으로 끄고 켜기</strong></span><br />
이제 마지막 마무리 단계로 스마트폰에 앱을 설치해서 스마트폰으로 크리스마트트리를 껐다 켰다 할 수 있도록 해 보겠습니다. 스케치 프로그램은 이미 블루투스로부터 들어오는 ‘ON’, ‘OFF’ 명령에 반응할 수 있도록 작성되어 있으므로 우리는 적당한 블루투스 앱을 스마트폰에 설치하여 실행하기만 하면 됩니다. 블루투스 앱은 상당히 많은 종류가 있는데 어떤 것을 사용하여도 무방하지만 여기서는 제가 익숙한 [Bluetooth Controller(블루투스 컨트롤)]라는 앱을 이용해 아래와 같이 실행해 보겠습니다. (해당 앱은 찾아서 설치하셔야 합니다.)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-19.jpg" rel="lightbox[32471]"><img class="alignnone  wp-image-32642" alt="39 ptb diyled (19)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-19.jpg" width="500" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-20.jpg" rel="lightbox[32471]"><img class="alignnone  wp-image-32643" alt="39 ptb diyled (20)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-20.jpg" width="500" /></a></p>
<p>· [Bluetooth Controller] 앱을 실행(1)하면, 위와 같은 화면(2)이 나타납니다.<br />
· [키설정]을 클릭하면 (3) 화면이 나타납니다.<br />
· [키 이름]과 [데이터 설정]에 각각 화면과 같이 ‘ON’, ‘1’, ‘OFF’, ‘O’을 입력하고 아래쪽으로 스크롤하여 [OK]를 클릭하면 (4)의 화면이 나타납니다.<br />
· [장치검색]을 클릭하여 (5) 화면이 나타납니다.<br />
· ‘JARDUINO-XXXX(4자리수)’를 찾아 (6) 화면이 나타나면서 “연결되었습니다.” 라는 메시지가 나타나면 스마트폰과 JARDUINO-UNO-BTmini가 패어링되어 통신이 가능한 상태가 된 것입니다.<br />
· 이제부터는 ‘ON’ 또는 ‘OFF’를 클릭하는 경우 JARDUINO-UNO-BTmini에 명령이 전달되어 크리스마스트리가 점등되거나 꺼지게 됩니다.</p>
<p>자, 그러면 이제 실제로 [OFF]를 클릭해 보지요. 1초, 2초, 오! 모두 꺼졌습니다. 다시 [ON]을 클릭해보면 1초, 바로 다시 동작합니다. 이것도 문제없이 성공! 다 잘 된 것 같네요.<br />
이렇게 해서 오늘의 주제인 [특별한 크리스마스 트리 제작]은 잘 마무리가 되었습니다. 올해는 독창적이고 멋진 크리스마스 트리를 보면서 새해를 맞을 수 있겠네요. 여러분도 기회가 된다면 한 번 시도해 보시기 바랍니다.<br />
참, 잊을뻔했네요. 마지막으로, [특별한 크리스마스 트리]에 사용된 다양한 형상을 디자인해 주신 신승현님(제이씨넷 디자이너)과 트리 제작 및 스케치 구현에 도움을 준 윤병우님(한밭대학교 학생)께도 깊은 고마움을 표합니다. 수고하셨습니다. 고맙습니다.</p>
<p><span style="color: #008000"><strong>카멜레온 DIY LED 기타 응용</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-21.jpg" rel="lightbox[32471]"><img class="alignnone  wp-image-32644" alt="39 ptb diyled (21)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-21-519x620.jpg" width="500" /></a><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-22.jpg" rel="lightbox[32471]"><img class="alignnone  wp-image-32645" alt="39 ptb diyled (22)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-22.jpg" width="500" /></a><a href="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-23.jpg" rel="lightbox[32471]"><img class="alignnone  wp-image-32646" alt="39 ptb diyled (23)" src="http://www.ntrexgo.com/wp-content/uploads/2016/11/39-ptb-diyled-23.jpg" width="500" /></a></p>
<p>저는 이번 [특별한 크리스마스 트리]를 만들면서 카DL의 응용 범위가 상당히 넓어질 수도 있다는 것을 새삼 느끼게 된 계기가 되었습니다. 부분적으로 만들어 본 사슴, 산타, 눈결정 등의 모양을 만들면서 어떠한 형상도 제작이 가능할 것 같다는 확신도 생겼고, 스케치 프로그램 입장에서도 상당히 다양한 라이브러리를 구현해 볼 수 있는 기회가 되었습니다.</p>
<p>여기에 자세히 소개하지는 않았지만 카DL은 생활 속 소품으로 무드등, 건물 모형 미니어처, 자동차 뒷면 표시등 등의 다양한 DIY 응용에 적용해 본 예가 있으며, 앞으로 여러분의 무한한 상상력이 가미되면 멋진 생활 소품이나 기상천외한 작품도 제작될 수 있으리라 예상합니다. 많은 시도를 기대하겠습니다.</p>
<p><span style="color: #008000"><strong>카DL 연재를 마치며</strong></span></p>
<p>작년 1년은 [너무 쉬운 아두이노 DIY] 연재로, 올해 1년은 [카멜레온 DIY LED 이야기] 연재로 디바이스마트 매거진의 독자 여러분과 만나게 되었는데, 이번 회를 마지막으로 아쉬운 작별 인사를 드립니다. 그동안 두 연재물을 사랑해주신 독자 여러분과 미흡한 글에 지면을 할당해 주신 디바이스마트 매거진 담당자 여러분께 진심으로 감사의 말씀 드리며, 다음 기회에 더 맑고 건강한 얼굴로 만나겠습니다. 안녕히 계십시오.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/32471/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[37호]카멜레온 DIY LED 이야기③</title>
		<link>http://www.ntrexgo.com/archives/31460</link>
		<comments>http://www.ntrexgo.com/archives/31460#comments</comments>
		<pubDate>Mon, 18 Jul 2016 00:49:50 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[37호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[LED]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[라이브러리]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[아두이노]]></category>
		<category><![CDATA[카멜레온]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=31460</guid>
		<description><![CDATA[디바이스마트매거진 37호 &#124; 우리보다 먼저 이런 형태의 컬러 LED를 접한 선배들이 당연히 만들어 놓았습니다. 이렇게 제공된 라이브러리의 종류는 꽤 되지만 이들 중 우리가 주목할 만한 것은 Adafruit_NeoPixel 과 FastLED입니다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/Cap-2016-10-20-14-29-25-163.png" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31731" alt="Cap 2016-10-20 14-29-25-163" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/Cap-2016-10-20-14-29-25-163.png" width="620" height="251" /></a></p>
<p>&nbsp;</p>
<p><span style="font-size: xx-large"><strong>카멜레온 DIY LED 이야기 3</strong></span></p>
<p><span style="font-size: medium"><strong>카멜레온 DIY LED를 위한 아두이노 라이브러리</strong></span></p>
<p style="text-align: right">글 | 신상석 ssshin@jcnet.co.kr</p>
<table style="background-color: #e2e2e2;;width: 620px" border="0" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>디바이스마트 매거진 독자 여러분, 안녕하세요. 앞으로 5회에 걸쳐 [카멜레온 DIY LED 이야기]를 진행할 신상석입니다.<br />
이 이야기는 WS2812B라는 컬러 LED를 기반으로 제작된 [카멜레온 DIY LED] 시리즈를 이용하여 생활에 필요한 다양한 형상을 꾸며보고 이것을 다양한 컬러로 디스플레이 해보는 내용입니다. 앞으로 진행할 내용에 대하여 간단히 알아보면 다음과 같습니다. (약간 변경될 수도 있습니다.)<br />
앞으로 즐겁고 유익한 강의가 될 수 있도록 많은 격려와 성원 부탁드립니다.</td>
</tr>
</tbody>
</table>
<p>디바이스마트매거진 독자 여러분, 안녕하세요. 반갑습니다.</p>
[카멜레온 DIY LED 이야기] 세번째 시간이 돌아왔습니다.<br />
지난 시간에는 카멜레온 DIY LED를 구성하고 있는 WS2812B의 동작 원리를 알아보았고 이를 기반으로 JLED-BAR-1(막대 모양 카멜레온 DIY LED 1개 모듈)로 무지개색을 표현해 보았으며, JLED-RING-12(원형의 카멜레온 DIY LED 12개 모듈)을 이용하여 알록달록 동그란 12색상환을 만들어 보았습니다. 기본 개념과 원리를 이해하고 실행해 보았으므로 이제부터는 어떤 모양, 어떤 컬러, 어떤 동작도 조금씩만 응용하면 모두 다 만들 수 있는 기초 능력은 갖추었지만, 그렇다고 해도 내가 원하는 형태로 바로 동작시킬 수 있다는 뜻은 아닙니다. 바둑에 비유하자면, 바둑을 배우는 것은 쉽지만 고수가 되는 것은 매우 많은 공부와 훈련, 실전을 필요로 하기 때문입니다. 지금 현재 상태는 이제 막 18급을 넘어선 상태라고나 할까요?<br />
한편, 지난번에 (기억이 나실 지 모르겠지만…) WS2812B가 인식하는 ‘0’과 ‘1’을 생성하기 위하여 정의한 ‘CODE0’와 ‘CODE1’ 마크로 선언은 개념적으로 실행해 본다는 의미에서 불명확한 타이밍을 기반으로 정의하여 사용하였으므로 이 부분도 오늘은 해결을 하고 넘어가야 하겠습니다.<br />
자, 그럼 천천히 라이브러리 이야기를 시작해 보겠습니다. 출발~</p>
<p><span style="font-size: medium;color: #008000"><strong>WS2812B를 위한 라이브러리가 있을까?</strong></span></p>
<p>C 언어를 처음 배울 때, C 언어의 사용법을 아주 간단하면서도 빠르게 이해시키기 위하여 가장 많이 사용하는 방법 중의 하나는 “Hello, World!”와 같은 문장을 C로 프로그램하고 이를 실행시켜 실제로 이 문장이 디스플레이되는 것을 보여주는 것입니다. 복잡한 설명 보다는 일단 아주 간단한 예를 보여주면 이해가 빠르고 흥미가 생기기 때문이지요.<br />
그 때를 회상하며 한 번 다시 보겠습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
#include &lt;stdio.h&gt;<br />
int main()<br />
{ printf(“Hello, World!\n”); }<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
</div>
내용을 보면 메인 프로그램 내부에 “printf”라는 함수만 달랑 한 줄 있는데 이 프로그램을 컴파일하고 실행시키면 터미널 창에 “Hello, World”라는 문장이 바로 디스플레이됩니다. “오우~ 신기하네! 당장 배워보자!” 이런 마음이 훅~ 하고 들어오지요. 이것이 가능한 이유는 누군가(아마도 고수!)가 이미 디스플레이를 가능케하는 printf( )라는 함수 프로그램을 잘 만들어서 이것을 라이브러리로 제공하였기 때문입니다. 이런 환경이 제공된다면 우리는 우리의 프로그램 첫 줄에 단지 “#include &lt;stdio.h&gt;”라는 선언문만 한 줄 넣어주기만 해도 printf( ) 함수 프로그램을 내가 작성한 것과 같은 효과를 얻을 수 있게 되는 것입니다.<br />
그렇다면, 혹시 printf( ) 함수처럼, “WS2812B를 기반으로 하는 컬러 LED의 색상을 누구나 쉽게 지정할 수 있도록 하는 함수를 어떤 고수가 라이브러리로 만들어놓지는 않았을까?” 하는 의문이 들만도 합니다.<br />
과연 그럴까요. 예, 과연 그렇습니다. “YES!”입니다.<br />
우리보다 먼저 이런 형태의 컬러 LED를 접한 선배들이 당연히 만들어 놓았습니다. 이렇게 제공된 라이브러리의 종류는 꽤 되지만 이들 중 우리가 주목할 만한 것은 Adafruit_NeoPixel 과 FastLED입니다.<br />
Adafruit_NeoPixel은 WS2812B를 기반으로 한 NeoPixel 제품(BAR, RING, MATRIX 등)을 생산 판매하고 있는 Adafruit 사에서 제공하는 라이브러리로, 조금은 단순하지만 &lt;LED에 색 지정하기&gt;와 &lt;LED에 데이터 전송하기&gt;의 기본 라이브러리 외에 &lt;한 개씩 색칠하기&gt;, &lt;무지개색 만들기&gt;, &lt;영화관 효과 만들기&gt; 등의 응용 함수를 제공합니다.<br />
FastLED는 Adafruit_NeoPixcel 보다는 조금 더 다양한 라이브러리를 제공하는데, 위에서 언급한 라이브러리나 예제에 더하여, &lt;좌우로 이동하기&gt; &lt;번지는 느낌의 색상 만들기&gt; 등의 기능도 더 제공하며, 적용할 수 있는 컬러LED도 우리가 사용하는 WS2812B 외에 LPD8806, APA102 등 거의 모든 컬러 LED로도 확장되는 장점이 있습니다. FastLED는 또한, 아두이노 외에 ESP9266, Teensy3 등의 플랫폼에서도 사용이 가능하도록 만들어진, 응용 범위가 조금 넓은 전문화된 라이브러리라고 하겠습니다.<br />
오늘 이야기에서는 일단 간단한 라이브러리인 Adafruit_NeoPixel 라이브러리를 이용해보는 것으로 하고 진행해 보겠습니다. (FastLED의 이용은 다음 기회에~)</p>
<p><span style="font-size: medium;color: #008000"><strong>Adafruits_NeoPixel 라이브러리 설치</strong></span></p>
<p>위에서도 언급했듯이 라이브러리를 사용하려면 이 라이브러리를 사용할 수 있는 환경을 만들어 주어야 합니다. NeoPixel 라이브러리를 사용하기 위한 설치 방법을 순서대로 나타내면 아래와 같습니다.</p>
<p>1. Github의 Adafruit_NeoPixel 프로젝트를 찾아갑니다. URL은 https://github.com/adafruit/Adafruit_NeoPixel 입니다. 아래의 화면이 나오면 화면 중간 오른쪽의 녹색으로 표시된 [Clones or download]를 클릭하고 새로 나타난 창에서 [Download ZIP]을 선택하여 적당한 디렉토리에 “Adafruit_NeoPixel-master.zip” 파일을 저장합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-1.jpg" rel="lightbox[31460]"><img alt="37 projects  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-1.jpg" width="620" height="360" /></a></p>
<p>2. “Adafruit_NeoPixel-master.zip” 파일의 압축을 풉니다. “Adafruit_NeoPixel-master” 디렉토리가 생성됩니다.<br />
3. “Adafruit_NeoPixel-master” 디렉토리를 통째로 아두이노 스케치의 라이브러리인 [\My Doucument \Arduino\library] 디렉토리 아래에 복사합니다. [\My Doucument \Arduino\library\Adafruit_NeoPixel-master] 형태로 보여져야 합니다.<br />
4. 아두이노를 실행합니다. 스케치 화면에서 [파일] ▶ [예제] ▶ {Adafruit_NeoPixel-master} ▶ [simple]를 클릭합니다. 아래와 같이 프로그램이 올라오면 설치가 잘 된 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-2.jpg" rel="lightbox[31460]"><img class="alignnone size-large wp-image-31737" alt="37 projects  (2)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-2-515x620.jpg" width="515" height="620" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #008000;font-size: medium"><strong>Adafruit NeoPixel 라이브러리 기본 함수</strong></span></p>
<p>이제 설치가 되었으니 Adafruit_NeoPixel 라이브러리를 사용할 수 있는 환경은 갖추어졌습니다. 그렇다면 실제로 어떤 라이브러리가 어떤 형태로 제공되는지만 알면 되겠네요. 그런데 여기서 잠깐! 돌발 퀴즈!<br />
“세부적인 함수를 사용하기 전에 가장 먼저 결정하고 선언해 놓아야 할 변수가 있는데, 이것은 무엇일까요?” “무엇이 결정되어야만 함수가 동작할 수 있을까요?”<br />
1분 동안만 잠시 각자 생각해 보겠습니다.<br />
흐음. 예, 상당수의 분들은 이미 예상하셨겠지만, Adafruit_NeoPixel 라이브러리 입장에서는 반드시 3가지가 미리 결정되어져야만 하는데, 그것은 첫째, 사용할 LED의 개수이고, 둘째, 데이터 입력으로 사용할 제어기(아두이노)의 출력핀 번호, 마지막으로 셋째, 사용할 LED의 타입(WS2811, WS2812)입니다.<br />
이것이 결정되었다면, Adafruit_NeoPixel 라이브러리는 아래 그림과 같이 원하는 크기(3 X LED 개수)의 버퍼를 준비하고 여기에 어떤 한 순간에 보여지기를 원하는 컬러 값으로 R(Red), G(Green), B(Blue) 값을 저장해 놓은 다음 이것을 데이터출력핀을 통하여 순서대로 끊김없이 카멜레온 DIY LED에게 전송하는 방식을 사용하는 것입니다. (주의 : 예전에 잠깐 이야기했듯이, 데이터의 모양은 RGB 형태이지만 실제 전송될 때는 WS2812B 특성에 맞추어 GRB 순으로 전송됨)</p>
<p>Leds[N]
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-3.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31738" alt="37 projects  (3)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-3.jpg" width="620" height="263" /></a><br />
이렇게 하면 어떤 한 순간 전제 LED의 컬러가 결정되어지므로, 이러한 동작을 시간 간격을 두고 반복적으로 실행하면 움직이는 컬러 LED의 형상을 만들 수 있습니다.<br />
개념적인 설명이 되었으므로, 이제 프로그램을 직접 작성해 보면서 Adafruit_NeoPixel의 기본 함수를 살펴 보겠습니다.<br />
JLED-BAR-10(카멜레온 DIY LED 10개 모듈)을 사용하여 모든 LED를 녹색(Green)으로 유지하는 프로그램을 한 번 작성해 보겠습니다. 아두이노 UNO의 6번핀을 출력핀으로 사용하는 경우 프로그램의 앞 부분은 아래와 같이 되겠습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
#include &lt;Adafruit_NeoPixel.h&gt; // Adafruit_NeoPixel 라이브러리 include, 필수 선언!!!<br />
#define PIN 6/ // 결정하여야 할 변수 1 → 데이터 출력핀 번호<br />
#define NUMPIXELS 10 // 결정하여야 할 변수 2 → LED 개수<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
</div>
아래는 연결된 모습입니다.<br />
JLED-BAR-10의 입력쪽으로 3개의 신호 GND, DIN, VCC(+5V)가 아두이노와 연결되어 있는 것을 확인할 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-4.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31739" alt="37 projects  (4)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-4.jpg" width="620" height="290" /></a></p>
<p>이제 Adafruit_NeoPixel 클래스로 pixels을 아래와 같이 선언합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);<br />
// pixels는 Adafrut_NeoPixel 구조체의 형태를 가짐<br />
// LED의 개수는 10(NUMPIXELS)이며,<br />
// WS2812B 타입(NEO_GRB + NEO_KHZ800)임<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
</div>
Adafruit_NeoPixel 클래스는 “Adafruit_NeoPixel.h”에 정의되어 있는데 필요한 부분만 간단히 발췌하여 나타내면 아래와 같습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
class Adafruit_NeoPixel {<br />
public:<br />
Adafruit_NeoPixel(uint16_t n, uint8_t p=6, uint8_t t=NEO_GRB + NEO_KHZ800);<br />
// n : LED 개수<br />
// p : 출력핀 번호 = 6<br />
// t : 타입 = NEO_GRB (GRB 순서로 데이터를 전송) + NEO_KHZ800 (800KHZ 타입)<br />
// 결국, WS2812B를 사용한다는 의미<br />
~Adafruit_NeoPixel();<br />
void<br />
begin(void), // 시작 함수<br />
show(void), // 데이터 전송 함수, 따로 설명<br />
setPin(uint8_t p), // 출력핀 셋업 함수<br />
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b), // n번째 LED를 r, g, b 값으로 설정하는 함수<br />
setPixelColor(uint16_t n, uint32_t c), // n번째 LED를 c 값(32비트)으로 설정하는 함수<br />
setBrightness(uint8_t), // 밝기 세팅 함수<br />
clear(); // LED OFF 함수<br />
uint8_t<br />
*getPixels(void) const,<br />
getBrightness(void) const;<br />
uint16_t<br />
numPixels(void) const; // 선언된 LED 개수를 추출하는 함수<br />
static uint32_t<br />
Color(uint8_t r, uint8_t g, uint8_t b);<br />
uint32_t<br />
getPixelColor(uint16_t n) const;<br />
inline bool<br />
canShow(void) { return (micros() &#8211; endTime) &gt;= 50L; }<br />
};<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
</div>
<p>pixels 클래스가 생성되었으므로 setup() 프로그램을 통하여 멤버 함수인 begin()을 콜하여 초기화를 실행합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
void setup() {<br />
pixels.begin(); // Adafruit_Neopixel 라이브러리 초기화<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
</div>
이제 실제로 어떤 컬러를 LED에 표현해 봅시다. 2가지의 동작이 필요합니다. 하나는 데이터를 준비하는 동작이고, 다른 하나는 준비된 데이터를 실제 LED에 전송하는 동작입니다. 여기서 중요한 것은 데이터를 LED에 전송하는 동작인데, 이것은 지난번에 살펴본 것처럼 데이터값에 따라 ‘CODE0’와 ‘CODE1’ 해당되는 신호를 WS2812B의 타이밍 규격에 맞도록 생성하고 이것을 카멜레온 DIY LED에 전송하는 동작입니다. 우리가 지난번에 찜찜하게 생각하였던 부분인데, 다행히(당연하지만…) Adafruit_NeoPixel 라이브러리에서는 show( )라는 멤버 함수를 제공하므로 이 함수를 사용하면 완전한 LED 동작을 보장받을 수 있습니다. show( ) 함수는 어셈블리언어로 매우 정교하게 만들어진 함수로 WS2812B의 타이밍 규격을 완전하게 만족하도록 프로그램되어 있습니다. (좀 더 자세한 내용은 “Adafruit_NeoPixel.h”의 해당 어셈블리 프로그램을 분석해 보시기 바랍니다. 한 번쯤 분석해 볼만한 가치가 있는 프로그램입니다.) 사용 방법은 너무나 간단합니다. 아래와 같이 실행하면 됩니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
pixels.show( ) // 준비된 데이터를 모두 전송<br />
</div>
<p>이제 이를 이용하여 녹색으로 10개 LED를 1초 간격으로 껐다 켰다 깜빡이도록(blink) 프로그램 해보겠습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
void loop() {<br />
for(int i=0; i&lt;NUMPIXELS; i++) // 전체 LED에 대하여<br />
pixels.setPixelColor(i, pixels.Color(0,150,0)); // Green 컬러(중간 밝기) 준비.<br />
pixels.show(); // 데이터 전송<br />
delay(1000); // 1초 동안 디스플레이<br />
for(int i=0; i&lt;NUMPIXELS; i++) // 전체 LED에 대하여<br />
pixels.setPixelColor(i, pixels.Color(0,0,0)); // Black 컬러(LED OFF) 준비.<br />
pixels.show(); // 데이터 전송<br />
delay(1000); // 1초 동안 디스플레이<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
</div>
조각 조각 설명하였는데 전체 프로그램을 합쳐보면 아래와 같습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
#include &lt;Adafruit_NeoPixel.h&gt; // Adafruit_NeoPixel 라이브러리 include, 필수 선언!!!<br />
#define PIN 6 // 결정하여야 할 변수 → 데이터 출력핀 번호<br />
#define NUMPIXELS 10 // 결정하여야 할 변수 → LED 개수</p>
<p>Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);<br />
// pixels 는 Adafrut_NeoPixel 구조체의 형태를 가짐<br />
// LED의 개수는 10(NUMPIXELS)이며,<br />
// WS2812B 타입(NEO_GRB + NEO_KHZ800)임<br />
void setup() {<br />
pixels.begin(); // Adafruit_Neopixel 라이브러리 초기화<br />
}</p>
<p>void loop() {<br />
for(int i=0; i&lt;NUMPIXELS; i++) // 전체 LED에 대하여<br />
pixels.setPixelColor(i, pixels.Color(0,150,0)); // Green 컬러(중간 밝기) 준비.<br />
pixels.show(); // 데이터 전송<br />
delay(1000); // 1초 동안 디스플레이<br />
for(int i=0; i&lt;NUMPIXELS; i++) // 전체 LED에 대하여<br />
pixels.setPixelColor(i, pixels.Color(0,0,0)); // Black 컬러(LED OFF) 준비.<br />
pixels.show(); // 데이터 전송<br />
delay(1000); // 1초 동안 디스플레이<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
</div>
이것을 아두이노 스케치를 통하여 업로드하고 제대로 실행되는지 보시지요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-5.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31740" alt="37 projects  (5)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-5.jpg" width="620" height="326" /></a></p>
<p>오오~! 성공입니다. 제가 좋아하는 은은한 녹색 LED가 깜빡깜빡 하네요. 기분 UP! 갑자기 히말라야 등정이 생각나는데, 이 정도면 4000m 고지에 베이스캠프 설치는 성공한 정도로 느껴집니다.</p>
<p><span style="color: #008000;font-size: medium"><strong>JLED-RING-12로 12색상환 표현하기</strong></span></p>
<p>실력이 얼마나 늘었는지는 예전과 비교해 보면 금방 알 수 있습니다. 지난번 이야기에서 마지막으로 다루었던 작품, JLED-RING-12로 12색상환 표현하기 과제를 라이브러리를 이용하여 한 번 구현해 보겠습니다.<br />
조금 전에 배운 라이브러리를 이용해서 (1) 어레이로 준비한 12가지 색상을, (2) 순서대로 데이터로 세팅한 후, (3) 이것을 JLED-RING-12로 전송하면 되겠습니다. 12가지 색상값은 지난번에 제시한 표와 동일한 값을 사용하겠습니다.</p>
<table style="width: 620px" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td style="text-align: center">색상</td>
<td style="text-align: center">빨강</td>
<td style="text-align: center">다홍</td>
<td style="text-align: center">주황</td>
<td style="text-align: center">귤색</td>
<td style="text-align: center">노랑</td>
<td style="text-align: center">연두</td>
</tr>
<tr>
<td style="text-align: center">데이터</td>
<td style="text-align: center">0xff0000</td>
<td style="text-align: center">0xdc143c</td>
<td style="text-align: center">0xff7f00</td>
<td style="text-align: center">0xf89b00</td>
<td style="text-align: center">0xffd400</td>
<td style="text-align: center">0x66cc00</td>
</tr>
<tr>
<td style="text-align: center">색상</td>
<td style="text-align: center">녹색</td>
<td style="text-align: center">청록</td>
<td style="text-align: center">파랑</td>
<td style="text-align: center">남색</td>
<td style="text-align: center">보라</td>
<td style="text-align: center">자주</td>
</tr>
<tr>
<td style="text-align: center">데이터</td>
<td style="text-align: center">0x00ff00</td>
<td style="text-align: center">0&#215;005666</td>
<td style="text-align: center">0x0000ff</td>
<td style="text-align: center">0x080b54</td>
<td style="text-align: center">0xee82ee</td>
<td style="text-align: center">0&#215;800080</td>
</tr>
</tbody>
</table>
<p>위에서 언급한 기본 라이브러리를 이용하면 다양한 응용 프로그램을 작성할 수 있는데, 이것에 대한 예제는 Adafruit_NeoPixel의 “strandtest” 프로그램에 잘 나타나 있습니다. 우리가 사용할 수 있는 프로그램을 하나씩 살펴봅시다.</p>
<p>어려울 것이 없어 설명없이 바로 스케치 진행합니다. 라이브러리를 사용하니까 정말 간단하네요.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
#include &lt;Adafruit_NeoPixel.h&gt; // Adafruit_NeoPixel 라이브러리 include, 필수 선언!!!<br />
#define PIN 6 // 결정하여야 할 변수 → 데이터 출력핀 번호<br />
#define NUMPIXELS 12 // 결정하여야 할 변수 → LED 개수</p>
<p>Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);<br />
// pixels 는 Adafrut_NeoPixel 구조체의 형태를 가짐<br />
// LED의 개수는 12(NUMPIXELS)이며,<br />
// WS2812B 타입(NEO_GRB + NEO_KHZ800)임<br />
void setup() {<br />
pixels.begin(); // Adafruit_Neopixel 라이브러리 초기화<br />
}</p>
<p>void loop() {<br />
unsigned long data[12] = {0xff0000, 0xdc143c, 0xff7f00, 0xf89b00, 0xffd400, 0x66cc00, 0x00ff00, 0&#215;005666, 0x0000ff, 0x080b54, 0xee82ee, 0&#215;800080}; // 12개 색상 준비<br />
for(int i=0; i&lt;NUMPIXELS; i++) // 전체 LED에 대하여<br />
pixels.setPixelColor(i,data[i]); // 12색상 데이터값 세팅<br />
pixels.show(); // 데이터 전송<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
</div>
실행 결과는 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-6.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31741" alt="37 projects  (6)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-6.jpg" width="620" height="286" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-7.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31742" alt="37 projects  (7)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-7.jpg" width="620" height="315" /></a></p>
<p>&nbsp;</p>
<p><span style="font-size: medium;color: #008000"><strong>다양한 응용 프로그램</strong></span></p>
<p>위에서 언급한 기본 라이브러리를 이용하면 다양한 응용 프로그램을 작성할 수 있는데, 이것에 대한 예제는 Adafruit_NeoPixel의 “strandtest” 프로그램에 잘 나타나 있습니다. 우리가 사용할 수 있는 프로그램을 하나씩 살펴봅시다.</p>
<table style="width: 620px" border="1" cellspacing="0" cellpadding="3">
<tbody>
<tr>
<td>응용 함수</td>
<td>설명</td>
</tr>
<tr>
<td>void colorWipe<br />
(uint32_t c, uint8_t wait)</td>
<td>LED를 하나씩 순서대로 동일한 컬러로 채우는 함수<br />
- c : 채우고자 하는 컬러<br />
- wait : 하나씩 채우는데 걸리는 간격 (ms)</td>
</tr>
<tr>
<td>void rainbow(uint8_t wait)</td>
<td>전체 LED의 컬러를 무지개처럼 다양한 컬러로 변화시키는 함수<br />
- wait : 컬러를 바꾸는 간격(ms)</td>
</tr>
<tr>
<td>void rainbowCycle<br />
(uint8_t wait)</td>
<td>LED의 컬러를 무지개처럼 다양한 컬러로 서로 다르게 세팅하고 이것을 돌아가면서 변화시키는 함수<br />
- wait : 컬러를 바꾸는 간격(ms)</td>
</tr>
<tr>
<td>void theaterChase<br />
(uint32_t c, uint8_t wait)</td>
<td>LED의 컬러를 동일한 컬러로 N개씩 건너서 세팅하되, 이것도 돌아가면서 LED에 할당하게 함으로써 번쩍번쩍하는 사이키 조명의 느낌을 만드는 함수<br />
- c : 채우고자 하는 컬러<br />
- wait : 변화하는 간격 (ms)</td>
</tr>
<tr>
<td>void theaterChaseRainbow<br />
(uint8_t wait)</td>
<td>LED의 컬러를 다양한 컬러로 3개씩 건너서 세팅하되, 이것도 돌아가면서 LED에 할당하게 함으로써 번쩍번쩍하는 사이키 조명의 느낌을 만드는 함수<br />
- wait : 변화하는 간격 (ms)</td>
</tr>
<tr>
<td>uint32_t Wheel<br />
(byte WheelPos)</td>
<td>0~255까지의 값을 전달하면 R과 G, G와 B, B와 R 값으로만 구성된 4 바이트 컬러값을 리턴하는 함수. 임의의 고르게 분포된 컬러값을 생성하기 위하여 사용<br />
- WheelPos : 0~255 사이의 값</td>
</tr>
</tbody>
</table>
<p>예를 들어 “colorWipe(0x00ff0000, 10)” 이렇게 사용하면 모든 LED의 컬러를 빨강색(Red, 0x00ff0000, (X)(R)(G)(B) 순)으로 세팅하되 처음부터 1개씩 10ms의 간격으로 하나씩 증가하는 방식으로 적용됩니다.</p>
<p>이러한 함수를 모두 사용하여 작성한 strandtest( ) 예제 프로그램 전체를 나타내면 아래와 같습니다.<br />
개별 함수의 동작을 이해하려면 약간의 시간과 노력이 필요하나, 하나씩 차근차근 생각해 보면 이해가 될 수 있는 부분이므로 여러분 모두가 짬을 내서 찬찬히 공부해 보시기 바랍니다. 이용에만 관심있는 분들은 굳이 개별 함수의 내부의 프로그램 동작을 이해하지 않고 그냥 기능적으로만 이해한 다음, 그냥 함수를 불러다 쓰기만 해도 괜찮겠습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
#include &lt;Adafruit_NeoPixel.h&gt;<br />
#define PIN 6</p>
<p>Adafruit_NeoPixel strip = Adafruit_NeoPixel(45, PIN, NEO_GRB + NEO_KHZ800);</p>
<p>void setup() {<br />
strip.begin();<br />
strip.show(); // Initialize all pixels to &#8216;off&#8217;<br />
}</p>
<p>void loop() {<br />
// Some example procedures showing how to display to the pixels:<br />
colorWipe(strip.Color(255, 0, 0), 50); // Red<br />
colorWipe(strip.Color(0, 255, 0), 50); // Green<br />
colorWipe(strip.Color(0, 0, 255), 50); // Blue<br />
// Send a theater pixel chase in&#8230;<br />
theaterChase(strip.Color(127, 127, 127), 50); // White<br />
theaterChase(strip.Color(127, 0, 0), 50); // Red<br />
theaterChase(strip.Color( 0, 0, 127), 50); // Blue</p>
<p>rainbow(20);<br />
rainbowCycle(20);<br />
theaterChaseRainbow(50);<br />
}</p>
<p>// Fill the dots one after the other with a color<br />
void colorWipe(uint32_t c, uint8_t wait) {<br />
for(uint16_t i=0; i&lt;strip.numPixels(); i++) {<br />
strip.setPixelColor(i, c);<br />
strip.show();<br />
delay(wait);<br />
}<br />
}</p>
<p>void rainbow(uint8_t wait) {<br />
uint16_t i, j;</p>
<p>for(j=0; j&lt;256; j++) {<br />
for(i=0; i&lt;strip.numPixels(); i++) {<br />
strip.setPixelColor(i, Wheel((i+j) &amp; 255));<br />
}<br />
strip.show();<br />
delay(wait);<br />
}<br />
}</p>
<p>// Slightly different, this makes the rainbow equally distributed throughout<br />
void rainbowCycle(uint8_t wait) {<br />
uint16_t i, j;</p>
<p>for(j=0; j&lt;256*5; j++) { // 5 cycles of all colors on wheel<br />
for(i=0; i&lt; strip.numPixels(); i++) {<br />
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) &amp; 255));<br />
}<br />
strip.show();<br />
delay(wait);<br />
}<br />
}</p>
<p>//Theatre-style crawling lights.<br />
void theaterChase(uint32_t c, uint8_t wait) {<br />
for (int j=0; j&lt;10; j++) { //do 10 cycles of chasing<br />
for (int q=0; q &lt; 3; q++) {<br />
for (int i=0; i &lt; strip.numPixels(); i=i+3) {<br />
strip.setPixelColor(i+q, c); //turn every third pixel on<br />
}<br />
strip.show();</p>
<p>delay(wait);</p>
<p>for (int i=0; i &lt; strip.numPixels(); i=i+3) {<br />
strip.setPixelColor(i+q, 0); //turn every third pixel off<br />
}<br />
}<br />
}<br />
}</p>
<p>//Theatre-style crawling lights with rainbow effect<br />
void theaterChaseRainbow(uint8_t wait) {<br />
for (int j=0; j &lt; 256; j++) { // cycle all 256 colors in the wheel<br />
for (int q=0; q &lt; 3; q++) {<br />
for (int i=0; i &lt; strip.numPixels(); i=i+3) {<br />
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on<br />
}<br />
strip.show();</p>
<p>delay(wait);</p>
<p>for (int i=0; i &lt; strip.numPixels(); i=i+3) {<br />
strip.setPixelColor(i+q, 0); //turn every third pixel off<br />
}<br />
}<br />
}<br />
}</p>
<p>// Input a value 0 to 255 to get a color value.<br />
// The colours are a transition r &#8211; g &#8211; b &#8211; back to r.<br />
uint32_t Wheel(byte WheelPos) {<br />
WheelPos = 255 &#8211; WheelPos;<br />
if(WheelPos &lt; 85) {<br />
return strip.Color(255 &#8211; WheelPos * 3, 0, WheelPos * 3);<br />
} else if(WheelPos &lt; 170) {<br />
WheelPos -= 85;<br />
return strip.Color(0, WheelPos * 3, 255 &#8211; WheelPos * 3);<br />
} else {<br />
WheelPos -= 170;<br />
return strip.Color(WheelPos * 3, 255 &#8211; WheelPos * 3, 0);<br />
}<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
</div>
<p>이제 이 프로그램을 아래와 같이 JLED-BAR-10, JLED-STAR-10, JLED-RING-12, JLED-SNOW-13의 4가지 카멜레온 DIY LED를 순서대로 연결한 [3단 아이스크림] 형상(LED 총 45개)에 적용하여 업로드하고 실행하여 보겠습니다.<br />
wheel( ) 함수는 다른 함수를 사용할 때 내부에서 사용되는 함수이므로 이것을 제외하고 나머지 5가지 함수는 눈으로 그 기능을 바로 확인할 수 있습니다. 아래에 결과 사진을 제시하였습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-8.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31743" alt="37 projects  (8)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-8.jpg" width="299" height="403" /></a></p>
<p>&lt;colorWipe( ) 함수&gt; 실행 결과</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-9.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31744" alt="37 projects  (9)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-9.jpg" width="620" height="441" /></a></p>
<p>&lt;rainbow( ) 함수&gt; 실행 결과</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-10.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31745" alt="37 projects  (10)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-10.jpg" width="620" height="441" /></a></p>
<p>&lt;rainbowCycle( ) 함수&gt; 실행 결과</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-11.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31746" alt="37 projects  (11)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-11.jpg" width="620" height="433" /></a></p>
<p>&lt;theaterChase( ) 함수&gt; 실행 결과</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-12.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31747" alt="37 projects  (12)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-12.jpg" width="620" height="433" /></a></p>
<p>&lt;theaterChaseCycle( ) 함수&gt; 실행 결과</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-13.jpg" rel="lightbox[31460]"><img class="alignnone size-full wp-image-31748" alt="37 projects  (13)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-13.jpg" width="620" height="433" /></a></p>
<p>당연한 이야기지만 다행히도(?) 모든 함수가 다 잘 동작하는 것 같죠?굿~입니다. 이제 히말라야 등정에서 6,000m 정도 위치에 제1캠프를 설치한 정도는 되지 않았을라나요? 여기서 더 나아간다면 이제부터는 조금씩은 자신의 루트를 개척하면서 가야하는 경우가 생길 수 있겠습니다. 물론 잘 찾아보면 아직도 많은 선배들이 닦아 놓은 훌륭한 루트가 중간 중간 많이 있긴 하겠습니다.</p>
<p>카멜레온 DIY LED를 위한 아두이노 라이브러리를 설명한다고 하면서 Adafruit_NeoPixcel 라이브러리만 설명하였는데… 사실 카멜레온 DIY LED제품이나 NeoPixel 제품은 형태만 다를뿐 WS2812B를 한 줄로 연결한 동일한 형태를 가지고 있기 때문에 라이브러리는 동일하게 사용 가능합니다. 그래도 카멜레온 DIY LED만을 위한 따로 제공하는 라이브러리가 몇 개는 있어야 한다구요? 예. 그러면 오늘은 일단 이 정도에서 마무리하고, 다음 시간 [다양한 형상의 카멜레온 DIY LED]를 만나보면서 좀 더 다이나믹한 응용 함수도 함께 소개하는 시간을 갖도록 하겠습니다.<br />
다음 회에 환한 얼굴로 또 만나겠습니다. 안녕히 계십시오. 야옹~</p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-14.jpg" rel="lightbox[31460]"><img class="wp-image-31749 aligncenter" alt="37 projects  (14)" src="http://www.ntrexgo.com/wp-content/uploads/2016/07/37-projects-14.jpg" width="434" height="303" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/31460/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[36호]카멜레온 DIY LED 이야기 2</title>
		<link>http://www.ntrexgo.com/archives/31253</link>
		<comments>http://www.ntrexgo.com/archives/31253#comments</comments>
		<pubDate>Fri, 20 May 2016 04:44:16 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[36호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[LED]]></category>
		<category><![CDATA[Project To Build]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=31253</guid>
		<description><![CDATA[디바이스마트매거진 36호 &#124; 카멜레온 DIY LED의 기본 LED인 WS2812B의 동작 원리에 대한 이야기로 시작해 보겠습니다. 어떤 분야든 개념과 원리가 중요하니까요. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-ptb.jpg" rel="lightbox[31253]"><img alt="36 카멜레온 ptb" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-ptb-620x235.jpg" width="620" height="235" /></a></p>
<p>&nbsp;</p>
<p><span style="font-size: xx-large"><strong>카멜레온 DIY LED 이야기 2</strong></span></p>
<p><span style="font-size: medium"><strong>WS2812B의 동작원리와 12색상환 만들기</strong></span></p>
<p>&nbsp;</p>
<p style="text-align: right">글 | 신상석 ssshin@jcnet.co.kr</p>
<table style="background-color: #e2e2e2;;width: 620px" border="0" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>디바이스마트 매거진 독자 여러분, 안녕하세요. 앞으로 5회에 걸쳐 [카멜레온 DIY LED 이야기]를 진행할 신상석입니다.<br />
이 이야기는 WS2812B라는 컬러 LED를 기반으로 제작된 [카멜레온 DIY LED] 시리즈를 이용하여 생활에 필요한 다양한 형상을 꾸며보고 이것을 다양한 컬러로 디스플레이 해보는 내용입니다. 앞으로 진행할 내용에 대하여 간단히 알아보면 다음과 같습니다. (약간 변경될 수도 있습니다.)<br />
앞으로 즐겁고 유익한 강의가 될 수 있도록 많은 격려와 성원 부탁드립니다.</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>디바이스마트 매거진 독자 여러분, 안녕하세요.</p>
[카멜레온 DIY LED 이야기] 두번째 시간이 돌아왔습니다.<br />
뜸하게 만나므로 지난 시간에 어디까지 이야기했는지 기억이 잘 나지 않으실 것 같은데, 지난 시간에는 카멜레온 DIY LED에 대한 정의, 형태, 종류, 타 모듈과의 비교, 응용 예 등과 같이 전반적인 소개가 이루어졌습니다. 이번 호부터는 좀 더 세부적으로 카멜레온 DIY LED에 대하여 알아보는 시간을 갖도록 하겠습니다. 일단은, 카멜레온 DIY LED의 기본 LED인 WS2812B의 동작 원리에 대한 이야기로 시작해 보겠습니다. 어떤 분야든 개념과 원리가 중요하니까요.</p>
<p><span style="color: #008000;font-size: medium"><strong>WS2812B의 동작 원리</strong></span></p>
<p>WS2812B의 특징은 간단하게 말해서, “내가 원하는 개수만큼 연속적으로 간단하게 연결하면서, 내가 원하는 시간에 내가 원하는 컬러(껐다 켰다 포함)로 자유롭게 표현할 수 있는 LED”라고 이야기한 바 있습니다.<br />
WS2812B의 외관 모습은 지난번에 보았으므로 오늘은 신호선과 핀 배열을 살펴보겠습니다. 아래와 같이 생겼습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-01.jpg" rel="lightbox[31253]"><img class="wp-image-31343 aligncenter" alt="36 카멜레온 01" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-01.jpg" width="301" height="142" /></a></p>
<p>4핀 중, VCC(+)와 GND(-)는 전원이고, DIN과 DOUT은 각각 데이터입력, 데이터출력 신호입니다. VCC와 GND는 3.5 V ~ 5.3 V 사이의 전원으로 여러 개의 WS2812B가 연결되는 경우에도 모두에게 공통으로 연결되어져야만 합니다. DIN은 WS2812B로 전달되는 데이터의 입력 신호선이고, DOUT은 DIN으로 들어온 데이터 중 자신이 사용하지 않는 데이터를 통과(bypass)시키는 출력 신호선인데, 여러 개의 WS2812B를 연결하는 경우에는 앞쪽 WS2812B의 DOUT이 뒤쪽 WS2812B의 DIN에 연결되는 형태로 직렬(시리얼) 연결합니다. 데이터를 공급해주는 제어기를 포함한 연결 관계를 그림으로 나타내 보면 아래와 같이 되겠습니다. 연결 방식은 상당히 간결한 편이지요.</p>
<table style="width: 620px;border: 1px solid #c8c8c8" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-02.jpg" rel="lightbox[31253]"><img class="wp-image-31344 aligncenter" alt="36 카멜레온 02" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-02-620x409.jpg" width="496" height="327" /></a></td>
</tr>
<tr>
<td style="text-align: center">데이터를 공급해주는 제어기를 포함한 연결 관계</td>
</tr>
</tbody>
</table>
<p>이렇게 연결하고도 LED마다 따로따로 여러가지 색채와 동작을 표현할 수 있다는 것이 신기할 따름인데… 과연 어떻게 동작하는 것일까요? 살펴 보겠습니다.<br />
세부적인 내부 회로도가 공개되어 있지 않아 정확하게 알 수는 없지만, 데이터시트에 나온 내용을 기준으로 WS2812B의 동작 방법을 설명하면 다음과 같습니다.</p>
<p style="padding-left: 30px">· 내부에 R(Red), G(Green), B(Blue)에 해당하는 컬러 LED와 이를 제어하는 로직이 함께 통합되어 있음<br />
· DIN으로 입력된 데이터는 내부의 데이터 래치에 의하여 저장되고 신호증폭 로직을 거쳐 DOUT으로 출력됨<br />
· 전원이 켜지거나, 데이터리셋이 되면, 내부 로직은 DIN 포트로부터 데이터를 받아들이는데, 처음 24비트는 자신의 내부 데이터 래치로 보내고 이후의 데이터는 DOUT 포트로 bypass하여 내보냄. 한편, LOW 전압이 50uS 이상 지속되면 데이터 리셋으로 간주하고 다시 처음부터 시작함<br />
· 내부에 전송된 3바이트(24비트) 데이터는 1바이트(8비트)씩 녹색, 빨강, 파랑의 컬러 LED 값을 나타내며, 전송 순서도 녹빨파(GRB, Green, Red, Blue) 순임</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-03.jpg" rel="lightbox[31253]"><img class="alignnone  wp-image-31345" alt="36 카멜레온 03" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-03.jpg" width="454" height="68" /></a></p>
<p style="padding-left: 30px">· 전원은 3.5 V ~ 5.3 V까지 사용이 가능하며, 입력 데이터는 0.7 x VCC 이상의 전압이면 HIGH, 0.3 x VCC 이하의 전압이면 LOW로 처리됨 (5 V 전원의 경우 3.5 V 이상이면 HIGH, 1.5 V 이하이면 LOW)<br />
· 데이터 전송 프로토콜은 펄스폭의 길이로 데이터값을 산정하는 방식을 사용하며, 아래와 같은 규격으로 판정함</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-04.jpg" rel="lightbox[31253]"><img class="alignnone  wp-image-31346" alt="36 카멜레온 04" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-04.jpg" width="258" height="178" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-ict-888.png" rel="lightbox[31253]"><img class="alignnone  wp-image-31369" alt="36 카멜레온 ict 888" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-ict-888-620x195.png" width="496" height="156" /></a></p>
<p>&nbsp;</p>
<p>즉, DIN 라인의 레벨이 400ns LOW + 850ns HIGH 를 유지하면 1비트의 데이터 HIGH로 인식하고, 800ns HIGH + 450ns LOW 를 유지하면 1비트의 LOW로 인식하는 방식<br />
이와 같은 규격을 기준으로 처음 그림과 같은 연결에서 데이터가 전송되는 방법을 나타내면 아래 그림과 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-06.jpg" rel="lightbox[31253]"><img class="alignnone  wp-image-31348" alt="36 카멜레온 06" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-06-620x365.jpg" width="496" height="292" /></a></p>
<p>예를 들어 만약 첫번째 LED에는 빨강, 두번째 LED에는 파랑, 세번째 LED에는 녹색으로 LED를 1초 동안 켜고 싶다면, 제어기에서는 (<span style="color: #ffffff;background-color: #008000">0&#215;00</span> ▶ <span style="color: #ffffff;background-color: #ff0000">0xFF</span> ▶<span style="color: #ffffff;background-color: #3366ff"> 0&#215;00</span>) ▶ (<span style="color: #ffffff;background-color: #008000">0&#215;00</span> ▶<span style="color: #ffffff;background-color: #ff0000"> 0&#215;00</span> ▶<span style="color: #ffffff;background-color: #3366ff"> 0xFF</span>) ▶ (<span style="color: #ffffff;background-color: #008000">0xFF </span>▶ <span style="color: #ffffff;background-color: #ff0000">0&#215;00</span> ▶<span style="color: #ffffff;background-color: #3366ff"> 0&#215;00</span>) 을 보내면 LED가 원하는 색으로 켜지고 1초 후에 다시 (<span style="color: #ffffff;background-color: #008000">0&#215;00</span> ▶ <span style="color: #ffffff;background-color: #ff0000">0&#215;00</span> ▶ <span style="color: #ffffff;background-color: #3366ff">0&#215;00</span>) ▶ (<span style="color: #ffffff;background-color: #008000">0&#215;00</span> ▶ <span style="color: #ffffff;background-color: #ff0000">0&#215;00</span> ▶<span style="color: #ffffff;background-color: #3366ff"> 0&#215;00</span>) ▶ (<span style="color: #ffffff;background-color: #008000">0&#215;00</span> ▶ <span style="color: #ffffff;background-color: #ff0000">0&#215;00</span> ▶ <span style="color: #ffffff;background-color: #3366ff">0&#215;00</span>) 을 보내면 LED가 모두 꺼지게 됩니다.</p>
<p>처음에 연속해서 9바이트의 데이터를 보내면, 첫번째 LED에서 3바이트를 사용하고, 이후 전달된 6바이트는 2번째 LED로 전달되며, 마찬가지로 두번째 LED는 전달된 6바이트 중 처음 3바이트를 사용하고 마지막 3바이트는 세번째 LED로 보내게 되는 방식을 사용하는 것입니다. 1초가 지난 후에 다시 9바이트의 데이터를 보내면 이것은 50us 보다 긴 시간 이후에 들어온 데이터이므로 이전 데이터의 연속으로 보지 않고, 새로운 데이터가 들어온 것으로 간주하여 다시 첫번째 LED에서 3바이트를 사용하는 방식으로 진행되겠습니다.</p>
<p>이런 원리를 잘만 이용하면, WS2812B LED를 내가 원하는 개수만큼 원하는 형태로 연결한 후, 이들의 색상이 시간에 따라 변화하도록 프로그램하는 것이 가능할 것 같네요. 오, 뭔가 있을 법한 느낌!!!</p>
<p><span style="font-size: medium;color: #008000"><strong>LED(JLED-BAR-1) 1개 불 켜기</strong></span></p>
<p>그럼, 이제 문제는 0, 1 데이터, 나아가서 GRB 데이터, 더 나아가서 여러 개의 WS2812B 연결시의 데이터를 어떻게 프로그램으로 생성할 수 있는가 하는 것인데…<br />
“천리길도 한 걸음부터”라고 했으니 일단 WS2812B 1개로 구성된 카멜레온 DIY LED인 JLED-BAR-1에 파랑색 불을 켜는 것으로부터 시작해 보겠습니다. 이 후 이것을 응용해서 1600만가지 이상의 컬러를 골라서 디스플레이 해보는 데까지 가보시지요. (와우!!!)<br />
일단 JLED-BAR-1의 모습을 보실까요. 짜잔~~~!</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-ptb555.jpg" rel="lightbox[31253]"><img class="alignnone size-full wp-image-31370" alt="36 카멜레온 ptb555" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-ptb555.jpg" width="325" height="122" /></a><br />
앞면에는 WS2812B가 1개 배치되어 있고(컨덴서 1개 포함), 뒷면에는 2.54mm 1X3 핀헤더가 양쪽으로 배치되어 있습니다. 뒷면의 실크 표시는, V는 VCC(+5V), G는 GND, I는 DIN(데이터입력), O는 DOUT(데이터 출력)입니다.</p>
<p>JLED-BAR-1은 WS2812B를 기반으로 하여 이미 출시되어 있는 다른 상품과 확연히 차이가 나는 것이 3가지 있습니다.</p>
<p>첫째, 1X3 입력핀과 1X3 출력핀의 형태가 DIP 타입(2.54mm 핀헤더 타입)입니다. 입출력 신호가 SMD로 되어 있는 것은 납땜을 해야하는 번거로움이 있지만 이렇게 DIP 타입을 사용하면 케이블이나 점퍼 등을 사용하여 연결을 매우 쉽게 할 수 있는 장점이 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-09.jpg" rel="lightbox[31253]"><img class="wp-image-31351 aligncenter" alt="36 카멜레온 09" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-09.jpg" width="482" height="270" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-11.jpg" rel="lightbox[31253]"><img class="wp-image-31353 aligncenter" alt="36 카멜레온 11" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-11.jpg" width="482" height="270" /></a></p>
<p>둘째, 가로와 세로의 길이가 각각 1cm입니다. BAR 시리즈의 경우는 LED가 증가할 때마다 1cm씩 가로 길이가 증가하도록 설계되어 있습니다. 이렇게 하면 용도에 따라 매우 편리하게 적용이 가능합니다. 예를 들어 30cm X 20 cm 되는 액자의 테두리를 BAR 시리즈로 만든다면 가로는 JLED-BAR-10을 3개 연속 연결하면 딱 알맞게 적용이 되는 것이지요. 급할 때는 자 대용으로도 사용이 가능합니다. 그러면 아래 JLED-BAR-10 의 길이는 얼마일까요? (답이 없어도 알겠죠?)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-10.jpg" rel="lightbox[31253]"><img class="wp-image-31352 aligncenter" alt="36 카멜레온 10" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-10.jpg" width="470" height="69" /></a></p>
<p>셋째, 그림으로는 식별이 잘 안되지만 1X3 입출력 핀헤더는 가장자리에서 안쪽으로 1.27mm 거리에 위치합니다. 이렇게 되면 카멜레온 DIY LED 모듈 여러 개를 연속적으로 연결시 2X3 쇼트핀(JLED-CON-0, 2핀간의 거리 2.54mm)으로 바로 연결이 가능하므로 레고처럼 붙였다 떼었다 하는 동작이 매우 용이합니다. JLED-BAR-1과 JLED-TRI-3을 쇼트핀 3개로 결합한 형태를 보시지요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-12.jpg" rel="lightbox[31253]"><img class="wp-image-31354 aligncenter" alt="36 카멜레온 12" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-12.jpg" width="482" height="270" /></a></p>
<p>쇼트핀 3개가 하나로 결합되어 있는 JLED-CON-0를 연결하면 아래와 같이 좀 더 깔끔하게 연결할 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-13.jpg" rel="lightbox[31253]"><img class="wp-image-31355 aligncenter" alt="36 카멜레온 13" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-13.jpg" width="482" height="270" /></a></p>
<p>앞면도 보여드리지요.</p>
<p style="text-align: center"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-14.jpg" rel="lightbox[31253]"><img class=" wp-image-31356 aligncenter" alt="36 카멜레온 14" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-14.jpg" width="482" height="270" /></a></p>
<p>자, 그럼 이제 JLED-BAR-1을 아두이노에 연결하여 파랑색 불을 켜는 것을 예로 들어 본격적으로 프로그램을 시작해 보겠습니다.<br />
일단, 제어기 연결은 해놓고 시작합니다. 아두이노 UNO를 제어기로 사용하는 경우 아래와 같이 연결이 되겠습니다. 아두이노와 JLED-BAR-1의 신호쌍으로 +5V-V(VCC)(빨강선), GND-G(GND)(검정선), D2-I(DIN)(녹색선)을 각각 연결합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-16.jpg" rel="lightbox[31253]"><img class="wp-image-31357 aligncenter" alt="36 카멜레온 16" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-16.jpg" width="482" height="270" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-17.jpg" rel="lightbox[31253]"><img class="wp-image-31358 aligncenter" alt="36 카멜레온 17" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-17.jpg" width="482" height="270" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-18.jpg" rel="lightbox[31253]"><img class="wp-image-31359 aligncenter" alt="36 카멜레온 18" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-18.jpg" width="482" height="315" /></a><br />
파랑색 불이 들어오게 하려면 제어기(아두이노)에서 (<span style="color: #ffffff;background-color: #008000">0&#215;00</span>,<span style="color: #ffffff;background-color: #ff0000"> 0&#215;00</span>,<span style="color: #ffffff;background-color: #3366ff"> 0xFF</span>)의 24비트 데이터를 JLED-BAR-1으로 보내주어야 합니다. 첫번째 데이터인 <span style="color: #ffffff;background-color: #008000">0&#215;00</span>을 보내려면 ‘0’ 을 나타내는 비트 신호를 8번 연속해서 보내주어야 하는데, 규격에 보면 ‘0’ 신호는 실제 WS2812B의 DIN 라인의 레벨을 ‘800ns HIGH + 450ns LOW’로 유지하여야 합니다. 우리는 제어기(아두이노)의 데이터 포트인 D2를 연결하였으므로 이 핀을 ‘800ns HIGH + 450ns LOW’로 8번 만들면 되겠네요.</p>
<p>엥? 그런데 어떻게 만들죠?</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>digitalWrite(D2) = HIGH;<br />
delay_ns(400); // nano sec 딜레이함수<br />
digitalWrite(D2) = LOW;<br />
delay_ns(850); // nano sec 딜레이함수</p>
</div>
<p>이렇게 하면 될까요?</p>
<p>바로 문제에 봉착하게 됩니다. 첫번째 문제는 delay_ns() 라는 ns 단위 딜레이 함수가 아두이노에 존재하지 않는다는 것이고,(ms, us 딜레이 함수는 있는데…) 두번째 문제는 혹시 함수를 새로 만든다고 가정해도, ns 와 같이 아주 짧은 시간 동안의 딜레이를 적용할 수 있는 정확한 함수를 프로그램 하는 것이 가능하지 않을 것으로 판단된다는 것이고, 세번째 문제는 혹 이런 함수를 비슷하게 작성한다 하더라도 실제 이 함수를 실행하는데 소요되는 시간을 매우 정교하게 제어하는 것이 어렵다는 사실입니다.</p>
<p>그렇다면 … 어떻게 해야 하나요?</p>
<p>예. 정답! 이것을 해결하려면, 고급 언어인 C 언어 레벨에서의 프로그램을 포기하고 어셈블리(assembly) 언어를 이용하여 프로그램을 작성하여야 합니다.<br />
어셈블리 언어는 기계어이므로, 실행 속도가 정해져 있습니다. 예를 들어 ‘nop’ 이라는 어셈블리 명령어는 거의 모든 프로세서에서 1 클록의 시간만을 사용합니다. 제어기(아두이노)가 만약 16Mhz 클록으로 동작하는 제어기(아두이노)라고 가정하면 ‘nop’을 실행하는데 걸리는 시간은 1/16000000 초 = 62.5ns가 됩니다. 이것을 잘 이용한다면 우리가 필요로 하는 형태의 데이터를 만들 수도 있을 것 같네요. 한 번 같이 해보실까요?</p>
<p>아두이노 UNO(16Mhz 클록)을 기준으로 ‘0’ 데이터를 한 번 만들어 보겠습니다.</p>
<p>‘0’ 데이터는 400ns HIGH + 850ns LOW 의 쌍으로 이루어집니다.<br />
400ns의 HIGH를 유지하려면, 400/62.5 = 6.4 = 약 6 클록이 필요하고, 850ns의 LOW를 유지하려면, 850/62.5 = 13.6 = 약 14 클록이 필요하므로, 아래와 같이 프로그램하면 될 것 같습니다. (규격에 보면 +/- 2 클록 정도의 오차는 허용이 되므로 정수배를 취하여도 무방함)</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>// WS2812B ‘0’ 데이터 만들기<br />
PORTD |= 0b00000100; // D2 디지털핀을 1로 만듬, 1-2 클록 소모(?)<br />
asm volatile(“nop”); // 첫번째 nop, 어셈블리 명령어로 실행, 컴파일러 최적화 금지!<br />
asm volatile(“nop”); // 두번째 nop, 어셈블리 명령어로 실행, 컴파일러 최적화 금지!<br />
…<br />
…<br />
asm volatile(“nop”); // 다섯번째 “nop”, 여기까지 6-7 클록 소모(?)<br />
PORTD |= 0b00000000; // D2 디지털핀을 0으로 만듬, 1-2 클록 소모(?)<br />
asm volatile(“nop”); // 첫번째 nop, 어셈블리 명령어로 실행, 컴파일러 최적화 금지!<br />
asm volatile(“nop”); // 두번째 nop, 어셈블리 명령어로 실행, 컴파일러 최적화 금지!<br />
…<br />
…<br />
asm volatile(“nop”); // 열세번째 “nop” , 여기까지 14-15 클록 소모(?)</p>
</div>
<p>D2 핀의 상태를 바꾸려는 명령어는 최소한 1-2 클록은 소모될 것이라고 가정하고 ‘nop’ 명령어를 필요한 개수보다 1개 적은 개수만큼만 시행하면 가장 근접한 신호 파형을 만들 수 있을 것입니다. 물론, 좀 더 정확하게 측정하려면 어셈블리어로 컴파일된 .S 파일을 분석하던지 실제 이 부분의 실행 파형을 오실로스코프로 확실하게 확인하는 것이 좋겠습니다. 우리는 일단 그냥 사용해 보고 실제 프로그램을 실행해서 정말 되는지를 확인해 보는 것으로 하겠습니다. 그리고, 1비트 데이터를 보낼 때마다 위와 같은 프로그램을 직접 써 넣어 프로그램할 수는 없으니까, 이것을 마크로(MACRO)를 이용하여 선언을 해 놓은 것이 좋을 듯 합니다.</p>
<p>아래와 같이 마크로를 정의해 놓으면 조금 편리하게 사용할 수 있겠네요.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define NOP asm volatile(“nop”)<br />
#define NOP2 NOP; NOP<br />
#define NOP3 NOP2; NOP<br />
#define NOP5 NOP3; NOP2<br />
#define NOP6 NOP3; NOP3<br />
#define NOP12 NOP6; NOP6<br />
#define NOP13 NOP6; NOP6; NOP</p>
</div>
이것을 이용하여 ‘0’ 데이터 만들기를 표현해 보면,</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>// WS2812B ‘0’ 데이터 만들기<br />
PORTD |= 0b00000100; // D2 디지털핀을 1로 만듬<br />
NOP5; // 5번의 “nop”<br />
PORTD &amp;= 0b11111011; // D2 디지털핀을 0으로 만듬<br />
NOP13; // 13번의 “nop”</p>
</div>
<p>같은 방법으로 ‘1’ 데이터를 만들어 보겠습니다.<br />
400ns의 HIGH를 유지하려면, 800/62.5 = 12.8 = 약 13클록이 필요하고, 450ns의 LOW를 유지하려면, 450/62.5 = 7.2 = 약 7클록이 필요하므로, 아래와 같이 프로그램하면 될 것 같습니다. (규격에 보면 150ns(+/- 2 클록 이상)의 오차가 허용이 되므로 정수배를 취하여도 무방합니다.)</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>// WS2812B ‘1’ 데이터 만들기<br />
PORTD |= 0b00000100; // D2 디지털핀을 1로 만듬<br />
NOP12; // 12번의 “nop”<br />
PORTD |= 0b00000000; // D2 디지털핀을 0으로 만듬<br />
NOP6; // 6번의 “nop”</p>
</div>
<p>0과 1을 만드는 것도 계속 사용할 것이니, 아예 이것도 ‘CODE0’, ‘CODE1’이라는 마크로로 선언해 놓는 것이 좋겠습니다. 덤으로 데이터리셋은 LOW 상태로 50us를 유지하는 것이므로 이것까지 ‘RES’라는 마크로로 함께 선언해 놓겠습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define CODE0 PORTD |= 0b00000100; NOP12; PORTD &amp;= 0b11111011; NOP6<br />
#define CODE1 PORTD |= 0b00000100; NOP5; PORTD &amp;= 0b11111011; NOP13<br />
#define RES PORTD &amp;= 0b00000000; delay Microseconds(50)</p>
</div>
<p>자, 이제 기본 준비가 되었으니, 파랑색을 나타내는 (G, R, B) 값 (0&#215;00, 0&#215;00, 0xFF) 총 24비트의 값을 연속적으로 보내는 프로그램을 작성해 봅시다. 1비트 값을 보내는 코딩을 확장하여 순서대로 8비트씩 3번, 총 24비트를 전송하면 되겠습니다. G-&gt;R-&gt;B 순으로 보내야 하고, 바이트 내에서는 HIGH 비트 순으로 먼저 보내는 것이 규격이므로, 아래와 같이 되겠네요.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define NOP asm volatile(“nop”)<br />
#define NOP2 NOP; NOP<br />
#define NOP3 NOP2; NOP<br />
#define NOP5 NOP3; NOP2<br />
#define NOP6 NOP3; NOP3<br />
#define NOP12 NOP6; NOP6<br />
#define NOP13 NOP6; NOP6; NOP</p>
<p>#define CODE0 PORTD |= 0b00000100; NOP5; PORTD &amp;= 0b11111011; NOP13<br />
#define CODE1 PORTD |= 0b00000100; NOP12; PORTD &amp;= 0b11111011; NOP6<br />
#define RES PORTD &amp;= 0b00000000; delayMicroseconds(50)</p>
<p>void setup()<br />
{<br />
pinMode(2, OUTPUT);<br />
}</p>
<p>void loop()<br />
{<br />
RES; // WS2812B 리셋, 0 상태로 50us delay<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // G(Green)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // R(Red)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // B(Blue)<br />
}<br />
</div>
<p>잘 되려나요? 한 번 해보겠습니다.<br />
아두이노 스케치 돌리고, 컴파일 &amp; 다운로드 얍!</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-19.jpg" rel="lightbox[31253]"><img class="alignnone size-full wp-image-31360" alt="36 카멜레온 19" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-19.jpg" width="602" height="338" /></a></p>
<p>파랑색 불이 잘 켜졌네요. 잘 된 것이겠죠?<br />
그럼, 한 숨 돌리고, 잠시 쉬었다가, 조금 더 전진해 보도록 하겠습니다.<br />
10분간 휴식~!</p>
<p><span style="font-size: medium;color: #008000"><strong>JLED-BAR-1으로 무지개색 불 켜기</strong></span></p>
<p>파랑색 불 켜는 것에 성공하였으니, 빨강색과 녹색 불 켜는 것은 쉽게 할 수 있겠지요?. 빨강색은 (G, R, B) 값을 (0&#215;00, 0xFF, 0&#215;00)로, 녹색은 (G, R, B) 값을 (0xFF, 0&#215;00, 0&#215;00)로 보내면 되니까 바로 되겠습니다. 그런데, 노랑색을 디스플레이 하려면, 어떻게 해야 할까요?</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-20.jpg" rel="lightbox[31253]"><img class="alignnone size-full wp-image-31361" alt="36 카멜레온 20" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-20.jpg" width="280" height="266" /></a></p>
<p>그림에서와 같이 빛의 3원색은 빨강, 녹색, 파랑이고, 노랑색은 빨강과 녹색을 동일 비율로 합하면 될 것 같으므로, 노랑색은 (<span style="color: #ffffff;background-color: #008000">G</span>, <span style="color: #ffffff;background-color: #ff0000">R</span>, <span style="color: #ffffff;background-color: #0000ff">B</span>) 값인 (<span style="color: #ffffff;background-color: #008000">0xFF</span>, <span style="color: #ffffff;background-color: #ff0000">0xFF</span>,<span style="color: #ffffff;background-color: #0000ff"> 0&#215;00</span>) = (0b<span style="color: #ffffff;background-color: #008000">11111111</span><span style="color: #ffffff;background-color: #ff0000">11111111</span><span style="color: #ffffff;background-color: #0000ff">00000000</span>)을 생성하여 보내면 될 것 같습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>void loop()<br />
{<br />
RES; // WS2812B 리셋, 0 상태로 50us delay<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // G(Green)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // R(Red)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // B(Blue)<br />
}</p>
</div>
결국, 내가 원하는 컬러를 디스플레이 하려면 위의 방법처럼 그 컬러에 해당되는 (<span style="color: #000000;background-color: #ffffff">G, R, B</span>) 값을 찾아서 거기에 해당되는 코드를 보내주면 되겠네요. 원하는 컬러의 (G, R, B) 값은 보통 아래와 같은 색상표에서 제공하므로 이것을 이용하면 되겠구요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-21.jpg" rel="lightbox[31253]"><img class="alignnone size-large wp-image-31362" alt="36 카멜레온 21" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-21-620x347.jpg" width="620" height="347" /></a></p>
<p><span style="color: #ff0000;background-color: #ffffff">조심하여야 할 것은 일반적인 색상표는 코드를 (R, <span style="color: #ffffff;background-color: #008000">G</span>,<span style="color: #ffffff;background-color: #0000ff"> B</span>) 순으로 표시하므로 이것을<strong> WS2812B로 전송할 때</strong>는 이 순서를 그대로 사용하면 안되고<strong> (<span style="color: #ffffff;background-color: #008000">G</span>, R, <span style="color: #ffffff;background-color: #0000ff">B</span>) 순으로 순서를 바꾸어 전송</strong>하여야 한다는 점입니다. 잊으시면 안됩니다!</span></p>
<p>예를 들어 주황색을 디스플레이하고 싶다면, 주황색의 (<span style="color: #ffffff;background-color: #ff0000">R</span>,<span style="color: #ffffff;background-color: #008000"> G</span>,<span style="color: #ffffff;background-color: #0000ff"> B</span>) 값은 (FF, 66, 00)이므로 (<span style="color: #ffffff;background-color: #008000">G</span>, <span style="color: #ffffff;background-color: #ff0000">R</span>,<span style="color: #ffffff;background-color: #0000ff"> B</span>) 코드값은 (66, FF, 00)=0b<span style="color: #ffffff;background-color: #008000">01100110</span><span style="color: #ffffff;background-color: #ff0000">11111111</span><span style="color: #ffffff;background-color: #0000ff">00000000 </span>이 되므로 프로그램은 아래와 같이 됩니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>void loop()<br />
{<br />
RES; // WS2812B 리셋, 0 상태로 50us delay<br />
CODE0; CODE1; CODE1; CODE0; CODE0; CODE1; CODE1; CODE0; // G(Green)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // R(Red)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // B(Blue)<br />
}</p>
</div>
<p>자, 그러면 이제 무지개색 표현에 도전해 보도록 합시다.<br />
한가지 컬러가 디스플레이 되는 시간을 1초 정도로 하면 보기가 좋을 것 같습니다.<br />
빨강색을 디스플레이하고 1초 기다렸다가, 다음에는 주황색을 디스플레이하고… 이렇게 7가지 컬러를 디스플레이하면 되겠네요. 1초 딜레이는 아두이노 라이브러리 delay()을 이용하면 쉽게 되겠지요? 모두 한 번 해 보겠습니다. 5분 기다려 봅니다.</p>
<p>(5, 4, 3, 2, 1, 0)<br />
같이 해보시지요.</p>
<p>일단, 빨주노초파남보에 해당되는 (<span style="color: #ffffff;background-color: #008000">G</span>, <span style="color: #ffffff;background-color: #ff0000">R</span>, <span style="color: #ffffff;background-color: #0000ff">B</span>) 코드를 위 색상표에서 눈대중으로 찾으면,<br />
빨강 = (<span style="color: #ffffff;background-color: #008000">00</span>, <span style="color: #ffffff;background-color: #ff0000">FF</span>, <span style="color: #ffffff;background-color: #0000ff">00</span>), 주황 = (<span style="color: #ffffff;background-color: #008000">66</span>, <span style="color: #ffffff;background-color: #ff0000">FF</span>, <span style="color: #ffffff;background-color: #0000ff">00</span>), 노랑 = (<span style="color: #ffffff;background-color: #008000">FF</span>, <span style="color: #ffffff;background-color: #ff0000">FF</span>,<span style="color: #ffffff;background-color: #0000ff"> 00</span>), 초록 = (<span style="color: #ffffff;background-color: #008000">FF</span>, <span style="color: #ffffff;background-color: #ff0000">00</span>, <span style="color: #ffffff;background-color: #0000ff">00</span>), 파랑 = (<span style="color: #ffffff;background-color: #008000">00</span>, <span style="color: #ffffff;background-color: #ff0000">00</span>,<span style="color: #ffffff;background-color: #0000ff"> FF</span>),남색 = (<span style="color: #ffffff;background-color: #008000">00</span>, <span style="color: #ffffff;background-color: #ff0000">33</span>, <span style="color: #ffffff;background-color: #0000ff">99</span>), 보라 = (<span style="color: #ffffff;background-color: #008000">00</span>,<span style="color: #ffffff;background-color: #ff0000"> 66</span>,<span style="color: #ffffff;background-color: #0000ff"> FF</span>) 정도로 표시될 것 같습니다.<br />
무식한 방법이긴 하지만 이 코드를 이용하여 위에서 사용했던 방법을 반복적으로 7번 사용하면서 디스플레이될 컬러만 순서대로 바꾸어주면 됩니다. 뭐 저라고 뾰족한 수는 없습니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define NOP asm volatile(“nop”)<br />
#define NOP2 NOP; NOP<br />
#define NOP3 NOP2; NOP<br />
#define NOP5 NOP3; NOP2<br />
#define NOP6 NOP3; NOP3<br />
#define NOP12 NOP6; NOP6<br />
#define NOP13 NOP6; NOP6; NOP</p>
<p>#define CODE0 PORTD |= 0b00000100; NOP5; PORTD &amp;= 0b11111011; NOP13<br />
#define CODE1 PORTD |= 0b00000100; NOP12; PORTD &amp;= 0b11111011; NOP6<br />
#define RES PORTD &amp;= 0b00000000; delayMicroseconds(50)</p>
<p>void setup()<br />
{<br />
pinMode(2, OUTPUT); // D2를 데이터비트로 사용<br />
}</p>
<p>void loop()<br />
{<br />
RES; // 빨강, WS2812B 리셋, 0 상태로 50us delay<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // G(Green)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // R(Red)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // B(Blue)<br />
delay (1000); // 1초 디스플레이</p>
<p>RES; // 주황, WS2812B 리셋, 0 상태로 50us delay<br />
CODE0; CODE1; CODE1; CODE0; CODE0; CODE1; CODE1; CODE0; // G(Green)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // R(Red)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // B(Blue)<br />
delay (1000); // 1초 디스플레이</p>
<p>RES; // 노랑, WS2812B 리셋, 0 상태로 50us delay<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // G(Green)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // R(Red)<br />
CODE0; CODE0<br />
; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // B(Blue)<br />
delay (1000); // 1초 디스플레이</p>
<p>RES; // 초록, WS2812B 리셋, 0 상태로 50us delay<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // G(Green)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // R(Red)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // B(Blue)<br />
delay (1000); // 1초 디스플레이</p>
<p>RES; // 파랑, WS2812B 리셋, 0 상태로 50us delay<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // G(Green)<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // R(Red)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // B(Blue)<br />
delay (1000);// 1초 디스플레이</p>
<p>RES; // 남색, WS2812B 리셋, 0 상태로 50us delay<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // G(Green)<br />
CODE0; CODE0; CODE1; CODE1; CODE0; CODE0; CODE1; CODE1; // R(Red)<br />
CODE1; CODE1; CODE1; CODE0; CODE1; CODE1; CODE1; CODE0; // B(Blue)<br />
delay (1000); // 1초 디스플레이</p>
<p>RES; // 보라, WS2812B 리셋, 0 상태로 50us delay<br />
CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; CODE0; // G(Green)<br />
CODE0; CODE1; CODE1; CODE0; CODE0; CODE1; CODE1; CODE0; // R(Red)<br />
CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; CODE1; // B(Blue)<br />
delay (1000); // 1초 디스플레이<br />
}</p>
</div>
다들 잘 디스플레이 되나요?</p>
<p>잘 되셨다면 자축의 물개박수~~~</p>
<p>내가 원하는 7가지 무지개 색깔을 디스플레이 하는데 성공하였다는 이야기는 R, G, B로 나타낼 수 있는 모든 경우의 컬러를 디스플레이할 수 있다는 이야기가 됩니다. 총 몇가지나 될까요? R, G, B 강도를 나타내는 비트가 각각 8비트씩이므로 만들어질 수 있는 총 가지수는 256X256X256 = 16,777,226(1600만 이상)이 됩니다.</p>
<p>와~ 내가 JLED-BAR-1 1개를 가지고 표현할 수 있는 컬러가 1600만가지라니… 뭔가 좀 뿌듯한 감정이 올라오는 것도 같죠?</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;color: #008000"><strong>JLED-RING-12 로 12색상환 만들기</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-22.jpg" rel="lightbox[31253]"><img class="alignnone  wp-image-31363" alt="36 카멜레온 22" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-22-620x584.jpg" width="278" height="262" /></a></p>
<p>이제 1개의 WS2812B LED의 색상은 자유롭게 표현 가능하므로 이번에는 여러 개의 WS2812B LED가 연속적으로 연결된 형태에서 다양한 색상을 만들어 보는 연습을 해보겠습니다. 목표는 WS2812B 12개를 연속적으로 연결하여 둥근 링 형태를 구성하고 여기에 12가지 컬러를 넣어 아래와 같은 12 색상환을 만들어보는 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-23.jpg" rel="lightbox[31253]"><img class="alignnone size-full wp-image-31364" alt="36 카멜레온 23" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-23.jpg" width="213" height="216" /></a><br />
12색상환은 초등학교 미술시간에 한번쯤은 색칠해 보았을 것으로 생각되는데요. 마침 카멜레온 DIY LED에 이것과 비슷하게 생긴 JLED-RING-12 라는 제품이 있으니 여기에 색상을 입히면 안성맞춤이 될 것 같네요.</p>
<p>JLED-RING-12는 앞에서 WS2812B 동작 원리를 설명하면서 사용하였던 연결관계 그림과 동일한 방법으로 WS2812B 12개를 직렬(시리얼)로 연결한 둥근 반지(RING) 형태를 띄고 있습니다.</p>
<p>프로그램 방법은 JLED-BAR-1에서 사용한 것과 거의 동일합니다. 조금 다른 것은 JLED-BAR-1의 컬러를 준비할 때는 1개의 RGB 쌍을 준비하였다면, 이번에는 12개의 RGB 쌍을 준비하여야 한다는 것과, 이 데이터를 순서대로 딜레이없이<span style="color: #ff0000"><strong>(중요!, 딜레이가 50us를 넘으면 12개 LED가 켜지는 것이 아니고 1개 LED만 컬러가 12번 바뀌면서 켜짐)</strong> </span>연속해서 내보내야 한다는 것입니다.</p>
<p>그럼 준비를 해볼까요?</p>
<p>인터넷에서 12색상환에 사용될 12가지 색상에 대한 코드를 찾아보니 아래와 같이 나옵니다. (RGB 순)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-ict-카멜레온-666.png" rel="lightbox[31253]"><img class="alignnone  wp-image-31371" alt="36 ict 카멜레온 666" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-ict-카멜레온-666-620x121.png" width="496" height="97" /></a></p>
<p>조금 번거롭긴 하지만 아직 라이브러리를 사용하는 방법을 배우지 않았으니, 오늘은 그냥 머슴처럼 꾹 참고 한 개씩 순서대로 내보내는 코딩으로 계속 가겠습니다. (좀 더 깔끔하고 간단한 방법은 다음 시간에…)<br />
숫자가 많이 나오므로 마크로 정의를 음성기호(phonetic alphabet)로 더 만들어 사용하면 편할 것 같으므로 아래와 같이 형태로 마크로를 추가합니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define ONE CODE0; CODE0; CODE0; CODE1 // 1 = 0&#215;1 = 0b0001<br />
#define TWO CODE0; CODE0; CODE1; CODE0 // 2 = 0&#215;2 = 0b0010<br />
…<br />
#define ALPHA CODE1; CODE0; CODE1; CODE0; // 10 = 0xa = 0b1010<br />
…<br />
#define FOXTROT CODE1; CODE1; CODE1; CODE1; // 15 = 0xf = 0b1111</p>
</div>
자, 준비가 다 되었으면 이제 실전 코딩입니다. GO~</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define NOP asm volatile(“nop”)<br />
#define NOP2 NOP; NOP<br />
#define NOP3 NOP2; NOP<br />
#define NOP5 NOP3; NOP2<br />
#define NOP6 NOP3; NOP3<br />
#define NOP12 NOP6; NOP6<br />
#define NOP13 NOP6; NOP6; NOP<br />
#define CODE0 PORTD |= 0b00000100; NOP5; PORTD &amp;= 0b11111011; NOP13<br />
#define CODE1 PORTD |= 0b00000100; NOP12; PORTD &amp;= 0b11111011; NOP6<br />
#define RES PORTD &amp;= 0b00000000; delayMicroseconds(50)</p>
<p>#define ZERO CODE0; CODE0; CODE0; CODE0 // 0 = 0&#215;00 = 0b0000<br />
#define ONE CODE0; CODE0; CODE0; CODE1 // 1 = 0&#215;01 = 0b0001<br />
#define TWO CODE0; CODE0; CODE1; CODE0 // 2 = 0&#215;02 = 0b0010<br />
#define THREE CODE0; CODE0; CODE1; CODE1 // 3 = 0&#215;03 = 0b0011<br />
#define FOUR CODE0; CODE0; CODE1; CODE1 // 4 = 0&#215;04 = 0b0100<br />
#define FIVE CODE0; CODE0; CODE1; CODE1 // 5 = 0&#215;05 = 0b0101<br />
#define SIX CODE0; CODE0; CODE1; CODE1 // 6 = 0&#215;06 = 0b0110<br />
#define SEVEN CODE0; CODE0; CODE1; CODE1 // 7 = 0&#215;07 = 0b0111<br />
#define EIGHT CODE0; CODE0; CODE1; CODE1 // 8 = 0&#215;08 = 0b1000<br />
#define NINE CODE0; CODE0; CODE1; CODE1 // 9 = 0&#215;09 = 0b1001<br />
#define ALPHA CODE0; CODE0; CODE1; CODE1 // 10 = 0x0a = 0b1010<br />
#define BRAVO CODE0; CODE0; CODE1; CODE1 // 11 = 0x0b = 0b1011<br />
#define CHARLIE CODE0; CODE0; CODE1; CODE1 // 12 = 0x0c = 0b1100<br />
#define DELTA CODE0; CODE0; CODE1; CODE1 // 13 = 0x0d = 0b1101<br />
#define ECHO CODE0; CODE0; CODE1; CODE1 // 14 = 0x0e = 0b1110<br />
#define FOXTROT CODE1; CODE1; CODE1; CODE1; // 15 = 0x0f = 0b1111</p>
<p>void setup()<br />
{<br />
pinMode(2, OUTPUT); // D2를 데이터비트로 사용<br />
}</p>
<p>void loop()<br />
{<br />
// WS2812B 리셋, 0 상태로 50us delay<br />
RES;<br />
// 빨강 : 0xff0000 ▶ 0x00ff00<br />
ZERO; ZERO; FOXTROT; FOXTROT; ZERO; ZERO;<br />
// 다홍 : 0xdc143c ▶ 0x14dc3c<br />
ONE; FOUR; DELTA; CHARLIE; THREE; CHARLIE;<br />
// 주황 : 0xff7f00 ▶ 0x7fff00<br />
SEVEN; FOXTROT; FOXTROT; FOXTROT; ZERO; ZERO;<br />
// 귤색 : 0xf89b00 ▶ 0x9bf800<br />
NINE; BRAVO; FOXTROT; EIGHT; ZERO; ZERO;<br />
// 노랑 : 0xffd400 ▶ 0xd4ff00<br />
DELTA; FOUR; FOXTROT; FOXTROT; ZERO; ZERO;<br />
// 연두 : 0x66cc00 ▶ 0xcc6600<br />
CHARLIE; CHARLIE; SIX; SIX; ZERO; ZERO;<br />
// 녹색 : 0x00ff00 ▶ 0xff0000<br />
FOXTROT; FOXTROT; ZERO; ZERO; ZERO; ZERO;<br />
// 청록 : 0&#215;005666 ▶ 0&#215;560066<br />
FIVE; SIX; ZERO; ZERO; SIX; SIX;<br />
// 파랑 : 0x0000ff ▶ 0000ff<br />
ZERO; ZERO; ZERO; ZERO; FOXTROT; FOXTROT;<br />
// 남색 : 0x080b54 ▶ 0x0b0854<br />
ZERO; BRAVO; ZERO; EIGHT; FIVE; FOUR;<br />
// 보라 : 0xee82ee ▶ 0x82eeee<br />
EIGHT; TWO; ECHO; ECHO; ECHO; ECHO;<br />
// 자주 : 0&#215;800080 ▶ 0&#215;008080<br />
ZERO; ZERO; EIGHT; ZERO; EIGHT; ZERO;<br />
RES;<br />
}<br />
</div>
<p>컴파일 ▶ 업로드 하면, … 와우~~~ 멋진 색상환이 나왔습니다.<br />
환상적이네요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-24.jpg" rel="lightbox[31253]"><img class="alignnone  wp-image-31365" alt="36 카멜레온 24" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-24-620x376.jpg" width="496" height="301" /></a></p>
<p>너무 밝아서 가까이에 가서 다시 크게 찍어 본 사진을 올려 봅니다. 또렷ㅍ하지는 않네요.<br />
실제 색상은 훨씬 더 화려하고 또렷합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-25.jpg" rel="lightbox[31253]"><img class="alignnone  wp-image-31366" alt="36 카멜레온 25" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/36-카멜레온-25-620x382.jpg" width="496" height="306" /></a></p>
<p>여러분도 모두 성공하셨죠? 또 축하의 박수!<br />
그리고, 또 하나의 중요한 사실은 이제 컬러 세팅하는 방법과 여러 개의 WS2812B를 제어하는 방법을 습득했으므로, 이제부터는 어떤 모양, 어떤 컬러, 어떤 동작도 조금씩만 응용하면 모두 다 만들 수 있는 능력을 갖추었다는 사실입니다. 엄청난 힘을 갖게 된 것이지요. 어벤저스(?) 같은 힘!<br />
물론, 조금 찜찜하게 남아 있는 부분도 있습니다.<br />
CODE0, CODE1을 생성하는 처리 방법이 확실하지 않다는 점과, 코드 작성이 MACRO로 하나씩 작성하도록 되어 있어 지루하다는 점입니다. 이것 때문일까요? JLED-RING-12의 불빛이 아주 살짝 흔들리는 것 같기도 하구요. 어쨌든, 여기에 대한 해결책은 다음 번 이야기 “카멜레온 DIY LED를 위한 아두이노 라이브러리”에서 깔끔하게 해결하는 것으로 하겠습니다.<br />
즐거운 시간 되셨나요? 오늘밤에는 꿈 속에서 알록달록한 12가지 아름다운 꿈이 펼쳐지도록 여러분의 머리맡에 12색상환 프로그램을 수행하는 JLED-RING-12를 켜놓고 주무시는 경험을 해보는 것도 좋겠습니다. 그럼, 이번 호의 이야기는 여기서 마치고 다음 호에서는 좀 더 재미있는 이야기를 가지고 다시 만나겠습니다. 안녕히 계십시오.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/31253/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[35호]카멜레온 DIY LED 이야기 ①</title>
		<link>http://www.ntrexgo.com/archives/30734</link>
		<comments>http://www.ntrexgo.com/archives/30734#comments</comments>
		<pubDate>Tue, 15 Mar 2016 05:12:57 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[35호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[LED]]></category>
		<category><![CDATA[Projects to build]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=30734</guid>
		<description><![CDATA[디바이스마트매거진 35호 &#124; 이 이야기는 WS2812B라는 컬러 LED를 기반으로 제작된 [카멜레온 DIY LED] 시리즈를 이용하여 생활에 필요한 다양한 형상을 꾸며보고 이것을 다양한 컬러로 디스플레이 해보는 내용입니다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-메인.jpg" rel="lightbox[30734]"><img class="alignnone size-large wp-image-30933" alt="35 프로젝트 메인" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-메인-620x234.jpg" width="620" height="234" /></a></p>
<p><span style="color: #000000;background-color: #ffffff"> </span></p>
<p><span style="font-size: x-large;color: #000000;background-color: #ffffff"><strong>카멜레온 DIY LED 이야기 ①</strong></span></p>
<p><span style="font-size: large;color: #000000;background-color: #ffffff">WS2812B와 카멜레온 DIY LED</span></p>
<p style="text-align: right">글 | 신상석 ssshin@jcnet.co.kr</p>
<p style="text-align: left">
<p style="text-align: left"><div class="symple-box grey none" style="text-align:left; width:100%;"> 
<p>디바이스마트 매거진 독자 여러분, 안녕하세요. 앞으로 5회에 걸처 [카멜레온 DIY LED 이야기]를 진행할 신상석입니다.<br />
작년에 [너무 쉬운 아두이노 DIY] 강좌를 1년 정도 진행했었는데, 이번에 디바이스마트 매거진 발행진의 배려로 연속하여 새로운 코너를 진행하게 되었습니다. 새로운 시작이므로 제 소개를 다시 한 번 간단히 드립니다.</p>
<p>■ 서울대 제어계측공학과(학사) ▷ KAIST 전산과(석사) ▷ KAIST 전산과(박사 수료)<br />
■ ETRI 책임연구원 ▷ 해동정보통신 연구소장 ▷ 욱성전자 연구소장 ▷ (현재) 제이씨넷 연구소장, 상명대학교 컴퓨터공학과 겸임교수,<br />
임베디드홀릭 카페(http://cafe.naver.com/lazydigital) 부매니저, 전자계산기 기술사</p>
<p>이 이야기는 WS2812B라는 컬러 LED를 기반으로 제작된 [카멜레온 DIY LED] 시리즈를 이용하여 생활에 필요한 다양한 형상을 꾸며보고 이것을 다양한 컬러로 디스플레이 해보는 내용입니다. 앞으로 진행할 내용에 대하여 간단히 알아보면 다음과 같습니다. (약간 변경될 수도 있습니다.)<br />
앞으로 즐겁고 유익한 강의가 될 수 있도록 많은 격려와 성원 부탁드립니다.</p>
<p style="text-align: left"></div>
<p><span style="color: #ffffff;font-size: medium;background-color: #003366"><strong>카멜레온 DIY LED?</strong></span></p>
<p>카멜레온 DIY LED라는 이름은 아마도 처음 들어보는 이름일 것이라 생각합니다. 왜냐하면 카멜레온 DIY LED라는 이름은 제이씨넷(http://www.jcnet.co.kr)에서 출시한 상품 이름이고 고유명사이기 때문입니다.<br />
이름도 생소한데 이것 저것 설명하려면 답답할 수 있으므로 일단 생김새부터 눈으로 보고 이야기를 시작하도록 하는 것이 좋곘습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-1.jpg" rel="lightbox[30734]"><img class="wp-image-30896 aligncenter" alt="35 프로젝트 1" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-1.jpg" width="482" height="209" /></a></p>
<p>위의 사진은 카멜레온 DIY LED 시리즈 중의 하나인 JLED-BAR-5 라는 모듈인데요. 길쭉한 PCB 판위에 5개의 네모난 부품이 얹혀 있는 형상입니다. 5개의 네모난 부품은 WS2812B라는 이름을 가지고 있는 컬러 LED로, 불이 켜지는 부분은 네모 형태 안쪽에 있는 동그라미 부분입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-2.jpg" rel="lightbox[30734]"><img class="wp-image-30897 aligncenter" alt="35 프로젝트 2" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-2.jpg" width="482" height="418" /></a></p>
<p>조금 다른 모양의 카멜레온 DIY LED 하나만 더 보겠습니다.<br />
이것의 이름은 JLED-SNOW-13입니다. 이쯤되면 약간 느낌이 오시지요? ‘내 눈에 콩깍지’라는 말처럼 혹시 저만 위 모듈이 ‘SNOW’로 보이는 것은 아니겠지요?<br />
이름 풀이를 해 보면, ‘JLED’는 제이씨넷(JCNET)이 만든 LED라는 의미로 ‘JLED’, LED의 배치 모양이 눈(SNOW) 형상을 닮았으므로 ‘SNOW’, 사용된 LED의 총 개수가 13개 이므로 ‘13’, 이것을 차례로 합하면 ‘JLED-SNOW-13’이 되겠습니다.<br />
내친김에, 카멜레온 DIY LED 이름도 어떻게 작명되었는지를 소개합니다. 아래 사진을 보시지요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-3.jpg" rel="lightbox[30734]"><img class="wp-image-30898 aligncenter" alt="35 프로젝트 3" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-3.jpg" width="309" height="378" /></a></p>
<p>JLED-BAR-5와 JLED-SNOW- 12를 연결한 형태에 LED가 켜진 상태의 모습인데요. 알록달록 LED 불빛 색깔이 예쁘죠? 나무인 것도 같고, 뒤집으면 훈장 같기도 합니다. 카멜레온 DIY LED 모듈은 아두이노나 AVR모듈을 연결하여 프로그램해 주면 주인이 원하는 컬러와 동작을 아주 다양하게 연출할 수 있답니다.<br />
이와 같이 카멜레온처럼 LED 색깔이 아주 환상적으로 자유롭게 변할 수 있으므로 ‘카멜레온’, JLED-BAR-5의 한쪽 끝과 JLED-SNOW-12가 서로 연결된 것처럼 다른 종류의 카멜레온 DIY LED를 연속해서, 쉽게, 내 멋대로 연결할 수 있기 때문에 ‘DIY’, 그리고, 당연히 LED이므로 ‘LED’, 이것을 합체하여 ‘카멜레온-DIY-LED’! 말 되나요?</p>
<p>내가 그의 이름을 불러주기 전에는<br />
그는 다만 하나의 몸짓에 지나지 않았다.<br />
내가 그의 이름을 불러주었을 때,<br />
그는 나에게로 와서 꽃이 되었다.</p>
<p>예전에 읽은 기억이 있는 김춘수 시인의 ‘꽃’이라는 시에 나오는 구절인데요. 이것처럼 우리가 이름을 붙여주어서 새로운 생명(신상품) 카멜레온 DIY LED 시리즈가 탄생하였답니다.</p>
<p>처음으로 나온 신상품을 바라보고 있으면 오우~ 기분이 흐뭇해집니다. “대박! 나자~~~”<br />
물론 약간의 걱정도 함께 있지요. “혹시 쪽박? ……”<br />
사실 이 이름으로 확정되기 전에는 수 많은 이름 후보가 있었습니다.</p>
<p>판타지아, 프리즘, RGB, 내맘대로,<br />
알라딘, 매직, 스케치, 지니, 지니어스&#8230;.</p>
<p>이리 불러보고 저리 불러보고, 이렇게 조합해보고, 저렇게 합체해보고, 이리 찾아보고, 저리 찾아보고, 이 사람에게 물어보고, 저 사람에게 의견 구하고, 하다가 이 제품을 가장 잘 표현할 수 있는 것으로 결국 카멜레온-DIY-LED 이름이 선택되고, 세상에 나온 것입니다.<br />
이미 똑같은 것, 비슷한 것이 많이 나와 있다구요? 으~ 정말이요?<br />
비슷한 부분도 있겠지만, 단언컨데 카멜레온 DIY LED는 현재까지 나온 종류와는 상당 부분 다릅니다. 뭐가 다른지는 앞으로의 이야기에서 자연스럽게 아실 수가 있을 것이고… 여기서 이야기를 이어가기 위하여 간단한 퀴즈! 카멜레온 DIY LED에서 가장 중요한 것은 무엇일까요?<br />
뭐 물어보나 마나 한 시시한 질문이지요?<br />
LED!!! 예, 정답입니다. “단팥없는 찐빵”이 있을 수 없고, “고무줄 없는 팬츠”가 존재할 수 없는 것처럼 LED 없는 카멜레온 DIY LED는 상상할 수가 없겠습니다.</p>
<p><span style="font-size: medium;color: #ffffff;background-color: #003366"><strong>WS2812B와 이를 이용한 모듈</strong></span></p>
<p>그렇다면 카멜레온-DIY-LED의 기반이 되는 LED의 정체는 무엇일까요? 아마도 몇몇 분들은 앞의 사진을 보시자마자 “척 보면 압니다!” 하셨을 것으로 압니다. 이 LED는 WS2812B라는 컬러 LED입니다.<br />
2010년에 설립된 Worldsemi라는 중국 회사가 개발한 LED인데 내부에 LED를 제어하는 제어 로직이 함께 들어가 있는, 특허도 가지고 있는 약간은 독특한 기능과 형태를 가진 컬러 LED랍니다. 일반적인 컬러 LED는 R(Red), G(Green), B(Blue) 핀과 VCC 또는 GND 핀으로 이루어진 4핀 인터페이스 형태를 가지고 있지만, WS2812는 VCC, GND와 DIN(Data Input), DOUT(Data Output)의 4핀 인터페이스를 가지고 있고 정해진 프로토콜에 의하여 데이터를 전송받아 R, G, B의 컬러를 표현하는 한다는 점에서 일반 컬러 LED와 크게 구별됩니다.</p>
<table style="width: 620px;border: 1px solid #c4c4c4" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-4.jpg" rel="lightbox[30734]"><img class="wp-image-30899 aligncenter" alt="35 프로젝트 4" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-4-300x253.jpg" height="200" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-5.jpg" rel="lightbox[30734]"><img class="wp-image-30900 aligncenter" alt="35 프로젝트 5" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-5-300x300.jpg" height="200" /></a></td>
</tr>
<tr>
<td style="text-align: center">WS2812</td>
<td style="text-align: center">WS2812B</td>
</tr>
</tbody>
</table>
<p>위에서 대강의 형태를 보았으니 이번에는 크게 확대해서 안을 조금 들여다 보겠습니다. 보는 김에 WS2812B의 초기버전인 WS2812도 함께 보시지요.<br />
2가지 모두에서 동그라미 내부에 아주 작은 직사각형으로 보이는 것이 3개 있는데 이것이 R(Red), G(Green), B(Blue) 개별 LED이고 LED 반대편으로 꽤 크게 보이는 직사각형이 이들의 제어로직입니다.<br />
WS2812는 출시된 지 얼마 되지 않아 효율성과 안정성이 강화된 WS2812B로 개량되었습니다. 핀 수도 6개에서 4개로 단순화되었고, 내부 로직도 더 효율적으로 개선되었으며, 무엇보다도, 전원의 (+)와 (-) 를 서로 바꾸어 연결해도 안전하도록 설계되었다고 합니다. 현재는 거의 WS2812B만 사용하므로 우리는 WS2812B만 조금 더 자세히 살펴보는 것으로 하겠습니다. 전체적인 특징부터 정리해 보지요.</p>
<p><span style="color: #ffffff;background-color: #003366"><strong>WS2812B의 특징</strong></span></p>
<p><strong>● 제어로직 내장형 고휘도 컬러 LED</strong><br />
· 표현할 수 있는 컬러 : 1600만 가지 이상<br />
· 낮에도 디스플레이 형상이 식별 가능한 고휘도<br />
· 가로 x 세로 크기가 5mm X 5mm 인 5050 SMD(Surface Mounting Device) 패키지</p>
<p><strong>● 직렬 연결 방식의 4핀 인터페이스</strong><br />
· 입력(DIN), 출력(DOUT) 핀 각 1개와 전원(VCC, GND) 2핀의 단순한 구조<br />
· 앞 WS2812B 출력(DOUT)이 뒤 WS2812B 입력(DIN)으로 연결되는 직렬 연결 방식<br />
· 연결 가능 최대 LED 개수 : Refresh 간격이 초당 30 프레임인 경우, 1024개 이상</p>
<p><strong>● 다음 LED까지의 최대 간격 : 5m</strong><br />
· 단순하고 효율적인 데이터 처리 방식</p>
<p><strong>● 데이터 전송 프로토콜 : NRZ(Non Return to Zero) 방식</strong></p>
<p><strong>● DIN 포트로 들어오는 24비트의 데이터를 취하여 이것을 내부 데이터 래치에 저장하고, 이후 들어오는 데이터는 DOUT 포트로 출력</strong></p>
<p><strong>● 연속적인 연결의 경우 하나의 WS2812B를 통과할 때마다 계속 24비트씩의 데이터가 감소하는 방식으로 무한대(?)의 WS2812B 연결 가능</strong></p>
<p>간단히 이야기하면, WS2812B를 한 줄로 죽~ 내가 원하는 대로 엄청나게 많이 연결하면서, 각 LED 단위로 내가 원하는 컬러로(껐다 켰다 포함) 자유롭게 표현할 수 있다는 이야기입니다. 와우!!! 이거 잘만 하면 뭔가 기발한 것을 만들어 볼 수 있겠다는 생각이 들지 않나요?<br />
세상에 나온 지 몇 년 되었으니 당연히 이것을 이용해서 이미 만들어진 것이 있겠지요. 확인해 보겠습니다.<br />
해외에는 Adafruit(www.adafruit.com)라는 회사가 NeoPixel 이라는 브랜드명으로 여러가지 상품을 만들어 판매하고 있습니다. (디바이스마트에서도 현재 수입 판매 중!) 대표적인 것들만 몇 개 보겠습니다.</p>
<table style="width: 620px;border: 1px solid #eaeaeb;border-color: #f2f2f3;border-width: 1px" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-6.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30901" alt="35 프로젝트 6" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-6-300x225.jpg" width="300" height="225" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-7.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30902" alt="35 프로젝트 7" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-7-300x225.jpg" width="300" height="225" /></a></td>
</tr>
<tr>
<td>Flora : 1개짜리 개별 LED로 4 방향으로 각각 신호선을 납땜할 수 있는 형태 (VCC, GND, DIN, DOUT)</td>
<td>Stick &#8211; 8개 LED가 막대처럼 연속 연결된 형태, 신호 연결을 위한 패드는 뒷면에 있음</td>
</tr>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-8.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30903" alt="35 프로젝트 8" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-8-300x225.jpg" width="300" height="225" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-9.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30904" alt="35 프로젝트 9" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-9-300x225.jpg" width="300" height="225" /></a></td>
</tr>
<tr>
<td>Stick  2개를 연속하여 연결한 모습으로 뒤로 제어기(예 : 아두이노)가 연결된 것이 보인다.</td>
<td>Stick의 뒷 모습으로 신호 연결을 위한 SMD 패드가 보이며, 여기에 전선을 연결하여 제어기(아두이노 등)와 연결하거나 다른 LED들을 연속하여 연결할 수 있다. 다른 제품들도 연결 방식은 모두 SMD 패드에 납땜하는 형태이다.</td>
</tr>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-10.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30905" alt="35 프로젝트 10" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-10-300x225.jpg" width="300" height="225" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-11.jpg" rel="lightbox[30734]"><img class="alignnone  wp-image-30906" alt="35 프로젝트 11" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-11.jpg" width="300" /></a></td>
</tr>
<tr>
<td>Jewel &#8211; 7개 LED로 구성되어 있으며, 뒤에 있는 제어기는 Adafruit의 Pro Trinket</td>
<td>Ring &#8211; 16개의 LED로 구성된 반지 모양의 모듈로 뒤쪽 제어기에 ARDUINO 글씨가 살짝 보인다.</td>
</tr>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-12.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30907" alt="35 프로젝트 12" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-12-300x225.jpg" width="300" height="225" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-13.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30908" alt="35 프로젝트 13" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-13-300x225.jpg" width="300" height="225" /></a></td>
</tr>
<tr>
<td>Matrix &#8211; 64 LED로 구성된 도트매트릭스 형태로 환상적인 색깔이네요.</td>
<td>Ring 머리 장식이나 귀걸이, 목걸이, 팔찌 등의 응용도 됩니다.</td>
</tr>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-14.jpg" rel="lightbox[30734]"><img class="alignnone  wp-image-30909" alt="35 프로젝트 14" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-14.jpg" width="300" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-15.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30910" alt="35 프로젝트 15" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-15-300x188.jpg" width="300" height="188" /></a></td>
</tr>
<tr>
<td>Strip 형태. 많은 양의 LED를 연결할 때 사용되는 제품으로 가위로 필요한 만큼 잘라 쓸 수 있답니다.</td>
<td>strip 형태. 신발에 총천연색 발광이라~.</td>
</tr>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-16.jpg" rel="lightbox[30734]"><img class="alignnone size-medium wp-image-30911" alt="35 프로젝트 16" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-16-300x211.jpg" width="300" height="211" /></a></td>
<td></td>
</tr>
<tr>
<td>Strip 형태. 이런 응용도 가능하네요.</td>
<td></td>
</tr>
</tbody>
</table>
<p>어쩌다 보니 NeoPixel 선전이 되어버린 것 같은데… 쩝! 어쨌든 응용범위가 넓은 것 같습니다. (나중에 아시겠지만 카멜레온 DIY LED는 응용 범위가 훨씬 더 넓습니다.) 시장이 작아서인지, Adafruit가 치고 나가서 엄두가 나지 않아서 인지는 잘 모르겠지만 해외에서도 Adafruit사 말고는 WS2812B 기반의 상품을 출시한 다른 회사는 거의 보이지 않습니다.<br />
그럼, 국내는 어떤지 보겠습니다.<br />
유일하게, N사에서 ‘R******시리즈’라고 이름을 붙여 아래와 같은 5개 제품을 출시하여 판매하고 있습니다. 형태는 NeoPixel의 일부 제품과 비슷한 것 같네요.<br />
지금까지 WS2812B를 사용하여 만들어진 제품을 간략히 살펴보았습니다. NeoPixel은 국내에서는 디바이스마트가 국내 공식 파트너로 판매중이고, R******시리즈는 디바이스마트 등에서 판매가 되고 있습니다.</p>
<table style="width: 620px" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td><a style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;font-size: 13px;line-height: 19px" href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-17.jpg" rel="lightbox[30734]"><img class="alignnone  wp-image-30912" alt="35 프로젝트 17" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-17-270x300.jpg" width="173" height="192" /></a></td>
<td colspan="2"><img class="alignnone  wp-image-30914" alt="35 프로젝트 19" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-19-270x300.jpg" width="173" height="192" /></td>
<td><img class="alignnone  wp-image-30913" alt="35 프로젝트 18" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-18-270x300.jpg" width="173" height="192" /></td>
</tr>
<tr>
<td rowspan="2" colspan="2"><img class="size-thumbnail wp-image-30916 aligncenter" alt="35 프로젝트 21" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-21-150x150.jpg" width="150" height="150" /></td>
<td rowspan="2" colspan="2"><img class="size-full wp-image-30915 aligncenter" alt="35 프로젝트 20" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-20.jpg" width="160" height="178" /></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #ffffff;font-size: medium;background-color: #003366"><strong>카멜레온 DIY LED 응용</strong></span></p>
<p>자, 이제 다른 제품들에 대하여 알아보았으니, 카멜레온 DIY LED에 대하여 좀 더 자세하게 알아보겠습니다.<br />
카멜레온 DIY LED 시리즈는 고휘도 WS2812B 컬러 LED를 여러개 조합하여 제작된 모듈이라는 점에서는 다른 제품들과 비슷하지만, 크게 2가지의 다음과 같은 다른 특장점을 가지고 있습니다.<br />
첫째, 카멜레온 DIY LED는 점, 막대, 원호, 다각형 등의 기본 도형 및 별, 하트, 눈, 화살표 등의 예쁘고 친근한 형상을 기본 모듈로 가지고 있습니다.<br />
둘째, 모든 모듈은 레고처럼 각 모듈끼리의 직접 연결을 통하여(납땜 불필요, 세계 최초!) 숫자나 문자, 도형은 물론 캐릭터나 동물 등 자신이 원하는 형상을 쉽고, 빠르고, 자유롭게 구현할 수 있습니다.<br />
카멜레온 DIY LED 시리즈는 현재 아래와 같이, 막대(BAR) 그룹, 원호(ARC) 그룹, 방향전환자(DIR) 그룹, 도형(FIG) 그룹, 아이템(ITEM) 그룹, 연결자(CON) 그룹의 총 6개 그룹 48개 모듈과 모듈 연결에 필요한 케이블 2종을 포함하여 총 50개의 모듈로 구성됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-22.jpg" rel="lightbox[30734]"><img class="alignnone size-large wp-image-30917" alt="35 프로젝트 22" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-22-620x438.jpg" width="620" height="438" /></a><br />
카멜레온 DIY LED로 형상을 만들고 아두이노나 AVR 등의 마이크로콘트롤러를 연결하여 각 LED마다 색상과 밝기, ON/OFF 동작을 원하는 대로 프로그램하면, 그 응용은 아래 사진과 같이 다양한 분야, 다양한 용도로 무한하게 확장 가능합니다.</p>
<table style="width: 620px;border: 1px solid #d6d4d7;border-width: 0px" border="0" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td colspan="2"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-23.jpg" rel="lightbox[30734]"><img class="size-full wp-image-30918 aligncenter" alt="35 프로젝트 23" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-23.jpg" width="316" height="186" /></a></td>
</tr>
<tr>
<td colspan="2">
<p style="text-align: center">카멜레온 DIY LED의 가장 간단한 모듈 JLED-BAR-1을 아두이노(JARDUINO-UNO-BTmni)에 연결</p>
</td>
</tr>
<tr>
<td colspan="2"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-24.jpg" rel="lightbox[30734]"><img class="aligncenter" alt="35 프로젝트 24" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-24.jpg" width="329" height="207" /></a></td>
</tr>
<tr>
<td colspan="2">
<p style="text-align: center">카멜레온 DIY LED의 JLED-RING-12를 아두이노 UNO에 연결하여 색상환을 디스플레이</p>
</td>
</tr>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-25.jpg" rel="lightbox[30734]"><img class="wp-image-30920 aligncenter" alt="35 프로젝트 25" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-25-300x197.jpg" width="270" height="177" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-26.jpg" rel="lightbox[30734]"><img class="size-medium wp-image-30921 aligncenter" alt="35 프로젝트 26" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-26-300x168.jpg" width="300" height="168" /></a></td>
</tr>
<tr>
<td colspan="2">
<p style="text-align: center">(좌) 카멜레온 DIY LED 다수개를 폼보드를 밑판으로 하여 회사명을 구현한 모습<br />
(우) 아두이노를 연결하고 프로그램한 후 실행한 디스플레이</p>
</td>
</tr>
<tr>
<td colspan="2"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-27.jpg" rel="lightbox[30734]"><img class="size-medium wp-image-30922 aligncenter" alt="35 프로젝트 27" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-27-300x171.jpg" width="300" height="171" /></a></td>
</tr>
<tr>
<td style="text-align: center" colspan="2">카멜레온 DIY LED를 밑판없이 연결자만을 이용하여 I Love(♥) U 형상을 구현</td>
</tr>
<tr>
<td colspan="2"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-28.jpg" rel="lightbox[30734]"><img class="size-medium wp-image-30923 aligncenter" alt="35 프로젝트 28" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-28-300x200.jpg" width="300" height="200" /></a></td>
</tr>
<tr>
<td style="text-align: center" colspan="2">카멜레온 DIY LED인 해(JLED-RING-12), 달(JLED-MOON-11), 별(JLED-STAR-10)을 아크릴판에 고정</td>
</tr>
<tr>
<td colspan="2"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-29.jpg" rel="lightbox[30734]"><img class="size-medium wp-image-30924 aligncenter" alt="35 프로젝트 29" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-29-300x168.jpg" width="300" height="168" /></a></td>
</tr>
<tr>
<td style="text-align: center" colspan="2">카멜레온 DIY LED를 조합하여 만든 장식용 안경</td>
</tr>
<tr>
<td colspan="2"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-31.jpg" rel="lightbox[30734]"><img class="size-medium wp-image-30925 aligncenter" alt="35 프로젝트 31" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-31-300x182.jpg" width="300" height="182" /></a></td>
</tr>
<tr>
<td style="text-align: center" colspan="2">카멜레온 DIY LED로 꾸며본 고양이 얼굴</td>
</tr>
<tr>
<td style="text-align: center" colspan="2"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-32.jpg" rel="lightbox[30734]"><img class="size-medium wp-image-30926" alt="35 프로젝트 32" src="http://www.ntrexgo.com/wp-content/uploads/2016/03/35-프로젝트-32-300x155.jpg" width="300" height="155" /></a></td>
</tr>
<tr>
<td style="text-align: center" colspan="2">카멜레온 DIY LED의 모든 LED 모듈을 한 개씩만 사용하여 구성한 비상하는 용의 모습</td>
</tr>
</tbody>
</table>
<p>이러한 카멜레온 DIY LED 모듈은 현재 디바이스마트<a href="//www.devicemart.co.kr" target="_blank">(http://www.devicemart.co.kr</a>)와 제이씨넷스토어팜(<a href="http://storefarm.naver.com/jcnet" target="_blank">http://storefarm.naver.com/jcnet</a>)등의 인터넷 쇼핑몰에서 판매가 되고 있으며, 전체적인 소개 동영상은 유투브 <a href="https://www.youtube.com/watch?v=OSUZdWhpAb8" target="_blank">https://www.youtube.com/watch?v=OSUZdWhpAb8</a>를 참조하시면 됩니다.</p>
<p>오늘은 세계 최초 레고타입 컬러 LED 모듈인 카멜레온 DIY LED 시리즈에 대하여 개략적으로 알아보았습니다. 다음 회에는 카멜레온 DIY LED 시리즈이 기반이 되는 WS2812B의 동작 원리에 대하여 자세히 알아보고, 이를 기반으로 한 카멜레온 DIY LED 모듈을 이용하여 12색상환 만들기에 도전해 보도록 하겠습니다.<br />
다음 회에 건강하고 멋진 모습으로 다시 만나기를 기원합니다. 안녕히 계십시오.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/30734/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[34호] 너무 쉬운 아두이노 DIY ⑥ &#8211; 스마트폰으로 조종하는 스마트카</title>
		<link>http://www.ntrexgo.com/archives/30243</link>
		<comments>http://www.ntrexgo.com/archives/30243#comments</comments>
		<pubDate>Fri, 15 Jan 2016 04:59:23 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[blog-posts]]></category>
		<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[34호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[Project To Build]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[스마트카]]></category>
		<category><![CDATA[스마트폰]]></category>
		<category><![CDATA[아두이노]]></category>
		<category><![CDATA[조종]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=30243</guid>
		<description><![CDATA[디바이스마트매거진 34호 &#124; 오늘의 주제는 ‘스마트폰으로 조종하는 스마트카’입니다. 스마트폰으로 조종하여 전진, 후진, 좌회전, 우회전 및 정지가 가능한 스마트카를 만들어 보겠습니다. 마지막이어서 조금은 어려울 수도 있겠지만 그동안 기본기를 많이 갈고 닦았으므로 무난히 다 잘 하실 수 있으리라 생각합니다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-아두이노.jpg" rel="lightbox[30243]"><img alt="34 아두이노" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-아두이노.jpg" width="620" height="174" /></a></p>
<p style="text-align: right;">글 | 신상석 ssshin@jcnet.co.kr</p>
<p> <div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>이 강의는 아두이노를 가지고 간단하게 생활에 필요한 용품을 만들어 보는 강의입니다. 뚝딱뚝딱 뭔가 자신만의 DIY 용품을 만들어 보는 쏠쏠한 재미가 있는 강의라고나 할까요? 이미 주변에 아두이노와 관련한 많은 책이 출간되었고 카페나 블로그를 통하여 강의가 진행된 경우도 꽤나 많이 있는데도 불구하고, 이 지면을 통하여 강의를 개설한 이유는 다음과 같습니다.</p>
<p>1. 아두이노의 초보자들을 위한 쉽고 재미있는 강의가 거의 없는 것 같아, 가능하면 초등학생(?)까지도 함께 해 볼 수 있는 그런 강의를 한 번 해보고 싶어서…<br />
2. 아두이노를 가지고 뭔가 조금은 다른, 자신만의 창의적인(?) DIY를 할 수 있는 자리를 만들어주고 싶어서…<br />
3. 디바이스마트매거진은 임베디드와 관련된 독자들이 많고, 발행 부수도 많아, 저와 제가 속한 회사(제이씨넷) 그리고 임베디드홀릭 카페의 홍보에 도움이 될 것 같아서…</p>
<p>현재 구상하고 있는 회차별 내용을 간략하게 정리해 보면 다음과 같습니다. (변경될 수 있습니다.)</p>
<table style="border: 1px solid #e2dee2; width: 340px;" border="1" cellspacing="0" cellpadding="1">
<tbody>
<tr>
<td style="text-align: center;">회차</td>
<td>내용</td>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td>3색 신호등 만들기</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td>카멜레온 반지, 스위치를 이용한 신호등 게임기</td>
</tr>
<tr>
<td style="text-align: center;">3</td>
<td>FND로 만드는 디지털전압계, 카운트다운 계수기</td>
</tr>
<tr>
<td style="text-align: center;">4</td>
<td>어두워지면 켜지는 정원등, 공중회전그네</td>
</tr>
<tr>
<td style="text-align: center;">5</td>
<td>캐롤송 카드, 컬러링 온도계</td>
</tr>
<tr>
<td style="text-align: center;">6</td>
<td>스마트폰으로 조정하는 스마트카</td>
</tr>
</tbody>
</table>
<p>앞으로 즐겁고 알찬 강의가 될 수 있도록 최선을 다할 것을 약속 드리며, 이 강의를 보는 독자들도 메일이나 카페를 통하여 Q&amp;A(Question &amp; Answer)나 피드백을 주셔서, 함께 정감을 나눌 수 있는 계기가 되기를 기대해 봅니다.<br />
</div>
<p>&nbsp;</p>
<p>여러분, 안녕하세요.<br />
쏜살갈이 시간은 흘러 어느덧 [너무 쉬운 아두이노 DIY] 강좌의 마지막 회입니다. 지난해 따뜻해지는 봄 기운을 느끼며 첫 회를 시작했는데, 시기도 적절하게 겨울 자락에 마지막 회로 마감하게 되었습니다. 유종지미(有終之美), ‘끝을 잘 맺는 아름다움’의 의미처럼 함께 마무리를 잘 해 보도록 하겠습니다.<br />
오늘의 주제는 ‘스마트폰으로 조종하는 스마트카’입니다. 스마트폰으로 조종하여 전진, 후진, 좌회전, 우회전 및 정지가 가능한 스마트카를 만들어 보겠습니다. 마지막이어서 조금은 어려울 수도 있겠지만 그동안 기본기를 많이 갈고 닦았으므로 무난히 다 잘 하실 수 있으리라 생각합니다.<br />
스마트카는 요즈음 IT에서 핫이슈가 되고 있는 분야입니다.<br />
구글은 완전한 자율주행이 가능한 자동차를 2018년까지 출시하기로 하고, 현재 상당한 진전을 이루고 있는 상태입니다. 3D 카메라, 레이저, 음파 센서, GPS 등의 다양한 전자기기가 장착되고 있으며, 이들을 통합 제어하는 구글오토라는 소프트웨어도 탑재하고 있습니다. 스마트카 시장에는 구글뿐만 아니라 테슬라, 애플 등의 IT업체와 BMW, 폭스바겐 등의 완성차 업체도 도전장을 내놓은 상태입니다. 이쪽 동네 이야기는 일단 시작하면 이야기가 길어지므로… 여기서 싹둑, 다시 본론으로 돌아갑니다.<br />
우리는 동작 원리에만 중점을 두어 최소한의 기능만 포함된 아주 간단한 스마트카를 만들어 보도록 하겠습니다.</p>
<p><span style="color: #ffffff; font-size: medium; background-color: #008000;"><strong>■ 내 자동차(Bory) 규격 및 준비물   </strong></span></p>
<p>자동차의 종류는 다양하여 승용차도 있고 트럭도 있고, 승용차 중에도 고급 승용차도 있고, 경차도 있지만 우리의 자동차는 그저 차체 프레임에 바퀴가 달려있어 굴러갈 수 있는 정도의 자동차로 일단 한정하겠습니다. 하지만 진짜 자동차에는 없는 기능으로, 스마트폰으로 명령을 내릴 수도 있고, 장착 여부에 따라서는 라인트레이서나 자율주행자동차도 될 수 있는 꽤 멋진 DIY 자동차가 될 수 있을 것입니다.<br />
일단 이름을 먼저 정하고 규격을 정한 다음 차근차근 구현해 보도록 하지요. 제 자동차의 이름은 보리(Bory)로 하겠습니다. 예전에 집에서 애완용으로 키웠던 페릿에게 붙여준 이름인데요. 이름이 구수하고 정겨워서 이것으로 합니다. 여러분도 자기 나름대로 이름을 붙이고 시작해 보시기를….<br />
자, 그러면 다음 단계로 규격을 정해볼까요?</p>
<p><strong>[보리(Bory) 스마트카 규격]</strong><br />
· 스마트폰의 앱으로 전진, 후진, 좌회전, 우회전 운행 가능<br />
· 아두이노 UNO로 제어<br />
· 크기는 손바닥 크기 정도<br />
· 뒤쪽에 바퀴 2개(모터 장착), 앞쪽에 바퀴(캐스터) 1개(모터 미장착, 지지대용)<br />
· 전원은 건전지(또는 리튬전지) 등의 휴대용 전원으로 공급</p>
<p><strong>[보리(Bory) 스마트카 형태]</strong><br />
아래 JARDUINO-UNO-CAR(V2.0)과 비슷한 모습</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-01.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30497" alt="34 프로젝트 01" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-01.jpg" width="496" height="412" /></a><br />
이러한 규격을 만족하기 위하여 필요한 부품을 살펴보면 아래와 같이 될 것 같습니다.</p>
<p>1. 아두이노 UNO가 있어야 하고,<br />
2. 차체(프레임)가 있어야 하겠습니다.<br />
3. 차체에 연결할 바퀴가 2개 있어야 하고,<br />
4. 앞쪽에는 캐스터(지지용 바퀴)가 1개 필요합니다.<br />
5. 바퀴 2개를 구동하려면 모터(DC 모터)가 2개 필요하겠죠?<br />
6. 이 모터를 구동할 모터 드라이버도 역시 준비해야겠네요..<br />
7. 스마트폰과 통신을 하기 위해서는 블루투스 시리얼 모듈이 있어야 하고,,<br />
8. 스마트카의 전원으로는 모터에 전원을 공급할 배터리(홀더)가 필요하며, 아두이노와, 모터드라이버, 블루투스 시리얼 모듈에 전원을 공급할 배터리(홀더) + 전원공급기가 필요하겠습니다. (일반적으로 모터는 전류를 많이 사용하고, 순간적인 과전류로 인한 전압강하도 일어나는 부품이므로 아두이노나 다른 부품과는 다른 전원을 사용하는 것이 좀 더 안전한 방법이기 때문에 2개의 다른 전원 소스를 사용하는 것이 좋습니다.)<br />
9. 마지막으로 모터(바퀴)나 캐스터 등을 차체에 고정할 브라켓이나 서포터, 나사, 전선 등도 다수 필요하겠습니다.</p>
<p>이 부품들은 따로 따로 하나씩 임의로 구해도 되지만 너무 복잡하므로 일정 부분 이미 상품으로 제공되는 것을 사용하도록 하겠습니다. 아래와 같이 정리가 되겠네요.</p>
<table style="width: 620px;" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>부품</td>
<td>개수</td>
<td>기능</td>
<td>기타</td>
</tr>
<tr>
<td>아두이노 UNO</td>
<td style="text-align: center;">1</td>
<td>스마트카 제어</td>
<td>아두이노 UNO<br />
정품 및 호환 제품</td>
</tr>
<tr>
<td>JKIT-CAR-1</td>
<td style="text-align: center;">2</td>
<td>아두이노 AVR 카 베이스 (차체 1개, 바퀴 2개, 모터 2개,<br />
캐스터 1개, 건전지홀더 1개, 브라켓 및 서포터, 나사 다수 포함,<br />
아두이노/AVR은 미포함)</td>
<td></td>
</tr>
<tr>
<td>JMODMOTOR-1</td>
<td style="text-align: center;">1</td>
<td>4.5~13.5V, 1.2A, 2채널 모터 드라이버(바퀴 구동)</td>
<td></td>
</tr>
<tr>
<td>JMOD-BT-1</td>
<td style="text-align: center;">1</td>
<td>블루투스 시리얼 모듈 (스마트폰과 통신)</td>
<td></td>
</tr>
<tr>
<td>JBATT-U5-LC (리튬전지 포함)</td>
<td style="text-align: center;">1</td>
<td>아두이노 및 기타 모듈에 전원 공급</td>
<td></td>
</tr>
<tr>
<td>소형 브레드보드</td>
<td style="text-align: center;">1</td>
<td>HC-SR04 장착용</td>
<td></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table style="width: 620px;" border="0" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-02.jpg" rel="lightbox[30243]"><img class="wp-image-30498 aligncenter" alt="34 프로젝트 02" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-02-284x300.jpg" width="159" height="168" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-03.jpg" rel="lightbox[30243]"><img class="wp-image-30499 aligncenter" alt="34 프로젝트 03" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-03-300x291.jpg" width="168" height="163" /></a></td>
</tr>
<tr>
<td style="text-align: center;">JKIT-CAR-1 + 아두이노 UNO</td>
<td style="text-align: center;">JMOD-MOTOR-1</td>
</tr>
<tr>
<td style="text-align: center;"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-04.jpg" rel="lightbox[30243]"><img class="wp-image-30500 aligncenter" alt="34 프로젝트 04" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-04-300x225.jpg" width="192" height="144" /></a></td>
<td style="text-align: center;"><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-05.jpg" rel="lightbox[30243]"><img class="alignnone size-medium wp-image-30501" alt="34 프로젝트 05" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-05-300x128.jpg" width="300" height="128" /></a></td>
</tr>
<tr>
<td style="text-align: center;">JMOD-BT-1</td>
<td style="text-align: center;">리튬전지 + JBATT-U5-LC</td>
</tr>
</tbody>
</table>
<p>그러면 위의 부품들을 가져다가 대충 한 번 연결해 보지요. 이런 형태가 될라나요?</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-06.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30502" alt="34 프로젝트 06" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-06.jpg" width="620" height="505" /></a><br />
기계적인 부분을 제외하면, 조금 더 자세하게 살펴보아야 할 부품은 모터드라이버, 블루투스 시리얼 모듈 정도인데, 모터드라이버는 이전 강좌에서 자세히 다루었으므로 생략하고, 블루투스 시리얼 모듈에 대해서만 기초 지식을 조금 더 보충한 후에 본격적인 스마트카 제작에 나서겠습니다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 시리얼 통신    </strong></span></p>
<p>블루투스 시리얼 모듈의 동작을 이해하려면 먼저 UART(Universal Asynchronous Receiver/Transmitter) 시리얼 통신에 대한 기초 지식을 갖추어야 합니다.<br />
일반적으로 컴퓨터나 전자기기 간에 데이터나 정보를 주고 받는 행위를 통신이라고 하는데, 이들은 사람이 아니므로 반드시 미리 정해진 규칙을 따라야만 통신이 가능합니다. 예를 들어, 나는 한국어로 이야기하고, 상대방은 아랍어로 이야기한다면 서로 알아들을 수가 없다는 것이지요. 한국어면 한국어, 아랍어면 아랍어 등, 한가지 규칙을 가지고 이야기해야만 대화가 가능하며, 이 경우도 사용하는 언어를 양쪽 사람이 모두 자유롭게 정확한 의미로 사용할 수 있어야 한다는 것은 물론입니다.<br />
아두이노도 외부 PC나 전자기기와 통신할 수 있는 통신 규칙(보통 통신 프로토콜(Communication Protocol)이라고 함)을 가지고 있는데, 그 중 대표적인 것이 시리얼통신입니다. 통신을 하려면 상대방과 연결되는 통로가 있어야 하는데, 여기서 돌발 퀴즈!<br />
아두이노가 PC와 통신을 한다고 하면 어떤 통로를 이용하여 통신을 할까요?</p>
<p>10초 드립니다. 10, 9, 8, 7, 6, 5, 4, 3, 2, 1. 종료!</p>
<p>뭐죠? USB 케이블? 예. 맞습니다. 아두이노가 PC와 연결되어 있는 것은 이것 한 개밖에 없으니까요. USB(Universal Serial Bus) 케이블은 피복에 싸여서 속을 볼 수는 없지만 이를 절단해 보면 보통 4개의 전선으로 구성되어 있습니다. 2개는 +5V와 GND 선으로 PC에서 아두이노로 전원을 공급해 주는 전원 선이고, 나머지 2개는 데이터를 주고 받는 통신 선입니다. 아두이노는 이 데이터 라인을 통하여 PC와 정보를 주고 받는데 이 통신 프로토콜을 시리얼(Serial) 통신이라고 합니다. (엄밀하게 말하면 시리얼 통신의 의미는 데이터를 한 개씩 순차적으로(Serial) 보내고 받는다는 일반적인 용어이고, 실제로 여기서 사용되는 통신은 UART(Universal Asynchronous Receiver/Transmitter)라는 이름의 프로토콜을 사용하지만 보통 아두이노에서 시리얼 통신이라고 하면 이 방식을 의미합니다.) 점점 복잡하게 만드는 것인지는 모르겠지만 좀 더 엄밀하게 말하면 USB 방식도 다양한 시리얼통신 방식 중의 하나이고 여기서는 (PC쪽 UART ←→ UART를 USB 방식으로 변환) ←→ USB 케이블 ←→ (USB를 UART 방식으로 변환 ←→ 아두이노쪽 UART) 형태로 사용되므로, 실제 눈으로 보이는 것은 USB 케이블이지만 PC와 아두이노 양쪽에서 사용하는 진짜 통신 방식은 UART 방식입니다. 아두이노에서 시리얼통신이다하면 우리는 그냥 이 UART방식으로 통신한다고 생각하면 되겠습니다. 어려운걸 쉽게 설명하려니 더 어렵네요. 이 말이 더 어렵나요?<br />
사실 시리얼통신(UART통신)의 세부적인 동작을 이해하는 것은 조금 시간이 걸리는 이야기인데, 여기서는 그냥 아래와 같은 특징을 가지고 동작한다고 이해하는 정도로 넘어가겠습니다.</p>
<p><strong>[시리얼 통신 기능/동작 설명]</strong><br />
(1) 사용하는 통신라인(신호)은 TxD, RxD, GND의 3개 선입니다.<br />
TxD는 송신 데이터, RxD는 수신 데이터, GND는 접지(0V) 신호이며, 통신하고자 하는 쌍방은 GND-GND, TxD-RXD, RxD-TxD의 짝으로 연결하여야 합니다. TxD는 Transmit Data의 약어로 송신 데이터를 의미하고, RxD는 Received Data의 약어로 수신 데이터를 의미하지요. 한쪽에서 TxD로 데이터를 보내면 상대방은 RxD로 데이터를 받아야 하므로 TxD-RxD, RxD-TxD의 쌍으로 신호를 연결하여야만 정상적인 통신이 가능합니다.</p>
<p>(2) PC(또는 스마트폰 등 상대방)와 아두이노는 서로 통신 속도가 맞아야 통신이 가능합니다.<br />
1초 동안에 주고 받을 수 있는 데이터 비트 수를 보레이트(baudrate)라고 하는데 시리얼통신에서는 이 보레이트를 서로 동일하게 맞추어야 통신이 가능합니다. 보레이트는 여러가지가 있지만 가장 많이 사용하는 것은 9600/38400/115200 baud이고, 아두이노에서는 9600 baud가 가장 많이 사용됩니다. 예를 들어, 9600 baud는 1초에 9600 비트(바이트로는 1200 바이트)가 되며, 통신시 들어가는 오버헤드를 감안하면 약 1,000 바이트, 즉 1,000개의 문자를 1초 동안에 주거나 받을 수 있는 정도의 통신 속도가 됩니다.</p>
<p>(3) 데이터는 한 문자(바이트) 단위로 전송됩니다.(write/read)<br />
데이터를 주고받는 단위는 한 바이트입니다. 바이트의 값은 어떤 값도 가능하지만 아래의 테이블과 같은 ASCII 코드를 이용하여 데이터를 주고 받는 것이 보통입니다. 예를 들어 ‘A’라는 글자는 표에서 찾아보면 16진수로 0&#215;41, 10진수로는 65의 값을 갖습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-07.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30503" alt="34 프로젝트 07" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-07.jpg" width="496" height="549" /></a></p>
<p>기왕 테이블이 나온 김에 보너스로 자주 사용되는 제어문자 몇 가지만 더 알아두고 가겠습니다.</p>
<table style="width: 620px;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td>ASCII 값</td>
<td>약어</td>
<td>이름</td>
<td>C 에서의 표기</td>
<td>기능</td>
</tr>
<tr>
<td>0&#215;00</td>
<td>NUL</td>
<td>Null</td>
<td>￦0</td>
<td>문장의 마지막을 나타냄</td>
</tr>
<tr>
<td>0&#215;08</td>
<td>BS</td>
<td>Back Space</td>
<td>￦b</td>
<td>커서 위치를 1칸 전 위치로</td>
</tr>
<tr>
<td>0x0a</td>
<td>LF/NL</td>
<td>Line Feed(New Line)</td>
<td>￦n</td>
<td>커서 위치를 1줄 아래 위치로</td>
</tr>
<tr>
<td>0x0d</td>
<td>CR</td>
<td>Carrage Return</td>
<td>￦r</td>
<td>커서 위치를 줄 첫번째 위치로</td>
</tr>
</tbody>
</table>
<p>예를 들어 PC등의 화면에서 한 문장을 끊어서 줄바꿈을 하려면 ‘0x0d’, ‘0x0a’를 문장의 마지막에 보내주면 됩니다. (물론 실제 프로그램 작성시에는 라이브러리를 사용하므로 직접 이것을 넣어주는 일은 별로 없겠습니다.)</p>
<p>(4) 새로운 데이터를 보내기 위하여는 관련 플래그를 체크한 후에, 송신 가능한 상태이면 송신버퍼에 쓰면(write) 데이터를 전송할 수 있습니다. 아두이노에서는 이와 같은 기능을 모두 라이브러리로 제공하므로 우리는 제공되는 함수를 그냥 사용하면 됩니다.</p>
<p>(5) 새로운 데이터가 들어왔다는 사실은 관련 플래그를 체크하면 알 수 있고, 이 때 수신버퍼를 읽으면 전송된 데이터를 가져올 수 있습니다. 아두이노에서는 이와 같은 기능을 모두 라이브러리로 제공하므로 우리는 그냥 제공되는 함수를 사용하면 됩니다.</p>
<p>&nbsp;</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 시리얼 통신을 위한 아두이노 라이브러리    </strong></span></p>
<p>이번에는 UART 통신을 위한 아두이노 라이브러리를 자세히 살펴보겠습니다. 블루투스 시리얼 통신을 하려면 미리 알아두어야 하는 라이브러리입니다.<br />
시리얼 장치의 baudrate를 결정하는 함수는 Serial.begin( ) 입니다. 이 함수는 처음에 한 번만 실행되면 되므로 setup( ) 프로그램에서 사용하면 되겠습니다.</p>
<p style="padding-left: 60px;"><span style="color: #008080;">void Serial.begin(baudrate)</span><br />
<span style="color: #008080;"> &#8211; baudrate : 실제 설정할 baudrate 값으로 9600, 38400, 115200 등이 사용됨</span></p>
<p>그런데, 이 라이브러리는 조금 이상한 점이 있네요?<br />
즉, 이제까지 배운 함수는 이름이 문자열로만 이루어졌는데, 이번에 나타난 함수는 이름에 ‘.’을 포함하고 있습니다. 음… 이게 뭘까?<br />
이것은 위 함수가 C에서 사용하는 함수가 아니라 C++에서 사용되는 클래스(Class)임을 나타냅니다. (C++의 클래스 개념이 어려운 분은 따로 공부하시기 바라며, 여기서는 그냥 ‘여러가지 비슷한 속성을 갖는 멤버들의 그룹 명칭’ 정도로 이해하고 넘어갑니다.) 즉, Serial은 아두이노가 시리얼통신을 수행할 때 필요한 클래스임을 나타내며 ‘.’ 뒤의 부분은 이 클래스에 속하는 멤버 함수를 표시하는 것이지요. 그러므로 Serial.begin( )은 Serial 클래스에 속하는 멤버 함수 중 begin( ) 함수를 의미하는 것입니다. 뒤에도 나오겠지만, Serial.available( ), Serial.write( ) 등도 같은 구조를 가지고 있습니다. 한편, Serial은 기본 클래스로 구분되어 있어 별도로 #include를 사용한 헤더파일을 포함하지 않아도 바로 처리가 되도록 되어있다는 점도 함께 알아두시면 왜 “#include …”문이 없어도 Serial.xxx( ) 함수가 실행되는지를 이해할 수 있을 것입니다.<br />
데이터가 들어왔는지를 검사하는 라이브러리는 Serial.avaliable( ) 함수입니다.<br />
UART 통신을 통하여 들어온 데이터의 개수가 리턴되며 최대 64까지의 값을 가질 수 있지만 보통은 1 또는 0 값이 리턴됩니다. 1이면 데이터가 1개 들어온 것이고, 0이면 전송된 데이터가 없는 것이지요.</p>
<p style="padding-left: 60px;"><span style="color: #008080;">int Serial.avaliable( )</span><br />
<span style="color: #008080;"> &#8211; return 값 : 입력된 데이터 수 (보통은 데이터가 있으면 1, 없으면 0)</span></p>
<p>상대방이 보낸 데이터 수신하는 라이브러리는 Serial.read( )입니다. 전송된 데이터가 여러 개 있다 하더라도 읽혀지지 않은 가장 먼저 입력된 데이터 1개만을 읽어오게 됩니다. 그러므로 입력된 데이터가 여려 개 있다면 이 함수를 여러 번 수행하여 순서대로 모든 데이터를 읽어오면 되겠습니다.</p>
<p style="padding-left: 60px;"><span style="color: #008080;">char Serial.read( )</span><br />
<span style="color: #008080;"> &#8211; return 값 : 입력된 데이터 버퍼의 첫번째 데이터(1 문자)</span></p>
<p>데이터를 상대방에게 송신하는 라이브러리는 Serial.write( )입니다.</p>
<p style="padding-left: 60px;"><span style="color: #008080;">int Serial.write(char val)</span><br />
<span style="color: #008080;"> &#8211; val : 전송(출력, write)하고자 하는 데이터값</span><br />
<span style="color: #008080;"> &#8211; return 값 : 전송된 데이터의 개수(문자수), 보통은 사용하지 않음</span></p>
<p>여러 개의 데이터를 한꺼번에 송신하는 라이브러리로는 Serial.print( )와 Serial.println( )이 있습니다.</p>
<p style="padding-left: 60px;"><span style="color: #008080;">void Serial.print(val)</span><br />
<span style="color: #008080;"> &#8211; val : 디스플레이되는 값으로 ASCII 처리가 기본, 실제 처리 예는 아래 참조</span><br />
<span style="color: #008080;"> * Serial.print(78) → “78”</span><br />
<span style="color: #008080;"> * Serial.print(1.23456) → “1.23” (소수점의 경우는 소수 둘째자리까지만 처리)</span><br />
<span style="color: #008080;"> * Serial.print(‘N’) → “N”</span><br />
<span style="color: #008080;"> * Serial.print(“Hello world.”) → “Hello world.”</span></p>
<p style="padding-left: 60px;"><span style="color: #008080;">void Serial.print(val, format)</span><br />
<span style="color: #008080;"> &#8211; val : 디스플레이되는 값으로 ASCII 처리가 기본, 실제 처리 예는 아래 참조</span><br />
<span style="color: #008080;"> &#8211; format : 정수의 경우는 진법(BIN : 2진법, DEC : 10진법, HEX : 16진법), 소수점의 경우는 소수점 아래 표시 개수</span><br />
<span style="color: #008080;"> * Serial.print(78, BIN) → “1001110”</span><br />
<span style="color: #008080;"> * Serial.print(78, DEC) →”78”</span><br />
<span style="color: #008080;"> * Serial.print(78, HEX) → “4E”</span><br />
<span style="color: #008080;"> * Serial.print(1.23456, 0) → “1”</span><br />
<span style="color: #008080;"> * Serial.print(1.23456, 4) → “1.2345”</span></p>
<p style="padding-left: 60px;"><span style="color: #008080;">void Serial.println(val)</span><br />
<span style="color: #008080;"> &#8211; Serial.print(val)과 동일하나 단지 마지막에 CR(Carrage Return, ‘\r’, 0x0d)와 NL(New Line, ‘\n’, 0x0a)가 더 추가되어 전송됨. 결과적으로는 한 줄 아래의 처음부터 디스플레이됨(줄바꿈)</span></p>
<p style="padding-left: 60px;"><span style="color: #008080;">void Serial.println(val, format)</span><br />
<span style="color: #008080;"> &#8211; Serial.println(val, format)과 동일하나 단지 마지막에 CR(Carrage Return, ‘\r’, 0x0d)와 NL(New Line, ‘\n’, 0x0a)가 더 추가되어 전송됨. 결과적으로는 한 줄 아래의 처음부터 디스플레이됨(줄바꿈)</span></p>
<p>이 외에도 더 많은 라이브러리가 있지만 이 정도면 일반적인 프로그램에서는 충분할 것 같네요.<br />
블루투스는 휴대폰, 노트북, 이어폰 등의 휴대기기를 서로 연결하여 정보를 교환할 수 있게 하는 무선 기술 표준 중의 하나로 ISM(Industrial Scientific and Medical) 주파수 대역인 2400~2483.5MHz를 사용합니다. ISM이란 산업, 과학, 의료용으로 할당된 주파수 대역인데 전파 사용에 대해 허가를 받을 필요가 없어서 아마추어 무선, 무선랜, 블루투스 등이 이 ISM 대역을 사용하고 있습니다. 블루투스는 기기 간 마스터(Master)와 슬레이브(slave) 구성으로 연결되는데, 두 기기가 동기화(paring)되지 못하면 통신이 이루어지지 않습니다. 하나의 마스터 기기에는 최대 7대의 슬레이브 기기를 연결할 수 있으며, 마스터 기기와 슬레이브 기기 간 통신만 가능할 뿐 슬레이브 기기 간의 통신은 불가능합니다. 물론, 스마트폰은 마스터 기능과 슬레이브 기능을 모두 가지고 있고, 우리가 사용하려는 블루투스 시리얼 모듈인 JMOD-BT-1도 마스터와 슬레이브 기능을 가지고 있습니다.(단, JMOD-BT-1은 사용시 마스터나 슬레이브 중 하나로 고정됩니다.)<br />
Bluetooth 2.0 규격의 경우, 보통 10m 이내 거리 (100m까지 되는 것도 있음)에서 통신이 가능하며, 10Mbps 이하의 데이터 전송 속도를 가집니다. 최근에는 저전력 버전인 BLE 4.0 이상 버전도 출시가 되고 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-09.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30505" alt="34 프로젝트 09" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-09.jpg" width="347" height="262" /></a></p>
<p>블루투스의 유래는 옛 스칸디나비아 지역을 통일한 덴마크와 노르웨이의 국왕 해럴드 블루투스(Harold “Bluetooth” Gormsson, ?~985 혹은 986)의 별명에서 나왔습니다. 그는 블루투스(Bluetooth, 푸른이빨)라는 별명을 가지고 있었는데, 그것은 블루베리를 좋아해 항상 치아가 푸르게 물들어 있었기 때문이라는 설과, 파란색 의치를 해 넣었기 때문이라는 설이 유력합니다. 위와 같이 생기신 분이지요. 입을 꽉 다물고 있어서 이빨이 푸른색인지는 확인이 안되지만요.<br />
어쨌든, 블루투스 SIG(개발자모임)는 자신들이 개발한 기술이 통신장치들을 하나의 무선 기술 규격으로 통일하기를 바라는 마음에서 공식명칭을 블루투스로 정했답니다. 이에 따라 블루투스의 공식 로고도 해러드 왕의 이니셜인 H(옛 스칸디나비아 룬 문자)와 블루투스의 이니셜인 B를 합하여 아래와 같이 만들어졌습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-10.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30506" alt="34 프로젝트 10" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-10.jpg" width="434" height="103" /></a><br />
블루투스 소개가 조금 길어졌네요. 너무 길어지면 또 지루하니까 이 정도에서 정리 끝!</p>
<p>&nbsp;</p>
<p><span style="color: #ffffff; font-size: medium; background-color: #008000;"><strong>■ 블루투스(Bluetooth) 통신을 이용한 스마트폰-아두이노 연결   </strong></span></p>
<p>블루투스 시리얼 모듈은 UART(Universial Asynchronous Receiver/Transmitter) 방식의 시리얼 통신을 블루투스 통신으로 변환시켜주는 모듈입니다. 이 모듈의 실제적인 세부 동작 원리 및 실행 방법은 조금 복잡할 수 있으므로, 우리는 개념적으로만 이해하면 쉬울 것 같습니다.<br />
블루투스 시리얼 모듈은 한마디로 UART 통신 방식의 유선 연결을 블루투스 방식의 무선 연결로 바꾸어주는 모듈입니다. 아래 그림은 블루투스 시리얼 모듈의 개념도로, 그림에서와 같이 유선으로 수신된 RXD 신호는 무선으로 송신하고, 무선으로 수신된 데이터는 TXD 신호로 내보내는 역할을 하는 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-11.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30507" alt="34 프로젝트 11" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-11.jpg" width="496" height="133" /></a></p>
<p>실제로 두 개의 시스템이 블루투스 시리얼 모듈을 이용하여 어떻게 시리얼 통신을 수행할 수 있는지에 대한 예를 보이면 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-12.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30508" alt="34 프로젝트 12" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-12.jpg" width="496" height="389" /></a></p>
<p>그림(A)는 아두이노 UNO 2개를 UART 통신을 이용하여 연결할 때의 연결도입니다. 아두이노 UNO는 UART 포트를 가지고 있으므로 서로의 UART 포트를 연결(TX-RX 짝으로)하면 시리얼 통신이 가능합니다. 그런데 만약 아두이노 UNO 1개가 손이 닿지 않거나 선을 연결할 수 없는 곳에 위치한다면 어떻게 하시겠습니까? 이런 경우에는 무선으로 연결할 수 있으면 되겠지요? 이럴 때 유선통신의 내용을 무선으로 바꿔주는 역할을 하는 것이 유선-to-무선 변환기이고 블루투스 시리얼(UART-to-블루투스)모듈은 이러한 변환기의 일종이라고 생각하시면 되겠습니다.<br />
그림(B)는 2개의 아두이노 UNO 각각에 블루투스 시리얼 모듈을 연결한 후 2개의 시스템을 블루투스 통신으로 연결하는 경우로, 이렇게 되면 2개의 아두이노 UNO 사이에는 유선으로 연결하지 않아도 통신이 가능하게 됩니다.<br />
이는, 그림(C)에 나타난 것처럼 블루투스 시리얼 모듈을 단지 유선을 무선으로 매질만 바꾸어 주는 기기라 생각하면(실제로도 그러함) 점선으로 보이는 것과 같이 직접 유선으로 연결한 것과 동일한 효과를 얻을 수 있기 때문이지요.<br />
이와 같이 생각한다면, 스마트폰의 경우 블루투스 기능을 가지고 있고, 이를 이용할 수 있는 터미널용 앱이 있으므로, 그림(D)와 같이 스마트폰과 아두이노 UNO 사이를 연결하는 경우에도 통신이 가능하다고 볼 수 있겠습니다.<br />
결과적으로 우리가 스마트폰의 가상 터미널 앱을 이용하여 특정한 값을 블루투스 통신으로 전송한다면, 이는 블루투스 시리얼 모듈을 통하여 결국 아두이노 UNO의 UART 포트로 전송되므로 아두이노 UNO의 프로그램에서 이 값을 받아서 처리할 수 있게 되는 것입니다. 또한, 반대의 경우를 생각하면 아두이노 UNO 에서 만들어진 어떤 값이 스마트폰으로 전달되어 스마트폰의 화면으로 나타낼 수도 있겠습니다. 예를 들어 실제로 우리가 나중에 스마트폰의 앱을 통하여 아래와 같이 특정 숫자를 아두이노로 보내면 아두이노는 이 숫자에 해당되는 기능을 실행할 수 있다는 것입니다.</p>
<p>‘1’ : 직진 ‘2’ : 좌회전 ‘3’ : 정지 ‘4’ : 우회전 ‘5’ : 후진</p>
<p>레알(REAL)? 레알(REAL)!</p>
<p><span style="color: #b70000; font-size: medium;"><strong>아두이노 UNO에 블루투스 시리얼 모듈을 연결하기</strong></span></p>
<p>기본적인 이론은 알았으므로 이제 아두이노 UNO에 블루투스 시리얼 모듈인 JMOD-BT-1을 연결하여 블루투스 연결을 완성해 보겠습니다.</p>
<table style="width: 620px;" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-04.jpg" rel="lightbox[30243]"><img class="alignnone size-medium wp-image-30500" alt="34 프로젝트 04" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-04-300x225.jpg" width="300" height="225" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-14.jpg" rel="lightbox[30243]"><img class="alignnone size-medium wp-image-30510" alt="34 프로젝트 14" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-14-300x168.jpg" width="300" height="168" /></a></td>
</tr>
</tbody>
</table>
<p>아두이노 UNO와는 UART 통신을 하게 되므로 JMOD-BT-1에서 아두이노 UNO와 연결해야 하는 핀은 TXD(송신 데이터), RXD(수신 데이터) 신호선과, 전원 핀인 VCC(3.3V~5V, 전원)와 GND(그라운드)로 총 4핀입니다. (나머지 핀들은 JMOD-BT-1의 세팅 시 필요한 핀이므로 실제 통신에서는 사용하지 않습니다.)<br />
그런데 여기서 한 가지 문제가 있습니다. 그것은 아두이노 UNO는 1개의 UART 인터페이스만을 가지고 있고, 이 UART 포트는 아두이노의 업로드 및 시리얼 모니터 연결용으로 이미 USB 쪽으로 연결이 되어 있다는 것입니다. 즉, 이 UART 포트를 함께 사용하는 경우, 우리는 시리얼 모니터와 블루투스 시리얼을 동시에 사용할 수 없을 뿐만 아니라, 아두이노 업로드 시에도 블루투스 시리얼 쪽의 경로와 충돌이 날 가능성 등을 고려해야 하는 아주 불편한 상황을 감수해야 합니다.<br />
그러면, 방법이 없을까요? 아니오~ 좋은 방법이 하나 있습니다.<br />
그것은 가상 UART인 소프트웨어시리얼(SoftwareSerial)을 이용하는 것입니다.<br />
소프트웨어시리얼은 아두이노의 일반적인 입출력(GPIO : General Purpose Input Output) 핀(D0~D13, A0~A5)을 이용하여 UART의 기능을 하도록 소프트웨어로 라이브러리화한 것으로, UART의 기능을 거의 그대로 재현할 수 있는 아두이노 라이브러리입니다.<br />
시리얼모니터에서 사용하는 클래스인 Serial과 비슷한 형태의 클래스로 SoftwareSerial을 제공하고 있으며, 멤버 함수도 begin, read, write 등을 Serial과 동일하게 사용할 수 있습니다.<br />
형태는 아래와 같습니다.</p>
<p style="padding-left: 60px;"><span style="color: #008080;">SoftwareSerial(unit8_t rx, unit8_t tx, bool inverse_logic = false)</span><br />
<span style="color: #008080;">rx : 수신 핀 번호</span><br />
<span style="color: #008080;">tx : 송신 핀 번호</span><br />
<span style="color: #008080;">inverse_logic : 송수신 비트 반전 (TRUE : 반전, FALSE : 반전하지 않음, default는 FALSE)</span></p>
<p>프로그램에서 사용하실 때는 첫 부분에 아래와 같은 선언이 필요하고,</p>
<p style="padding-left: 60px;"><span style="color: #008080;">#include &lt;SoftwareSerial.h&gt;</span></p>
<p style="padding-left: 60px;"><span style="color: #008080;">SoftwareSerial ABC = SoftwareSerial(RX, TX);</span><br />
<span style="color: #008080;">ABC : 이 스케치에서 SoftwareSerial로 사용할 이름</span><br />
<span style="color: #008080;">RX : RX핀으로 사용할 핀 번호</span><br />
<span style="color: #008080;">TX ; TX 핀으로 사용할 핀 번호</span></p>
<p>실제 사용시에는 Serial 클래스와 같이, 아래와 같은 형태로 사용하면 됩니다.</p>
<p style="padding-left: 60px;"><span style="color: #008080;">ABC.begin(115200);</span></p>
<p>오, 요런 방법이 있었네요. 그러면 이것을 이용하여 아두이노 UNO와 JMOD-BT-1을 직접 연결해 보도록 하겠습니다. SoftwareSerial에 사용된 핀은 RX는 4번(D4), TX는 5번(D5)를 사용하는 것으로 하지요. 한가지 조심하여야 하는 것은 송신 핀과 수신 핀의 연결인데요. 앞에서도 언급하였지만, 두 기기의 연결에서 한 쪽의 송신핀(TXD)은 다른쪽의 수신핀(RX)에, 한 쪽의 수신핀(RXD)은 다른 쪽의 송신핀(TX)에 연결하여야 한다는 점은 꼭 확인하고 연결하셔야 합니다.<br />
아래와 같이 연결하면 될 것 같네요. JMOD-BT-1의 뒷면에 신호 이름이 적혀있으니 잘 보고 연결하시기 바랍니다.</p>
<table style="width: 620px;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td style="text-align: center;">아두이노 UNO 핀</td>
<td style="text-align: center;">JMOD-BT-1핀</td>
</tr>
<tr>
<td style="text-align: center;">+5V</td>
<td style="text-align: center;">VCC</td>
</tr>
<tr>
<td style="text-align: center;">GND</td>
<td style="text-align: center;">GND</td>
</tr>
<tr>
<td style="text-align: center;">D4(RX, SoftwareSerial)</td>
<td style="text-align: center;">TXD</td>
</tr>
<tr>
<td style="text-align: center;">D5(TX, SoftwareSerial</td>
<td style="text-align: center;">RXD</td>
</tr>
</tbody>
</table>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-15.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30511" alt="34 프로젝트 15" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-15.jpg" width="620" height="446" /></a></p>
<p><span style="color: #b70000; font-size: medium;"><strong>스마트폰의 블루투스 앱으로 아두이노와 통신하기</strong></span></p>
<p>자, 연결은 되었으니 이번에는 실제로 스마트폰과 아두이노 UNO가 블루투스를 이용하여 통신이 가능한지 알아보기 위한 테스트를 실행해 보겠습니다.<br />
일단 스마트폰에 블루투스 앱이 필요할텐데…, 이것은 이미 존재하는 앱을 가져다가 사용하는 것이 좋겠습니다. 블루투스 통신을 위한 앱은 여러가지가 있지만, 나중에 스마트카를 조종하는 것을 고려하여 버튼을 이용하여 데이터를 보낼 수 있도록 설계된 ‘블루투스 컨트롤러(Bluetooth Controller)’라는 앱을 사용하는 것으로 하겠습니다. 이 앱은 안드로이드 스마트폰의 ‘PLAY 스토어’에서 ‘블루투스 컨트롤러’(“Bluetooth Controller”)이라는 이름으로 검색하면 찾을 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-21.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30530" alt="35 PTB CAP (2)" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-21.jpg" width="496" height="247" /></a></p>
<p>스마트폰의 ‘블루투스’ 항목을 ‘ON’ 상태로 설정한 후에 위와 같이 ‘Bluethooth Controller’ 앱을 실행하면 아래와 같은 화면이 나타나는데, 여기에서 위쪽 오른쪽에 있는 [키 설정] 메뉴를 누르면 다음의 화면이 나타납니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-11.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30531" alt="35 PTB CAP (1)" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-11.jpg" width="496" height="310" /></a></p>
[키 이름]에 자신이 원하는 이름을 넣고, [데이터 설정]에는 통신 시 이 키를 눌렀을 때 아두이노 쪽으로 전달될 데이터값(예를 들어 ‘1’)을 넣으면 됩니다. 우리는 나중에 스마트카를 제어해야 하므로 제공되는 9개의 칸에 아래와 같이 직관적으로 배치 하겠습니다.</p>
<table style="width: 500px;" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td style="text-align: center;"></td>
<td style="text-align: center;">전진(&#8220;1&#8243;)</td>
<td style="text-align: center;"></td>
</tr>
<tr>
<td style="text-align: center;">좌회전(&#8220;2&#8243;)</td>
<td style="text-align: center;">정지(&#8220;3&#8243;)</td>
<td style="text-align: center;">우회전(&#8220;4&#8243;)</td>
</tr>
<tr>
<td style="text-align: center;"></td>
<td style="text-align: center;">후진(&#8220;5&#8243;)</td>
<td style="text-align: center;"></td>
</tr>
</tbody>
</table>
[OK]를 누루면 아래의 화면이 나타납니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-3.jpg" rel="lightbox[30243]"><img alt="35 PTB CAP (3" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-3.jpg" width="581" height="337" /></a></p>
<p>자, 연결이 잘 되었는지 테스트를 해볼까요? 아두이노 UNO에는 블루투스를 통하여 들어온 데이터를 되돌려 보내는(echoback하는) 프로그램을 업로드하여 스마트폰에서 보낸 데이터(예를 들어 ‘1’, ‘2’ 등)가 다시 스마트폰으로 되돌아 오면 성공이 되겠습니다.</p>
<p><strong>[테스트 규격]</strong><br />
· 스마트폰 블루투스 콘트롤러 앱에서 보낸 데이터가 아두이노 UNO까지 전달되었다가 되돌아 오는 블루투스 통신 시스템<br />
· 통신 경로 : 스마트폰 블루투스 콘트롤러 앱 → (블루투스 통신) → JMOD-BT-1 TXD → 아두이노 RX → echoback(아두이노 프로그램) → 아두이노 TX → JMOD-BT-1 RXD → (블루투스 통신) → 스마트폰 블루투스 콘트롤러 앱</p>
<p><strong>[알고리즘]</strong><br />
· SoftwareSerial로 정해진 핀을 설정하고, baudrate는 115200(JMOD-BT-1의 기본 설정)으로 설정한 후, RX 핀으로 수신된 데이터는 항상 TX 핀으로 송신(echoback)</p>
<p>설명하느라 많은 시간을 할애했지만, 실제 프로그램은 너무 쉬워서 알고리즘이라고 할 것도 없습니다. 바로 스케치 프로그램으로 넘어갑니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include &lt;SoftwareSerial.h&gt;</p>
<p>#define SS_RX 4 // SoftSerial RX 핀번호 = 4<br />
#define SS_TX 5 // SoftSerial TX 핀번호 = 5</p>
<p>SoftwareSerial btSerial = SoftwareSerial(SS_RX, SS_TX); // 블루투스시리얼은 SoftSerial 사용<br />
// 4번, 5번 핀 할당</p>
<p>void setup()<br />
{<br />
btSerial.begin(115200); // 블루투스 시리얼 모듈(JMOD-BT-1) 통신 속도<br />
= 115200<br />
}</p>
<p>void loop()<br />
{<br />
if (btSerial.available()) // 블루투스 시리얼 모듈을 통하여 데이터가 수신되면<br />
{<br />
data = btSerial.read(); // 그 데이터를 읽어서<br />
btSerial.write(data); // 블루투스 시리얼 모듈을 통하여 다시 송신(loopback)<br />
}<br />
}</p>
</div>
<p>얼른 업로드하고, 앱을 이용하여 연결이 잘 되었는지 확인해 보겠습니다.</p>
<p>1. 스마트폰에서 블루투스 컨트롤러 앱을 실행하고</p>
<p>2. 아두이노 UNO에 연결된 JMOD-BT-1과 패어링(pairing : 블루투스 마스터와 블루투스 슬레이브가 통신할 수 있는 상태로 진입하는 것)을 한 후<br />
<span style="color: #ff0000;">(주의 : 처음 연결할 때는 PIN 번호를 물어보게 되는데 이 때는 ‘1234’를 입력합니다.)</span></p>
<p>3. 버튼을 눌러 대응되는 숫자가 되돌아 오는지 확인(즉, ‘전진’ 버튼을 누르면 ‘1’, 좌회전을 버튼을 누르면 ‘2’, 정지 버튼을 누르면 ‘3,’ 우회전 버튼을 누르면 ‘4’, 후진 버튼을 누르면 ‘5’, 값이 스마트폰 앱 화면 창에 나타나면 성공!)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-31.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30524" alt="34 프로젝트 31" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-31.jpg" width="620" height="318" /></a></p>
<p>&nbsp;</p>
<h1><span style="font-size: small;"><a href="https://www.youtube.com/watch?v=VpklRysoiu0" target="_blank">블루투스 통신을 이용한 스마트폰과 아두이노 연결 영상보러가기</a></span></h1>
<p><span style="color: #ffffff; font-size: medium; background-color: #008000;"><strong>■ 내 스마트카 조립     </strong></span></p>
<p>자, 이제 필요한 기본 지식은 모두 갖추었으니 드디어 내 차를 만들고 운전해 볼 시간입니다. 실제로 이미 자동차를 가지고 계신 분도 있고, 아직은 없는 분도 있겠지만, 오늘 DIY할 스마트카는 아두이노 장난감차니까, 부담없이 내 맘대로 만들어서 내 멋대로 이리저리 마구 운전해 봅시다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-21.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30515" alt="34 프로젝트 21" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-21.jpg" width="620" height="453" /></a></p>
<p><strong>[아두이노 연결]</strong><br />
아~ 이 그림 하나 그리느라고 거의 4시간이나 잡아먹었습니다.<br />
중간에 배터리 연결 형태가 바뀌기도 하고, fritzing과 캡처, 포토샵, 파워포인트 \…로 이렇게 꾸미는 것이 꽤 많은 시간을 필요로 하네요. 어쨌든 좌충우돌하여 완성입니다. 야호~</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-4.png" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30537" alt="35 PTB CAP (4" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-4.png" width="513" height="286" /></a></p>
<p>연결된 부분을 잠시 설명해 보면, 아래 표와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-5.png" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30538" alt="35 PTB CAP (5" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-5.png" width="508" height="429" /></a><br />
전원 연결은 아래와 같습니다.<br />
모터드라이버 연결 시에는 약간 주의할 것이 있는데, PWM 신호는 아날로그 출력이므로 신호에 물결 표시(~, tild)가 있는 D3, D5, D6, D9, D10, D11번 핀에 연결해야 한다는 것입니다. 이러한 이유로 PWMA는 D6에, PWMB는 D9에 할당하였습니다. PWM 출력이 가능한 모터가 2개인 것을 제외하고는 지난 시간에 다 해본 것이므로 모터드라이버와 블루투스 시리얼과의 연결은 특별한 설명이 더 필요하지는 않을 것 같습니다. <span style="color: #808080;"><em>(기억이 나지 않으면 지난번 강의를 참조!!!)</em></span><br />
마지막으로 좀 더 설명하고 넘어가야 하는 것은 전원에 관련된 것입니다. 도입 부분에서도 약간 언급하였는데, 이번 DIY는 자동차이므로 PC로부터 USB 케이블을 통하여 공급되는 전원은 사용할 수가 없습니다. 그러므로 휴대용 전원으로 사용되는 건전지나 수은전지, 리튬전지 등을 이용하여 전원을 공급해야 하지요. 여러가지 경우를 여기서 모두 설명하기에는 내용이 좀 길어지므로 이번에는 우리가 사용할 방법만 간단하게만 설명하겠습니다.</p>
<p>일단 모터를 구동하는 전원과 아두이노 및 다른 모듈에서 사용할 전원은 분리하도록 합니다. 모터는 일반적으로 전류를 많이 사용하고, 모터마다 사용 전압도 다르며, 기동시 순간적인 과전류로 인한 전원 소스의 흔들림(전압강하)도 생길 수 있는 부품이어서 아두이노나 블루투스 시리얼 모듈로 공급되는 전원과는 다른 전원 소스를 사용하는 것을 권장합니다.</p>
<p>만약, 모터가 5V로 구동이 가능하여 동일한 5V 전원 소스로 사용하려 할 때에는 전원 소스의 전류 공급용량이 충분한지, 전원 드랍(drop)은 영향이 없는지 등의 여부를 잘 살펴서 사용하셔야 불안정한 동작을 방지할 수 있습니다. 우리는 1.5V 건전지 4개를 직렬 연결한 배터리 홀더에 넣어서, 6V를 모터의 전원으로 사용하겠습니다. 그리고 아두이노와 블루투스 시리얼 모듈, 그리고 모터드라이버 모듈의 제어 부분 전원으로는 5V를 공급해야 하므로 이것은 리튬전지(4.2V)를 스텝업 레귤레이터를 이용하여 5V로 만들어 주는 전원조종기인 제이씨넷의 JBATT-U5-LC를 사용하겠습니다. (참고로, JBATT-U5-LC는 리튬전지를 사용하고 USB 케이블로 충전이 가능하며, 전원 ON/OFF 스위치가 내장된 소형 전원공급기입니다.) 물론, 시중에 나와 있는 임의의 전압공급기 모듈을 사용해도 되고, 직접 전압공급기 회로를 제작하여 사용해도 되지요. 또는, 7V 이상의 전원 소스가 있다면 아두이노 VIN 핀으로 직접 이 전원을 넣어주고, +5V 핀으로부터 블루투스 시리얼 모듈과 모터드라이버 모듈의 제어 부분 전원을 연결하여 사용하는 것도 한가지 방법이 되겠습니다.</p>
<p>모터드라이버 모듈의 경우는 내부에서 사용하는 전원과 모터로 공급되는 전원, 2개를 모두 연결해주어야 하는 것에 주의하셔야 하고, 2개의 전원소스의 GND는 어떤 형태로든 연결되어 있어야 함에 주의하시기 바랍니다. 조금 복잡할 수 있으므로 모터 드라이버의 핀 연결을 확대하여 다시 한 번 연결 형태를 정리해 보면 아래와 같이 되겠습니다. 6V 전원(건전지홀더)의 GND는 외부에서 5V 전원의 GND와 연결한다는 의미로 점선 &#8211; - &#8211; 으로 표시하였습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-22.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30516" alt="34 프로젝트 22" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-22.jpg" width="620" height="471" /></a></p>
<p><strong>[조립하기]</strong><br />
이제 조립을 하기 위한 모든 준비는 끝난 것 같네요. 프로그램을 하기 전에 일단 조립부터 해보고(빨리 만들고 싶으니까요.) 이후에 프로그램을 준비해 보는 것으로 하시지요. 선이 제법 많고 부속 모듈도 많으므로 공간을 잘 이용해서 배치하고 연결하여야 할 것 같습니다. 저는 편하게 양면테이프를 이용하여 아래와 같이 모듈 뒤쪽에 붙이고 이것을 적당하게 배치하여 처리하였습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-23.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30517" alt="34 프로젝트 23" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-23.jpg" width="620" height="464" /></a></p>
<p>초기 앞면, 뒷면을 조립하면 아래와 같은 모양이 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-24.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30518" alt="34 프로젝트 24" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-24.jpg" width="298" height="385" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-25.jpg" rel="lightbox[30243]"><img class="alignnone  wp-image-30519" alt="34 프로젝트 25" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-25.jpg" width="298" height="319" /></a></p>
<p>그리고 각 모듈과 전원까지 모두 연결하면~</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-26.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30520" alt="34 프로젝트 26" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-26.jpg" width="620" height="428" /></a><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-27.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30521" alt="34 프로젝트 27" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-27.jpg" width="620" height="499" /></a><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-28.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30522" alt="34 프로젝트 28" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-28.jpg" width="620" height="414" /></a></p>
<p>짠~~~! 이렇게 만들어졌습니다.<br />
선들이 조금 난잡하여 폼이 덜 나긴 하지만, 전원까지 넣어주면 불이 반짝반짝 하는게 꽤 그럴 듯 하게 보입니다. 작은 끈 같은 것으로 선을 묶어주면 좀 깔끔해 질 것도 같지만, 근처에는 현재 눈에 띄지가 않으므로 생략! 그냥 산발한 채로 넘어갑니다.<br />
어쨌거나 조립은 잘 완성되어 기분은 좋아졌습니다.<br />
노동하느라 애썼으니까 커피 한 잔하면서 휴식을 조금 취한 후 다시 와서 마지막 프로그램을 완성하도록 하겠습니다.<br />
10분간 휴식~~~</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 내 스마트카 프로그램     </strong></span></p>
<p>이제 차체는 모두 완성하였으니 스케치 프로그램만 작성하여 업로드해 봅시다.<br />
블루투스 연결 쪽은 소프트시리얼로 처리해야 한다는 것을 염두에 두고, 전체적인 알고리즘을 생각해 보겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-6.png" rel="lightbox[30243]"><img alt="35 PTB CAP (6" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-6.png" width="545" height="299" /></a></p>
<p>스마트폰에서 들어온 입력을 검사하여 각 숫자에 대응되는 동작인 전진, 후진, 좌회전, 우회전, 정지의 5가지 기능 중 하나를 실행하면 되겠습니다. 또한, 각 기능은 모터 2개의 동작으로 구현할 수 있는데 이는 아래의 표를 확인하기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-7.png" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30539" alt="35 PTB CAP (7" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/35-PTB-CAP-7.png" width="597" height="187" /></a></p>
<p>예를 들어 좌회전 기능을 구현한다면, 왼쪽 바퀴(모터)는 천천히 전진하고 오른쪽 바퀴(모터)는 앞으로 전진하면 차제가 왼쪽으로 기울면서 좌회전하는 형태가 되겠습니다. 실제로 좀 더 부드럽게 동작하려면 왼쪽 바퀴(모터)는 조금 천천히 구동되고, 오른쪽 바퀴(모터)는 빨리 구동되는 형태로 구현하면 되겠지요. (이 동작은 PWMA, PWMB의 값을 아날로그적으로 0~255까지 조절이 가능하므로 적당한 값을 주어 구현이 가능합니다.)<br />
<span style="color: #ff0000;">편의상 스마트카의 오른쪽 바퀴(모터)는 모터A를, 왼쪽 바퀴(모터)는 모터B를 할당합니다.</span><br />
이번에도 설명이 좀 길었는데 실제 구현은 크게 어렵지 않게 될 것 같네요. 여러분의 힘으로 한 번 생각해 보시고 스스로 먼저 구현해 보시지요. 약 20분 기다립니다.</p>
<p>(20), (19), (18), …… (3), (2), (1), (0) !</p>
<p>아래를 보시지요.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include&lt;SoftwareSerial.h&gt;</p>
<p>#defineSS_RX 4 // SoftSeiral RX 핀 &lt;-&gt; JMOD-BT-1의 TXD 연결<br />
#defineSS_TX 5 // SoftSerial TX 핀 &lt;-&gt; JMOD-BT-1의 RXD 연결</p>
<p>#define FORWARD ‘1’ // 전진 명령어<br />
#define FORWARD_L ‘2’ // 좌회전 명령어<br />
#define FORWARD_R ‘4’ // 우회전 명령어<br />
#define BACKWARD ‘5’ // 후진 명령어<br />
#define STOP ‘3’ // 정지 명령어</p>
<p>#defineSPEED_100 255 // PWM값 255(0~255), 100% 값<br />
#defineSPEED_75 192 // PWM값 192(0~255), 75% 값<br />
#defineSPEED_50 128 // PWM값 128(0~255), 50% 값<br />
#defineSPEED_25 64 // PWM값 64 (0~255),25% 값<br />
#defineSPEED_0 0 // PWM값0(LOW) (0~255), 0% 값</p>
<p>SoftwareSerialbtSerial = SoftwareSerial(SS_RX, SS_TX);</p>
<p>constint pwma = 6; // 모터 APWM 입력핀<br />
constint ain1 = 7; // 모터 AIN1 입력핀<br />
constint ain2 = 8; // 모터 AIN2 입력핀<br />
constint pwmb = 9; // 모터 BPWM 입력핀<br />
constint bin1 = 10; // 모터 BIN1 입력핀<br />
constint bin2 = 11; // 모터 BIN2 입력핀</p>
<p>voidforw() // 전진 처리,모터 A = 전진, 모터 B = 전진<br />
{<br />
digitalWrite(ain1, HIGH); digitalWrite(ain2,LOW); analogWrite(pwma, SPEED_75);<br />
digitalWrite(bin1, HIGH); digitalWrite(bin2,LOW); analogWrite(pwmb, SPEED_75);<br />
}</p>
<p>voidforwL() // 좌회전 처리, 모터 A= 전진, 모터B = 약하게 전진<br />
{<br />
digitalWrite(ain1, HIGH); digitalWrite(ain2,LOW); analogWrite(pwma, SPEED_75);<br />
digitalWrite(bin1, HIGH); digitalWrite(bin2,LOW); analogWrite(pwmb, SPEED_50);<br />
}</p>
<p>voidforwR() // 우회전 처리, 모터 A = 약하게 전진, 모터B = 전진<br />
{<br />
digitalWrite(ain1, HIGH); digitalWrite(ain2,LOW); analogWrite(pwma, SPEED_50);<br />
digitalWrite(bin1, HIGH); digitalWrite(bin2,LOW); analogWrite(pwmb, SPEED_75);<br />
}</p>
<p>voidback() // 후진 처리,모터 A = 후진, 모터 B = 후진<br />
{<br />
digitalWrite(ain1, LOW); digitalWrite(ain2,HIGH); analogWrite(pwma, SPEED_75);<br />
digitalWrite(bin1, LOW); digitalWrite(bin2,HIGH); analogWrite(pwmb, SPEED_75);<br />
}</p>
<p>voidstop() // 정지 처리,모터 A = 정지, 모터 B = 정지<br />
{<br />
analogWrite(pwma, SPEED_0);<br />
analogWrite(pwmb, SPEED_0);<br />
}</p>
<p>voidsetup()<br />
{<br />
pinMode(pwma, OUTPUT); // 모터 제어핀은 아두이노 입장에서 모두 출력<br />
pinMode(ain1, OUTPUT);<br />
pinMode(ain2, OUTPUT);<br />
pinMode(pwmb, OUTPUT);<br />
pinMode(bin1, OUTPUT);<br />
pinMode(bin2, OUTPUT);<br />
btSerial.begin(115200); // JMOD-BT-1 통신baudrate = 115200(초기값)<br />
}</p>
<p>voidloop()<br />
{<br />
char rxData;<br />
if (btSerial.available() &gt; 0) // 스마트폰으로부터의 입력 데이터가 있는지확인<br />
{<br />
rxData = btSerial.read(); //데이터(명령어)가무엇인지 확인<br />
if (rxData == FORWARD) forw(); // 전진 명령 처리<br />
elseif (rxData == FORWARD_L) forwL(); // 좌회전 명령 처리<br />
elseif (rxData == FORWARD_R) forwR(); // 우회전 명령 처리<br />
elseif (rxData == BACKWARD) back(); // 후진 명령 처리<br />
elseif (rxData == STOP) stop(); // 정지 명령 처리<br />
else;<br />
}<br />
delay(100);<br />
}<br />
</div>
<p>모터 제어에서 “analogWrite(pwma,SPEED_75)”와 같이 PWM 핀에 192(=SPEED_75)와 같은 값을 주는 것은 전체값인 255(SPEED_100)을 주었을 때 모터가 너무 빨리 회전하여 스마트카가 너무 빨리 움직일 것 같아 적당한 값을 준 것이며, 한편으로는 모터에 의하여 소모되는 전력을 조금 적게 하여 건전지의 수명을 조금 연장하려는 의미도 있습니다.<br />
이제 준비가 되었으니 업로드하고, 앱을 이용하여 프로그램이 잘 되었는지 확인해 보겠습니다. 이전 예에서 사용한 형태와 똑같이 앱을 구성하여 실행하는 것으로 합니다.</p>
<p>1. 스마트폰에서 블루투스 컨트롤러 앱을 실행하고</p>
<p>2. 아두이노 UNO에 연결된 JMOD-BT-1과 패어링(pairing : 블루투스 마스터와 블루투스 슬레이브가 통신할 수 있는 상태로 진입)한 후<br />
<span style="color: #ff0000;">(주의 : 처음 연결할 때는 PIN 번호를 물어보게 되는데 이 때는 ‘1234’를 입력합니다.)</span></p>
<p>3. 버튼을 눌러 정해진 명령대로 스마트카가 움직이는지 확인 (전진 버튼을 누르면 ‘1’, 좌회전을 버튼을 누르면 ‘2’, 정지 버튼을 누르면 ‘3,’ 우회전 버튼을 누르면 ‘4’, 후진 버튼을 누르면 ‘5’ 값이 스마트폰 → JMOD-BT-1 → 아두이노로 전달되고 아두이노는 이 명령어에 해당되는 기능을 수행</p>
<p>진짜 그렇게 되는지 동영상을 보시겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-30.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30523" alt="34 프로젝트 30" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-30.jpg" width="620" height="345" /></a><a href="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-32.jpg" rel="lightbox[30243]"><img class="alignnone size-full wp-image-30525" alt="34 프로젝트 32" src="http://www.ntrexgo.com/wp-content/uploads/2016/01/34-프로젝트-32.jpg" width="620" height="345" /></a></p>
<p><a href="http://serviceapi.nmv.naver.com/flash/convertIframeTag.nhn?vid=692FC5251832776F46E37E48F7778B839E76&amp;outKey=V1224038aa41defe898a3141b435665847e8823f7bae11b25cbdf141b435665847e88&amp;width=720&amp;height=438" target="_blank">동영상 보러가기</a><br />
와우, 보리(Bory) 스마트카가 제대로 움직입니다!!<br />
내가 조종하는대로 막 가네요.!<br />
여러분의 스마트카도 여러분의 의도대로 잘 움직이나요?<br />
그렇다구요?<br />
예, 모두들 잘 되었습니다. 축하드립니다.<br />
만약 혹시라도 잘 안되신 분들은 선 연결이나 조립, 프로그램에 문제가 없는지 차근차근 다시 점검하고 수정한다면 모두들 잘 되시리라 생각합니다.</p>
<p>오늘은 [스마트폰으로 조종하는 스마트카]를 DIY하여 보았는데요.<br />
오늘의 강좌를 마지막으로 이번 [너무 쉬운 아두이노 DIY] 강좌 전체를 마칩니다. 그동안 이 강좌를 사랑해주시고 성원해주신 여러분께 진심으로 감사의 말씀을 드리며, 다음에 좋은 인연으로 다시 만날 수 있기를 희망하겠습니다.<br />
여러분, 2016년 새해 복 많이 받으십시오. 감사합니다.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/30243/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[33호]너무 쉬운 아두이노 DIY ⑤ &#8211; 캐롤송 카드 &amp; 컬러링 온도계</title>
		<link>http://www.ntrexgo.com/archives/29852</link>
		<comments>http://www.ntrexgo.com/archives/29852#comments</comments>
		<pubDate>Thu, 15 Oct 2015 07:54:25 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[33호]]></category>
		<category><![CDATA[Projects to build]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[아두이노]]></category>
		<category><![CDATA[캐롤송]]></category>
		<category><![CDATA[컬러링]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=29852</guid>
		<description><![CDATA[디바이스마트매거진 33호 &#124; 너무 쉬운 아두이노 DIY 5번째 이야기! 연말(年末)을 즐겁게 마무리하는 의미로 오늘은 다가오는 크리스마스에 사용할 멋진 캐롤송 카드와 집안에 장식하면 좋을 듯한 컬러링 온도계를 만들어보도록 하겠습니다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/Cap-2016-01-15-16-19-06-424.jpg" rel="lightbox[29852]"><img alt="Cap 2016-01-15 16-19-06-424" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/Cap-2016-01-15-16-19-06-424-620x180.jpg" width="620" height="180" /></a></p>
<p><span style="font-size: large; color: #000080;"><strong>너무 쉬운 아두이노 DIY ⑤</strong></span></p>
<p><span style="font-size: medium; color: #000080;">캐롤송 카드 &amp; 컬러링 온도계</span></p>
<p style="text-align: right;">글 | 신상석 ssshin@jcnet.co.kr</p>
<p> <div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>이 강의는 아두이노를 가지고 간단하게 생활에 필요한 용품을 만들어 보는 강의입니다. 뚝딱뚝딱 뭔가 자신만의 DIY 용품을 만들어 보는 쏠쏠한 재미가 있는 강의라고나 할까요? 이미 주변에 아두이노와 관련한 많은 책이 출간되었고 카페나 블로그를 통하여 강의가 진행된 경우도 꽤나 많이 있는데도 불구하고, 이 지면을 통하여 강의를 개설한 이유는 다음과 같습니다.</p>
<p>1. 아두이노의 초보자들을 위한 쉽고 재미있는 강의가 거의 없는 것 같아, 가능하면 초등학생(?)까지도 함께 해 볼 수 있는 그런 강의를 한 번 해보고 싶어서…<br />
2. 아두이노를 가지고 뭔가 조금은 다른, 자신만의 창의적인(?) DIY를 할 수 있는 자리를 만들어주고 싶어서…<br />
3. 디바이스마트매거진은 임베디드와 관련된 독자들이 많고, 발행 부수도 많아, 저와 제가 속한 회사(제이씨넷) 그리고 임베디드홀릭 카페의 홍보에 도움이 될 것 같아서…</p>
<p>현재 구상하고 있는 회차별 내용을 간략하게 정리해 보면 다음과 같습니다. (변경될 수 있습니다.)</p>
<table style="border: 1px solid #e2dee2; width: 340px;" border="1" cellspacing="0" cellpadding="1">
<tbody>
<tr>
<td style="text-align: center;">회차</td>
<td>내용</td>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td>3색 신호등 만들기</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td>카멜레온 반지, 스위치를 이용한 신호등 게임기</td>
</tr>
<tr>
<td style="text-align: center;">3</td>
<td>FND로 만드는 디지털전압계, 카운트다운 계수기</td>
</tr>
<tr>
<td style="text-align: center;">4</td>
<td>어두워지면 켜지는 정원등, 공중회전그네</td>
</tr>
<tr>
<td style="text-align: center;">5</td>
<td>캐롤송 카드, 컬러링 온도계</td>
</tr>
<tr>
<td style="text-align: center;">6</td>
<td>스마트폰으로 조정하는 스마트카</td>
</tr>
</tbody>
</table>
<p>앞으로 즐겁고 알찬 강의가 될 수 있도록 최선을 다할 것을 약속 드리며, 이 강의를 보는 독자들도 메일이나 카페를 통하여 Q&amp;A(Question &amp; Answer)나 피드백을 주셔서, 함께 정감을 나눌 수 있는 계기가 되기를 기대해 봅니다.<br />
</div>
<p>여러분, 안녕하세요. 날씨가 많이 추워지고 있습니다. 눈의 계절 겨울이 시작되고 있고, 2015년도 저물어가고 있습니다. 연말(年末)을 즐겁게 마무리하는 의미로 오늘은 다가오는 크리스마스에 사용할 멋진 캐롤송 카드와 집안에 장식하면 좋을 듯한 컬러링 온도계를 만들어보도록 하겠습니다. 카드를 열면 신나는 징글벨 음악이 나오는 캐롤송 카드를 예쁘게 만들어서 사랑하는 연인에게 선사하고, 실내 온도가 낮아지거나 높아지면 경보음이 울리는 컬러링 온도계를 만들어서 거실에 설치해 보세요~재미있을 것 같죠?</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 소리   </strong></span></p>
<p>아두이노를 가지고 소리를 내고 음악을 연주하기 전에 일단 소리에 대하여 간단히 알아보고 가겠습니다. 소리는 공기를 진동시켜 생성된 압력파가 귀의 고막으로 전달되어 감지되는 것인데요. 보통은 일정한 주파수를 갖는 정현파(正弦波, 사인파) 형태로 나타냅니다. 전자회로로 소리를 생성할 때는 디지털 주기 파형으로 HIGH값과 LOW값을 순간적으로 바꾸는 형태이므로 정현파가 아니라 구형파(矩形波, 사각파) 형태가 되는데 이 구형파는 정현파에 비하여 소리가 날카롭고 귀에 거슬리는 단점이 있습니다. 아두이노의 경우, DAC(Digital Analog Converter, 디지털-아날로그 변환기)를 내장한 아두이노 두에(DUE)를 제외한 다른 아두이노는 오직 구형파 형태만 생성할 수 있습니다. 우리가 가지고 있는 아두이노 UNO도 그러니까 구형파만 만들 수 있는 것이지요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-1.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30136" alt="33 아두이노  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-1.bmp" width="431" height="95" /></a></p>
<p>소리를 구분 짓는 요소는 크게 3가지가 있는데, 그것은 높이, 세기, 맵시(소리의 3요소라 함)입니다. 소리의 높이는 보통 음계로 나타내는데, 진동수(주파수)가 많아지면(높아지면) 높은 음의 소리가 나게 됩니다. 소리의 세기는 보통 데시벨(dB)로 나타내는데, 진폭(파고)이 클 수로 큰(센) 소리가 되겠습니다. 마지막으로 소리의 맵시는 파형의 형태로 구분되는데, 소리를 생성한 소스(원인)에 따라 소리의 생긴 모양(파형)이 다르게 나타나는 것으로, 맵시가 다르기 때문에 같은 높이의 같은 세기의 소리라도 피아노 소리와 바이올린 소리는 구별이 되는 것입니다. 아래 그림을 보면 이해가 조금 더 쉽게 될 것 같네요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-2.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30140" alt="33 아두이노  (2)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-2.bmp" width="517" height="283" /></a></p>
<p>&nbsp;</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 삐에조 버저    </strong></span></p>
<p>소리에 대한 기초를 공부했으니까, 이번에는 소리를 만들어내는 도구인 버저(buzzer)에 대하여 알아보겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-3.bmp" rel="lightbox[29852]"><img class="alignnone size-large wp-image-30143" alt="33 아두이노  (3)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-3.bmp" /></a></p>
<p>버저는 전자석의  코일에 단속적(斷續的)으로 전류를 보내어 철판 조각을 진동시켜 내는 소리 생성 장치를 말합니다. 소리를 내는 원리는 아래와 같이 소리를 내는 철편이 전자석 근처에 있어서 전자석에 전류를 흘리면 전자석이 철편을 잡아당겨 붙게 되면서 소리가 나는 것이지요. 이렇게 전류를 흘렸다 끊었다 하는 동작을 1초에 몇 번 수행하는가에 따라, 주파수를 높이면 높은 음의 소리가 나게 되고 주파수를 낮추면 낮은 음의 소리가 나게 되는 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-4.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30146" alt="33 아두이노  (4)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-4.bmp" width="477" height="136" /></a></p>
<p>한편, 우리는 삐에조 버저를 사용할 것인데, 이것은 압전 현상을 이용한 것입니다. 석영(quartz)이나 세라믹과 같은 물질에 전압을 가하면 물체에 변형(늘어짐과 수축)이 생기게 되는데 이를 이용하면 공기를 진동시켜 소리를 낼 수 있습니다. 아래 왼쪽 그림은 삐에조 버저를 분해하여 본 것인데, 둥그런 판처럼 생긴 것은 수정진동자를 포함하여 2개의 서로 다른 물질이 접착된 원형 판입니다. 전원을 가하거나 끊게 되면 석영 판이 늘어나거나 수축되어 원형 판이 아래 오른쪽 그림과 같이 굽혀졌다 펴졌다 하면서 공기를 진동시켜 소리가 나게 되는 것입니다.</p>
<table style="width: 620px;" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td><img class="alignnone  wp-image-30149" alt="33 아두이노  (5)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-5.bmp" width="275" height="216" /></td>
<td><a style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px;" href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-6.bmp" rel="lightbox[29852]"><img class="alignnone size-large wp-image-30152" alt="33 아두이노  (6)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-6.bmp" /></a></td>
</tr>
</tbody>
</table>
<p>삐에조 버저도 종류가 여러가지 있지만 여기서는 간단한<a href="http://www.devicemart.co.kr/32839"> BPE-1404P-40</a>의 규격을 간단히 살펴보고 가겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-2.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30142" alt="33 아두이노  (2)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-2.png" width="386" height="120" /></a></p>
<p>5V를 연결해주고, 4000Hz 근처의 주파수를 삐에조 버저 양단에 걸어주면 약 80 데시벨(dB) 정도 크기의 소리가 날 것 같네요. 사람들이 보통 이야기하는 소리의 크기가 약 50~60 데시벨(dB) 정도이고, 청소기 돌리는 소리가 70~80 데시벨(dB) 정도라고 하니 거리가 떨어져 있다 해도 동작시키면 꽤나 큰 소리가 들릴 것 같습니다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 삐 ~ 소리내기    </strong></span></p>
<p>이 정도면 기초 지식은 갖추었으니, 삐에조 버저로 소리를 내 보도록 하겠습니다. 일단은 욕심 부리지 말고 “삐~” 소리를 4000Hz의 소리로 내 보겠습니다.<br />
아두이노는 좋은 것이, 이렇게 보편적으로 필요로 할 것 같은 기능은 거의 다 함수(라이브러리)로 만들어 놓았다는 것입니다. 버저도 예외는 아니어서 아두이노는 소리를 내는 함수로 tone( )이라는 아주 편리한 함수를 제공합니다. 아래 내용을 보시지요.</p>
<p style="padding-left: 60px;"><span style="color: #008000;">tone(pin, frequency, duration)</span><br />
<span style="color: #008000;"> &#8211; pin : 소리를 출력할 핀 번호</span><br />
<span style="color: #008000;"> &#8211; frequency : 출력할 소리의 주파수</span><br />
<span style="color: #008000;"> &#8211; duration : 출력할 소리의 지속 시간(ms), 인수를 생략하는 경우는 noTone() 함수를 호출하기 전까지 소리 출력이 계속됨</span></p>
<p>여기서 주의하셔야 하는 것은 tone 함수를 사용하여 버저를 제어할 경우, 버저는 반드시 PWM(Pulse Width Control)이 가능한 핀에 연결하여야 한다는 것입니다(아두이노에서 PWM이 가능한 핀은 핀 번호에 물결 표시(‘~’)가 있음).<br />
예를 들어 5번 핀에 삐에조 버저를 연결하고, tone(5, 4000, 3000) 을 실행하면 4000Hz의 소리가 3000ms(3초) 동안 생성되겠습니다. 이거야 정말 쉽네요. 벌써 해답이 나와 버렸습니다. 바로 해 봐야겠죠?</p>
<p><strong>[아두이노 연결]</strong><br />
아두이노 연결은 아래와 같습니다. 연결이 너무 간단하여 설명이 필요 없겠습니다. 삐에조 버저의 (+) 부분은 PWM 제어가 가능한 5번핀에 연결하고, (-) 부분은 GND에 연결하면 끝! 와우~ 정말 쉽다!</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-7.bmp" rel="lightbox[29852]"><img class="alignnone size-large wp-image-30155" alt="33 아두이노  (7)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-7.bmp" /></a></p>
<p><strong>[알고리즘]</strong><br />
구현한 규격은 조금 전에 예로 들었던, 4000Hz 음높이로 삐~ 소리를 3초간 내는 것으로 합니다. 알고리즘이라고 할 것도 없지만 굳이 형식을 취한다면 이렇게 되겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-1.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30139" alt="33 아두이노  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-1.png" width="441" height="91" /></a></p>
<p><strong>[스케치 프로그램]</strong><br />
자, 그럼 프로그램을 작성해 보시지요.</p>
<p>너무 쉬워서 바로 갑니다.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define PIEZO 5</p>
<p>void setup()<br />
{<br />
pinMode(PIEZO, OUTPUT); // PIEZO 버저 핀은 출력<br />
}</p>
<p>void loop()<br />
{<br />
tone(PIEZO, 4000, 3000); // 4Khz(4000) 주파수로 3초(3000) 동안 출력<br />
delay(3000); // tone 함수 자체는 시간을 소모(delay)하지 않음<br />
while(1) ; // 3초후 정지, 다시 시작하려면 RESET 버튼을 누름<br />
}</p>
</div>
tone() 함수 자체는 시간을 소모하지 않고 내부적으로 Timer/Counter를 사용하여 파형을 만드는 것이므로 소리가 날 동안 다른 일을 진행하지 않을 것이면 delay()를 주어서 동기를 맞추어 줄 필요가 있다는 것만 조심하면 될 듯 합니다.<br />
바로 실행시켜 보겠습니다.</p>
<p><span style="font-size: large; color: #ff0000;">삐&#8211;</span></p>
<p>와~ 소리가 잘 나네요.(한 번 더 실행해 보려면 아두이노의 RESET 버튼을 누르면 됩니다!)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-13.jpg" rel="lightbox[29852]"><img class="alignnone  wp-image-30170" alt="33 아두이노  (13)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-13-620x316.jpg" width="434" height="221" /></a></p>
<p><a href="https://www.youtube.com/watch?v=MngcqOZq5IA">동영상 보러가기</a></p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 음계      </strong></span></p>
<p>일단 한 걸음을 내디뎠으니 반은 온 것이나 다름 없습니다. 본격적으로 캐롤송 노래 연주를 위한 작업에 들어가야 하는데, 일단, 연주를 하려면 음계를 알아야 하니까 이것부터 해결하고 가지요.<br />
음계는 “음악에 쓰이는 음을 높이의 차례대로 배열한 음의 층계”(두산백과사전)라고 사전에 정의되어 있습니다. 쉽게 말해서 “도, 레, 미, 파, 솔, 라, 시, 도”를 말하는 것이지요. 기본 음의 주파수는 세계적으로 표준 주파수가 이미 정해져 있습니다. 예를 들어 6번째 옥타브의 주파수는 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30179" alt="33 아두이노" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-620x91.png" width="434" height="64" /></a></p>
<p>아래쪽 ‘도’와 위쪽 ‘도’의 주파수를 비교해 보면 주파수가 2배 차이가 나는 것을 알 수 있지요. 어쨌든 음계에 따라 주파수가 정해져 있으므로 우리가 원하는 노래의 음계를 안다면, 당연히 주파수를 알 수 있고, 주파수를 안다면 그 주파수를 tone( ) 함수를 이용하여 음의 길이만큼만 실행하면 원하는 노래를 연주할 수 있을 것 같습니다. 그렇다면, 음계와 음의 길이는 악보를 찾으면 되고, 음계에 해당되는 주파수만 찾으면 되는데, 이건 당연히 … 누군가가 정리해 놓았겠죠?</p>
<p>맞습니다. 아두이노 예제에서 pitches.h 라는 파일을 제공하는데 여기에 각 음계에 해당되는 주파수가 모두 정의되어 있답니다. 위의 6번째 옥타브에 해당되는 것만 살펴보면 요렇게 …</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define NOTE_C6 1047 // 도 (6옥타브)<br />
#define NOTE_CS6 1109<br />
#define NOTE_D6 1175 // 레 (6옥타브)<br />
#define NOTE_DS6 1245<br />
#define NOTE_E6 1319 // 미 (6옥타브)<br />
#define NOTE_F6 1397 // 파 (6옥타브)<br />
#define NOTE_FS6 1480<br />
#define NOTE_G6 1568 // 솔 (6옥타브)<br />
#define NOTE_GS6 1661<br />
#define NOTE_A6 1760 // 라 (6옥타브)<br />
#define NOTE_AS6 1865<br />
#define NOTE_B6 1976 // 시 (6옥타브)<br />
#define NOTE_C7 2093 // 도 (7옥타브)</p>
</div>
<p>위의 표보다 음의 개수가 많은 것은 반음에 해당되는 것도 모두 정의되어 있기 때문인데, 하나씩 비교하여 보면 똑같다는 것을 알 수 있습니다. 음. 그럼, 이 pitches.h 파일만 include 하여 프로그램을 작성하면 되니까 이제 프로그램 작성 준비도 모두 마친 것 같습니다.<br />
알고 보면 별 것 아니죠?</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 캐롤송 카드     </strong></span></p>
<p>자, 이제 준비가 다 되었으니 오늘의 메인 메뉴인 DIY 캐롤송 카드를 만들어 봅시다. GO, GO~ 먼저 기능 규격부터 살펴봅니다.</p>
<p><strong>[기능 규격]</strong></p>
<p>카드를 열면 3초 후에 징글벨 노래가 나오는 캐롤송 카드 만들기</p>
<p>이번엔 어떻게 구현하면 될 지 방법을 잠시 생각해 보겠습니다.</p>
<p><strong>[구현 방법]</strong></p>
<p>(1) 아두이노 PWM 핀에 삐에조 버저의 (+) 단자를, GND에 (-) 단자를 연결하고, PWM을 이용하여 ‘징글벨’ 음계에 해당되는 주파수를 음표 길이에 해당하는 시간만큼 연이어서 출력<br />
(2) 음계에 해당되는 파일은 아두이노에 이미 “pitches.h”이 존재하므로 이를 include 하여 사용<br />
(3) 크리스마스 카드를 만들거나 준비한 후 카드 양단에 전도성 패드를 붙이고 한쪽은 아두이노의 RESET 신호를, 다른 한 쪽은 GND에 연결해 놓고, 카드가 접혀져 있는 상태에는 두 신호가 연결되도록 함 (클립 등으로 접함, RESET 상태)<br />
(4) 카드가 열리면 RESET 신호가 단락되도록 하여 아두이노가 실행되면서 3초후에 징글벨 노래가 연주됨</p>
<p><strong>[알고리즘]</strong></p>
<p>정리된 알고리즘은 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-3.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30145" alt="33 아두이노  (3)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-3.png" width="441" height="139" /></a></p>
<p><strong>[아두이노 연결]</strong><br />
크리스마스 카드와 아두이노, 버저의 연결 방법은 다음과 같이 되겠네요~</p>
<p>(1) 지난번 버저를 연결한 형태에 추가하여, RESET 핀과 GND 핀을 점퍼선으로 끌어내어 카드가 서로 겹치는 부분에 테이프 등을 이용하여 끝을 X자 형태가 되도록 부착<br />
(2) 카드를 접어서 RESET 점퍼선과 GND 점퍼선이 서로 단락이 되도록 하고 이 부분을 클립 등을 이용하여 고정</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-8.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30158" alt="33 아두이노  (8)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-8.bmp" width="498" height="297" /></a></p>
<p><strong>[스케치 프로그램]</strong><br />
자, 그럼 아래의 징글벨 노래 악보를 보면서 프로그램을 작성해 봅시다.<br />
길이가 길어서 저는 첫번째 줄 악보만 입력하겠으니 여유가 조금 있으신 분들은 나머지 음계를 모두 채워서 프로그램 해보시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-9.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30161" alt="33 아두이노  (9)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-9.bmp" width="422" height="323" /></a></p>
<p>&nbsp;</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include “pitches.h”<br />
#define PIEZO 5</p>
<p>// 징글벨 첫 소절 음계 : 알기 쉽게 다장조의 음계로 변환하여 처리<br />
int song[ ] = { NOTE_G4, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_G4, 0, // 솔미레도솔(쉼표)<br />
NOTE_G4, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_A4, 0, // 솔미레도라(쉼표)<br />
NOTE_A4, NOTE_F5, NOTE_E5, NOTE_D5, NOTE_B4, 0, // 라파미레시(쉼표)<br />
NOTE_G5, NOTE_G5, NOTE_F5, NOTE_D5, NOTE_E5, NOTE_C5, 0 }; // 솔솔파레미도(쉼표)</p>
<p>// 징글벨 첫 소절 연주시간<br />
int time[ ] = { 250, 250, 250, 250, 750, 250, // 8분음표 = 250ms<br />
250, 250, 250, 250, 750, 250,<br />
250, 250, 250, 250, 750, 250,<br />
250, 250, 250, 250, 500, 250, 250 };</p>
<p>void setup() // 한 번만 연주하게 하기 위하여<br />
// 실행 프로그램을 setup()에서 처리<br />
{<br />
int i;<br />
pinMode(PIEZO, OUTPUT); // PIEZO 버저핀은 출력<br />
delay(3000); // 카드를 열고 3초후에 연주 시작<br />
for (i=0; i&lt;25; i++) // 연주 길이만큼 숫자 조정<br />
{<br />
tone(PIEZO, song[i], time[i]); // 배열순으로 노래 재생<br />
delay(time[i]);<br />
}<br />
}</p>
<p>void loop() // 한 번만 연주하게 하기 위하여<br />
{ // loop()에서는 아무 것도 처리하지 않음<br />
}</p>
</div>
<p>&nbsp;</p>
<p>노래는 한 번만 들으면 되므로 loop()가 아닌 setup() 내부에 프로그램한 점이 예전 것과 약간 다르며, 만약 연주가 반복되게 하려면 loop() 내부에 프로그램을 넣으면 됩니다.<br />
한편, 프로그램 실행시 한가지 주의할 점은 pitches.h 파일을 추가하는 방법인데, pitches.h 파일은 다음과 같은 방법으로 현재 실행 디렉토리에 가져와야 합니다. (그냥 임의로 파일을 옮겨 놓으면 에러가 발생하므로 주의!)</p>
<p>(1) 프로그램에서 [스케치] ▶ [파일추가] 메뉴 선택<br />
(2) 파일 대화 상자가 나오면 “C:\Program Files(x86)\Arduino\examples2.Digital\toneKeboard\pitches.h”를 선택하여 추가<br />
(3) 새로운 탭이 열리면서 현재 실행 디렉토리에 pitches.h 파일이 자동으로 생성됨<br />
(4) 이 상태에서 컴파일 후 업로드 실행</p>
<p>자, 어떻게 되었나요? 캐롤송이 잘 나오나요? 브라보!!! 라구요?</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-14.jpg" rel="lightbox[29852]"><img class="alignnone  wp-image-30172" alt="33 아두이노  (14)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-14-620x319.jpg" width="496" height="255" /></a></p>
<p><a href="https://www.youtube.com/watch?v=Ln_EEmGS5vM">동영상 보러가기</a></p>
<p>눈도 오고 흥겨운 캐롤송도 나오고, 기분도 UP되는 크리스마스와 연말연시를 기대해 봅니다.<br />
Merry Christmas &amp; Happy New Year!</p>
<p>이제, 두번째 DIY 작품을 만들어 보기 전에 잠시 휴식을 취하겠습니다.<br />
각자 나름대로 스트레칭도 하고, 바깥의 신선한 공기도 마신 후 다시 시작하시지요. 모두 휴식~!</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 온도 센서    </strong></span></p>
<p>오늘의 두번째 DIY 주제는 “경보 장치가 내장된 컬러링 온도계”입니다.<br />
컬러 LED를 이용하여 현재의 온도를 색깔로 나타내주고, 설정 온도 범위를 벗어나면 주기적으로 버저를 울려주는 온도계를 만들어 안방이나 거실에 장착해 보는 것으로 하겠습니다.<br />
온도센서는 영어로는 Thermistor라고 하는데, 이것은 니켈이나 코발트, 구리, 철 등의 화합물로 이루어진 물질을 이용하여 온도를 측정하는 센서입니다. 보통 이 물질은 아래 그림과 같이 온도가 높아지면 저항값이 내려가고, 온도가 내려오면 저항값이 올라가는 특성을 가지는데 이러한 성질을 잘 이용하면 온도를 측정할 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-10.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30163" alt="33 아두이노  (10)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-10.bmp" width="233" height="148" /></a></p>
<p>예를 들어, 어떤 Thermistor 저항은 100°C 경우 1KΩ 이하, 0°C 경우 15KΩ 정도, -10°C 경우 25KΩ 정도가 됩니다.<br />
온도값에 따라 저항값이 달라진다면, 예전에 이와 비슷한 성질을 갖는 센서가 있었는데…<br />
예. 광센서! 빛의 세기에 따라 저항값이 달라지는 물질이었죠.<br />
이것을 아래와 같이 연결한 후 “? V” 에 해당되는 지점을 아두이노의 ADC 포트(A0)에 연결한 후 이 값을 측정하면 광량을 측정할 수 있었습니다. 기억나시나요? 안난다면… 다시 복습! Back to the Future!</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-3.jpg" rel="lightbox[29852]"><img class="alignnone  wp-image-30144" alt="33 아두이노  (3)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-3.jpg" width="441" height="170" /></a></p>
<p>그렇다면 이번에도 이와 비슷하게 아래와 같이 Thermistor를 연결하면 예전과 마찬가지로 측정이 가능하지 않을까요?</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-4.jpg" rel="lightbox[29852]"><img class="alignnone  wp-image-30147" alt="33 아두이노  (4)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-4.jpg" width="496" height="151" /></a></p>
<p>예. 맞습니다. 원리가 같으니까 예전처럼 하면 되겠습니다. 온도센서가 아날로그 온도센서인 경우에는 그냥 이렇게 처리하면 되겠습니다.<br />
그런데 한가지 더 생각해 볼 것은 아날로그 온도센서의 경우는 위에서 본 것과 같이 온도 변화에 따른 저항값이 선형적이지 않게 변화되므로 사용자가 이를 고려하여 프로그램하는 것이 매우 귀찮고 쉽지 않은 작업이라는 것입니다. 그리고 또 하나는 라즈베리파이 같이 ADC 포트가 아예 없는 마이크로콘트롤러들도 있습니다. 그래서 온도의 정확도도 높이고, 인터페이스도 단순하게 만든 디지털 온도센서가 출현하게 되었는데(물론 이것도 내부적으로는 아날로그 온도센서를 내장하고 있습니다.) 그 형태는 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-5.jpg" rel="lightbox[29852]"><img class="alignnone  wp-image-30150" alt="33 아두이노  (5)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-5.jpg" width="496" height="130" /></a><br />
내부에 디지털로직이 함께 결합되어 외부와는 UART(Universal Asynchronous Receiver/Transmitter)나 I2C(Inter Integrated Circuit), SPI(Serial Pheriperal Interface)와 같은 시리얼통신 인터페이스를 통하여 아두이노 내부의 마이크로콘트롤러에 연결되는 것이고, 이를 통하여 측정된 온도값이 전달되는 것입니다.<br />
온도센서 모듈은 여러가지가 있지만 오늘은 I2C 통신 인터페이스를 제공하는 제이씨넷사의 JMOD-TEMP-1 디지털 온도센서를 사용하여 DIY 설계를 진행해 보겠습니다. JMOD-TEMP-1 디지털 온도센서 모듈을 사용하기 위하여는 일단 I2C에 대하여 먼저 알아야 하기 때문에, 이것부터 먼저 간단히 공부해 봅시다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ I2C 통신 프로토콜    </strong></span></p>
<p>I2C는 “I Square C”라고 발음하는데, Philips 사가 1980년에 제안한 근거리용 직렬 동기식 양방향 통신 규격을 말합니다. SCL(Serial Clock, 마스터 제공 클록), SDA(Serial Data, 마스터와 슬레이브가 공유하는 데이터)의 2개 신호만 사용하여 통신하며, 최대 128개의 기기(센서 등)를 연결할 수 있는데 통신 속도는 100kbps, 400kbps, 3.4Mbps의 3가지가 대표적입니다.<br />
연결된 모습을 보면 아래와 같습니다. SDA와 SCL 신호는 Open Drain/Open Collector 방식으로 연결되기 때문에 풀업 저항(R1, R2)을 장착해 주어야 하며 저항값은 보통 10KΩ 이상입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-6.jpg" rel="lightbox[29852]"><img class="alignnone  wp-image-30153" alt="33 아두이노  (6)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-6.jpg" width="441" height="200" /></a></p>
<p>아두이노를 연결하는 경우 I2C 통신 프로토콜에 대하여 자세하게 알아야 할 필요는 없지만, 어느 정도는 원리를 이해하는 것이 도움이 될 것 같아 조금만 더 설명하도록 하겠습니다. 이 부분이 너무 어려운 분들은 세부적인 내용을 이해하지 않아도 되며, 다만, 이러한 일을 실행해야만 통신이 이루어진다는 점만 이해하고 넘어가셔도 되겠습니다.<br />
아래 그림은 I2C 통신 규격입니다. WRITE는 마스터(예-아두이노)가 슬레이브(예-온도센서)에게 데이터(예-명령어)를 전달할 때의 규격이고 READ는 마스터(예-아두이노)가 슬레이브(예-온도센서)로부터 데이터(예-온도값)를 전달받을 때의 규격입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-11.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30165" alt="33 아두이노  (11)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-11.bmp" width="442" height="188" /></a></p>
<p>(WRITE)일 때의 동작을 간단히 설명해 보면, 다음과 같습니다.</p>
<p style="padding-left: 30px;">1. 마스터는 START 신호 생성<br />
2. 마스터는 통신하고자 하는 슬레이브 어드레스(7비트) + READ/WRITE 상태(1비트, 1이면 READ, 0이면 WRITE, 여기서는 WRITE이므로 1)의 총 8비트 생성<br />
3. 2번 과정에서 생성한 슬레이브 어드레스에 해당되는 슬레이브가 ACKNOWLEDGE 신호 생성(해당 슬레이브가 없으면 ACKNOWLEDGE가 생성되지 않음-에러)<br />
4. 마스터는 슬레이브에 전달하고자 하는 데이터값(예-명령어) 생성<br />
5. 슬레이브는 데이터값을 취한 후 ACKNOWLEDGE 생성(이후 다수의 데이터가 필요한 경우 4번, 5번 과정을 필요한 만큼 반복, 마지막은 ACKNOWLEDGE를 생성하지 않을 수도 있음)<br />
6. 마스터는 STOP 신호 생성</p>
<p>(READ)일 때의 동작을 간단히 설명해 보면, 다음과 같습니다.</p>
<p style="padding-left: 30px;">1. 마스터는 START 신호 생성<br />
2. 마스터는 통신하고자 하는 슬레이브 어드레스(7비트) + READ/WRITE 상태(1비트, 1이면 READ, 0이면 WRITE, 여기서는 READ이므로 0)의 총 8비트 생성<br />
3. 2번 과정에서 생성한 슬레이브 어드레스에 해당되는 슬레이브가 ACKNOWLEDGE 신호 생성(해당 슬레이브가 없으면 ACKNOWLDEGE가 생성되지 않음-에러)<br />
4. 슬레이브는 마스터에게 전달하고자 하는 데이터값(예-온도값) 생성<br />
5. 마스터는 데이터값을 취한 후 ACKNOWLEDGE 생성(이후 다수의 데이터가 필요한 경우 4번, 5번 과정을 필요한 만큼 반복, ACKNOWLEDGE를 생성하지 않음)<br />
6. 마스터는 STOP 신호 생성</p>
<p>여기서 START 신호와 STOP 신호, 데이터 전송값 등을 전달하는 방법은 앞서 이야기한 대로 SCL 및 SDA 신호를 아래와 같은 형태로 생성하여 처리합니다. 이해가 조금 어려운 분들은 너무 고민하지 마시고, “그냥 그렇게 된다는구만~~~” 하고 넘어가셔도 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-12.bmp" rel="lightbox[29852]"><img class="alignnone size-large wp-image-30167" alt="33 아두이노  (12)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-12.bmp" /></a></p>
<p>어쨌든 결론은 이러한 I2C 통신 방법을 이용하면 아두이노가 I2C 인터페이스를 제공하는 온도센서에게서 온도값을 읽어올 수 있다는 것이지요. 얼추~ 이해는 되셨죠? 그럼, 얼른 다음으로 넘어가 봅시다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ JMOD-TEMP-1    </strong></span></p>
<p>백그라운드 지식을 갖추었으니 이제 우리가 타겟으로 삼은 JMOD-TEMP-1 온도센서에 대하여 알아봅시다.<br />
사용자 설명서에 의하면 JMOD-TEMP-1 규격은 아래와 같습니다.</p>
<p>· LM75A 온도센서를 기본으로 한 I2C 디지털 온도센서 모듈<br />
· 측정 범위 : -55° ~ 125°C<br />
· 동작 전압 : 2.7V ~ 5.5V<br />
· 아두이노나 AVR과의 연결이 쉬운 소켓핀 타입의 I2C 인터페이스 제공<br />
· SDA 및 SCL 신호에 pullup 저항 제공<br />
· 내부 어드레스 A6~A3은 “1001”로 정해져 있으며, 어드레스 신호(A2, A1, A0) 값은 0과 1의 값을 선택할 수 있도록 선택용 점퍼 제공(예를 들어 점퍼를 모두 연결하면 A6~A0는 0b1001111=0x4F가 되고, 점퍼를 하나도 연결하지 않으면 A6~A0는 0b1001000=0&#215;48이 됨)</p>
<p>외관은 아래와 같이 생겼습니다. 실제 크기는 엄지 손톱 크기 정도로 작습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-13.bmp" rel="lightbox[29852]"><img class="alignnone size-large wp-image-30169" alt="33 아두이노  (13)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-13.bmp" /></a></p>
<p>배치도를 이용하여 자세히 살펴보면 아래와 같습니다. I2C 인터페이스이므로 당연히 SCL, SDA을 아두이노에 연결해야 하고, 부가적으로 VCC(+5V)와 GND도 함께 연결해 주어야 함은 물론입니다. O.S 신호는 여기서는 사용하지 않으므로 O.S 신호를 제외한 아래 4개의 신호만 아두이노와 전선으로 연결해주면 되겠습니다. 또한, A2~A0 점퍼의 장착 여부에 따라 JMOD-TEMP-1의 슬레이브 어드레스가 결정되므로 이것은 사용자가 결정하여야 합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-4.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30148" alt="33 아두이노  (4)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-4.png" width="446" height="180" /></a></p>
<p>다른 것은 생각하지 않고, 아두이노와 JMOD-TEMP-1과의 연결만을 나타내보면 아래와 같습니다.</p>
<p><strong>[아두이노 연결]</strong><br />
1. JMOD-TEMP-1은 VCC(+5V), GND, SCL, SDA 신호를 해당되는 아두이노 신호와 연결<br />
2. SCL은 아두이노의 A5 핀에, SDA는 아두이노의 A4 핀에 연결 (A5, A4 핀은 아두이노가 I2C 통신을 이용하는 경우 각각 SCL, SDA 신호로 고정됨)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-14.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30171" alt="33 아두이노  (14)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-14.bmp" width="427" height="375" /></a></p>
<p>&nbsp;</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 아두이노 ISC 라이브러리    </strong></span></p>
<p>LM75A에 대하여 알아보기 전에, 우리는 아두이노를 사용하여 I2C 통신을 구현하여야 하므로 일단 아두이노에서 I2C 통신을 위하여 제공하는 라이브러리가 어떤 것이 있는지 알아보는 것이 더 좋겠습니다. 왜냐하면, 이것을 알아야 이 라이브러리를 사용하여 LM75A로부터 온도값을 읽어올 스케치 프로그램에 사용할 수 있기 때문입니다. 아래를 보시지요.</p>
<p><strong>[아두이노에서 제공하는 I2C 관련 함수(라이브러리)]</strong></p>
<p style="padding-left: 30px;">· Wire.begin() // I2C 버스 활성화, I2C 버스 사용 처음에 반드시 실행<br />
· Wire.beginTransmission(address); // Start 전송 (버스 시작), address = 슬레이브 어드레스<br />
· Wire.write(data); // Write (데이터값 Write), data = Write할 데이터값(바이트 크기)<br />
· Wire.endTransmission(); // Stop 전송 (버스 종료)<br />
· Wire.requestFrom(address, count); // Read Request (데이터 요청), address = 슬레이브 어드레스, count = 요청하는 데이터의 개수(바이트 수)<br />
· Wire.available() // 데이터 도착 확인, return값 = Read한 데이터 개수<br />
· Wire.read(); // Read (데이터값 입력), return값 = 데이터 값(바이트 크기)</p>
<p>물론 위 라이브러리를 사용하려면, 아두이노 스케치 프로그램의 첫머리에 “#include &lt;Wire.h&gt;”를 넣어주어야 하는 것도 잊지 말아야 합니다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ LM75A 구조 및 동작    </strong></span></p>
<p>JMOD-TEMP-1은 내부에 온도센서 IC 칩인 LM75A를 내장하고 있으므로, 아두이노와 JMOD-TEMP-1과의 동작은 실제로는 아두이노와 LM75A와의 동작을 의미합니다. 그러므로 우리는 이제 LM75A에 대한 정보를 알아야 하겠네요. 아래는 LM75A의 구조입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-15.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30173" alt="33 아두이노  (15)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-15.bmp" width="515" height="339" /></a></p>
<p>VCC, GND 신호는 전원 신호이며, SCL, SDA 신호는 I2C 신호, A2, A1, A0 신호는 LM75A의 슬레이브 어드레스를 결정하는 어드레스 신호임은 앞에서 살펴본 것과 같습니다. A2, A1, A0 신호는 JMOD-TEMP-1 내부에 점퍼를 이용하여 값을 지정해 주는 형태로 구현되어 있으므로(이번 DIY에서는 점퍼를 장착하지 않은 상태로 진행하므로 A6~A0 = 0b1001000 = 0&#215;48 임) 아두이노와의 직접적인 연결 신호는 VCC, GND, SCL, SDA 신호가 되겠습니다.<br />
LM75A는 주기적으로 내부의 아날로그 온도센서의 값을 읽어 이것을 ‘Temperature Register’에 저장하는데, I2C 버스를 통하여 LM75A 내부의 ‘Temperature Register’ 값을 읽어 오려면 아래와 같은 절차를 밟아야 합니다. (LM75A datasheet 참조 요망)</p>
<p>(1) Start (버스 시작) 실행 및 타겟 어드레스 지정<br />
(2) Configuration Register를 지정하는 데이터 값(00)을 Write<br />
(3) Configuration Register가 저장할 값(01 = Temperature Register)을 Write<br />
(4) Stop (버스 종료) 실행<br />
(5) Start (버스 시작) 실행 및 타겟 어드레스 지정<br />
(6) Temperature Register를 지정하는 데이터 값(01)을 Write<br />
(7) Temperature Register로부터 2바이트 데이터를 Read 하고 이 값을 지정<br />
(8) Stop (버스 종료) 실행</p>
<p>구조도를 보면서 보충 설명을 조금 더 하자면, LM75A는 내부에 Pointer Register를 가지고 있는데, 이 Pointer Register에 저장한 값(0&#215;00~0&#215;03)에 따라 순서대로 오른쪽 4개의 레지스터(Configuration Regitser(0&#215;00), Temperature Register(0&#215;01), TOS Register(0&#215;02), THYST Register(0&#215;03)) 중 하나를 지정하게 되고, 이 상태에서 연속하여 데이터를 읽거나(Read) 쓰면(Write), 지정된 레지스터에 대하여 값을 읽거나(Read), 쓰게(Write) 됩니다. 참고로, 세부적인 버스 상의 동작을 그림으로 나타내면 아래와 같습니다. (조금 어렵게 느껴지는 분은 그냥 넘어가셔도 됩니다.)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-17.bmp" rel="lightbox[29852]"><img class="alignnone size-large wp-image-30175" alt="33 아두이노  (17)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-17.bmp" /></a></p>
<p>이제 동작은 알았으니 Configuration Register의 내용과 Temperature Register의 내용이 무엇을 의미하는지만 알면 되겠습니다. 다시 LM75A 데이터시트를 찾아봐야 하겠네요. 아래와 같이 나옵니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-5.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30151" alt="33 아두이노  (5)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-5.png" width="460" height="367" /></a></p>
<p>Nomal 모드로 동작하면 되고(B0 = 0), 다른 값들은 별 의미가 없으니 Configuration Register의 값은 0&#215;00 으로 하면 되겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-6.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30154" alt="33 아두이노  (6)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-6.png" width="460" height="367" /></a></p>
<p>Temp Register 데이터의 값은 11비트로 부호(Sign) 비트 + 7비트 정수 + 3비트 소수 형태를 갖추고 있습니다. 2’s complement 형식으로 표현하고 있으므로 이것을 처리하면 순수 온도를 표시할 수 있을 것 같습니다. 여기서 2’s complement 표현 방식이란 음수를 표현할 때, 양수로 표현한 데이터의 complement를 취한 후(2진수로 나타내는 경우 모든 비트의 0과 1을 반대로 1과 0으로 바꿈) 이 값에 1을 더해서 표현하는 방법을 말합니다. 예를 들어 8비트의 표현에서 -3은 양수인 3의 2진값을(0b00000011), complement를 취하고(0b11111100) 여기에 1을 더해서(0b11111101) 표현하는 것입니다. 우리는 소수첫째자리를 0.5 단위까지만 표현하는 것으로 하겠습니다.<br />
오우~, 이제 구현에 필요한 기본적인 백그라운드(Background)는 갖추어진 것 같네요.<br />
그렇다면 최종 목표인 “경보장치가 내장된 컬러링 온도계”를 완성하러 가아죠? 계속 GO~ GO~</p>
<p><span style="color: #ffffff; font-size: medium; background-color: #008000;"><strong>■ 경보장치가 내장된 컬러링 온도계    </strong></span></p>
<p>언제나 그렇듯이 일단 목표(타겟)를 정해야 합니다. 무엇을 만들까? 어떤 기능을 하도록 만들까? 주요 기능 규격에 해당되는 것은 일단 정하고 가는 것이 중요합니다. 자, 정해볼까요?</p>
<p><strong>[기능 규격]</strong><br />
1. 겨울철 실내(생활) 온도에 따라 컬러 LED의 색깔이 변함 (각각의 색깔은 1도 정도의 온도 변화에 따라 단계별로 변하도록 함 (보통 20도 정도가 적당한 온도라고는 하나 약간 추운듯한 느낌이 들고, 체온으로 시험해보기 위해서 아래와 같이 임의로 결정함. 여름철에는 프로그램을 다르게 해야 되겠죠?)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-7.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30157" alt="33 아두이노  (7)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-7.png" width="460" height="160" /></a><br />
2. 5초 마다 온도를 측정하여 온도 변화가 예전 온도와 1도 이상 오르면 높은 음으로 “삐~” 알람을 1초간 울리고, 1도 이상 내리면 낮은 음으로 “삐~” 알람을 1초간 울림<br />
3. 최저온도(24도) 미만이거나 최고온도(29)도 이상이면 높은 음과 낮은 음을 혼합하여 “삐~뽀~삐~뽀~”를 4초간 울림</p>
<p>온도센서 값을 읽어오는 것은 조금 전에 배웠고, 컬러 LED의 색깔을 결정하는 방법과 tone() 함수를 이용하여 소리를 만드는 것은 이전 DIY에서 배웠으니 이것들을 조합하면 해결 방법을 찾을 수 있을 것 같습니다.</p>
<p><strong>[연결도]</strong><br />
사용되는 부품은 아두이노 외에 3색 LED, 삐에조버저, 온도센서가 있으면 되겠네요. 3색 LED는 공통 캐소드 타입을 사용하고(RGB 핀 번호는 3색 LED마다 다를 수 있으니 각 모듈마다 확인 후 사용 요망), 버저는 삐에조버저를, 온도센서는 JMOD-TEMP-1 모듈을 사용하는 것으로 하면, 연결도는 아래와 같이 될 것 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노26.bmp" rel="lightbox[29852]"><img class="alignnone  wp-image-30181" alt="33 아두이노26" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노26.bmp" width="379" height="267" /></a></p>
<p><strong>[알고리즘]</strong><br />
자, 이제 어떻게 위의 기능을 구현할 지 찬찬히 생각해봐야 할 때입니다. 일단, 온도센서로 온도를 재고, 여기에 대응되는 색깔을 찾아서 이것을 3색 LED에 디스플레이 하고, 이전(5초전)에 잰 온도보다 1도 이상 온도가 올라갔거나 내려갔으면 “삐~” 알람을 울리고, 마지막으로 온도가 24도 보다 작거나 29도 보다 크면 “삐~뽀~삐~뽀~” 알람을 울리면 되겠네요. 다시 정리해 보면 아래와 같이 되겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-8.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30160" alt="33 아두이노  (8)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-8.png" width="460" height="276" /></a><br />
자, 그러면 차근차근 하나씩 구현해 볼까요?<br />
이번 구현처럼 코드의 양이 조금 많아 지는 경우에는 코드를 처음부터 끝까지 한꺼번에 프로그램하기 보다는 기능 단위나 블록 단위로 나누어 프로그램을 작성하면 조금 더 편리합니다. 알고리즘에 쓰는 용어로 Divide-and-Conqure 방식이 자주 이용됩니다. 이것은 전체의 문제를 몇 개의 큰 덩어리로 잘라 따로 따로 해결 방법을 찾는 방식입니다. 예를 들어 올림픽 행사를 치른다고 할 때, 정부의 여러 부처가 역할을 분담하여 일을 맡고, 각 부처는 다시 하부조직인 부나 실, 팀 등으로 구분하여 일을 처리하는 것을 생각하면 이해가 빠를 겁니다. 비슷한 방법으로 프로그램에서는 이렇게 큰 덩어리로 구분한 것 각각을 하나의 함수로 할당하여 처리하면 조금 더 편리합니다. 단, 함수로 처리할 때는 입력과 출력을 정확하게 정의하여야 하는 것을 잊으시면 안됩니다.</p>
<p>그럼, 위의 내용을 함수로 한 번 표현해 보겠습니다.</p>
<p style="padding-left: 30px;"><span style="color: #008080;"><strong>온도값 읽기 : read_temp( )</strong></span><br />
<span style="color: #008080;"> &#8211; 리턴값 = 1바이트의 정수 온도값</span></p>
<p style="padding-left: 30px;"><span style="color: #008080;"><strong>온도값을 3색 LED에 디스플레이 : display_temp(unsigned char temperature)</strong></span><br />
<span style="color: #008080;"> &#8211; 입력값 = 1바이트의 온도값</span><br />
<span style="color: #008080;"> &#8211; 리턴값 = 없음</span></p>
<p style="padding-left: 30px;"><span style="color: #008080;"><strong>알람음 발생 : tone(pin, frequency, duration)</strong></span><br />
<span style="color: #008080;"> &#8211; 아두이노 제공 라이브러러리</span></p>
<p style="padding-left: 30px;"><span style="color: #008080;"><strong>tone(pin, frequency, duration)</strong></span><br />
<span style="color: #008080;"> &#8211; pin : 소리를 출력할(버저가 연결된) 핀 번호</span><br />
<span style="color: #008080;"> &#8211; frequency : 출력할 소리의 주파수</span><br />
<span style="color: #008080;"> &#8211; duration : 출력할 소리의 지속 시간(ms)</span></p>
<p>위 함수를 기본으로 프로그램을 작성해 보겠습니다.</p>
<p>일단 read_temp()와 display_temp(temperature)는 잠시 후에 따로 코딩하도록 하고 전체 아우트라인을 작성해 보지요. (#include와 #define및 global 변수 선언도 일단은 생략하고 추후 코드 합체 시 넣겠습니다.)</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>void setup()<br />
{<br />
pinMode(PIEZO, OUTPUT);<br />
pinMode(RED_LED, OUTPUT);<br />
pinMode(GREEN_LED, OUTPUT);<br />
pinMode(BLUE_LED, OUTPUT);</p>
<p>Wire.begin(); // I2C 활성화<br />
Wire.beginTransmission(temp_addr); // Start (버스 시작) 및 타겟 어드레스 지정<br />
Wire.write(byte(0&#215;01)); // Configuration 레지스터(01) 지정<br />
Wire.write(byte(0&#215;00)); // Configuration 레지스터에 값(00)을 Write : Normal 모드<br />
Wire.endTransmission(); // Stop (버스 종료)<br />
}</p>
<p>void loop()<br />
{<br />
int i;</p>
<p>temperature = read_temp();// JMOD-TEMP-1 모듈로부터 측정된 온도를 읽어옴<br />
display_temp(temperature); // 3-컬러 LED에 온도에 해당되는 색깔을 디스플레이<br />
if ((temperature &lt; TEMP_LOW) || (temperature &gt;= TEMP_HIGH)) // (현재 온도 &lt; 최저 온도) 또는 (현재 온도 &gt;= 최고 온도) 인 경우는 “삐~뽀~삐~뽀~”(6옥타브 ‘도’ 음과 4옥타브 ‘’도’ 음을 번갈아 2번 울림<br />
{<br />
tone(PIEZO, NOTE_C6, 1000); delay(1000);<br />
tone(PIEZO, NOTE_C4, 1000); delay(1000);<br />
tone(PIEZO, NOTE_C6, 1000); delay(1000);<br />
tone(PIEZO, NOTE_C4, 1000); delay(1000);<br />
}<br />
if (temperature &gt;= (pre_temperature + TEMP_DIFF)) // 온도 1도 증가시<br />
tone(PIEZO, NOTE_C6, 1000);// “삐~”(6옥타브 ‘도’ 음) 알람 1초 울림<br />
else if (temperature &lt;= (pre_temperature + TEMP_DIFF)) // 이전(5초전) 온도와 1도 차이가 나는지 비교<br />
tone(PIEZO, NOTE_C4, 1000); // “삐~”(4옥타브 ‘도’ 음) 알람 1초 울림<br />
pre_temperature = temperature; // 다음 측정시(5초후) 비교를 위하여 현재 온도값 저장<br />
delay(5000); // 5초마다 측정<br />
}</p>
</div>
<p>코딩은 간단하니까 주석을 보면 전체적인 흐름은 쉽게 이해가 될 것 같습니다.<br />
삐에조버저와 3색 LED의 3핀은 모두 “~” 표시가 있는 digital 핀에 할당된 것을 주의해서 보시고(이 핀들은 모두 analog 출력 &#8211; 엄밀하게 말하면 pwm digital 출력이 가능하여야 하므로), 또한 TEMP_LOW 및 TEMP_HIGH 값은 자신이 원하는 대로 DIY해서 선택하면 되겠네요. 저는 테스트를 고려하여 24도~29도를 기준으로 잡았습니다.<br />
그럼, 이제 read_temp() 함수를 프로그램해 보겠습니다. 모두 함께 해보시지요!</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>unsigned char read_temp(void)// 1 바이트 처리 (0~127도까지 표현 가능하므로)<br />
{<br />
unsigned char c, d;<br />
Wire.beginTransmission(temp_addr); // Start (버스 시작) 및 타겟 어드레스 지정<br />
Wire.write(byte(0&#215;00)); // Temperature 레지스터(00) 지정<br />
Wire.requestFrom(temp_addr, 2); // 2 bytes read<br />
while(Wire.available() &lt; 2) ; // Wating 2 byte available<br />
c = Wire.read(); // 첫번째 데이터 저장<br />
d = Wire.read(); // 두번째 데이터 저장<br />
Wire.endTransmission(); // Stop (버스 종료)<br />
return(c); // 온도의 정수부분만 반환<br />
}</p>
</div>
<p>LM75A의 출력은 2’s complement 형태의 2바이트 값으로 되어 있다고 했는데, 우리는 실내온도 범위만 측정하려고 하니까 그냥 간단하게 온도값 중 정수값만 취하여 처리하도록 하겠습니다. (소수점까지 계산하려면 귀찮으니까요…) 즉, 읽어온 데이터 중 앞의 1바이트가 정수부분이고, 이 바이트의 MSB(Most Significant Bit, Bit7)만 부호인데, 실내에서는 이 값이 0이므로(영상 온도) 이것만 return 값으로 돌려주면 되겠네요. 엄청 쉽죠?</p>
<p>계속해서, 이번에는 display_temp(temperature) 함수를 작성해 보겠습니다. 온도값의 범위에 따라 위에서 정해진 색깔을 3색LED에 표현하면 되겠습니다. 이것은 예전 강좌(카멜레온링)를 또 참조해서 작성해야 할 것 같으니까 시간이 조금 더 걸리겠네요. 한 10분 기다릴테니, 자, 기억을 더듬거나 찾아서 해보실까요?</p>
<p>아, 참 이번에는 색깔 정하는 것을 그냥 아래 색상표에서 골라서 하는 것으로 해보시지요. 첫번째 바이트가 빨강에 대한 값이고, 두번째 바이트가 녹색, 세번째 바이트가 파랑입니다. 데이터는 지난번처럼 2차원 어레이로 처리하면 되겠구요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-1.gif" rel="lightbox[29852]"><img class="alignnone size-large wp-image-30137" alt="33 아두이노  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-1-446x620.gif" width="446" height="620" /></a></p>
<p>우리가 온도에 따라 사용하고자 하는 색과 여기에 해당하는 코드를 위 색상표에서 찾으면 아래와 같이 될 것 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-08888.png" rel="lightbox[29852]"><img class="alignnone  wp-image-30182" alt="33 아두이노 08888" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-08888.png" width="431" height="162" /></a></p>
<p>&nbsp;</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#define TEMP_SKYBLUE 24<br />
#define TEMP_GREEN 25<br />
#define TEMP_YELLOW 26<br />
#define TEMP_ORANGE 27<br />
#define TEMP_WINE 28<br />
#define TEMP_RED 29</p>
<p>int color[7][3] = {{0&#215;00, 0&#215;00, 0xFF}, {0&#215;00, 0xFF, 0xFF}, {0&#215;00, 0xFF, 0&#215;00}, {0xFF, 0xFF, 0&#215;00}, {0xFF, 0&#215;99, 0&#215;00}, {0xFF, 0&#215;00, 0xFF}, {0xFF, 0&#215;00, 0&#215;00}};// 7가지 색, 각 색마다 3가지 값, 2차원 어레이</p>
<p>void display_temp(unsigned char temperature)<br />
{<br />
if (temperature &lt; TEMP_SKYBLUE)<br />
{analogWrite(RED_LED, color[0][0]); analogWrite(GREEN_ LED, color[0][1]); analogWrite(BLUE_LED, color[0][2]);} // 파랑<br />
else if (temperature &lt; TEMP_GREEN)<br />
{analogWrite(RED_LED, color[1][0]); analogWrite(GREEN_ LED, color[1][1]); analogWrite(BLUE_LED, color[1][2]);} // 하늘색<br />
else if (temperature &lt; TEMP_YELLOW)<br />
{analogWrite(RED_LED, color[2][0]); analogWrite(GREEN_ LED, color[2][1]); analogWrite(BLUE_LED, color[2][2]);} // 연두<br />
else if (temperature &lt; TEMP_ORANGE)<br />
{analogWrite(RED_LED, color[3][0]); analogWrite(GREEN_ LED, color[3][1]); analogWrite(BLUE_LED, color[3][2]);} // 노랑<br />
else if (temperature &lt; TEMP_SCARLET)<br />
{analogWrite(RED_LED, color[4][0]); analogWrite(GREEN_ LED, color[4][1]); analogWrite(BLUE_LED, color[4][2]);} // 주황<br />
else if (temperature &lt; TEMP_RED)<br />
{analogWrite(RED_LED, color[5][0]); analogWrite(GREEN_ LED, color[5][1]); analogWrite(BLUE_LED, color[5][2]);} // 자주<br />
else<br />
{analogWrite(RED_LED, color[6][0]); analogWrite(GREEN_ LED, color[6][1]); analogWrite(BLUE_LED, color[6][2]);} // 빨강<br />
}</p>
</div>
<p>&nbsp;</p>
<p>휴, 이제 코드는 다 살펴 본 것 같지요? 그럼 전체를 합쳐 보겠습니다. 이번에는 #include와 #define및 global 변수 선언도 필요한 것은 다 맞추어 넣어서 완성해야겠네요.</p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include &lt;Wire.h&gt; // I2C 관련 라이브러리 사용 (JMOD-TEMP-1 억세스용)<br />
#include “pitches.h” // tone() 함수 사용</p>
<p>#define TEMP_LOW 24 // 알람 기준 최저 온도<br />
#define TEMP_HIGH 29 // 알람 기준 최고 온도<br />
#define TEMP_DIFF 1 // 알람을 울리는 온도차</p>
<p>#define PIEZO 3 // 삐에조버저는 3번핀에 할당<br />
#define RED_LED 5 // 빨강색은 5번핀에 할당<br />
#define GREEN_LED 6 // 초록색은 9번핀에 할당<br />
#define BLUE_LED 9 // 파랑색은 6번핀에 할당</p>
<p>#define TEMP_SKYBLUE 24<br />
#define TEMP_GREEN 25<br />
#define TEMP_YELLOW 26<br />
#define TEMP_ORANGE 27<br />
#define TEMP_WINE 28<br />
#define TEMP_RED 29</p>
<p>const int temp_addr = 0&#215;48;</p>
<p>int color[7][3] = {{0&#215;00, 0&#215;00, 0xFF}, {0&#215;00, 0xFF, 0xFF}, {0&#215;00, 0xFF, 0&#215;00}, {0xFF, 0xFF, 0&#215;00}, {0xFF, 0&#215;99, 0&#215;00}, {0xFF, 0&#215;00, 0xFF}, {0xFF, 0&#215;00, 0&#215;00}}; // 7가지 색, 각 색마다 3가지 값, 2차원 어레이</p>
<p>unsigned char temperature;<br />
unsigned char pre_temperature;</p>
<p>unsigned char read_temp(void) // 1바이트 처리 (0~127도까지 표현 가능하므로)<br />
{<br />
unsigned char c, d;<br />
Wire.beginTransmission(temp_addr); // Start (버스 시작) 및 타겟 어드레스 지정<br />
Wire.write(byte(0&#215;00)); // Temperature 레지스터(00) 지정<br />
Wire.requestFrom(temp_addr, 2); // 2 bytes read<br />
while(Wire.available() &lt; 2) ; // Wating 2 byte available<br />
c = Wire.read(); // 첫번째 데이터 저장<br />
d = Wire.read(); // 두번째 데이터 저장<br />
Wire.endTransmission(); // Stop (버스 종료)<br />
return(c); // 온도의 정수부분만 반환<br />
}</p>
<p>void display_temp(unsigned char temperature)<br />
{<br />
if (temperature &lt; TEMP_SKYBLUE)<br />
{analogWrite(RED_LED, color[0][0]); analogWrite(GREEN_ LED, color[0][1]); analogWrite(BLUE_LED, color[0][2]);} // 파랑<br />
else if (temperature &lt; TEMP_GREEN)<br />
{analogWrite(RED_LED, color[1][0]); analogWrite(GREEN_ LED, color[1][1]); analogWrite(BLUE_LED, color[1][2]);} // 하늘색<br />
else if (temperature &lt; TEMP_YELLOW)<br />
{analogWrite(RED_LED, color[2][0]); analogWrite(GREEN_ LED, color[2][1]); analogWrite(BLUE_LED, color[2][2]);} // 연두<br />
else if (temperature &lt; TEMP_ORANGE)<br />
{analogWrite(RED_LED, color[3][0]); analogWrite(GREEN_ LED, color[3][1]); analogWrite(BLUE_LED, color[3][2]);} // 노랑<br />
else if (temperature &lt; TEMP_WINE)<br />
{analogWrite(RED_LED, color[4][0]); analogWrite(GREEN_ LED, color[4][1]); analogWrite(BLUE_LED, color[4][2]);} // 주황<br />
else if (temperature &lt; TEMP_RED)<br />
{analogWrite(RED_LED, color[5][0]); analogWrite(GREEN_ LED, color[5][1]); analogWrite(BLUE_LED, color[5][2]);} // 자주<br />
else<br />
{analogWrite(RED_LED, color[6][0]); analogWrite(GREEN_ LED, color[6][1]); analogWrite(BLUE_LED, color[6][2]);} // 빨강<br />
}<br />
void setup()<br />
{<br />
pinMode(PIEZO, OUTPUT);<br />
pinMode(RED_LED, OUTPUT);<br />
pinMode(GREEN_LED, OUTPUT);<br />
pinMode(BLUE_LED, OUTPUT);</p>
<p>Wire.begin(); // I2C 활성화<br />
Wire.beginTransmission(temp_addr); // Start (버스 시작) 및 타겟 어드레스 지정<br />
Wire.write(byte(0&#215;01)); // Configuration 레지스터(01) 지정<br />
Wire.write(byte(0&#215;00)); // Configuration 레지스터에 값(00)을 Write : Normal 모드<br />
Wire.endTransmission(); // Stop (버스 종료)<br />
}</p>
<p>void loop()<br />
{<br />
int i;</p>
<p>temperature = read_temp(); // JMOD-TEMP-1 모듈로부터 측정된 온도를 읽어옴<br />
display_temp(temperature); // 3-컬러 LED에 온도에 해당되는 색깔을 디스플레이<br />
if ((temperature &lt; TEMP_LOW) || (temperature &gt;= TEMP_HIGH)) // 현재 온도 &lt; 최저 온도 또는 현재 온도 &gt;= 최고 온도 인 경우는 “삐~뽀~삐~뽀~”(6옥타브 ‘도’ 음과 4옥타브 ‘’도’ 음을 번갈아 2번 울림 {<br />
tone(PIEZO, NOTE_C6, 1000); delay(1000);<br />
tone(PIEZO, NOTE_C4, 1000); delay(1000);<br />
tone(PIEZO, NOTE_C6, 1000); delay(1000);<br />
tone(PIEZO, NOTE_C4, 1000); delay(1000);<br />
}<br />
if (temperature &gt;= (pre_temperature + TEMP_DIFF))<br />
tone(PIEZO, NOTE_C6, 1000); // “삐~”(6옥타브 ‘도’ 음) 알람 1초 울림<br />
else if (temperature &lt;= (pre_temperature &#8211; TEMP_DIFF)) // 이전(5초전) 온도와 1도 차이가 나는지 비교<br />
tone(PIEZO, NOTE_C4, 1000); // “삐~”(4옥타브 ‘도’ 음) 알람 1초 울림<br />
pre_temperature = temperature; // 다음 측정시(5초후) 비교를 위하여 현재 온도값 저장<br />
delay(5000); // 5초마다 측정<br />
}</p>
</div>
<p>조금 긴 것 같긴 한데&#8230; 컴파일하고, 에러가 없다면 업로드하고, 잘 돌아라~ 얍! 이 상태에서 손가락을 JMOD-TEMP-1에 부착된 LM75A에 갖다 대면 온도가 좀 오를 테니… 한 번 해 보지요. 아래 동영상처럼 되겠네요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-9.jpg" rel="lightbox[29852]"><img alt="33 아두이노  (9)" src="http://www.ntrexgo.com/wp-content/uploads/2015/10/33-아두이노-9-620x407.jpg" width="434" height="285" /></a></p>
<p><a href="http://serviceapi.nmv.naver.com/flash/convertIframeTag.nhn?vid=AEEDA129DE0FC16A0600227738350106D1EA&amp;outKey=V12767f0e60ea38a5024d9d6a553fbf3dd2bf74c26e7d916b60299d6a553fbf3dd2bf&amp;width=720&amp;height=438%20)">동영상 보러가기</a></p>
<p>손을 갖다대면 체온에 의하여 온도가 1도 올라갈 때마다 색깔이 변하고 높은 “삐~” 소리가 나지요.<br />
손을 떼면 다시 온도가 1도 떨어지니까 낮은 “삐~” 소리가 나구요.<br />
계속 누르고 있으면 온도가 계속 올라가서 29도 이상으로 올라가면 빨강색 LED가 켜지면서 “삐~뽀~삐~뽀~” 소리가 나는 모습을 볼 수 있겠습니다.<br />
오~ 이번에도 성공입니다. (사실은 1번에 성공한 것이 아니라 10번도 더 고쳤답니다. 글자 오타부터 가지 각색의 에러는 항상 나타나므로 디버깅을 해서 모든 오류가 수정된 후에야 성공이지요. 여러분도 10번 정도 수정하여 성공한다면 정상입니다!)<br />
시간이 되면 온도계 테두리도 만들고 좀 꾸미면 그럴 듯 하게 될 것 같으므로 그것은 여러분이 챙기시기 바랍니다.<br />
오늘은 캐롤송카드와 컬러링 온도계를 제작해 보았습니다. 나름대로 자신에게 맞도록 노래를 바꾸거나 설정 온도값을 바꾸거나 구미에 맞도록 DIY하여 사용하시면 될 것 같습니다.<br />
오늘도 수고 많이 하셨고, 다음 DIY 시간은 마지막 시간으로 “스마트폰으로 조정하는 스마트카”를 DIY해 보도록 하겠습니다.</p>
<p>모두모두 안녕~~~</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/29852/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[32호]너무 쉬운 아두이노 DIY ④ &#8211; 정원등과 공중회전그네</title>
		<link>http://www.ntrexgo.com/archives/28795</link>
		<comments>http://www.ntrexgo.com/archives/28795#comments</comments>
		<pubDate>Tue, 15 Sep 2015 01:12:29 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[프로젝트]]></category>
		<category><![CDATA[32호]]></category>
		<category><![CDATA[diy]]></category>
		<category><![CDATA[Projects to build]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[아두이노]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=28795</guid>
		<description><![CDATA[어두워지면 저절로 켜지는 정원등과 공중회전그네, 오늘은 [어두워지면 저절로 켜지는 정원등]과 [공중회전그네]를 만들어 볼까 합니다. 
]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32아두이노04.jpg" rel="lightbox[28795]"><img alt="32아두이노04" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32아두이노04.jpg" width="620" height="166" /></a></p>
<p>&nbsp;</p>
<p style="text-align: right;">글 | 신상석 ssshin@jcnet.co.kr</p>
<p> <div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>이 강의는 아두이노를 가지고 간단하게 생활에 필요한 용품을 만들어 보는 강의입니다. 뚝딱뚝딱 뭔가 자신만의 DIY 용품을 만들어 보는 쏠쏠한 재미가 있는 강의라고나 할까요? 이미 주변에 아두이노와 관련한 많은 책이 출간되었고 카페나 블로그를 통하여 강의가 진행된 경우도 꽤나 많이 있는데도 불구하고, 이 지면을 통하여 강의를 개설한 이유는 다음과 같습니다.</p>
<p>1. 아두이노의 초보자들을 위한 쉽고 재미있는 강의가 거의 없는 것 같아, 가능하면 초등학생(?)까지도 함께 해 볼 수 있는 그런 강의를 한 번 해보고 싶어서…<br />
2. 아두이노를 가지고 뭔가 조금은 다른, 자신만의 창의적인(?) DIY를 할 수 있는 자리를 만들어주고 싶어서…<br />
3. 디바이스마트매거진은 임베디드와 관련된 독자들이 많고, 발행 부수도 많아, 저와 제가 속한 회사(제이씨넷) 그리고 임베디드홀릭 카페의 홍보에 도움이 될 것 같아서…</p>
<p>현재 구상하고 있는 회차별 내용을 간략하게 정리해 보면 다음과 같습니다. (변경될 수 있습니다.)</p>
<table style="border: 1px solid #e2dee2; width: 340px;" border="1" cellspacing="0" cellpadding="1">
<tbody>
<tr>
<td style="text-align: center;">회차</td>
<td>내용</td>
</tr>
<tr>
<td style="text-align: center;">1</td>
<td>3색 신호등 만들기</td>
</tr>
<tr>
<td style="text-align: center;">2</td>
<td>카멜레온 반지, 스위치를 이용한 신호등 게임기</td>
</tr>
<tr>
<td style="text-align: center;">3</td>
<td>FND로 만드는 디지털전압계, 카운트다운 계수기</td>
</tr>
<tr>
<td style="text-align: center;">4</td>
<td>어두워지면 켜지는 정원등, 공중회전그네</td>
</tr>
<tr>
<td style="text-align: center;">5</td>
<td>캐롤송 카드, 컬러링 온도계</td>
</tr>
<tr>
<td style="text-align: center;">6</td>
<td>스마트폰으로 조정하는 스마트카</td>
</tr>
</tbody>
</table>
<p>앞으로 즐겁고 알찬 강의가 될 수 있도록 최선을 다할 것을 약속 드리며, 이 강의를 보는 독자들도 메일이나 카페를 통하여 Q&amp;A(Question &amp; Answer)나 피드백을 주셔서, 함께 정감을 나눌 수 있는 계기가 되기를 기대해 봅니다.<br />
</div>
<p>&nbsp;</p>
<p>여러분, 안녕하세요. 항상 환한 강사 신상석입니다.<br />
지난번 주제였던 [시한폭탄 카운트다운 계수기] DIY는 한 번 만들어 보셨나요? 양방향 대화가 아니어서 질문하는 것이 조금 멋적긴 하지만, “그래도 한 열 분 정도는 시도해보지 않았을까?” 라고 나름 생각하면서 즐겁게 계속 진도 나갑니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-01.jpg" rel="lightbox[28795]"><img class="aligncenter" alt="32PTB 4강 01" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-01.jpg" width="226" height="340" /></a><br />
오늘은 [어두워지면 저절로 켜지는 정원등]과 [공중회전그네]를 만들어 볼까 합니다.<br />
어둑어둑 해질 무렵의 놀이동산, 노오란 정원등이 하나 둘씩 저절로 켜지고 내가 좋아하는 공중회전그네가 빙글빙글 돌아가는 풍경… 많이 비슷하게는 안되겠지만 기분이라도 이렇게 낭만적으로 상상하면서 한 번 가보도록 하지요.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 광센서 <strong>■ </strong></strong></span></p>
<p>어두워지면 저절로 켜지는 정원등을 만들려면, 일단 어두워졌다는 사실을 알아야 합니다. 즉, 빛의 밝기를 측정할 수 있는 센서가 있어야 하는데, 이러한 센서를 광센서라고 합니다. 보통 광센서는 아래와 같이 생긴 황화카디늄(CdS) 센서를 많이 사용하는데, 이것은 황화카디늄(CdS) 성분이 빛이 밝아지면 전기저항값이 작아지고, 빛이 어두워지면 전기저항값이 커지는 성질이 있기 때문입니다. 오~ 저항값이 변한다면 가변저항의 역할을 할 수 있다는 것이므로 이 성질을 잘 이용하면 뭔가 해답이 나올 것 같지요? 세부적인 방법은 잠시 후에 기본 회로를 꾸며가면서 살펴보기로 하고 일단은 빛과 광센서에 대하여 먼저 알아보겠습니다.<br />
빛의 밝기는 룩스(LUX)로 측정이 되는데, 엄밀한 정의는 이해도 어렵고 필요도 없으므로 룩스 값에 따른 예를 보면서 이해하는 것이 더 좋을 것 같습니다. 아래를 보시지요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-02.png" rel="lightbox[28795]"><img class="aligncenter" alt="32 아두이노 02" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-02.png" width="425" height="264" /></a></p>
<p>사람마다 느끼는 것이 다르겠지만 우리는 위의 표와 같이 조금 어두워지는 것 같다고 느껴지는 저녁 황혼의 밝기인 10 룩스 정도에서 정원등이 켜지도록 하겠습니다.<br />
이제 빛의 빛의 밝기에 따라 변하는 광센서의 저항값을 알아봅시다. 아래는 CdS 광센서중의 하나인 GL5537 광센서의 모습과 규격 일부입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-03.png" rel="lightbox[28795]"><img class="aligncenter" alt="32 아두이노 03" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-03.png" width="425" height="131" /></a></p>
<p>우리가 측정하고자 하는 빛의 밝기인 10 LUX는 정도에서 약 20~50KΩ 정도의 저항값을 갖는 것으로 되어 있습니다. 조금은 틀려도 크게 문제는 없을 것이기에 우리는 이 때의 대표 저항값을 중간값인 35 KΩ 라 생각하고 진행하는 것으로 하지요.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 아날로그 센서 측정을 위한 기본 회로 <strong>■ </strong></strong></span></p>
<p>결국 광센서는 빛의 밝기에 따라 저항값이 변하는 가변저항의 역할을 하는 것이고, 우리의 아두이노는 아날로그 입력으로 전압값을 측정할 수 있는 능력이 있으므로 이 광센서의 저항값이 변함에 따라 특정 지점의 전압이 변하도록 회로를 꾸미면 아두이노로 광센싱이 가능하겠습니다. 지난번에 과제로 내주었던 [FND-과제-2]와 비슷한 회로가 될 것 같은데…<br />
아래와 같이 회로를 꾸며 보도록 하지요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-065.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28910 aligncenter" alt="32 아두이노 065" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-065.jpg" width="425" height="192" /></a></p>
<p>이렇게 연결한 후 (?V)로 표기된 부분을 아두이노의 아날로그 입력(A0~A5) 핀 중 하나에 연결하고(우리는 A1에 연결) 전압을 측정하면 현재 빛의 밝기를 알 수 있겠습니다. 즉, 광센서의 저항값을 R1, 여기에 직렬로 연결한 저항값을 R2(고정값)으로 설정하고, 양단에 전압 +5V를 인가하면 이 회로에 흐르는 전류(I)는,</p>
<p style="padding-left: 60px;">5 = R1 x I + R2 x I 에서,<br />
I = 5 / (R1+R2)가 되므로<br />
아날로그 입력(A1)에서 측정한 전압값(?V)은<br />
?V = I x R2 = (5 / (R1+R2)) x R2 가 됩니다.</p>
<p>R2는 고정값인 상수이므로 측정된 전압값(?V)를 알면 결국 R1 값을 구할 수 있고, R1 값을 알면 GL5537의 규격표에서 이에 대응되는 현재 빛의 밝기를 알 수 있게 되는 것이지요.<br />
아하~ 그렇구나~</p>
<p><span style="font-size: medium;"><strong>■ 어두워지면 저절로 켜지는 정원등</strong></span></p>
<p>자, 이제 기초적인 원리는 이해가 되었으니 오늘의 주제 중 하나인 [어두워지면 저절로 켜지는 정원등]을 만들어 봅시다. 항상 그렇듯이 일단, 어떤 것을 만들 것인지 기능 규격부터 정해볼까요?</p>
<p><span style="color: #ff0000;"><strong>[기능 규격]</strong></span><br />
· 주변이 10 룩스 정도 밝기로 어두워지면 저절로 켜지는 정원등 제작<br />
· LED를 정원등이라고 생각하고 LED의 ON/OFF 제어</p>
<p><span style="color: #ff0000;">※ 실제 정원등을 제어하려면 AC 전원이 연결된 정원등 스위치를 ON/OFF 하여야 하는데 이것은 릴레이로 스위치를 대신하고 이 릴레이를 제어하면 되므로, 여기서는 그냥 원리만을 알아보는 차원에서 정원등을 DC 5V에 대응되는 LED라고 가정하고 진행합니다.</span></p>
<p>기능 규격을 보니 우리가 공부한 기본 원리를 이용하면 바로 구현이 가능할 것 같습니다. 아래와 같이 하면 되겠네요.</p>
<p><span style="color: #ff0000;"><strong>[아두이노 연결]</strong></span><br />
· GL5537의 규격이 4KΩ ~ 2MΩ 정도의 범위에서 변하므로, 로그 스케일로 그 중간 정도에 있는 값인 200KΩ(또는 그 근처 저항)을 고정저항(R2)으로 선정<br />
· [+5V --- GL5537 광센서 --- 200 KΩ 저항 --- GND] 형태로 회로를 구성하고 GL5537과 200KΩ 저항이 만나는 지점을 아두이노 A1 아날로그 핀에 연결(노란색 도선)<br />
· 아두이노 D3핀(디지털출력, 녹색 도선)에 LED(직렬 저항 포함) 연결</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-04.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28888 aligncenter" alt="32PTB 4강 04" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-04.jpg" width="602" height="435" /></a><br />
<span style="color: #ff0000;"><strong>[알고리즘]</strong></span><br />
정리된 알고리즘은 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-07.png" rel="lightbox[28795]"><img class="size-full wp-image-28912 aligncenter" alt="32 아두이노 07" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-07.png" width="425" height="275" /></a><br />
10룩스일 때의 GL5537은 데이터시트에 보면 20~50 KΩ 으로 나타나므로 중간값인 35 KΩ 으로 추정하였을 때 위에서 공부한 이론을 적용하여 10룩스일 때의 전압값(?V)을 계산하여 보면, ?V = (5 / (R1+R2)) x R2 = (5 / (35 + 200)) x 200 = 5 x 200 / 235 이 됩니다. 5V에 대응되는 아날로그로 값은 1024이므로 위의 전압에 해당되는 아날로그 값을 계산하면 5 : 1024 = 5 x 200 / 235 : ?V 의 식으로 표현되므로 ?V 에 해당되는 값을 구하면 ?V = 5 x 200 x 1024 / 235 / 5 = 871 이 되겠습니다.</p>
<p>결론적으로, 위와 같이 연결한 회로에서 10룩스의 밝기가 되면 A0 핀으로는 871값이 읽히게 되므로, 읽은 값이 이 값 보다 작거나 같으면 정원등(LED)을 ON하고, 그렇지 않으면 정원등(LED)를 OFF하도록 스케치 프로그램을 작성하여야 하겠습니다.</p>
<p><span style="color: #ff0000;"><strong>[스케치 프로그램]</strong></span><br />
이제 모든 것이 결정되었으니 프로그램 작성이 가능하겠죠? 바로 갑니다.</p>
<table style="border: 0px solid #564a4b; width: 600px; border-width: 1px; border-color: #c8c5c5;" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>const int LED=3;<br />
const int CDS=1;<br />
#define CDS_10 871 // 200/(35+200) * 1024, 10룩스일 때의 CDS 저항값인 35KΩ에 대응되는 아날로그 값&nbsp;</p>
<p>void setup()<br />
{<br />
pinMode(LED, OUTPUT); // LED 핀은 출력<br />
pinMode(CDS, INPUT); // 광센서 핀은 입력<br />
}</p>
<p>void loop()<br />
{<br />
int value;<br />
value = analogRead(CDS);<br />
if (value &lt;= CDS_10)<br />
digitalWrite(LED, HIGH);<br />
else<br />
digitalWrite(LED, LOW);<br />
delay(1000);<br />
}</td>
</tr>
</tbody>
</table>
<p>에러가 없다면 바로 업로드를 실행한 후 광센서(GL5537) 앞쪽으로 손바닥을 가깝게 가져갔다가 멀리했다가 하는 동작을 반복해 봅시다. 손바닥이 가까이 가면 빛을 차단하게 되므로 어두워져서 빛의 밝기가 10룩스 아래로 내려가게 되어 LED가 켜질 것이고, 다시 멀리하면 빛의 밝기가 10룩스 위로 올라가게 되어 LED가 꺼지게 되겠습니다. 동영상과 같이 된다면 이번 DIY도 성공이네요. 와우~~~</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-05.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28889 aligncenter" alt="32PTB 4강 05" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-05.jpg" width="598" height="434" /></a></p>
<p style="text-align: center;"><a href="https://www.youtube.com/watch?v=mVnkjjk6S_I" target="_blank">동영상 보러가기</a></p>
<p>한가지 더 알려드리고 싶은 것은, 시중에 나와 있는 센서는 광센서와 같이 가변저항의 성질을 이용한 것이 상당히 많다는 사실입니다. 예를 들어 온도센서는 주변 온도에 따라 저항값이 변하는 성질을 이용하며, 압력센서의 경우는, 압력에 따라 저항값이 변하는 성질을 이용하는 것입니다.</p>
<p>이러한 종류의 센서는 지금까지 사용한 방법과 비슷한 방법으로 쉽게 구현할 수 있으므로 이번 예를 잘 응용한다면 앞으로의 다른 DIY 작업도 식은 죽 먹기로… (윽. 너무 오버?)<br />
자, 그러면 첫번째 DIY는 이쯤에서 마치고 잠시 후에는 오늘의 메인 DIY인 공중회전그네 제작에 도전해 보도록 하겠습니다. 조금은 쉬었다 가야겠지요? 모두 10분간 휴식~~~</p>
<p>…(1분)<br />
…(2분)<br />
…(3분)<br />
…(4분)<br />
…(5분)<br />
…(6분)<br />
…(7분)<br />
…(8분)<br />
…(9분)<br />
…(10분)</p>
<p>편안한 휴식이 되셨나요? 그러면 이제 오늘의 메인 DIY인 공중회전그네에 도전해 봅시다.<br />
처음으로 움직이는 작품을 만들어 볼 기회가 되겠네요.<br />
우리가 할 수 있는 것 중에서 단순하면서도 재미있는 것을 이것 저것 생각하다가 찾은 것이 공중회전그네입니다. 이름이 정확한지는 잘 모르겠는데, 롯데월드에 제가 생각한 것과 비슷한 것을 하나 찾았습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-06.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28890 aligncenter" alt="32PTB 4강 06" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-06.jpg" width="373" height="249" /></a><br />
버섯처럼 생긴 부분이 돌아가면 거기에 매달려 있는 그네가 공중에 붕 떠서 도는 것이지요. 저도 타보지는 않았지만 요것, 일반 그네보다는 훨씬 재미있을 것 같으니 여러분도 기회가 되면 꼭 한 번 타보시기 바랍니다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■  모터  <strong>■ </strong><br />
</strong></span></p>
<p>어떤 물건을 움직이려면 동력을 발생시키는 주체가 있어야 하는데, 이것이 모터입니다. 모터의 쓰임새는 거의 무한이어서, 자동차 바퀴, 선풍기 날개, 믹서기 커터, 비행기 프로펠러 등등 그 쓰임새는 셀 수가 없을 정도입니다. 그리고 꼭 회전이 아니더라도 자동문, 도어락, 포크레인 집게 등 생명체가 아니면서 움직이는 것의 대부분은 모터에 의한 것이라고 봐도 과언이 아니지요.</p>
<p>그러니까, 우리도 일단 공중회전그네를 만들기 전에 모터에 대하여 조금은 알고 넘어가는 것이 좋을 듯 합니다.<br />
모터(Motor)는 우리말로 전동기라고 하는데, “전류가 흐르는 도체가 자기장 속에서 받는 힘을 이용하여 전기에너지를 역학적에너지로 바꾸는 장치”입니다. 뭔가 좀 어려운 설명인데, 우리는 그냥 “전기를 넣어주면 축을 중심으로 회전하는 것이 모터”다 라고 알아두면 되겠습니다.</p>
<p>어떤 전류를 사용하느냐에 따라 건전지 같은 전원을 사용하면 DC(Direct Current, 직류) 모터, 220V 같은 콘센트 전원을 사용하면 AC(Alternating Current, 교류) 모터로 구분합니다. 또한, 사용하는 형태에 따라서도 일반 모터, 서보(Servo) 모터, 스테핑(Stepping) 모터로 나눌 수가 있는데, 일반 모터는 그냥 왱~ 하면서 돌아가는 모터구요. 서보 모터는 일정한 각도 만큼만 회전하는 모터로 차단기, 자동문 등에 사용하는 모터입니다. 또한, 스테핑 모터는 아주 정밀한 각도를 움직일 수 있도록 만든 모터가 되겠습니다.</p>
<p>우리는 DC 모터를 사용할텐데, DC 모터는 보통 2개의 단자를 가지고 있고 이 단자의 양단에 모터의 정격에 알맞은 전압을 가하면 회전하게 됩니다. 또한, 일반적으로 2단자의 극성을 바꾸면 반대방향으로 회전하게 되지요.</p>
<p>그러면 이제 아두이노에 모터를 연결하는 방법에 대하여 간단히 알아보겠습니다.<br />
요렇게 연결하면 될까요? (M 표시가 있는 것은 모터 심볼입니다.)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-07.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28891 aligncenter" alt="32PTB 4강 07" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-07.jpg" width="236" height="302" /></a><br />
아두이노의 핀 하나(OUT1)를 모터의 한쪽에 연결하고, 모터의 다른 한쪽은 GND에 묶어 놓으면, 아두이노에서 제어가 가능할 것 같습니다. OUT1 = 1이면 모터가 돌고, OUT1 = 0 이면 모터가 정지하겠네요.<br />
음. 한번에 완성?<br />
반대 방향으로도 돌려야 할 필요성도 있겠네요. 모터는 보통 양단의 극성을 바꾸어 전원을 공급하면 반대 방향으로 회전하므로 아래쪽에도 GND 대신 포트를 하나 할당하는 것이 좋겠습니다. 값을 1, 0 마음대로 바꿀 수가 있으니까요. 아래와 같이 연결해 보지요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-08.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28892 aligncenter" alt="32PTB 4강 08" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-08.jpg" width="234" height="312" /></a><br />
오, 이렇게 되면, OUT1= 1, OUT2 = 0 인 경우는 모터가 정방향으로 돌고, OUT1 = 0, OUT2 = 1 이렇게 만들면 모터가 역방향으로 돌고… OUT1 = 0, OUT2 = 0 또는 OUT1 = 1, OUT1 = 1 이면…<br />
OUT1 및 OUT2 양단 사이에 전위차가 없으니 모터가 정지할 것 같습니다. 괜찮은 설계가 된 것 같네요.</p>
<p>모두 만족? 음. 약간 부족한 것 같네요. 몇가지 더 생각할 게 있어요.<br />
모터라는 녀석은 힘으로 먹고 사는 녀석이어서… 모터가 도는 힘에 비례하여 전류를 많이 소모합니다. 모터마다 5V-1A, 12V-2A, …, 이런 식으로 규격이 정해져 있지요. 요점은 OUT1 ▶ 모터 ▶ OUT2 방향으로 많은 전류를 흐르게 할 수 있는 지의 여부입니다. 예를 들어 1A의 전류를 모터로 흘려보내야 한다면 그 전류를 아두이노의 출력핀에서 공급하는 것이 가능한지를 살펴보아야 합니다. 오우~ NO! 아두이노 디지털출력핀은 전류를 많이 공급하지 못하네요. 기껏해야 한 신호당 약 40mA 정도가 최대랍니다. 엄청나게 모자라네요.<br />
그렇다면 불가능할까요?<br />
아니겠죠? 다른 방법이 당연히 있습니다.<br />
이렇게 많은 양의 전류를 흘려야 하는 경우에는 전류를 아두이노 출력핀에서 직접 공급하지 않고 간접적으로 흐르게 하는 방법을 사용하여야 하는데, 이런 경우 가장 많이 사용하는 방법은 바로 트랜지스터를 이용하는 것입니다.<br />
트랜지스터는 PNP형과 NPN형이 있는데 여기서는 NPN형을 기준으로 한 번 설명해 보겠습니다. 아래와 같이 생겼습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-09.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28893 aligncenter" alt="32PTB 4강 09" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-09.jpg" width="186" height="203" /></a><br />
여기서 B는 베이스(Base), C는 컬렉터(Collector), E는 에미터(Emitter)인데 아래와 같은 특징이 있습니다. (엄밀한 의미로는 틀릴 수 있는 내용이지만 여기서는 쉽게 설명하기 위하여 개념을 간략화 합니다.)</p>
<p><span style="color: #008000;">1. B-E(베이스-에미터)간 전압이 0.7V 이상 순방향으로 걸리면 트랜지스터는 턴-온(Turn-On)되었다고 하고, 이 때 C-E(컬렉터-에미터)는 서로 직접 연결된 것으로 간주합니다. (물론 0.2V 정도의 전위차가 있긴 하지만 그냥 직접 연결되었다고 생각해도 무방합니다.)</span></p>
<p><span style="color: #008000;">2. B-E(베이스-에미터)간 전압이 0.7V 이하이면 트랜지스터는 턴-오프(Turn-Off)되었다고 하고, 이 때 C-E(컬렉터-에미터)는 연결이 끊어진 것으로 간주합니다.</span></p>
<p><span style="color: #008000;">3. 턴-온 되는 경우 B-E 경로로는 수 mA 정도만 흘러도 C-E 경로로는 B-E 전류의 10~1000배 정도의 전류, 즉 수십 mA ~ 수 A 정도의 전류를 흘릴 수 있습니다. (그렇게 흘러도 아무런 문제가 되지 않습니다. 즉, 트랜지스터가 그 정도의 전류를 견디어 냅니다.)</span></p>
<p>PNP형의 경우는 NPN의 경우와 반대라고 생각하고, B-E간의 전압이 역방향으로 걸리면 턴-온 된다고 생각하면 됩니다.<br />
그러면, 이제 이 트랜지스터를 이용하여 우리의 모터 연결을 수정하여 보겠습니다.</p>
<p>트랜지스터가 방향성을 가지므로, 정방향, 역방향을 모두 수용하려면 아래와 같이 2개의 경우가 생기겠네요. 왼쪽의 경우는 OUT1 = 1, OUT2 = 0 이면 Q1, Q2 트랜지스터가 모두 턴-온되어 모터가 회전하고, 오른쪽의 경우는 OUT1 = 0, OUT2 = 1 이면 Q3, Q4 트랜지스터가 모두 턴-온되어 모터가 회전하겠습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-10.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28894 aligncenter" alt="32PTB 4강 10" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-10.jpg" width="469" height="387" /></a></p>
<p>이미 눈치 채신 분이 있으시겠지만 <span style="color: #008000;">이 경우 트랜지스터는 턴-온, 턴-오프 상태를 갖는 스위치의 역할을 하게 되며, OUT1, OUT2 출력 신호는 아두이노가 생성할 수 있고, 모터에 흐르는 전류는 모두 VCC ▶ 트랜지스터 ▶ 모터 ▶ 트랜지스터 ▶ GND(접지) 로 흐르므로 모터의 전류 용량도 무난히 소화할 수 있겠습니다. 한가지 더 주의 깊게 보아야 할 것은 VCC로 표시된 전압은 +5V가 아니어도 괜찮다는 것입니다. 즉, OUT1이나 OUT2를 결정하는 로직 레벨과 무관하게 모터(M)의 정격에 알맞은 전압(예를 들어 3V~24V)을 걸어주면 된다는 것이지요. 오, 전류도 맘대로 되고, 전압도 맘대로 할 수 있으니, 일거양득(一擧兩得)! 신세대 은어로는 개이득이네요.</span></p>
<p>다시 돌아가서, 한 개의 모터를 가지고 위 2가지의 경우에 모두 적용되어야 하므로 이제 2개의 회로를 합쳐서 그려보겠습니다. 아래와 같이 될 것 같습니다. 모습이 H 형태와 비슷하다고 하여 이 회로의 이름을 ‘H-브릿지’라고 부릅니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-11.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28895 aligncenter" alt="32PTB 4강 11" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-11.jpg" width="483" height="374" /></a><br />
일단, 맞는지 잘 확인해 보시지요. (특히, Q1, Q1, Q3, Q4 위치)<br />
똑같죠? 왠지 멋져 보입니다.<br />
그럼, 최종 점검해 보겠습니다.<br />
OUT1 = 1, OUT2 = 0 이면 Q1 = ON, Q2 = ON, Q3 = OFF, Q4 = OFF이므로 아래 그림과 같이 VCC ▶ Q1 ▶ 모터(M) ▶ Q2 ▶ GND 방향으로 전류가 흘러서 모터가 순방향으로 회전합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-12.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28896 aligncenter" alt="32PTB 4강 12" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-12.jpg" width="432" height="332" /></a><br />
OUT1 = 0, OUT2 = 1 인 경우는 Q1 = OFF, Q2 = OFF, Q3 = ON, Q4 = ON 이므로 모터로 흐르는 전류 방향이 반대가 되므로 역방향으로 회전하겠네요. (여러분이 한번 전류 흐름을 그려보세요.)</p>
<p>또한, OUT1 = 1, OUT2 = 1 이거나, OUT1 = 0, OUT2 = 0 이면 VCC 쪽이거나 GND 쪽에 연결된 트랜지스터가 OFF 되어 모터로 전류가 흐르지 않으므로 모터는 정지하겠습니다.<br />
이것이면 완전 끝인가요?<br />
아쉽게도 좀 더 세부적으로 들어가면, 모터의 정격 전압, 전류 등에 대하여 제대로 알아야 하구요. 이를 구동할 트랜지스터의 타입, 전류 구동 능력, 관성 다이오드(flywheel diode)의 규격 및 이들의 상관 관계 등 세부적인 계산 방법은 간단하지가 않습니다. 또한, 잘못 연결하거나 맞지 않는 규격을 사용할 경우 모터나 트랜지스터에 손상을 일으킬 여지도 있어, 실제로 모터를 동작시킬 때에는 회로를 직접 꾸미기 보다는 이미 잘 동작하도록 제작된 전용 드라이버 칩 또는 이러한 칩을 사용하여 제작한 모듈을 사용하는 경우가 대부분입니다.<br />
그러므로 우리는 기본 원리를 이해하는 정도에서 만족하고, 실제 DIY에서는 전용 모터드라이버 모듈을 사용하도록 하는 것으로 방향을 잡겠습니다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 모터 드라이버 : JMOD-MOTOR-1 <strong>■ </strong></strong></span></p>
<p>모터드라이버는 앞에서 이야기한대로 모터를 쉽게 구동할 수 있도록 트랜지스터와 저항, 관성다이오드를 내장함은 물론 모터가 도는 방향도 선택하여 제어할 수 있는 구조를 가진 모듈을 의미하며, 시장에는 여러 종류의 모터드라이버가 출시되어 있습니다. 여기서는 우리의 목적에 적합한 모터드라이버로 제이씨넷 사의 JMOD-MOTOR-1이라는 모터드라이버를 사용하여 설명하도록 하겠습니다. (물론, 규격에 알맞은 다른 모터 드라이버를 사용하셔도 됩니다.)<br />
JMOD-MOTOR-1 은 TB6612FNG 칩 기반의 2채널 DC 모터 드라이버입니다. 4.5V~13.5V 범위의 DC 모터를 사용할 수 있고 채널당 최대 1.2A 까지의 전류를 공급할 수 있으며 다른 모터드라이버에 비하여 효율이 상당히 높다는 장점을 가지고 있습니다. 2.54mm 핀헤더 타입 및 2&#215;5 박스헤더 타입의 인터페이스를 함께 제공하여, 아두이노나 AVR 모듈 등과의 연결이 편리한 아래와 같이 생긴 제품(http://www.devicemart.co.kr/1160053)입니다.<br />
세부 구조 및 핀 배치는 다음과 같습니다.</p>
<p style="text-align: center;"><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-13.jpg" rel="lightbox[28795]"><img class="wp-image-28897" alt="32PTB 4강 13" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-13.jpg" width="334" height="326" /></a></p>
<p style="text-align: center;"><a href="//www.devicemart.co.kr/1160053)" target="_blank">제품 상세보러가기</a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-14.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28898 aligncenter" alt="32PTB 4강 14" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-14.jpg" width="538" height="331" /></a><br />
이론적으로 공부한 H-브릿지 드라이버와 실제 드라이버와의 매핑을 해보면 아래와 같이 됩니다. 한가지 다른 점은 TB6612에는 PWMA 라는 신호가 하나 더 있는데, 이것은 제어 입력인 AIN1, AIN2이 회전하는 경우 속도를 제어하기 위한 제어 신호로 PWMA가 High인 경우만 AIN1, AIN2 신호가 AO1, AO2로 그대로 전달되고, PWMA가 Low인 경우는 전달되지 않는다고 생각하시면 되겠습니다.</p>
<p>그렇다면 PWMA를 High로 했다가 Low로 했다가… 를 적당한 길이로 조정하면 모터가 돌다가 쉬다가… 할테니 속도를 조절할 수가 있겠습니다. 쉽게 설명하려고 했는데 설명이 더 어려운 것 같기도 하고…</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-15.jpg" rel="lightbox[28795]"><img class="size-large wp-image-28899 aligncenter" alt="32PTB 4강 15" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-15-506x620.jpg" width="506" height="620" /></a><br />
어쨌든 결과적으로, 우리가 제어하여야 할 핀은 PWMA, AIN1, AIN2의 3핀이고, 이 3핀의 값에 따라 AO1, AO2가 결정되어, 결국 모터가 정회전(CW, ClockWise, 시계방향), 역회전(CCW, CounterClockWise, 반시계방향), 정지(Break, Stop) 기능을 아래 표와 같이 수행하게 됩니다. 조금 장황한 듯 하지만 결국 3개의 신호선만 우리가 원하는 대로 알맞게 출력해 주면 모터는 동작하는 것이지요.<a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32아두이노-09.png" rel="lightbox[28795]"><img class="size-full wp-image-28928 aligncenter" alt="32아두이노 09" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32아두이노-09.png" width="443" height="149" /></a></p>
<p>마지막으로, 모터 전원의 경우는 외부에서 따로 제공하여야 하며, +5V 전원이라 할지라도 아두이노에서 사용하고 있는 +5V 전원과는 다른 전원을 사용하는 것이 좋습니다. 왜냐하면 모터는 기본적으로 전류용량이 커서 최소 수백 mA 이상을 사용하며, 또한 모터 기동시에는 이것의 2-3배 정도의 전류가 더 필요하게 되므로, USB 케이블을 통하여 아두이노에 제공되는 전류 용량(보통 500mA)만으로는 부족한 경우가 많아 모터가 동작하지 않거나 아두이노가 리셋이 되는 경우 등 오동작하는 경우가 발생할 수 있기 때문입니다.</p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 간단한 선풍기 <strong>■ </strong></strong></span></p>
<p>자, 이제 이론적인 준비가 끝났으니 DIY 작품을 만들어 보도록 하지요. 공중회전그네를 만들기 전에 먼저 간단한 선풍기를 만들어보겠습니다. 선풍기를 만든 다음에 요것을 변신시켜서 공중회전그네를 만들거랍니다.<br />
기본 재료인 모터는 3V DC 모터인 WRE-260을, 소형프로펠러는 아래와 같이 생긴 프로펠러를 사용하도록 하겠습니다. 다른 이유는 없고 그저 값이 싸다는 이유이므로, 다른 모터를 사용하여도 되고, 프로펠러는 그냥 간단히 스카치테이프나 색종이 등을 모터 축에 오려 붙여서 만들어도 되겠습니다.<br />
다행이도 프로펠러는 모터에 꼭 맞네요.</p>
<table style="width: 620px;" border="0">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-16.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28900 aligncenter" alt="32PTB 4강 16" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-16.jpg" width="204" height="204" /></a></td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-17.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28901 aligncenter" alt="32PTB 4강 17" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-17.jpg" width="167" height="158" /></a></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong style="color: #ff0000;">[기능 규격]</strong></p>
<p>· 소형 DC 모터에 모형 날개를 달고 아두이노로 제어하여 간단한 선풍기 제작<br />
· 5초간 정회전, 2초간 정지, 3초간 역회전, 2초간 정지를 반복 실행</p>
<p><span style="color: #ff0000;"><strong>[알고리즘]</strong></span><br />
정리된 알고리즘은 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32아두이노-09.png" rel="lightbox[28795]"><img class="aligncenter" alt="32아두이노 09" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32아두이노-09.png" width="443" height="149" /></a></p>
<p>· 위의 표에서 정회전, 역회전, 정지에 해당되는 PWMA, AIN1, AIN2 값을 정해진 시간 동안 차례로 출력</p>
<p><span style="color: #ff0000;"><strong>[아두이노 연결]</strong></span><br />
PWMA는 아두이노 5번핀에 할당하고, AIN1과 AIN2는 각각 7번핀, 8번핀에 할당</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-18.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28902 aligncenter" alt="32PTB 4강 18" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-18.jpg" width="360" height="445" /></a><br />
<span style="color: #008000;">※ 참고 : 모터 전원용으로 배터리(팩)를 연결할 때 배터리의 (+)는 JMOD-MOTOR-1의 VCC에 직접 연결하고 GND는 아두이노의 GND에 연결하면 추가 배선없이 연결됩니다. 모터가 3V용이어서 1.5V 건전지 2개를 직렬로 연결하여 모터 전원(VCC)에 공급하면 됩니다.</span></p>
<p><span style="color: #ff0000;"><strong>[스케치 프로그램]</strong></span><br />
자, 이제 연결은 되었으니, 프로그램해서 돌려 봅시다.<br />
장황하게 왔는데, 프로그램은 항상 너무 간단하죠.</p>
<table style="width: 600px;" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>const int MOTOR_PWM = 5; // 모터 PWM 입력핀, PWM핀으로 할당<br />
const int MOTOR_IN1 = 7; // 모터 IN1 입력핀<br />
const int MOTOR_IN2 = 8; // 모터 IN2 입력핀&nbsp;</p>
<p>void setup()<br />
{<br />
pinMode(MOTOR_PWM, OUTPUT);<br />
pinMode(MOTOR_IN1, OUTPUT);<br />
pinMode(MOTOR_IN2, OUTPUT);<br />
}</p>
<p>void loop()<br />
{<br />
digitalWrite(MOTOR_PWM, HIGH); // 3초간 선풍기 정회전<br />
digitalWrite(MOTOR_IN1, HIGH);<br />
digitalWrite(MOTOR_IN2, LOW);<br />
delay(3000);<br />
digitalWrite(MOTOR_PWM, LOW); // 3초간 선풍기 정지<br />
digitalWrite(MOTOR_IN1, LOW);<br />
digitalWrite(MOTOR_IN2, LOW);<br />
delay(3000);<br />
digitalWrite(MOTOR_PWM, HIGH); // 3초간 선풍기 역회전<br />
digitalWrite(MOTOR_IN1, LOW);<br />
digitalWrite(MOTOR_IN2, HIGH);<br />
delay(3000);<br />
digitalWrite(MOTOR_PWM, LOW); // 3초간 선풍기 정지<br />
digitalWrite(MOTOR_IN1, HIGH);<br />
digitalWrite(MOTOR_IN2, HIGH);<br />
delay(3000);<br />
}</td>
</tr>
</tbody>
</table>
<p>으, 별 것 없죠?<br />
실행 결과은 어떻게 되었나요?<br />
아래 동영상처럼 잘 돌아가나요? 작은 선풍기인데 생각보다는 꽤 쌩쌩~~~ 도네요.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-19.jpg" rel="lightbox[28795]"><img class="size-full wp-image-28903 aligncenter" alt="32PTB 4강 19" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-19.jpg" width="572" height="335" /></a></p>
<p style="text-align: center;"><a href="https://www.youtube.com/watch?v=LUHBFqI9Qu0" target="_blank">동영상 보러가기</a></p>
<p><span style="font-size: medium; color: #ffffff; background-color: #008000;"><strong>■ 공중회전그네 <strong>■</strong></strong></span></p>
<p>자, 이제 드디어 마지막 목적지인 공중회전그네 DIY 입니다. 앞에서 제작한 선풍기를 약간 개조하여 공중회전그네를 만들어 보겠습니다. 아마도, 어떻게 만들지 벌써 감을 잡으신 분들이 대부분이겠지요?</p>
<p>선풍기를 꺼꾸로 매달아 공중회전그네의 동력으로 쓰고, 선풍기 날개 끝에 구멍을 뚫어 그네를 매달아 회전을 시키는 형태로 하면 될 것 같습니다. 사용하고 싶은 재료를 자유롭게 골라서 만들면 될 것 같구요. 저는 그네줄은 점퍼케이블로 구현하고, 그네는 그냥 클립으로 찝어 그네라고 우기면서 간단히 꾸며려 합니다.</p>
<p>놀이기구이니까 그냥 도는 것 보다는 회전 속도와 회전 방향을 랜덤하게 하면 좀 더 재미가 있을 것 같으니 그렇게 한 번 해보지요.</p>
<p><span style="color: #ff0000;"><strong>[기능 규격]</strong></span><br />
· 여러명의 사람을 태울 수 있는 공중회전그네<br />
· 한 번은 시계 방향, 한 번은 반시계 방향 회전하며 회전 후에는 2초간 정지<br />
· 한 번 회전시 1~9초간 랜덤 시간 회전<br />
· 저속, 중속, 고속의 랜덤 속도로 회전</p>
<p><span style="color: #ff0000;"> <strong>[필요 함수]</strong></span><br />
<span style="color: #008000;">randomSeed(seed)</span></p>
<p style="padding-left: 60px;"><span style="color: #008000;">· 난수 초기화 함수</span><br />
<span style="color: #008000;"> · seed : 난수 초기화를 위한 초기값</span></p>
<p>랜덤한 값을 만들어 내기 위한 초기값을 결정하는 함수로 seed값에 따라 랜덤한 값의 시작점이 달라짐. seed값도 랜덤하게 하기 위하여 이 값을 analogRead(A0) 를 수행한 값으로 하면 임의의 랜덤값을 얻을 수 있음</p>
<p><span style="color: #008000;">random(min, max) 또는 random(min)</span></p>
<p style="padding-left: 60px;"><span style="color: #008000;">· 난수값 생성 (리턴값)</span><br />
<span style="color: #008000;"> · min : 난수값의 최소값 (범위 포함)</span><br />
<span style="color: #008000;"> · max : 난수값의 최대값 + 1 (범위 불포함)</span></p>
<p>랜덤한 값을 만들어 내는 함수로 min, max 값을 주어 랜덤값의 범위를 결정함</p>
<p><span style="color: #ff0000;"><strong>[알고리즘]</strong></span><br />
정리된 알고리즘은 아래와 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-08.png" rel="lightbox[28795]"><img class="alignnone size-full wp-image-28911" alt="32 아두이노 08" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-08.png" width="425" height="450" /></a></p>
<p>여기서 주의하여야 할 점은 2가지입니다.<br />
하나는 난수 생성을 어떻게 하는가 하는 것인데, 앞에서 배운 것처럼, 난수를 발행하려면 초기값을 생성해 주어야 하며 이 함수는 random(seed)입니다. 여기서 seed 값에 따라 난수표의 초기 위치가 결정되므로 seed 값도 random으로 입력할 수 있으면 진정한 난수가 될 수 있겠지요. 그래서 보통 사용하는 방법은 이 seed 값을 analogRead(0), 즉 아날로그 포트 0에 아무 것도 연결하지 않은 상태를 읽는 방법을 사용합니다. 포트 0에 신호를 연결하지 않고 그냥 읽으면 일반적으로 0~1023 사이의 랜덤한 값이 읽히게 되는 전기적인 현상을 이용하는 것이지요.<br />
두번째는 속도를 결정하여 이것을 출력하는 것인데, PWM핀에 출력할 때는 이전 예제와는 다르게 digitalWrite( ) 함수를 사용하면 안되고 analogWrite( ) 함수를 사용하여야 한다는 점입니다.<br />
즉, 고속, 중속, 저속의 3가지 경우에 각각 적당한 0~1023 사이의 PWM 값을 결정하여 analogWrite(PWM포트, PWM값)의 형태로 사용하여야 하겠습니다. (실제로는 돌려보고 적당한 값으로 튜닝하는 것이 맞겠네요.)<br />
프로그램은 선풍기 프로그램을 기본으로 난수 발생 함수만 잘 요리하면 되겠습니다. 혼자서도 하실 수 있는 분들은 아래를 보기 전에 먼저 혼자 해 보시구요.</p>
<p>아래와 비슷하게 되겠네요.</p>
<table style="width: 600px;" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>const int MOTOR_PWM = 5; // 모터 PWM 입력핀, PWM핀으로 할당<br />
const int MOTOR_IN1 = 7; // 모터 IN1 입력핀<br />
const int MOTOR_IN2 = 8; // 모터 IN2 입력핀&nbsp;</p>
<p>#define PWM_HIGH 320 // 빠른 속도, 그네 무게에 따라 조정 필요<br />
#define PWM_MID 80 // 중간 속도, 그네 무게에 따라 조정 필요<br />
#define PWM_LOW 20 // 느린 속도, 그네 무게에 따라 조정 필요<br />
#define PWM_ZERO 0 // 정지</p>
<p>void setup()<br />
{<br />
int value;<br />
pinMode(MOTOR_PWM, OUTPUT);<br />
pinMode(MOTOR_IN1, OUTPUT);<br />
pinMode(MOTOR_IN2, OUTPUT);<br />
value = analogRead(0); // A0 포트에 아무런 입력 신호가 없으면 random한 값이 읽혀지는데 이것을 사용<br />
randomSeed(value); // 위 값을 난수 발생의 초기값(seed)으로 사용<br />
}</p>
<p>void loop()<br />
{<br />
int random_value, level;<br />
random_value = random(1, 4);<br />
switch (random_value)<br />
{<br />
case 1: level = PWM_HIGH; break;<br />
case 2: level = PWM_MID; break;<br />
case 3: level = PWM_LOW; break;<br />
default: break;<br />
}<br />
analogWrite(MOTOR_PWM, level); // 한 번은 정회전<br />
digitalWrite(MOTOR_IN1, HIGH);<br />
digitalWrite(MOTOR_IN2, LOW);<br />
delay(random(1,10)*1000); // random(1,10)의 결과는 1~9까지의 정수, 즉 1초~9조간 임의의 시간 동안 회전<br />
analogWrite(MOTOR_PWM, PWM_ZERO);<br />
// 한 번 회전 후에는 항상 2초간 정지<br />
digitalWrite(MOTOR_IN1, LOW);<br />
digitalWrite(MOTOR_IN2, LOW);<br />
delay(2000);<br />
analogWrite(MOTOR_PWM, level); // 다음 번은 역회전<br />
digitalWrite(MOTOR_IN1, LOW);<br />
digitalWrite(MOTOR_IN2, HIGH);<br />
delay(random(1,10)*1000);<br />
// random(3,9)의 결과는 1~9까지의 정수, 즉 1초~9조간 임의의 시간 동안 회전<br />
analogWrite(MOTOR_PWM, PWM_ZERO);<br />
// 한 번 회전 후에는 항상 2초간 정지<br />
digitalWrite(MOTOR_IN1, LOW);<br />
digitalWrite(MOTOR_IN2, LOW);<br />
delay(2000);<br />
}</td>
</tr>
</tbody>
</table>
<p>돌려 본 결과는 아래와 같습니다.</p>
<table style="width: 600px;" border="0">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-22.jpg" rel="lightbox[28795]"><img class="size-medium wp-image-28906 alignleft" alt="32PTB 4강 22" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-22-194x300.jpg" width="194" height="300" /></a></td>
<td><img class="alignnone size-medium wp-image-28907" alt="32PTB 4강 23" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32PTB-4강-23-247x300.jpg" width="247" height="300" /></td>
</tr>
</tbody>
</table>
<p><a href="https://www.youtube.com/watch?v=kPFmsmO6UYw" target="_blank">동영상 보러가기</a></p>
<p>&nbsp;</p>
<p>빌빌빌… 돌기도 하고, 약간 썡~ 돌기도 하네요.</p>
<p>어쨌든 제가 원했던 공중회전그네와 비슷합니다. 저는 만족!<br />
만들고 시험하노라면 시간이 조금 많이 걸리기는 하는데… 그래도 나름 재미있는 DIY를 해 본 것 같습니다.<br />
저는 사실 조금 게을러서… 꾀를 내어 간단히 만들어 보았지만 여러분은 좀 더 멋있게 정말 공중회전그네처럼 만들어서 동작시켜 보시기를 기대해 보겠습니다.<br />
여기까지 함께 하시느라 고생하셨구요.</p>
<p>다음에는 좀 더 즐겁고 재미있는 내용으로 환하게 다시 만나겠습니다! 모두모두, 안녕~~~</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-100.png" rel="lightbox[28795]"><img class="alignnone size-full wp-image-28929" alt="32 아두이노 100" src="http://www.ntrexgo.com/wp-content/uploads/2015/09/32-아두이노-100.png" width="443" height="206" /></a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/28795/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
