<?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/tag/%ec%9e%85%ec%84%a0/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>[56호]라즈베리파이를 활용한 허브 통합 IoT 시스템 구축</title>
		<link>http://www.ntrexgo.com/archives/37675</link>
		<comments>http://www.ntrexgo.com/archives/37675#comments</comments>
		<pubDate>Thu, 31 Oct 2019 00:00:45 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[56호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[입선]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=37675</guid>
		<description><![CDATA[디바이스마트매거진56호 &#124; 비용에 대한 부담과 다양한 제품의 호환 문제들이 우리가 상상하는 스마트홈을 구축하는 데에 있어 결코 지나칠 수 없는 문제점이라 인식했기에 이에 주안점을 두고 스마트홈 제작을 시작하였다]]></description>
				<content:encoded><![CDATA[<p><span style="color: #0000ff"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-1.png" rel="lightbox[37675]"><img class="alignnone size-large wp-image-37678" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-1-620x193.png" width="620" height="193" /></a></strong></span></p>
<p>&nbsp;</p>
<p><span style="font-size: medium"><strong>2019 ICT 융합 프로젝트 공모전 입선</strong></span></p>
<p><span style="font-size: x-large;color: #0000ff"><strong>라즈베리파이를 활용한 허브 통합 IoT 시스템 구축</strong></span></p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> IoT라는 것은 새로운 기술이 아닌, 기존에 있던 장치와 네트워킹 시스템을 연동하도록 하는 것이 가장 큰 핵심 내용입니다. 이러한 IoT의 개념으로 보자면 이 프로젝트는 IoT에 가장 근접한 작품 구성이 아닐까 하는 생각도 듭니다. 완전히 새로운 것이 아닌 이미 구현되어 있는 여러 기술들을 함께 사용할 수 있도록 구성의 중요 포인트에 집중하는 내용은 높이 평가합니다. 라즈베리파이를 이용하여 home bridge를 구성하여 Apple 솔루션을 적용 가능하게 하고, 타사의 상용 솔루션 하드웨어를 채택하고, IoT에 가장 유용히 사용되는 MQTT 적용을 통해 개발 제작자의 의도를 완성 시켜 나가는 방향의 진행은 매우 탁월한 것으로 보입니다. 하지만, 반대로 보자면 자신들만의 하드웨어나 솔루션이 많지 않았다는 것은 단점으로 볼수도 있는 부분이라, 구성에서 주요 파트는 직접 설계 개발하는 형태도 이후 고려하면 좋을듯 합니다.<br />
<strong>뉴티씨</strong> 현실적인 소재를 사용하여 작품을 구현한 점이 눈에 띕니다. 실제로 적용이 가능할 것이라는 생각이 듭니다. IoT 환경에서 실제 생활환경의 장치들을 구현하는 것에 대한 연습으로, 직접 옥내서버를 사용하여 만들었다는 점에서, 로컬한 환경에서의 IoT 환경을 가진 서비스를 제공하는 것으로 작은 규모의 프로젝트 싸이트에서 사용될 수 있을 것으로 생각됩니다. 클라우드 환경에서 운영이 대세인데, 간혹 보안이나 비용등의 이유로 내부에서 운영하기를 원하는 경우도 있는데, 그런 경우에 좋은 예가 될 수 있다고 생각합니다. 좀 더 보완하여, 실제 환경에서 적용되기를 기대해 봅니다.<br />
<strong>위드로봇</strong> 기존 오픈 소스에 이 팀만의 아이디어가 추가로 들어가면 더 좋은 작품이 될 것 같습니다.<br />
<strong>펌테크</strong> 스마트홈 구현에 사용 가능한 다양한 응용분야를 미니어처 형태로 짜임새 있게 잘 구성한 수준급 작품이라고 생각합니다. 아이폰의 음성인식에 사용되는 시리를 사용하여 스마트홈 내부의 다양한 IOT 장치를 기술적으로 안정되게 구현한 점과 스마트홈 제어에 사용한 APP도 심플한 형태로 깔끔하게 잘 구성되었다고 생각합니다. 전체적으로 꼼꼼한 구성과 완성도가 상당히 높은 우수한 작품이라고 생각합니다.</p>
<p><span style="color: #0000ff"><strong>2. 개요</strong></span><br />
알람을 따로 맞춰놓지 않더라도 예정된 일정에 따라 알아서 알람이 울리고, 일제히 전등이 켜지면서 커튼이 따라서 걷힌다. 그날 하루의 일기예보와 집주인의 패션스타일 등을 고려해 옷장에서 그날에 적합한 옷을 골라준다. 시간에 맞춰 씻을 준비를 마쳐놓은 욕실에서 씻고 나온 후 마찬가지로 준비된 식탁에서 아침을 먹고 출근을 하자 집안의 모든 전기기구의 전원이 일제히 내려간다. 우리가 한 번쯤은 영화에서 보거나 상상해본 적 있을법한 미래의 집이다.<br />
인간은 언제나 상상을 현실로 만들기 위해 노력해왔다. 물건을 편하게 옮기고 싶다는 꿈은 바퀴를 만듦으로써 실현되었고, 하늘을 날고 싶다는 오랜 소망은 비행기를 만들어냈다. 같은 맥락으로 살아 움직이는, 알아서 나의 기호에 맞춰주는 집에 대한 상상력은 놀랍게도 영화에서나 볼법한 스마트홈을 IoT시스템을 통해 구현할 수준에 이르렀다.<br />
여기서 스마트홈과 IoT란 정확히 무엇일까? 스마트홈이란 가전제품을 비롯한 집 안의 모든 장치를 연결해 제어하는 기술을 말하며 사물인터넷(Internet of Things : IoT)은 각종 사물에 센서와 통신 기능을 내장하여 인터넷에 연결하는 기술. 즉, 무선 통신을 통해 각종 사물을 연결하는 기술을 의미한다. IoT 시스템을 통해 스마트홈을 구축할 수 있게 된다는 것이다.<br />
시장조사회사 가트너(Gartner)는 2012년 10대 전략기술에 IoT를 처음으로 선정했다. 또한 4차 산업혁명 시대를 선도할 기술로 주목받고 있는 사물인터넷은 처음 업계에 소개된 이후 많은 기업에서 IoT 기술이 탑재된 다양한 가전제품들이 출시되었고, 집안의 많은 가구가 상호 연결되며 상상 속에만 존재하던 스마트홈의 실현이 가능해졌다. 구글에서는 Home Assistant, 애플에서는 HomeKit, 삼성에서는 Smart Things 등 많은 회사에서 자사 IoT 가전제품을 위한 스마트허브를 출시했다. 번거롭게 움직이지 않고 스마트폰 터치만으로 해결할 수 있는 제품들에 소비자들은 환호를 보내며 매년 판매량 또한 증가하고 있다. 하지만 HY-ENA팀은 각 회사별 제품에서 공통적 장점인 편의성뿐만이 아니라 단점에도 주목하지 않을 수 없었다. 스마트 홈의 중추 역할을 해줄 스마트 허브의 가격은 결코 저렴한 가격이 아닐뿐더러 이를 구매하였을 시에 회사마다 고유의 통신 프로토콜을 통해 작동된다. 즉, A라는 회사의 스마트 허브를 구매하였을 시 A사의 IoT 가전제품만으로 스마트홈을 구성해야 하는, 소비자의 입장에서 선택의 폭이 좁아지는 문제가 발생하였다.<br />
이렇게 비용에 대한 부담과 다양한 제품의 호환 문제들이 우리가 상상하는 스마트홈을 구축하는 데에 있어 결코 지나칠 수 없는 문제점이라 인식했기에 이에 주안점을 두고 스마트홈 제작에 착수하게 되었다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #008080"><strong>3.1. 주요 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-2.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37680" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-2.png" width="620" height="347" /></a></p>
<p>저비용과 호환성은 HY-NEA팀이 구상한 스마트 홈 구축에 꼭 필요한 요소였다. 이에 매우 적합한 물건인 라즈베리 파이를 스마트 홈 허브로 이용하였다. 라즈베리 파이는 영국의 라즈베리 파이 재단에서 컴퓨터 프로그래밍 및 과학 교육 증진을 위해 만들어진 SBC(Single Board Computer)로 저렴한 가격과 확장성으로 널리 사용되고 있다.<br />
라즈베리 파이에 Node.js 기반으로 만들어진 홈킷 에뮬레이션 서버인 Homebridge를 다운받아 이를 각종 스마트 홈 디바이스에 연결하면 아이폰 홈 앱을 통해 손쉽게 제어가 가능해진다. 다시 말해, Apple HomeKit 액세서리 인증을 받지 못한 IoT 기기라도 이 Homebridge를 통해 홈 앱으로 제어할 수 있다. 또한 아이폰에 내장되어 있는 앱은 Siri를 통한 제어를 기본 지원하기 때문에 IoT 기기들을 음성인식으로 제어할 수 있는 장점이 있다. Homebridge를 설치한 라즈베리 파이는 IoT 장치들과 네트워크로 연결되어 아이폰에서 입력된 명령을 IoT 장치들로 전송해준다.<br />
HY-ENA 팀은 직접 제작한 IOT기기 뿐만 아니라 이미 나와있는 샤오미 온습도계를 연동하였고, Wi-Fi로 동작하는 장치들에는 다양한 프로토콜(HTTP, MQTT)을 적용했다. 이를 Homebridge와 연동해 홈 앱에서 작동되는 것을 확인함으로서 이미 나와있는 IoT 장치들과의 호환성을 확인했다. 이러한 스마트홈 가전제품들이 Wi-Fi공유기의 네트워크 내부 디바이스들과 통신하며 홈 앱에서 입력된 명령을 실행한다. HY-ENA팀에서 만든 스마트 콘센트를 예로 들자면 사용자의 홈 앱과 스마트 콘센트가 같은 네트워크 안에 존재할 때 사용자가 홈 앱에 명령을 입력하면 이를 Homebridge에서 인식해 명령을 출력해 주는 구조이다.</p>
<p><span style="color: #008080"><strong>3.2. 전체 시스템 구성</strong></span><br />
스마트홈 시스템을 구축하기 위한 전제조건은 Wi-Fi 환경이다. 각각의 떨어져있는 IoT 기기들과 서버 역할을 하는 라즈베리파이 그리고 이를 제어할 스마트폰까지 동일한 네트워크에 속해 있어야 서로 통신을 할 수 있다. HY-ENA 팀은 네트워크를 구축하기 위해 공유기 한 대를 ‘IoT’라는 SSID로 설정해 운용했다. Zigbee는 Wi-Fi에 비해 속도는 느리지만 훨씬 적은 전력을 소모하기 때문에 배터리를 전원으로 사용하는 장치에는 적합한 통신이다. 샤오미의 온습도 센서는 Zigbee 통신을 사용하기 때문에 이를 지원하기 위해 라즈베리파이에 Ti 사의 CC2531기반의 Zigbee Packet Sniffer 모듈을 추가했다. 따라서 이번 프로젝트에서는 Wi-Fi 와 Zigbee 환경 모두를 지원할 수 있게 되었다.<br />
네트워크가 구축이 되었다면 ESP-8266을 이용하여 IoT기기 각각의 서버를 만들어 접속을 시켜준다. 동작이 단순한 스마트콘센트와 스마트전등의 구현은 ESP-01을 통하여 구현한다. 커튼 및 선풍기 미니어쳐는 제어를 위하여 PWM 출력 및 여러 개의 I/O를 사용하기 때문에 ESP-12E 와이파이 모듈을 탑재한 개발보드인 nodeMCU를 사용한다. 이로써 시스템을 구성하기 위한 하드웨어는 준비가 끝났다.<br />
Wi-Fi로 통신하는 기기들은 HTTP 와 MQTT 프로토콜로 Homebridge 와 통신하게 된다. 스마트 폰은 HTTP 프로토콜로 Homebridge 와 통신하지만, 선풍기 미니어처는 전원 On/Off 제어와 속도 제어까지 해야하기 때문에 MQTT 프로토콜을 이용해 통신한다.</p>
<p><span style="color: #008080"><strong>3.3. 개발 환경</strong></span><br />
<span style="color: #99cc00"><strong>3.3.1. 아두이노 개발도구(Arduino IDE)와 Visual Studio 설치</strong></span><br />
전체적인 작품제작 과정에서 우리가 이용할 디바이스는 ESP-8266(ESP-01, NodeMCU)였다. 이 디바이스들은 간단하게 코드 업로드가 가능하며 스마트 홈에서의 통신에도 중요한 역할을 한다. 위 디바이스에 우리가 작성한 코드를 업로드하기 위해 아두이노 IDE를 사용했다. 원래 아두이노 IDE는 아두이노 개발환경에서 코드 업로드를 위해 사용되나, 우리는 아두이노 IDE에 ESP보드 라이브러리 설치를 통해 ESP 모듈에 코드 업로드를 가능하게 했다.<br />
코드 작성을 하기에 앞서 아두이노 IDE는 간편함을 중점으로 나온 통합 개발환경이기 때문에 지속적으로 개발을 하기에는 불편한 점이 많다. 따라서 우리는 좀 더 편한 개발환경을 위해 코드 작성은 Visual Studio에서 하고 컴파일 및 업로드는 아두이노 IDE의 기능을 사용하였다. 또한 이 두 프로그램을 연동시켜주는 Visual micro 플러그인을 사용하여 Visual Studio에서 코드 작성부터 ESP 보드에 업로드까지 가능하게 하였다.</p>
<p><span style="color: #99cc00"><strong>3.3.2. 스마트 홈 개발을 위한 네트워크 환경 구축</strong></span><br />
IoT 기기간의 통신은 기본적으로 Wi-Fi 환경을 기반으로 이루어진다. 따라서 우리는 개발용 공유기를 별도로 설치해 SSID = ‘IoT’, Password = ‘12345678’ 으로 설정하여 사용하였다. 또한 이 프로젝트에서 사용하는 장비중 샤오미 온습도계는 Zigbee 환경을 사용하기 때문에 라즈베리파이에 CC2531기반의 Zigbee Packet Sniffer 모듈을 장착하여 Zigbee 통신환경도 구축하였다.</p>
<p><span style="color: #99cc00"><strong>3.3.3. 라즈베리 파이 개발환경(raspbian이미지 라이팅, ssh 활성화) 구축</strong></span><br />
라즈베리 파이를 사용하기에 앞서 라즈베리 파이를 운용할 수 있도록 운영체제를 설치해 주어야 한다. 라즈베리 파이에서 사용되는 라즈비안(Raspbian)은 리눅스 계열의 운영체제인데 이는 라즈베리 파이 홈페이지(https://www.raspberrypi.org)에서 다운받을 수 있다. 우리는 Raspbian Stretch (2018.11 version)을 사용했다. 라즈비안 이미지를 sd카드에 라이팅(복사) 해야 하는데 이때 ‘rufus’ usb 툴을 이용했다. rufus는 부팅 가능한 ISO파일(윈도우, 리눅스 등)을 usb를 이용하여 설치할 때 사용된다.<br />
2016년 11월 25일 이후, 출시된 라즈비안은 보안상의 이유로 디폴트로 ssh가 비활성화 되어 있다. 활성화 하기 위해서는 라즈비안 sd 카드의 root 폴더에 ssh 라는 이름의 파일을 생성해주면 활성화 된다.<br />
<span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #008080"><strong>4.1. 라즈베리파이 개발환경 구축 (Node.js 및 Homebridge 설치)</strong></span><br />
<span style="color: #99cc00"><strong>4.1.1. 라즈베리 파이에 할당된 IP 확인</strong></span><br />
명령 프롬프트에 ‘ipconfig’ 라는 명령어를 실행하면 기본 게이트웨이(사용자의 컴퓨터와 라즈베리파이가 사용하는 공유기) ip를 알아낸다. 게이트 웨이 ip를 통해 공유기 관리 페이지에 접속한다. 라즈베리파이에 랜선이 연결되어 있다면 라즈베리 파이는 이 공유기 네트워크를 사용하므로 할당된 IP를 확인할 수 있다.</p>
<p><span style="color: #99cc00"><strong>4.1.2. powershell을 통해 라즈베리파이 접속</strong></span><br />
Windows 에서 PowerShell은 시스템 관리자를 위해 특별히 설계된 Windows 명령줄 셸이다. powershell을 켠 후 라즈베리 파이에 접속하기위해 다음과 같은 명령어를 작성한다.<br />
ssh pi@192.168.2.13(HY-ENA팀이 할당받은 라즈베리 파이 IP 예시)<br />
다음은 비밀번호를 입력하는데 이는 디폴트값으로 raspberry 로 설정되어 있다.</p>
<p><span style="color: #99cc00"><strong>4.1.3. 시스템 최적화</strong></span><br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
위 명령어는 시스템에 설치된 프로그램들을 최신화하는 과정이다.</p>
<p><span style="color: #99cc00"><strong>4.1.4. Homebridge 설치에 필요한 라이브러리 설치</strong></span><br />
Homebridge는 Node.js 기반 애플리케이션이므로 Node.js를 먼저 설치한다.<br />
필요한 라이브러리를 설치한다.</p>
<p style="padding-left: 90px">wget -O &#8211; https://raw.githubusercontent.com/sdesalas/node-pi-zero/master/install-node-v.lts.sh | bash</p>
<p>Homebridge를 설치한다. 다음과 같이 -g 옵션을 주어 전역 패키지로 설치한다.</p>
<p style="padding-left: 60px">$ sudo apt-get install libavahi-compat-libdnssd-dev</p>
<p>다음과 같이 node.sh 프로필을 작성한다.</p>
<p style="padding-left: 60px">$ npm i -g homebridge</p>
<p>텍스트 에디터로 위의 파일을 열어서 다음과 같이 입력하고 저장한다.</p>
<p style="padding-left: 60px">sudo touch /etc/profile.d/node.sh<br />
sudo chmod +x /etc/profile.d/node.sh</p>
<p>export PATH=$PATH:/opt/nodejs/bin</p>
<p><span style="color: #99cc00"><strong>4.1.5. Homebridge 데몬화</strong></span><br />
Homebridge의 데몬화는 프로세스를 background에서 이용하기 위해 필요하다. Homebridge서버 관리를 위해 Node.js의 프로세스 매니저인 pm2를 설치한다. 먼저 PM2를 설치하고 OS를 리부트할 때 PM2가 자동으로 시작되도록 설정한다.</p>
<p><span style="color: #99cc00"><strong>4.1.6. 플러그인 설치</strong></span></p>
<p style="padding-left: 60px">$ npm i -g pm2<br />
$ pm2 startup systemd<br />
$ cd ~/.homebridge<br />
$ pm2 start homebridge<br />
$ pm2 save</p>
<p>homebridge는 NPM에서 다양한 플러그인을 다운로드 받아 설치해 줄 수 있다. 이번 프로젝트에서 사용한 플러그인은 다음과 같다.<br />
위의 4개의 플러그인을 설치하기위해 SSH 쉘에 아래와 같이 입력한다.</p>
<p style="padding-left: 60px">homebridge-config-ui-x : homebridge를 편하게 설정하기 위한 플러그인<br />
homebridge-http : HTTP 프로토콜을 사용하기 위한 플러그인<br />
homebridge-fan-accessory : MQTT프로토콜로 Fan을 제어하기 위한 플러그인<br />
homebridge-zigbee : Zigbee 모듈을 사용하기 위한 플러그인</p>
<p>미니어처 선풍기는 MQTT 프로토콜을 사용하기 때문에 MQTT Broker를 설치해야 한다. MQTT Broker 로는 오픈소스 Broker인 Mosquitto를 사용한다.</p>
<p style="padding-left: 60px">npm i -g homebridge-config-ui-x<br />
npm i -g homebridge-http<br />
npm i -g homebridge-fan-accessory<br />
npm i -g homebridge-zigbee</p>
<p>모든 설치를 다 했다면 이를 homebridge에서 사용할 수 있도록 config.json 파일에 등록을 해줘야 한다. config.json 파일은 ./homebridge 경로에 있다.</p>
<p style="padding-left: 60px">wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key<br />
sudo apt-get add mosquitto-repo.gpg.key<br />
cd /etc/apt/sources.list.d/<br />
sudo wget http://repo.mosquitto.org/debian/mosquitto-stretch.list<br />
sudo apt-get update<br />
sudo apt-get install mosquitto mosquitto-clients<br />
sudo /etc/init.d/mosquitto.conf</p>
<p>config.json 파일은 보고서의 길이를 고려하여 6.기타에 별도로 첨부하였다. 이렇게 config.json 파일을 작성하면 라즈베리 파이 환경 구축이 끝난다.</p>
<p style="padding-left: 60px">cd ~/.homebridge<br />
nano config.json</p>
<p><span style="color: #99cc00"><strong>4.1.7. Homebridge 등록</strong></span><br />
아이폰에 있는 “홈” 앱에 위에서 설정한 Homebridge를 등록한다. 그림에서 나타난 QR 코드를 이용한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-3.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37682" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-3.png" width="620" height="347" /></a></p>
<p><strong style="color: #008080">4.2. 릴레이를 이용한 스마트 콘센트</strong></p>
<p><span style="color: #99cc00"><strong>4.2.1. ESP-01에 스케치 업로드</strong></span><br />
이 디바이스들은 공통적으로 ESP-01 Wi-Fi 모듈을 이용한다. ESP-01 은 Wi-Fi 네트워크 통신을 지원하는 통신 모듈로, 하드웨어 제어 기능도 상당부분 수행할 수 있다. ESP-01에 하드웨어 제어를 위한 코드를 업로드하기 위해 Serial Programming 모드로 실행시킨다. 코드를 업로드 하기 위해 PC와 연결해야 하는데 이때는 FTDI 모듈을 사용했다. FTDI와 ESP-01의 각 단자별 연결법을 아래에 설명했다.</p>
<p>&lt;ESP-01&gt; &lt;FTDI&gt;<br />
RX &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&gt; TX<br />
TX &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&gt; RX<br />
GPIO0 (LOW) &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&gt; GND<br />
GPIO2 (HIGH) &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&gt; VCC<br />
VCC (HIGH) &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&gt; 3.3V<br />
GND (LOW) &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-&gt; GND<br />
CH_PD (HIGH) &#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&gt; VCC</p>
<p>여기서 주의할 점은 ESP-01은 3.3V 전압을 이용한다는 점이다. 이번 프로젝트에서는 ESP-01을 개발하기위한 IDE로 아두이노 IDE를 사용할 것이다. 따라 Serial Programming 모드가 실행되었다면, 아두이노 IDE를 이용하여 스케치를 업로드한다.</p>
<p><span style="color: #99cc00"><strong>4.2.2. 회로구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-4.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37684" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-4.png" width="620" height="350" /></a></p>
<p>회로구성에 있어서 중요한 점은 ESP-01모듈에는 전원이 지속적으로 공급되어야 함과 동시에 콘센트와 전구에는 전원이 끊겨있는 상태를 유지하는 것이었다. 이를 실현시키기 위해서 콘센트와 전구에 들어가는 (+)전선을 끊어 그 사이에 릴레이를 배치했다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-1.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37677" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-1.jpg" width="620" height="353" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-2.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37679" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-2.jpg" width="620" height="353" /></a></p>
<p>이 릴레이는 ESP-01에서 신호를 주었을 때만 연결되도록 설계되었다. 이와 별개로 ESP-01모듈에는 3.3V전원이 지속적으로 공급되어야 하는데 이는 끊기지 않은(-) 전원과 플러그에서 나와 릴레이로 곧바로 들어가는 (+)전선에서 선을 따로 빼 AC to DC 컨버터에 연결했다. 컨버터에서 변압된 3.3V DC 전류는 ESP-01에 공급되어 콘센트와 전구에는 전원이 끊겨있는 상태는 유지하면서 외부에서의 제어에는 반응할 수 있는 상태로 만들 수 있게 되었다.</p>
<p><span style="color: #008080"><strong>4.3. DC모터 및 L9110 드라이브를 이용한 스마트 커튼 미니어쳐 제작</strong></span><br />
스마트 커튼 미니어쳐 제작의 핵심은 DC모터의 정역회전을 제어하는 것인데 이는 L9110 드라이버를 이용하여 구현하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-5.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37686" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-5.png" width="620" height="352" /></a></p>
<p>L9110 드라이버의 모습과 각 핀에 대한 설명이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-6.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37688" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-6.png" width="620" height="316" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-3.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37681" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-3.jpg" width="620" height="299" /></a></p>
<p>모터의 회전을 제어하기 위해 두개의 입력이 필요하므로 nodeMCU (ESP-8266)와 드라이버를 연결하는 회로를 구성한 후 Visual Micro를 통해 코드를 업로드하여 드라이버에 입력되는 값을 제어할 수 있게 하였다.</p>
<p><span style="color: #008080"><strong>4.4. 선풍기 미니어처 제작</strong></span><br />
<span style="color: #99cc00"><strong>4.4.1. nodeMCU와 MQTT 프로토콜</strong></span><br />
이 선풍기 미니어처에는 앞에서 사용하였던 ESP-8266계열의 ESP-01 Wi-Fi 모듈을 사용하지 않고 ESP-12E 모듈 기반의 nodeMCU를 사용하였다. 둘다 Wi-Fi 네트워크 통신을 지원하는 통신 모듈이며, 하드웨어 제어 기능 있었지만 pwm(펄스폭 제어) 기능을 ESP-01에서는 지원하지 않기 때문에 nodeMCU를 선택하게 되었다. 이 pwm 기능을 통해 선풍기는 단계적으로 속도를 제어할 수 있게 되었다.<br />
또한 단순히 켜고 끔만 통제하는 것이 아닌 속도제어까지 해야하기 때문에 HTTP 프로토콜이 아닌 MQTT 프로토콜을 사용하였다. MQTT 프로토콜은 MQTT Client가 MQTT broker에게 메시지를 publish 하게 되면 이를 subscribe한 또다른 MQTT Client(연결된 기기)들이 메시지를 수신하는 구조의 프로토콜로 메시지 내용에 다양한 내용을 담을 수 있기 때문에 HTTP 대비 더욱 복잡한 제어를 할 수 있다는 장점이 있다.</p>
<p><span style="color: #99cc00"><strong>4.4.2. 회로구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-7.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37690" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-7.png" width="620" height="333" /></a><br />
회로 구성에 있어서 한 개의 capacitor를 사용하였다. 모터가 동작하는 데에 있어 상대적으로 큰 전류를 사용하기에 전원공급이 불안정해질 수 있었다. 이에 전압이 불안정해지고 ESP-12E 모듈이 불안정해졌기 때문에 50V 100㎌의 capacitor를 사용해 이 문제를 해결하였다.</p>
<p>※스마트 선풍기 세기별 작동상태</p>
<p><span style="color: #008080"><strong>4.5. CC2531 Zigbee packet sniffer를 이용한 샤오미 온습도 센서 연동</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-4.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37683" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-4.jpg" width="620" height="418" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-5.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37685" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-5.jpg" width="620" height="418" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-6.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37687" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-6.jpg" width="620" height="393" /></a></p>
<p>샤오미 온습도계는 Wi-Fi 통신을 사용하는 것이 아닌 Zigbee 통신을 사용한다. 원래는 샤오미 온습도계를 사용하기 위해서는 샤오미 게이트웨이를 통해 연결해야 하지만 이번 프로젝트에서는 Ti 사의 CC2531 Zigbee Packet Sniffer를 이용하여 게이트웨이 없이 바로 Homebridge에 연결하여 홈앱에서 사용할 수 있도록 하였다.<br />
CC2531 Zigbee 모듈을 Homebridge에서 사용하기 위해서는 펌웨어를 교체해야 한다. 펌웨어를 교체하기 위해서는 SmartRF Flash Programmer 프로그램과 Smartrf04EEB 프로그래머 보드를 이용해야 하므로 링크(https://github.com/itsmepetrov/homebridge-zigbee/blob/HEAD/docs/Flashing.md)에서 드라이버와 교체할 펌웨어를 다운로드받는다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-8.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37692" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-8.png" width="620" height="336" /></a></p>
<p>펌웨어를 업로드 한 뒤 라즈베리파이에 연결하고 Config.json을 설정한 다음 Homebridge를 실행하면 홈앱 화면에 Permit Join 이라는 스위치가 생긴다. 그 후 Permit Join 스위치를 켜고 Zigbee 기기와 페어링을 진행하면 .homebridge 폴더에 Zigbee.db 라는 파일이 생성되며 그 파일 안에 페어링 된 기기가 등록된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-9.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37694" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-9.png" width="620" height="343" /></a></p>
<p><strong><span style="color: #008080">4.6. 우드락을 이용한 홈 미니어쳐 제작</span></strong></p>
<p>스마트 홈 구현과 시연을 위해 우드락으로 집 모형을 제작하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-7.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37689" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-7.jpg" width="620" height="351" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-8.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37691" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-8.jpg" width="620" height="351" /></a></p>
<p><span style="color: #0000ff"><strong>5. 스마트 홈 구현</strong></span><br />
스마트 콘센트</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-10.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37696" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-10.png" width="620" height="355" /></a></p>
<p>스마트 전구</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-11.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37697" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-11.png" width="620" height="355" /></a><br />
스마트 커튼</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-12.png" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37698" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-12.png" width="620" height="353" /></a></p>
<p>스마트 선풍기</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-9.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37693" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-9.jpg" width="620" height="395" /></a><br />
온습도계</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-10.jpg" rel="lightbox[37675]"><img class="alignnone size-full wp-image-37695" alt="56 ict 라즈베리를 활용한 iot 시스템구축 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ict-라즈베리를-활용한-iot-시스템구축-10.jpg" width="620" height="347" /></a></p>
<p><strong style="color: #0000ff">6. 기타</strong></p>
<p><span style="color: #008080"><strong>6.1. 소스코드</strong></span><br />
<strong>6 config.json 파일</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>{ “bridge”: {<br />
“name”: “Homebridge”,<br />
“username”: “CC:22:3D:E3:4A:30”,<br />
“port”: 51826,<br />
“pin”: “031-78-157”<br />
},<br />
“accessories”: [<br />
{<br />
“accessory”: “Http”,<br />
“name”: “SmartPlug”,<br />
“on_url”: “http://192.168.2.5/gpio/0”,<br />
“off_url”: “http://192.168.2.5/gpio/1”,<br />
“http_method”: “GET”<br />
},<br />
{<br />
“accessory”: “Http”,<br />
“name”: “Smart_Light”,<br />
“on_url”: “http://192.168.2.9/crispy/0”,<br />
“off_url”: “http://192.168.2.9/crispy/1”,<br />
“http_method”: “GET”<br />
},<br />
{<br />
“accessory”: “Http”,<br />
“name”: “Curtain”,<br />
“on_url”: “http://192.168.2.10/curtain/0”,<br />
“off_url”: “http://192.168.2.10/curtain/1”,<br />
“http_method”: “GET”<br />
},<br />
{<br />
“accessory”: “fan-accessory-rotation”,<br />
“name”: “Room Fan”,<br />
“url”: “mqtt:localhost”,<br />
“topics”: {<br />
“getOn”: “getFanOn”,<br />
“setOn”: “OnOff”,<br />
“getRotationSpeed”: “getSpeed”,<br />
“setRotationSpeed”: “Speed”<br />
}<br />
}<br />
],<br />
“platforms”: [<br />
{<br />
“platform”: “config”,<br />
“name”: “Config”,<br />
“port”: 8080,<br />
“sudo”: false<br />
},<br />
{<br />
“platform”: “ZigBeePlatform”<br />
}<br />
]
}<br />
</div>
<p><strong>Relay Switch를 이용한 스마트 콘센트 제어 스마트 전등 및 스마트 콘센트 소스코드</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;ESP8266WiFi.h&gt;</p>
<p>#define relay_pin 0</p>
<p>const char* ssid = “IOT”;<br />
const char* password = “12345678”;</p>
<p>WiFiServer server(80);</p>
<p>void setup() {<br />
Serial.begin(115200);<br />
delay(10);</p>
<p>pinMode(relay_pin, OUTPUT);</p>
<p>digitalWrite(relay_pin, 1);</p>
<p>WiFi.begin(ssid, password);</p>
<p>while (WiFi.status() != WL_CONNECTED) {<br />
delay(500);<br />
}<br />
server.begin();<br />
}</p>
<p>void loop() {</p>
<p>// Serial.println(“intro”);<br />
// Check if a client has connected<br />
WiFiClient client = server.available();<br />
// Serial.println(digitalRead(sw_pin));</p>
<p>if (!client) {<br />
return;<br />
}</p>
<p>// Wait until the client sends some data<br />
while (!client.available()) {<br />
// Serial.println(“0”);</p>
<p>delay(10);<br />
}</p>
<p>// Serial.println(“2”);</p>
<p>// Read the first line of the request<br />
String req = client.readStringUntil(‘\r’);<br />
Serial.println(req);<br />
client.flush();</p>
<p>// Serial.println(“3”);</p>
<p>// Match the request<br />
int val;<br />
if (req.indexOf(“/gpio/0”) != -1) {<br />
val = 0;<br />
}<br />
else if (req.indexOf(“/gpio/1”) != -1) {<br />
val = 1;<br />
}<br />
else {<br />
client.stop();<br />
return;<br />
}</p>
<p>// Serial.println(“4”);</p>
<p>// Set GPIO according to the request<br />
digitalWrite(relay_pin, val);</p>
<p>client.flush();</p>
<p>// Prepare the response<br />
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;\r\nGPIO is now “;<br />
s += (val) ? “high” : “low”;<br />
s += “&lt;/html&gt;\n”;</p>
<p>// Send the response to the client<br />
client.print(s);<br />
delay(1);</p>
<p>//Serial.println(“5”);<br />
}</p>
<p>*스마트 전등</p>
<p>#include &lt;ESP8266WiFi.h&gt;</p>
<p>#define relay_pin 0</p>
<p>const char* ssid = “IOT”;<br />
const char* password = “12345678”;</p>
<p>WiFiServer server(80);</p>
<p>void setup() {<br />
Serial.begin(115200);<br />
delay(10);</p>
<p>pinMode(relay_pin, OUTPUT);</p>
<p>digitalWrite(relay_pin, 1);</p>
<p>WiFi.begin(ssid, password);</p>
<p>while (WiFi.status() != WL_CONNECTED) {<br />
delay(500);<br />
}<br />
server.begin();<br />
}</p>
<p>void loop() {</p>
<p>// Serial.println(“intro”);<br />
// Check if a client has connected<br />
WiFiClient client = server.available();<br />
// Serial.println(digitalRead(sw_pin));</p>
<p>if (!client) {<br />
return;<br />
}</p>
<p>// Wait until the client sends some data<br />
while (!client.available()) {<br />
// Serial.println(“0”);</p>
<p>delay(10);<br />
}</p>
<p>// Serial.println(“2”);</p>
<p>// Read the first line of the request<br />
String req = client.readStringUntil(‘\r’);<br />
Serial.println(req);<br />
client.flush();</p>
<p>// Serial.println(“3”);</p>
<p>// Match the request<br />
int val;<br />
if (req.indexOf(“/crispy/0”) != -1) {<br />
val = 0;<br />
}<br />
else if (req.indexOf(“/crispy/1”) != -1) {<br />
val = 1;<br />
}<br />
else {<br />
client.stop();<br />
return;<br />
}</p>
<p>// Serial.println(“4”);</p>
<p>// Set GPIO according to the request<br />
digitalWrite(relay_pin, val);</p>
<p>client.flush();</p>
<p>// Prepare the response<br />
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;\r\nGPIO is now “;<br />
s += (val) ? “high” : “low”;<br />
s += “&lt;/html&gt;\n”;</p>
<p>// Send the response to the client<br />
client.print(s);<br />
delay(1);</p>
<p>//Serial.println(“5”);<br />
}</p>
<p>void sw_interrupt(int sw_statue)<br />
{<br />
WiFiClient client;<br />
int val;<br />
val = !sw_statue;<br />
digitalWrite(relay_pin, val);<br />
// Prepare the response<br />
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;\r\nGPIO is now “;<br />
s += (val) ? “high” : “low”;<br />
s += “&lt;/html&gt;\n”;</p>
<p>// Send the response to the client<br />
client.print(s);<br />
delay(1);<br />
}<br />
</div>
<p><strong></strong><br />
<strong> DC모터 및 L9110 드라이브를 이용한 커튼 미니어쳐 제작</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;ESP8266WiFi.h&gt;</p>
<p>#define motor_1 4<br />
#define motor_2 5</p>
<p>const char* ssid = “IOT”;<br />
const char* password = “12345678”;</p>
<p>WiFiServer server(80);</p>
<p>int val = 3;<br />
void setup() {<br />
Serial.begin(115200);<br />
delay(10);</p>
<p>pinMode(motor_1, OUTPUT);<br />
pinMode(motor_2, OUTPUT);<br />
digitalWrite(motor_1, LOW);<br />
digitalWrite(motor_2, LOW);</p>
<p>WiFi.begin(ssid, password);</p>
<p>while (WiFi.status() != WL_CONNECTED) {<br />
delay(500);<br />
}<br />
server.begin();<br />
Serial.println(“IP address: “);<br />
Serial.println(WiFi.localIP());<br />
}</p>
<p>void loop() {</p>
<p>WiFiClient client = server.available();</p>
<p>if (!client) {<br />
return;<br />
}</p>
<p>while (!client.available()) {<br />
delay(10);<br />
}</p>
<p>String req = client.readStringUntil(‘\r’);<br />
Serial.println(req);<br />
client.flush();</p>
<p>if (req.indexOf(“/curtain/0”) != -1) {<br />
val = 0;<br />
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;\r\nGPIO is now “;<br />
s += (val) ? “high” : “low”;<br />
s += “&lt;/html&gt;\n”;</p>
<p>client.print(s);<br />
Serial.println(“curtain/0”);<br />
delay(1);<br />
}<br />
else if (req.indexOf(“/curtain/1”) != -1) {<br />
val = 1;<br />
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n&lt;!DOCTYPE HTML&gt;\r\n&lt;html&gt;\r\nGPIO is now “;<br />
s += (val) ? “high” : “low”;<br />
s += “&lt;/html&gt;\n”;</p>
<p>client.print(s);<br />
Serial.println(“curtain/1”);<br />
delay(1);<br />
}<br />
else {<br />
client.stop();<br />
return;<br />
}<br />
if (val == 0) {<br />
digitalWrite(motor_1, HIGH);<br />
digitalWrite(motor_2, LOW);<br />
delay(7000);<br />
digitalWrite(motor_1, LOW);<br />
digitalWrite(motor_2, LOW);<br />
val = 3;<br />
}<br />
else if (val == 1) {<br />
digitalWrite(motor_2, HIGH);<br />
digitalWrite(motor_1, LOW);<br />
delay(7000);<br />
digitalWrite(motor_1, LOW);<br />
digitalWrite(motor_2, LOW);<br />
val = 3;<br />
}<br />
client.flush();<br />
}<br />
</div>
<strong> IRF520 Mosfet을 이용한 선풍기 미니어쳐 제작</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;ESP8266WiFi.h&gt;<br />
#include &lt;PubSubClient.h&gt;</p>
<p>const char* ssid = “IOT”;<br />
const char* password = “12345678”;<br />
const char* mqtt_server = “192.168.2.8”; //MQTT Broker 서버 주소<br />
char* Fan_OnOff = “OnOff”; //OnOff 토픽을 Fan_OnOff 로 설정<br />
char* Fan_Speed = “Speed”; //Speed 토픽을 Fan_Speed 로 설정</p>
<p>WiFiClient espClient;<br />
PubSubClient client(espClient);<br />
long lastMsg = 0;<br />
char msg[50];<br />
int value = 0;<br />
int pwm_value = 0;<br />
bool onoff;</p>
<p>//WI-FI 설정부분<br />
void setup_wifi() {</p>
<p>delay(10);<br />
Serial.println();<br />
Serial.print(“Connecting to “);<br />
Serial.println(ssid);</p>
<p>WiFi.begin(ssid, password);</p>
<p>while (WiFi.status() != WL_CONNECTED) {<br />
delay(500);<br />
Serial.print(“.”);<br />
}</p>
<p>randomSeed(micros());</p>
<p>Serial.println(“”);<br />
Serial.println(“WiFi connected”);<br />
Serial.println(“IP address: “);<br />
Serial.println(WiFi.localIP());<br />
}</p>
<p>//MQTT 메세징이 도착했을때 CallBack 해주는 함수<br />
void callback(char* topic, byte* payload, unsigned int length) {<br />
int j = 0;<br />
pwm_value = 0;<br />
Serial.println(length);<br />
if (length == 4) //메세지 길이가 4글자이면(true)<br />
onoff = true;<br />
else if (length == 5) //메세지 길이가 5글자이면(false)<br />
onoff = false;<br />
if (onoff == true) {<br />
if ((char)payload[0] &gt;= 48 &amp;&amp; (char)payload[0] &lt;= 57) {<br />
for (int i = length; i &gt; 0; i&#8211;) {<br />
pwm_value += ((char)payload[i - 1] &#8211; 48) * pow(10, j); //메세지로 받은 내용을 숫자로 변경<br />
j++;<br />
}<br />
Serial.print(“PWM : “);<br />
Serial.println(pwm_value);<br />
analogWrite(5, pwm_value * 2); //PWM 출력<br />
}<br />
}<br />
else if (onoff == false) {<br />
analogWrite(5, 0);<br />
}</p>
<p>}<br />
//예외 처리<br />
void reconnect() {<br />
// Loop until we’re reconnected<br />
while (!client.connected()) {<br />
Serial.print(“Attempting MQTT connection&#8230;”);<br />
// Create a random client ID<br />
String clientId = “ESP8266Client-”;<br />
clientId += String(random(0xffff), HEX);<br />
// Attempt to connect<br />
if (client.connect(clientId.c_str())) {<br />
Serial.println(“connected”);<br />
// Once connected, publish an announcement&#8230;<br />
client.publish(“outTopic”, “hello world”);<br />
// &#8230; and resubscribe<br />
client.subscribe(“inTopic”);<br />
}<br />
else {<br />
Serial.print(“failed, rc=”);<br />
Serial.print(client.state());<br />
Serial.println(“ try again in 5 seconds”);<br />
}<br />
}<br />
}</p>
<p>void setup() {<br />
Serial.begin(115200);<br />
setup_wifi();<br />
client.setServer(mqtt_server, 1883); //MQTT 서버 접속<br />
client.setCallback(callback); //Callback 설정<br />
}</p>
<p>void loop() {</p>
<p>if (!client.connected()) {<br />
reconnect();<br />
client.subscribe(Fan_OnOff); //Fan_OnOff 토픽 구독<br />
client.subscribe(Fan_Speed); //Fan_Speed 토픽 구독<br />
}<br />
client.loop();<br />
}<br />
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/37675/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[56호]yoyo! Toilet Paper</title>
		<link>http://www.ntrexgo.com/archives/37426</link>
		<comments>http://www.ntrexgo.com/archives/37426#comments</comments>
		<pubDate>Thu, 31 Oct 2019 00:00:05 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[56호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이스마트]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[입선]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=37426</guid>
		<description><![CDATA[디바이스마트매거진 56호 &#124; 공공 화장실의 두루마리 휴지를 낭비없이 깨끗하고 깔끔하게 이용하도록 도와주는 제품을 만든다. ]]></description>
				<content:encoded><![CDATA[<p><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-1.png" rel="lightbox[37426]"><img class="alignnone size-large wp-image-37728" alt="56 ICT YOYO  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-1-620x192.png" width="620" height="192" /></a></strong></p>
<p><strong>2019 ICT 융합 프로젝트 공모전 입선</strong></p>
<p><span style="font-size: x-large"><strong>yoyo! Toilet Paper </strong></span></p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 기술적 난이도 보다는 아이디어가 돋보이는 개발 작품입니다. 실생활에서 느끼는 불편함을 아주 간단하게 해결할수 있는 방안을 보여준듯 합니다. 간단한 아이디어와 심플한 구성으로 작품에 대하여 흥미를 끌게 하네요. 다만 휴지걸이에 보통 전원이 포함되어 있지 않는데, 이 부분에 대한 해결이나 방안도 심플하게 해결이 가능할지 궁금해지는 작품입니다.<br />
<strong>뉴티씨</strong> 매우 간단한 발상인데, 편리한 상품이 될 것으로 생각됩니다. 꼭 상품화하면 좋겠습니다. 화장실에서 휴지가 안에 말려 들어가 있어서 문제가 된 경우도 많고, 또는 너무 많이 풀어놓는 사람들도 있어서, 이를 자동으로 말아서 적당히 밖으로 내준다면 참 도움이 될 것 같습니다.<br />
<strong>위드로봇</strong> 애초 계획한대로 제작이 되었으나 실용성 부분에 보완이 필요합니다.<br />
<strong>펌테크</strong> 실생활에 활용이 가능한 아이디어와 실용성을 갖춘 작품이라고 생각합니다. 학부과정의 학생이 구현하기에 적정한 난이도를 가진 작품이라고 생각합니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
yoyo! Toilet Paper 공공 화장실의 두루마리 휴지를 낭비없이 깨끗하고 깔끔하게 이용하도록 도와주는 제품</p>
<p><span style="color: #33cccc"><strong>2.1. 연구 목적</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-2.png" rel="lightbox[37426]"><img class="alignnone size-full wp-image-37729" alt="56 ICT YOYO  (2)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-2.png" width="620" height="203" /></a><br />
공공 화장실을 이용할 때, 화장실 칸으로 들어가면 널브러져 있는 휴지들 때문에 불편하고 더럽게 느끼는 경험이 누구나 있을 것입니다. 휴지들이 휴지 거치대 밖으로 나와 있으면 위생적으로도 나쁘고, 바닥에 닿을 수도 있어 다음 사용자에게 더욱 불쾌함을 줄 수 있다고 생각합니다. 이런 경험을 바탕으로 공공 화장실에 비치된 두루마리 휴지를 적당량만 꺼내주는 제품이 필요하다고 느끼게 되었습니다.</p>
<p><span style="color: #33cccc"><strong>2.2. 기대효과</strong></span><br />
1) 두루마리 휴지의 낭비를 줄일 수 있다.<br />
2) 화장실 칸 안의 휴지로 인한 지저분함을 줄일 수 있다.<br />
3) 휴지를 다시 집어넣거나 빼는 번거로움을 줄일 수 있다.<br />
4) 휴지가 없는 것을 시각적으로 확실히 보여주기 때문에 휴지가 없어서 발생하는 당황스러운 상황을 막을 수 있다.<br />
이와 같은 기대효과로 전국의 지하철, 휴게소 등등 휴지가 비치된 공공 화장실에서 yoyo! Toilet Paper를 사용하면 화장실의 청결함을 늘리고 낭비되는 휴지를 줄일 수 있을 것이다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong>3.1. 제품 알고리즘</strong></span></p>
<p><span style="color: #33cccc"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-3.png" rel="lightbox[37426]"><img class="alignnone size-full wp-image-37730" alt="56 ICT YOYO  (3)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-3.png" width="620" height="471" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-4.png" rel="lightbox[37426]"><img class="alignnone size-full wp-image-37731" alt="56 ICT YOYO  (4)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-4.png" width="620" height="408" /></a></strong></span></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-1.jpg" rel="lightbox[37426]"><img class="alignnone size-full wp-image-37727" alt="56 ICT YOYO  (1)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-1.jpg" width="620" height="392" /></a></p>
<p><span style="color: #33cccc"><strong>3.2. 전체 시스템 구성</strong></span><br />
· 휴지 인식 O, X : 적외선 근접센서 → 휴지 케이스 입구 부분에서의 휴지 여부 인식<br />
· 휴지 꺼내고 넣기 &amp; 1/2만큼 되돌리기<br />
· 스텝모터 &amp; 모터드라이버 → 휴지를 꺼내고 다시 넣는 작동<br />
· 휴지 꺼내는 count 변수<br />
· count 이용하여 더 이상 꺼낼 휴지가 없으면 LED HIGH : LED → 휴지가 없으면 빨강 LED로 시각적 표시<br />
· 다음 사람 사용 전까지 기다림</p>
<p><span style="color: #33cccc"><strong>3.3. 개발 환경</strong></span><br />
· 개발언어 : : C언어, C++<br />
· Tool : : 스케치(Arduino IDE Sketch)<br />
· 사용 시스템 : : 아두이노 우노 보드(SMD)</p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong> 4.1. 아이디어 생각</strong></span><br />
· 휴지롤 입구에 센서를 달아서 딱 입구만큼만 휴지가 나오고 남은 휴지는 다시 들어가도록 돌린다.<br />
· 휴지가 들어가있으면 빼주고, 나와있으면 넣어준다.<br />
· 센서에 휴지 인식 X 여러 번 → 휴지를 다 쓴 것 → 휴지 없음 표시<br />
· 배경 : 공중 화장실 칸에 들어갔는데 길게 널브러져 땅에 닿아있는 휴지를 보고 찝찝해서 뜯어버리고 휴지를 새로 꺼내서 쓴 경험을 바탕으로 적당량만 나와있는 휴지롤러가 있으면 좋겠다고 생각</p>
<p><span style="color: #33cccc"><strong>4.2. 1아이디어 선정과 피드백</strong></span><br />
· 휴지롤러 다시 넣기<br />
· 다음 사람이 사용하기 까지 충분한 시간 있음<br />
· 실제와 비슷하지만 작은 버전으로 시뮬레이션 준비<br />
· 서브모터 사용 → 앞, 뒤 방향과 각도를 디테일하게 조절 가능</p>
<p><span style="color: #33cccc"><strong>4.3. 캘리브레이션 방법 생각</strong></span></p>
<p><span style="color: #33cccc"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-5.png" rel="lightbox[37426]"><img class="alignnone size-full wp-image-37732" alt="56 ICT YOYO  (5)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-5.png" width="620" height="137" /></a></strong></span></p>
<p><span style="color: #33cccc"><strong>4.4. 코드 알고리즘 생각</strong></span><br />
휴지 O → 0 : LOW / 휴지 X → 1 : HIGH</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-6.png" rel="lightbox[37426]"><img class="alignnone size-full wp-image-37726" alt="56 ICT YOYO  (6)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-YOYO-6.png" width="620" height="386" /></a><br />
<span style="color: #33cccc"><strong>4.5. 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;Stepper.h&gt;<br />
#define SENSOR 5 // 적외선근접센서 핀 설정<br />
#define LED 3 // 휴지 없을 때 켜지는 LED 핀 설정<br />
#define BAUD 9600 // 통신속도 설정<br />
const int stepsPerRevolution = 512; // 90도<br />
int count = 0; // 휴지 꺼내는 count<br />
Stepper myStepper(stepsPerRevolution,11,9,10,8);</p>
<p>void setup() {<br />
// put your setup code here, to run once:</p>
<p>pinMode(LED, OUTPUT);<br />
pinMode(SENSOR, INPUT);<br />
Serial.begin(BAUD);<br />
myStepper.setSpeed(30);</p>
<p>}<br />
void loop() {</p>
<p>if(!digitalRead(SENSOR)){ // 휴지인식O<br />
digitalWrite(LED,LOW);<br />
myStepper.step(stepsPerRevolution); // 휴지 집어넣기<br />
Serial.println(“EXIST”);<br />
if(digitalRead(SENSOR)){ // 많이 들어가면<br />
myStepper.step(-stepsPerRevolution/2); // 반만큼 꺼내기<br />
delay(5000); // 모터 정지 (다음사람 오는 시간) -&gt; 여기서는 5초 기다리기<br />
}<br />
}<br />
else{ // 휴지인식X<br />
myStepper.step(-stepsPerRevolution); // 휴지 꺼내기<br />
count++; // count 1 증가<br />
if(!digitalRead(SENSOR)){ // 많이 나오면<br />
myStepper.step(stepsPerRevolution/2); // 집어넣기<br />
delay(5000); // 모터 정지 (다음사람 오는 시간) -&gt; 여기서는 5초 기다리기<br />
}<br />
if(count &gt;= 5){ // count가 5번 이상이면<br />
digitalWrite(LED,HIGH); // 휴지가 없다고 판단<br />
Serial.println(“NOT EXIST”);<br />
delay(100000000); // 모터 정지<br />
}<br />
}<br />
delay(100);</p>
<p>}<br />
</div>
<p><span style="color: #0000ff"><strong>5. 참고문헌</strong></span><br />
[1] Jeremy Blum 『익스플로링 아두이노』(한빛아카데미 2014)<br />
[2] Monk, Simon 『(33가지 프로젝트로 배우는) 아두이노』(한빛미디어 2014)<br />
[3] 고재관 『(쉽게 따라하는) 아두이노 배우기』(서울: 정보문화사 2016)<br />
[4] 아두이노 TCRT5000 근접센서 / 라인센서 / 한글보드</p>
<p>https://blog.naver.com/roboholic84/221084185743</p>
[5] [아두이노 강좌] 아두이노 근접센서 사용하기</p>
<p>https://blog.naver.com/roboholic84/220522339575</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/37426/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[56호]맥돼지</title>
		<link>http://www.ntrexgo.com/archives/37431</link>
		<comments>http://www.ntrexgo.com/archives/37431#comments</comments>
		<pubDate>Thu, 31 Oct 2019 00:00:01 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[56호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이마트]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[입선]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=37431</guid>
		<description><![CDATA[디바이스마트매거진 56호 &#124; 고독사 방지를 위한 기능을 탑재한 AI 스피커를 만들었다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-1.png" rel="lightbox[37431]"><img class="alignnone size-large wp-image-37754" alt="56 ICT 맥돼지 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-1-620x193.png" width="620" height="193" /></a></p>
<p><strong>2019 ICT 융합 프로젝트 공모전 입선</strong></p>
<p><span style="font-size: x-large"><strong>맥돼지</strong></span></p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 다양한 기능의 집합이 돋보이는 작품입니다. 그 중 음성 인식 엔진 API를 적용한 것이 가장 눈에 띄는 기능이지만, java script engine을 사용하기보다는 Phython을 이용하여 새로운 방식의 자신만의 솔루션을 찾는 건 어땠을까 하는 아쉬움이 듭니다. 많은 기능을 포함하였으나, 여러 기능에 대하여 위에 말했듯이 음성 인식을 통한 기능 구현이었다면 훨씬 개발 작품의 가치를 올릴 수 있었을 듯 합니다.<br />
<strong>뉴티씨</strong> 독거노인 등을 위한 실버 시대를 대비한 맥돼지. 좋은 작품이네요. 여러가지 아이디어를 접목해서, 편리하게 쓸 수 있도록 노력한 점이 돋보입니다. 음성인식을 사용하여 작품의 편리성을 높인 점도 최근의 추세를 반영한 작품이라고 하겠습니다.<br />
<strong>위드로봇</strong> 구현이 잘 된 완성도가 높은 작품입니다. 추후 추가 작업이 기대됩니다.<br />
<strong>펌테크</strong> 작품의 아이디어와 실용성 창의성이 돋보이는 작품으로 생각됩니다. 음성인식기술을 접목하여 편의성을 높이는 등 군더더기 없이 꼭 필요한 기능으로 목적에 맞는 최적의 시스템으로 잘 구성하였고 작품의 완성도 역시 상당이 높았다고 생각합니다. 전체적으로 작품의 기획의도, 기술 구현도, 완성도 등에서 높은 평가를 주고 싶은 작품입니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
<strong>2.1. AI 스피커란?</strong><br />
인공지능 스피커(artificial intelligence speaker, AI Speaker)란, 음성인식을 통해 음악 감상, 정보 검색 등의 기능을 수행하는 스피커이다. 인공지능 서비스의 시장 전망은 매우 밝은데, 미국의 정보 기술 연구 및 자문 회사인 가트너는 AI 스피커 시장 규모가 2015년 약 4050억 원에서 매년 40% 이상 성장을 예상, 2020년에는 약 2조 3600억 원이 될 것으로 전망했다. 또한, 시장조사기관 오범(Ovum)은 가상 비서와 음성 AI를 지원하는 스마트 홈 제품, TV, 웨어러블 기기의 수는 2021 년에 16억 3,000만 대에 육박할 것으로 예상하고 있다. 우리 일상에서도 애플의 시리(Siri), 구글의 구글 어시스턴트(Google Assistant), KT의 기가지니(GiGA Genie) 등과 같은 AI 스피커들을 쉽게 볼 수 있다. AI 스피커의 주 사용층은 20~30대이며 주 사용 목적은 음성을 통한 시간 확인, 알람 설정, 일정 등록 및 메모, 문자, 전화 등이다.</p>
<p><strong>2.2. 독거노인 비율 증가 및 그에 따른 고독사의 증가</strong><br />
우리는 기존의 젊은 층을 겨냥한 AI 스피커와 달리, 정보 소외 계층을 위한 AI 스피커를 제작하고 싶었다. 제작 방향에 관한 회의 초기에는 정보 소외 계층에게 어떻게 하면 정보를 쉽게 전달할 수 있을 지를 중점으로 토의를 진행했다. 그러나 곧 정보 소외 계층은 대부분이 노인층이므로 단순히 정보 전달만이 목적이 아닌, 그들의 편의 및 안전을 보장해줄 수 있는 AI 스피커를 만들어보자는 것으로 의견을 합쳤다.<br />
노인층에 가장 필요한 것은 무엇인지 토의해보고 조사해보는 과정에서 독거노인의 고독사에 관한 자료를 보았다. 보건복지부의 통계에 따르면 독거노인 무연고 사망자 수는 2011년 693명부터 시작하여 2016년에는 1232명으로 시간이 지남에 따라 계속 증가하는 추세를 보이고 있다. 홀로 사시는 분들은 쓰러지시더라도 집에 방문하는 사람이 없어 빠르게 응급처치를 취하지 못하고, 오랜 시간이 흘러 사망하신 후에야 발견되는 것이다. 우리는 바로 이 점에 주목하여 고독사 방지를 위한 기능을 탑재한 AI 스피커를 만들기로 했다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-2.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37756" alt="56 ICT 맥돼지 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-2.png" width="620" height="394" /></a></p>
<p><strong>2.3. 작명 및 외관에 관하여</strong><br />
외관은 어르신들께서 친근함을 느낄 수 있도록 제작하고자 했다. 아이, 강아지, 돼지 형상 등의 의견이 나왔고 이 중 가장 의미를 둘 만한 것으로 결정하기로 했다. 또한, 간단히 모델링할 수 있는 쉬운 모양인지의 여부도 검토했다. 돼지는 약 4800여년 전부터 긴 세월을 인간과 함께한 동반자와 같은 동물이며, 머리부분과 귀 부분, 코 정도의 특징을 살리면 쉽게 모델링 가능하다는 점에 착안하여 최종적으로 외관은 돼지 모양으로 하기로 했다. 그리고 작품명은 우리가 속한 소모임 이름이 MAC이며 작품의 외관이 돼지 모양이므로 ‘맥돼지’로 정했다.</p>
<p><strong>2.4. 주차별 프로젝트 일정</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-3.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37757" alt="56 ICT 맥돼지 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-3.png" width="620" height="277" /></a><br />
<span style="color: #0000ff"><strong> 3. 작품 설명</strong></span><br />
<span style="color: #339966"><strong> 3.1. 전체 시스템 구성</strong></span><br />
<strong>1) 라즈베리파이 인공지능 스피커 구현과 기능추가</strong><br />
· 인공지능 스피커 구현<br />
· 날씨정보 구현<br />
· LCD 구현</p>
<p><strong>2) 아두이노 기능추가</strong><br />
· 초음파센서를 통한 고독사 방지 알람<br />
· 무드등, LED기능 구현</p>
<p><strong>3) 하드웨어 3D 모델링</strong><br />
· 디자인 설계<br />
· 3D 모델링 파일 제작 및 출력</p>
<p>위와 같이 총 3분야로 나누어 기능을 구현하였다. 첫 번째 분야는 라즈베리파이를 이용한 인공지능 스피커의 핵심기능 구현이다. 인공지능 스피커의 특성상 전체적인 시스템의 구현을 위해서는 끊임없이 인터넷 서버와 통신하여야 하기에 인터넷 통신에 적합한 프로그래밍 언어를 사용하는 것이 좋다. 그렇기 때문에 이 부분은 인터넷의 서버에서 정보를 송수신하기 쉽도록 제작된 프로그래밍언어인 자바 스크립트로 진행하였고, 날씨정보 불러오기와 유튜브 동영상 재생과 같이 인터넷을 사용하는 기능들을 자바 스크립트로 프로그래밍 하였다. 이외에 인공지능 스피커의 전체적인 시스템을 라즈베리파이가 담당하기에 LCD 구현도 라즈베리파이로 진행하였다.<br />
두 번째 분야는 아두이노 IDE를 사용한 코딩이다. 초음파센서를 통한 응급상황 정보 확인, 무드등 기능은 라즈베리파이로도 구현이 가능하긴 하지만, 이와 같은 추가기능을 위해서는 많은 포트가 필요하며, 인터넷 통신이 필요없기에 복잡한 자바스크립트로 전체 시스템을 구성하는 것은 낭비였다. 따라서 자바 스크립트보다 간편하고 포트가 겹칠 수 있는 문제점도 해결할 수 있는 아두이노를 대안으로 활용하기로 하였다.<br />
세 번째 분야는 3D 모델링이다. 3D 프린터를 이용하여 작품을 제작하는 단계는 크게 모델링(modeling), 프린팅(printing), 피니싱(finishing)의 3단계로 나뉜다.<br />
첫 번째로 모델링은 3D 도면을 제작하는 단계인데, 이번 작품에서는 ‘오토데스크 인벤터(Autodesk Inventor)’를 이용하였다. 다음으로 프린팅은 인벤터로 설계한 도면을 ‘stl’파일로 저장하고 ‘gcode’로 전환한 후 3D 프린터를 이용하여 뽑아내는 단계이다. 3D 프린터는 신도리코의 ‘3D WOX’를 사용하였고, 제작물의 재료는 PLA이다. 마지막 단계인 피니싱은 3D 프린터로 뽑아낸 제작물에 보완 작업을 하는 단계로 이번 작품에서는 사포질과 도색으로 피니싱 작업을 하였다. 우선 뽑아낸 모든 제작물을 사포질하여 잘 붙여질 수 있도록 표면을 연마시키고, 스프레이로 도색을 하였다. 돼지 머리와 몸통은 분홍색, 리본은 빨간색, 그리고 돼지의 귀는 LED 불빛이 잘 보일 수 있도록 하얀색으로 도색하였다.</p>
<p><span style="color: #008000"><strong>3.1.1. 돼지 귀 모델링</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-4.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37758" alt="56 ICT 맥돼지 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-4.png" width="275" height="222" /></a><br />
귀는 XZ평면 위로 서로 수직인 직선을 그은 후 직선의 끝점을 호로 연결하여 평면을 만들었다. 회전을 이용하여 입체도형을 완성하였다.<br />
귀는 머리에 부착하여야 하기 때문에 머리와 똑같은 반원모형을 XY평면에 만든 후 회전시켜 귀와 겹치는 부분을 돌출을 이용하여 차집합하여 제거해주었다 그 후 무드등으로 활용하기 위해 셀을 이용하여 두께를 1mm만 남도록 설정하고 3D 프린터로 뽑을 때 밀도를 낮추어 LED 불빛이 잘 비추게 만들어 주었다 .</p>
<p><span style="color: #008000"><strong>3.1.2. 박스 모델링</strong></span></p>
<p><span style="color: #008000"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-1.jpg" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37753" alt="56 ICT 맥돼지 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-1.jpg" width="273" height="223" /></a></strong></span><br />
라즈베리파이와 아두이노, 약배급기가 들어갈수 있도록 각 변의 길이가 180mm인 직사각형을 만들어 주었다. 그 후 돌출을 이용하여 두께가 150mm인 육면체를 만들어주었다. 직사각형의 평면에 양변이 170mm인 직사각형을 만들어 양변에 5mm의 여유공간이 남도록 하였다. 이를 또 돌출시켜 깊이가 145mm인 육면체를 만든 후 이를 차집합 시켜 박스 모양만 남도록 하였다. 아두이노와 라즈베리파이가 부착 될 직육면체를 박스 가운데 세운 후 앞면에 디스플레이를 설치하기 위해 직사각형으로 된 구멍과 마이크가 잘 작동할수 있게 작은 구멍 또한 뚫어주었다.</p>
<p><span style="color: #008000"><strong>3.1.3. 돼지 몸통 모델링(1)</strong></span></p>
<p><span style="color: #008000"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-5.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37759" alt="56 ICT 맥돼지 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-5.png" width="265" height="223" /></a></strong></span><br />
돼지의 몸통은 XY평면에 높이가 60mm, 윗변이 50mm, 아랫변이 75mm인 사다리꼴을 스케치한 후, 회전을 이용하여 대략적인 입체도형을 완성하였다. 그 후 쉘을 이용하여 윗면은 두께가 5mm, 아랫면은 두께가 30mm가 되도록 몸통의 내부를 비워주었다. 그리하여 최종적으로 돼지 몸통 위에 돼지 머리가 안정적으로 장착될 수 있도록 설계하였다.</p>
<p><span style="color: #008000"><strong>3.1.4. 돼지 몸통 모델링(2)</strong></span></p>
<p><span style="color: #008000"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-6.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37760" alt="56 ICT 맥돼지 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-6.png" width="273" height="224" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-7.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37761" alt="56 ICT 맥돼지 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-7.png" width="273" height="224" /></a></strong></span><br />
돼지 몸통의 윗부분을 더 파이게 하면 돼지 머리가 더 안정적으로 안착될 수 있지 않을까 하는 생각으로 ‘돼지 몸통 모델링(1)’에서 조금 수정을 해보았다. 돼지 몸통 윗 부분의 XY평면에 반지름 60mm인 원을 스케치한 후 양쪽으로 100mm만큼 돌출시킨 후 차집합을 이용하여 잘라내었다. 하지만 ‘돼지 몸통 모델링(1), (2)’를 모두 3D 프린터로 뽑아내어 돼지 머리와 붙여본 결과 처음에 만들었던 (1)번 모델링이 머리를 더 잘 받쳐주어 최종적으로 원래 도안이었던 (1)번 모델링을 선택하여 결과물을 완성하였다.</p>
<p><span style="color: #008000"><strong>3.1.5. 돼지 코 모델링</strong></span></p>
<p><span style="color: #008000"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-8.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37762" alt="56 ICT 맥돼지 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-8.png" width="272" height="202" /></a></strong></span><br />
정면 가운데에 알림센서가 있어야 잘 작동하기때문에 돼지 코의 두 부분 중 한 곳을 뚫어 주어 그 안에 센서를 넣어주었다. 돼지 코 안의 센서는 독거노인들의 고독사를 방지하기 위한 알림 센서이다.</p>
<p><span style="color: #008000"><strong>3.1.6. 돼지 리본 모델링</strong></span></p>
<p><span style="color: #008000"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-9.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37763" alt="56 ICT 맥돼지 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-9.png" width="549" height="205" /></a></strong></span><br />
돼지 리본을 한꺼번에 출력하지 않고 두 부분으로 나누어서 설계한 이유는 센서를 리본의 뚫린 부분에 넣고 조립을 더 손쉽게 하기 위해서이다. 돼지 리본 안에 넣은 센서는 돼지 귀 내부에 있는 LED를 ON/OFF하고 색을 바꾸는 센서이다.</p>
<p><span style="color: #008000"><strong>3.1.7. 약 배급기 모델링</strong></span></p>
<p><span style="color: #008000"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-10.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37764" alt="56 ICT 맥돼지 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-10.png" width="549" height="204" /></a></strong></span><br />
독거노인을 위한 인공지능 스피커이기도하고 요즘 많은 사람들이 영양제, 약등 챙겨먹을 일이 많은데 간단히 인공지능 스피커에서 약을 먹을 시간을 체크해주고 인공지능 스피커에서 바로 약을 먹을수 있게 약통을 만들어 알람이 울리면 그 자리에서 까먹지 않고 먹을수 있게 설계하였다.</p>
<p><span style="color: #008000"><strong>3.1.8. 본체 부품 모델링</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-11.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37765" alt="56 ICT 맥돼지 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-11.png" width="553" height="208" /></a></p>
<p><span style="color: #33cccc"><strong>3.2. 주요 동작 및 특징</strong></span><br />
1) 초음파센서를 통한 고독사 방지용 알람 기능<br />
2) 유튜브 노래재생<br />
3) 알람 설정 및 일정 등록<br />
4) 무드등<br />
5) 약 보관 및 배급 기능, 무선충전 기능</p>
<p><span style="color: #33cccc"><strong>3.3. 개발환경</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-12.png" rel="lightbox[37431]"><img class="alignnone size-large wp-image-37766" alt="56 ICT 맥돼지 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-12-498x620.png" width="498" height="620" /></a></p>
<p><strong><span style="color: #0000ff">4. 단계별 제작과정</span></strong><br />
<span style="color: #33cccc"><strong> 4.1. 라즈베리파이</strong></span><br />
<span style="color: #339966"><strong> 4.1.1. 음성인식 API 선정</strong></span><br />
인공지능 스피커의 핵심은 음성인식 API라고 할 수 있다. 음성인식 API 시스템에 대하여탐색해 보았고 그 결과 네이버 음성인식 API, KT 음성인식 API, 구글 어시스턴트 등 크게 음성인식 API가 지원되는 3가지 시스템을 찾을 수 있었다. 이후 어느 음성인식 API를 사용할 것인지 회의를 하였다. 회의결과 네이버 음성인식 API는 정보량이 부족하였으며, 구글 어시스턴트는 한글 인식능력이 떨어진다는 결론을 내었다. 그래서 한국어 인식능력도 좋으며 비교적 정보량도 많은 편인 KT 음성인식 API를 사용하기로 결정하였고, 시스템구현을 시작하였다.</p>
<p><span style="color: #339966"><strong>4.1.2. 코딩</strong></span><br />
라즈베리파이에서 인공지능 스피커 기능을 구현하기 위해서 자바스크립트 엔진 위에서 동작하는 이벤트 처리 I/0 프레임워크 NODE.JS을 이용하였다. 파이썬을 통한 기능구현도 검토해 보았으나, 관련 자료가 부족하고 자바스크립트를 활용하는게 더 효율적이라 판단하여 자바스크립트를 활용하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-13.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37767" alt="56 ICT 맥돼지 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-13.png" width="620" height="399" /></a></p>
<p><span style="color: #339966"><strong>4.1.3. 디스플레이추가</strong></span><br />
처음에는 인공지능 스피커 전면에 3.5인치 TFT LCD를 부착하여 간단한 조작 및 날씨정보를 제공하려 했었다. 그러나 라즈베리파이에서 마이크 보드가 사용하는 핀과 TFT LCD가 사용하는 핀 사이에서 충돌이 일어나 작동 오류가 일어났다. 그래서 라즈베리파이의 GPIO 포트를 사용하지 않고 DSI케이블을 연결해 사용하는 라즈베리파이용 7인치 디스플레이를 사용하여 간단한 터치 조작 및 날씨 정보 제공을 하였다.</p>
<p><span style="color: #33cccc"><strong>4.2.아두이노</strong></span><br />
<span style="color: #339966"><strong> 4.2.1. 고독사 방지용 알림 기능</strong></span><br />
<strong>1) 알고리즘</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-14.png" rel="lightbox[37431]"><img class="alignnone size-large wp-image-37768" alt="56 ICT 맥돼지 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-14-411x620.png" width="411" height="620" /></a></p>
<p><strong>2) 회로 연결</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-15.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37769" alt="56 ICT 맥돼지 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-15.png" width="614" height="310" /></a><br />
<strong> 3) 코딩</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
#define BUZZER 7 //BUZZER 7번 핀에 할당<br />
#define MESSAGE_BUZ 6 //MESSAGE BUZZER 6번 핀에 할당<br />
#define SENSOR 10 //IR센서 10번 핀에 할당<br />
#define BUZZER_TIMER 10000 //손 대지 않았을 시 BUZZER 울릴 시간 설정<br />
#define MESSAGE_TIMER 15000 //손 대지 않았을 시 MESSAGE BUZZER 울릴 시간 설정<br />
unsigned long start_millis; //센서 인식 시의 시간 값 저장할 변수 정의<br />
int mode = 0 ; // mode : 0 = stop , 1 구동<br />
void setup() {<br />
Serial.begin(9600); //Board rate 지정<br />
mode = 0;<br />
pinMode(BUZZER, OUTPUT); //BUZZER 출력 할당<br />
pinMode(MESSAGE_BUZ, OUTPUT); //MESSAGE BUZZER 출력 할당<br />
pinMode(SENSOR, INPUT); //IR 센서 입력 할당<br />
}<br />
void loop() {<br />
int sensor_Value = digitalRead(SENSOR); //IR 센서 인식 확인 변수 정의<br />
if ( sensor_Value == 0 ) { //센서 인식<br />
Serial.println(“Hand Clap”); //Serial Monitor에 ‘Hand Clap’ 출력<br />
if ( mode == 0 ) { //센서 인식했으며 mode가 1일 때<br />
mode = 1; //mode를 0에서 1로 바꿔줌<br />
start_millis = millis(); //스탑워치 시작, Start_millis에 현재 시간값 저장<br />
Serial.println(“STARTED”); //Serial Monitor에 ‘STARTED’ 출력<br />
noTone(BUZZER); //BUZZER 끔<br />
noTone(MESSAGE_BUZ); //MESSAGE BUZZER 끔<br />
sensor_Value = 2 ; //Sensor_Value를 2로 바꿔줌<br />
}<br />
if ( mode == 1 ) { //mode가 1일 때<br />
if (sensor_Value == 0) { //센서 인식되면<br />
start_millis = millis(); //start_millis에 현재 시간값 저장<br />
Serial.println(“TIMER INIT.”); //스탑워치 리셋, Serial Monitor에 ‘TIMER INIT.’ 출력<br />
noTone(BUZZER); //BUZZER 끔<br />
noTone(MESSAGE_BUZ); //MESSAGE BUZZER 끔<br />
} } }<br />
if ( mode == 1 ) { //mode가 1일 때<br />
if ( ( millis() &#8211; start_millis ) &gt; BUZZER_TIMER ) { //현재시간값-이전에 저장한 시간값이<br />
BUZZER_TIMER보다 크면<br />
Serial.println(“BUZZER”); //Serial Monitor에 ‘BUZZER’ 출력<br />
tone(BUZZER,440); //BUZZER 울림<br />
noTone(MESSAGE_BUZ); //MESSAGE BUZZER 끔<br />
}<br />
if ( ( millis() &#8211; start_millis ) &gt; MESSAGE_TIMER ) { //현재시간값-이전에 저장한 시간값이<br />
MESSAGE_TIMER보다 크면<br />
Serial.println(“SEND MESSAGE”); //Serial Monitor에 ‘SEND MESSAGE’ 출력<br />
noTone(BUZZER); //BUZZER 끔<br />
tone(MESSAGE_BUZ,494); //MESSAGE BUZZER 울림<br />
}<br />
Serial.print(“MILLIS = “); //Serial Monitor에 ‘MILLIS = ‘ 출력<br />
Serial.print(millis()); //Serial Monitor에 처음 센서 인식부터<br />
현재까지의 전체 시간값 출력<br />
Serial.print(“,”); //Serial Monitor에 ‘,’ 출력<br />
Serial.print(“TIMER = “); //Serial Monitor에 ‘TIMER = ‘ 출력<br />
Serial.println(millis() &#8211; start_millis); //Serial Monitor에 스탑워치 시간 출력<br />
}<br />
delay(500);<br />
}<br />
</div>
<span style="color: #008000"><strong> 4.2.2. 무드등</strong></span><br />
<strong>1) 알고리즘</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-16.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37770" alt="56 ICT 맥돼지 (16)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-16.png" width="596" height="200" /></a></p>
<p><strong>2) 회로 연결</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-17.png" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37771" alt="56 ICT 맥돼지 (17)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-17.png" width="607" height="271" /></a></p>
<p><strong>3) 코딩</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#define ledr 11 //red led 11번 핀에 할당<br />
#define ledg 10 //green led 10번 핀에 할당<br />
#define ledb 9 //blue led 9번 핀에 할당<br />
#define ledr2 7 //두 번째 red led 7번 핀에 할당<br />
#define ledg2 6 //두 번째 green led 6번 핀에 할당<br />
#define ledb2 5 //두 번째 blue led 5번 핀에 할당<br />
#define Sensor 3 //적외선 센서 3번 핀에 할당</p>
<p>float RGB[3]; //3가지 값을 한 번에 처리할 수 있는 변수 RGB<br />
float x; //소수값까지 표현할 수 있는 변수 x<br />
int flag1 = 0; //현재 센서 값을 받을 변수<br />
int flag2 = 0; //이전의 센서 값 저장할 변수<br />
int state = 5; //switch case 역할을 할 변수</p>
<p>void setup() {<br />
pinMode(ledr,OUTPUT); //red led 출력 설정<br />
pinMode(ledg,OUTPUT); //green led 출력 설정<br />
pinMode(ledb,OUTPUT); //blue led 출력 설정<br />
pinMode(ledr2,OUTPUT); //두 번째 red led 출력 설정<br />
pinMode(ledg2,OUTPUT); //두 번째 green led 출력 설정<br />
pinMode(ledb2,OUTPUT); //두 번째 blue led 출력 설정<br />
pinMode(Sensor, INPUT); //적외선 센서 입력 설정<br />
Serial.begin(9600); //board rate 9600<br />
}</p>
<p>void loop() {<br />
flag1 = digitalRead(Sensor); //적외선 센서 값을 받음<br />
if((flag1==0)&amp;&amp;(flag2==0)) { //센서 인식 된 상태 &amp; 직전에 센서 인식 안됨<br />
state = state-1 ; //state값 1만큼 내려줌<br />
}<br />
flag2 = 1-flag1; //이후의 센서 인식값과 비교할 현재의 센서 값 저장<br />
if(state == 5){ //state가 5일 때<br />
delay(100); //chattering 현상 방지 위한 delay<br />
analogWrite(ledr, 255); //red led 끔<br />
analogWrite(ledg, 255); //green led 끔<br />
analogWrite(ledb, 255); //blue led 끔<br />
analogWrite(ledr2, 255); //두 번째 red led 끔<br />
analogWrite(ledg2, 255); //두 번째 green led 끔<br />
analogWrite(ledb2, 255); //두 번째 blue led 끔<br />
}<br />
if(state == 4){ //state가 4일 때<br />
analogWrite(ledr, 0); //red led 최대 밝기<br />
analogWrite(ledg, 123); //green led 중간 밝기<br />
analogWrite(ledb, 255); //blue led 끔<br />
analogWrite(ledr2, 0); //두 번째 red led 최대 밝기<br />
analogWrite(ledg2, 123); //두 번째 green led 중간 밝기<br />
analogWrite(ledb2, 255); //두 번째 blue led 끔<br />
delay(100); //chattering 현상 방지 위한 delay<br />
}<br />
if(state == 3){ //state가 3일 때<br />
analogWrite(ledr, 255); //red led 끔<br />
analogWrite(ledg, 0); //green led 최대 밝기<br />
analogWrite(ledb, 255); //blue led 끔<br />
analogWrite(ledr2, 255); //두 번째 red led 끔<br />
analogWrite(ledg2, 0); //두 번째 green led 최대 밝기<br />
analogWrite(ledb2, 255); //두 번째 blue led 끔<br />
delay(100); //chattering 현상 방지 위한 delay<br />
}<br />
if(state == 2) { //state가 2일 때<br />
analogWrite(ledr, 255); //red led 끔<br />
analogWrite(ledg, 255); //green led 끔<br />
analogWrite(ledb, 0); //blue led 켬<br />
analogWrite(ledr2, 255); //두 번째 red led 끔<br />
analogWrite(ledg2, 255); //두 번째 green led 끔<br />
analogWrite(ledb2, 0); //두 번째 blue led 켬<br />
delay(100); //chattering 현상 방지 위한 delay<br />
}<br />
if(state == 1 ){ //state가 1일 때<br />
delay(300); //chattering 현상 방지 위한 delay<br />
for (float x=0;x&lt;PI;x=x+0.000003){ //led들에 입력할 변수를 할당하기 위해 변수 x를 만듦<br />
RGB[0]=255*abs(sin(x*(180/PI))); //red led에 입력할 변수 할당<br />
RGB[1]=255*abs(sin((x+PI/3)*(180/PI))); //green led에 입력할 변수 할당<br />
RGB[2]=255*abs(sin((x+(2*PI)/3)*(180/PI))); //blue led에 입력할 변수 할당<br />
analogWrite(ledr,RGB[0]); //red led에 변수 입력<br />
analogWrite(ledg,RGB[1]); //green led에 변수 입력<br />
analogWrite(ledb,RGB[2]); //blue led에 변수 입력<br />
analogWrite(ledr2,RGB[0]); //두 번째 red led에 변수 입력<br />
analogWrite(ledg2,RGB[1]); //두 번째 green led에 변수 입력<br />
analogWrite(ledb2,RGB[2]); //두 번째 blue led에 변수 입력<br />
if(digitalRead(Sensor)==0) { //센서 인식된 상태이면<br />
state=5; //state를 5로 바꾸고<br />
break; //for문을 break함, 위의 if(state==5)로 돌아감<br />
} } }<br />
Serial.println(state); //serial monitor로 state값 확인<br />
}<br />
</div>
<span style="color: #0000ff"><strong>5. 완성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-2.jpg" rel="lightbox[37431]"><img class="alignnone size-full wp-image-37755" alt="56 ICT 맥돼지 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-맥돼지-2.jpg" width="607" height="511" /></a></p>
<p><span style="color: #0000ff"><strong>6. 참고자료</strong></span><br />
· 스마트스피커(AI 스피커) : https://ko.wikipedia.org/wiki/%EC%8A%A4%EB%A7%88%ED%8A%B8_%EC%8A%A4%ED%94%BC%EC%BB%A4<br />
· [단독]’고독한 대한민국’…무연고 사망자, 5년 새 2배 폭증 (아시아경제 19.02.14) : http://view.asiae.co.kr/news/view.htm?idxno=2019 021411080903737<br />
· Jeremy Blum, 『익스플로링 아두이노』, 한빛아카데미, 14.05.19<br />
· 데릭 몰로이, 『익스플로링 아두이노』, 위키북스, 18.04.03<br />
· 송형주,고현준, 『인사이드 자바스크립트』, 한빛미디어, 14.01.02</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/37431/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[56호]인공지능 실버 케어 강아지 로봇 [AI-Based Sliver Care Robot System with IoT]</title>
		<link>http://www.ntrexgo.com/archives/37428</link>
		<comments>http://www.ntrexgo.com/archives/37428#comments</comments>
		<pubDate>Thu, 31 Oct 2019 00:00:00 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[56호]]></category>
		<category><![CDATA[ict]]></category>
		<category><![CDATA[공모전]]></category>
		<category><![CDATA[디바이마트]]></category>
		<category><![CDATA[매거진]]></category>
		<category><![CDATA[입선]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=37428</guid>
		<description><![CDATA[디바이스마트매거진 56호 &#124; 강아지 형태의 친숙한 반려동물 형태의 노인 돌봄 로봇으로 노인문제에 접근하고, AI(인공지능)와 IoT(사물인터넷)를 기반으로 하여 기존의 노인 돌봄 로봇과는 차별화되는 인공지능·챗봇·CCTV 등 내장되어있는 다기능 노인 돌봄 로봇을 만들었다.]]></description>
				<content:encoded><![CDATA[<p><strong style="font-size: x-large"><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-1.png" rel="lightbox[37428]"><img class="alignnone size-large wp-image-37736" alt="56 ICT 인공지능 실버케어 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-1-620x193.png" width="620" height="193" /></a></strong></p>
<p><span style="font-size: x-large"><strong>인공지능 실버 케어 강아지 로봇 </strong></span></p>
<p><span style="font-size: medium"><strong>[AI-Based Sliver Care Robot System with IoT]</strong></span></p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 시스템의 구성과 실제 최종 목표가 매우 촘촘하게 구성된 듯합니다. 기획의 의도에 맞는 설계 개발 과정이 진행된 것으로 예상되고, 사진으로 확인되는 결과물 또한 훌륭해 보이는 게 사실이지만, 심사를 위한 보고서의 내용이 매우 미흡합니다. 또한 실제 결과물의 동작이나 내장된 기능을 확인할 수 있는 자료가 포함되어 있지 않아 평가를 하는데 아쉬움이 남습니다.<br />
<strong>뉴티씨</strong> 강아지형 로봇으로 감성을 불러일으켜 외롭지 않게 함과 동시에 노인들이 약 복용 등을 할 수 있도록 도움을 드리고, 심박수 등을 감시하여 보고할 수 있도록 한 점에서 누군가에게는 매우 중요한 필수품이 될 수도 있겠다고 하는 생각이 들었습니다. 점점 실버시대로 접어들고 있고, 이로 인하여 자동화가 진행되어야 하는 부분이 많아질 것인데, 이러한 개발은 현시대에 도움이 되는 기술로 보입니다.<br />
<strong>위드로봇</strong> 하드웨어와 소프트웨어 모두 난이도가 높은 부분을 잘 구현한 작품입니다. 다양한 환경에서 실험한 결과 분석이 보고서에 추가되면 더욱 좋을 것 같습니다.<br />
<strong>펌테크</strong> 일본에서는 이미 상용화되어 있는 반려견 로봇은 로봇 body 설계, 카메라를 통한 영상 인지 기능, 서보모터 구동, AI 알고리즘 구성까지 각각의 과정 과정이 상당히 난도가 높은 제품으로 학생들이 도전하기에는 다소 무리가 된다고 생각할 정도의 기술집약적인 제품이라고 볼수 있습니다. 출품된 작품의 경우 제출된 문서를 감안하자면 최종 완성이 되지 않은 것으로 판단되지만 기획 과정이 쳬계적이라는 생각이 들었고 개발과정 또한 최종 단계까지는 아니지만 중간단계 정도까지는 어느 정도 진행된 것으로 판단됩니다. 최종 개발 작품을 내년도 공모전에서는 볼 수 있기를 바랍니다.</p>
<p><span style="color: #0000ff"><strong>2. 개발동기 및 목적, 필요성</strong></span><br />
한국을 포함한 많은 나라들은 저 출산과 고령화 현상을 동시에 경험하고 있습니다. 그 결과 전체 인구에서 노령인구가 차지하고 있는 비율은 급속하게 증가하여 고독사, 노인의 자살 등 노인문제가 심화되고 있습니다. 앞으로 경제적 능력이 떨어지고 정신건강 측면에서도 매우 취약한 거대한 노령인구집단을 어떻게 해야 하는지는 매우 중요한 과제가 될 것입니다. 그에 저희는 강아지 형태의 친숙한 반려동물 형태의 노인 돌봄 로봇으로 노인문제에 접근하고, AI(인공지능)와 IoT(사물인터넷)를 기반으로 하여 기존의 노인 돌봄 로봇과는 차별화되는 인공지능·챗봇·CCTV 등 내장되어있는 다기능 노인 돌봄 로봇을 만들었습니다.</p>
<p><span style="color: #0000ff"><strong>3. 과제 해결 방안 및 과정</strong></span></p>
<p><span style="color: #0000ff"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-2.png" rel="lightbox[37428]"><img class="alignnone size-full wp-image-37737" alt="56 ICT 인공지능 실버케어 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-2.png" width="620" height="455" /></a></strong></span><br />
본 과제에서 통계청의 통계와 실제 팀원의 조부모님들께 진행한 조사를 토대로 노인분들의 불편하신 점을 외로움·건강·방범 등으로 잡고, 조사한 문제들을 해결하고 더 나아가 생활이 편리해지고 재난 등에도 대비할 수 있는 로봇 제작을 수행하였습니다. 외로움을 위해 반려동물의 역할을 할 수 있는 감정을 추가하고 대화가 가능한 챗 봇을 내장하였고, 환경 변화와 재난에 취약한 노인분들의 문제점을 해결하고자 로봇 내에 온/습도 센서, 미세먼지 센서, 가스센서를 내장하고 변화에 즉각적 반응하며 사용자와 보호자에게 푸시 알람이 가는 시스템으로 구성했습니다. 인공지능 기반의 방법으로 앉아있는 사람, 뒷모습, 숨어있는 모습을 통해 방문자를 인식할 수 있고, 사용자가 외출 시 자율주행하며 집안의 상황을 실시간으로 체크할 수 있습니다. 사용자에게 제공되는 스마트 웨어러블 기기는 실시간으로 심박수와 체온을 OLED를 통해 출력하며, 저체온, 고체온, 심정지 시에 응급상황을 인지, 보호자에게 푸시알림으로 알릴 수 있게 되어있습니다. 뿐 만 아니라 사용자가 노인분들이라는 것을 고려하여 편리하게 사용 가능하도록 음성명령, 약 복용 알람 기능 등이 내장되어 있습니다.</p>
<p><span style="color: #0000ff"><strong>4. 출품과제의 핵심 기술</strong></span><br />
① 강아지 형태의 반려동물 역할 로봇으로 동물매개치료(Animal Assisted Therapy)효과를 얻을 수 있습니다.<br />
② 챗봇을 내장하여 말벗 기능을 구현해 사회적 고립감을 해소할 수 있습니다.<br />
③ 인공지능을 통해 주인과의 교감·음성명령·방범이 가능합니다.<br />
④ IoT 기반 시스템으로 어디서든 스마트폰 어플리케이션으로 전체시스템 모니터링, 제어가 가능하고 시스템 수정과 타 장치와의 연동이 편리합니다.<br />
⑤ 스마트 웨어러블 기기를 통한 응급상황 인지와 고독사 방지가 가능합니다.<br />
⑥ 플라즈마 이온 모듈이 내장되어 집안환경개선(항균, 탈취 바이러스)이 가능합니다.<br />
⑦ 실시간 영상 스트리밍과 자율주행이 내장되어 노인의 상태확인·방범이 가능합니다<br />
⑧ 환경개선 이온 모듈, 약 알림이 있어 집안의 환경을 개선하고 규칙적인 약 섭취를 통해 건강관리가 가능합니다.</p>
<p><span style="color: #0000ff"><strong>5. 개념설계 및 상세설계</strong></span><br />
<span style="color: #33cccc"><strong> 5.1. 개념설계</strong></span><br />
<strong> 5.1.1. 필요성</strong><br />
2018년 한국이 세계에서 가장 빠른 속도로 고령사회에 진입하고 OECD 국가 중 노인 자살률이 지난 10년 이상 1위를 기록하는 등 현 사회에서의 노인문제는 점점 심화될 것으로 예측되고, 해결할 필요성을 느꼈습니다.</p>
<p><strong>5.1.2. 시장성</strong><br />
2019년 보건복지부 예산안 중 노인복지가 가장 높은 폭(26.1% 2조 8840억) 예산 증가와 함께 노인 돌봄 서비스도 증액(13.8% 1140억)하며 수요의 증가를 확인 할 수 있었고, 또한 세계 서비스 로봇 시장은 매년 15% 넘게 성장하며 시장성이 할 수 있었습니다.</p>
<p><strong>5.1.3. 목표</strong><br />
저희는 노인 분들이 거부감을 느끼는 기존의 로봇형태가 아닌 친숙한 반려동물의 형태로 다가가며, 4차 산업혁명의 기술 중 하나인 인공지능으로 로봇이 감정을 지니고 방범의 역할을 수행할 수 있게 하고, IoT(사물인터넷)를 구현하여 보호자와 사용자가 편리하게 사용할 수 있는 다기능의 로봇을 만드는 것을 목표로 과제를 진행하였습니다.</p>
<p><span style="color: #33cccc"><strong>5.2. 상세설계</strong></span><br />
시스템 구성도</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-3.png" rel="lightbox[37428]"><img class="size-large wp-image-37738 aligncenter" alt="56 ICT 인공지능 실버케어 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-3-620x278.png" width="620" height="278" /></a></p>
<p><span style="color: #0000ff"><strong>6. 개념설계 및 상세설계</strong></span><br />
<span style="color: #33cccc"><strong> 6.1. 어플리케이션</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-4.png" rel="lightbox[37428]"><img class="size-large wp-image-37739 aligncenter" alt="56 ICT 인공지능 실버케어 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-4-620x308.png" width="620" height="308" /></a><br />
<span style="color: #33cccc"><strong> 6.2. 기구설계</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-5.png" rel="lightbox[37428]"><img class="size-large wp-image-37740 aligncenter" alt="56 ICT 인공지능 실버케어 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-5-465x620.png" width="465" height="620" /></a><br />
<span style="color: #33cccc"><strong> 6.3. 인공지능 알고리즘 YOLO V3</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-6.png" rel="lightbox[37428]"><img class="alignnone size-full wp-image-37741" alt="56 ICT 인공지능 실버케어 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-6.png" width="620" height="282" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-7.png" rel="lightbox[37428]"><img class="alignnone size-full wp-image-37742" alt="56 ICT 인공지능 실버케어 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-7.png" width="620" height="456" /></a><br />
<span style="color: #0000ff"><strong> 7. 기대효과</strong></span><br />
인공지능 기반의 실버 케어 로봇은 증가하는 노인 복지 수요에 발 맞춰 공공기관 및 사립기관의 노인복지 인력난을 해소할 수 있고, 늘어나는 1인가구의 외로움 해소와 스마트홈 구축에 큰 도움이 될 수 있습니다. 뿐만 아니라 저희 로봇은 강아지라는 친숙한 디자인과 사용하는 노인 분들에 맞춰 인터페이스를 제작하여 로봇을 보다 편리하고 쉽게 제어 가능하게 하여 실질적으로 노인 분들이 쉽게 사용하고 접근할 수 있도록 설계되었습니다. 또한 저희 로봇은 노인 복지 뿐만 아니라 시스템이 IoT를 기반으로 되어있어 스마트 홈의 가구제어·전자제품제어 등 쉽게 연동되어 편리한 생활이 가능해집니다.<br />
늘어나는 고령인구와 1인 가구의 문제들을 효과적으로 해결 가능하며, 기존의 노인 돌봄 로봇과는 차별화되는 디자인과 기술로 노인 돌봄 로봇 사업에 큰 임팩트가 있을 거라 예상됩니다.</p>
<p><span style="color: #0000ff"><strong>8. 내부 프로그램 설명</strong></span><br />
<span style="color: #33cccc"><strong> 8.1. 펌웨어 프로그래밍</strong></span><br />
<span style="color: #339966"><strong> 8.1.1. 프로그래밍</strong></span></p>
<p><span style="color: #339966"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-8.png" rel="lightbox[37428]"><img class="size-full wp-image-37743 aligncenter" alt="56 ICT 인공지능 실버케어 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-8.png" width="338" height="456" /></a></strong></span><br />
시스템 내부에는 위 그림과 같이 Arduino 기반의 IoT 보드 Wemos사의 D1 mini를 이용하여 시스템을 구성하였고, 위의 센서들을 활용하고 있습니다. IoT 보드를 이용하여 상용 웹서버 Firebase와 연동하여 MCU와 통신을 하고 있습니다. IoT 보드에서 Firebase와 연동하는 소스코드는 다음과 같습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-9.png" rel="lightbox[37428]"><img class="alignnone size-full wp-image-37744" alt="56 ICT 인공지능 실버케어 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-9.png" width="620" height="515" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-10.png" rel="lightbox[37428]"><img class="size-full wp-image-37745 aligncenter" alt="56 ICT 인공지능 실버케어 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-10.png" width="620" height="435" /></a><br />
메카넘 휠이란 각 바퀴에 가해지는 동력에 따라 벡터값이 생기게 되는데, 그 벡터값의 합이 기구의 방향이 되는 바퀴를 말합니다.<br />
메카넘 휠을 제어하기 위해서는 방향별로 바퀴의 제어 방법을 숙지하여 프로그램을 구성해야 하기 때문에 방향별로 함수를 만들어 간단하게 로봇을 제어할 수 있도록 했습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-11.png" rel="lightbox[37428]"><img class="size-full wp-image-37746 aligncenter" alt="56 ICT 인공지능 실버케어 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-11.png" width="620" height="590" /></a></p>
<p><span style="color: #33cccc"><strong>8.2. 영상처리 기술</strong></span><br />
로봇 내의 방문자 인식 시스템을 위해 딥러닝을 이용한 YOLO v3 알고리즘과 Haar 특징 추출기 기반의 얼굴인식 알고리즘이 내장되어 있습니다. 사람 이미지 17,000장을 트레이닝 시킨 YOLO v3 모델과 Haar 특징 추출기 기반의 얼굴이 학습된 모델을 통해서 방문자를 인식하고 외부인인지, 내부인인지 판별할 수 있게 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-12.png" rel="lightbox[37428]"><img class="size-large wp-image-37747 aligncenter" alt="56 ICT 인공지능 실버케어 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-12-250x620.png" width="250" height="620" /></a><br />
위와 같은 과정을 통해서 방문자 인식을 진행하게 됩니다. 얼굴인식 알고리즘을 통해 얼굴 위치를 추출하고 딥러닝을 통해 학습된 객체 “사람”이 학습된 모델은 앉은 모습, 뒷모습 등의 모습에서도 사람임을 인지해낼 수 있습니다. 이미지는 CCTV 스트리밍 서버에서 이미지로 받아와 연산을 한 후 Firebase에 결과 값을 전송합니다.</p>
<p><span style="color: #33cccc"><strong>8.3. 임베디드 프로그래밍</strong></span><br />
로봇의 MCU Raspberry PI 3 B+는 Firebase의 값을 연산하여 블루투스 통신을 통해 Arduino Mega2560을 제어하여 로봇의 움직임을 제어합니다. 또 한 Wemos 의 IoT 보드와 상호 통신하며 자율주행 및 움직임을 제어합니다. 핵심 기능 중 하나인 CCTV 또한 MCU에 내장되어있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-13.png" rel="lightbox[37428]"><img class="size-full wp-image-37748 aligncenter" alt="56 ICT 인공지능 실버케어 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-13.png" width="403" height="575" /></a><br />
다음과 같이 Raspberry PI 3 B+을 통해서 Firebase 값을 수신 받아 아두이노와 블루투스 통신을 하여 모터를 제어합니다. 또 한 라즈캠을 통해서 CCTV 서버에 영상 스트리밍을 진행하여 전체 시스템에 영상을 송신할 수 있습니다.</p>
<p><span style="color: #33cccc"><strong>8.4. 안드로이드 어플리케이션</strong></span><br />
탭은 Fragment형식을 이용해 보다 부드러운 swipe 방식을 구현하였습니다. 첫 번째 탭에서는 Open weather를 통한 gps기반의 날씨와, 센서를 통해 Firebase database로 들어오는 값(로봇 내 및 wearable기기)을 보여주기 위해 Image View와 Text View로 화면을 구성하였습니다. 두 번째 로봇 제어 탭에서는 raspberry pi 기반의 ip로 구현된 웹서버를 통해 이뤄진 실시간 영상 스트리밍과 간편 전화 버튼 기능을 넣었습니다. 모터제어 버튼을 넣어 CCTV의 사각지대를 없애도록 하였습니다. 그리고 세 번째 탭은 놀이기능으로, 조이스틱을 통해 로봇을 8방향으로 자유롭게 움직일 수 있고, 각종 동작 버튼으로 로봇의 동작을 제어 할 수 있으며, 음성 명령이 들어가면 그에 따른 명령을 수행 할 수 있도록 하였고, 자율주행 ON/OFF기능을 넣어 자율적 주행이 가능하도록 하였습니다. 네 번째 탭은 Firebase storage를 통해 어플리케이션과의 상호보안을 이뤄 자체적 사진첩 라이브러리를 가능케 하였습니다. 다섯 번 째 탭은 알람 기능을 넣어 약 복용 시간을 돕는 기능을 합니다. 마지막으로 여섯 번 째 탭은 로봇과 어플리케이션. 그리고 wearable까지 전체적인 사용법 및 역할을 간략히 소개한 설명서 탭입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-14.png" rel="lightbox[37428]"><img class="size-large wp-image-37749 aligncenter" alt="56 ICT 인공지능 실버케어 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2019/10/56-ICT-인공지능-실버케어-14-530x620.png" width="530" height="620" /></a><br />
Firebase database를 통해 실시간으로 수신한 데이터를 활용해 어플리케이션 외부에서도 사용자가 팝업 알람을 통해 긴급한 상황을 처리할 수 있도록 하였습니다. 어플리케이션이 실행 중이지 않아도 정보를 수신하고 알람이 울리는 등의 이벤트를 처리하기 위해서는 어플리케이션이 스마트폰의 백 그라운드에서 동작할 수 있도록 해야 하고 이를 코딩 시에는 서비스의 형태로 코딩해야 합니다. 따라서 위의 실시간으로 데이터를 수신할 때 활용한 Mapping의 방법을 백 그라운드에서도 실행할 수 있도록 해줍니다. 이후 알람이 필요한 상황에 팝업 알람을 울려줍니다. 팝업이 될 때의 소리나 진동 세기, 진동 길이 등은 설정이 가능합니다. 또한 알람의 제목과 내용 또한 설정이 가능합니다. 알람이 울리는 긴급한 상황은 wearable의 심박 수와 체온이 비정상적인 값일 때, 일산화가스 값을 받을 때(화재 경보), 또는 방문자를 인식할 때 4가지입니다.</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/37428/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[41호]Wearable 미세먼지 측정 자전거 헬멧  Good! : Get out of Dust!</title>
		<link>http://www.ntrexgo.com/archives/33392</link>
		<comments>http://www.ntrexgo.com/archives/33392#comments</comments>
		<pubDate>Sat, 25 Mar 2017 02:50:15 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[41호]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[ict]]></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=33392</guid>
		<description><![CDATA[디바이스마트 매거진 41호 &#124; 자전거 헬멧 뒤편에 미세먼지 센서를 부착하여 미세먼지의 농도를 측정하고 앞부분에 부착된 LED를 통해 운전자에게 현재 수치를 알려줍니다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain.png" rel="lightbox[33392]"><img class="alignnone size-large wp-image-31056" alt="2016 ictmain" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain-620x156.png" width="620" height="156" /></a></p>
<p><span style="font-size: large"><strong>2016 ICT 융합 프로젝트 공모전 입선</strong></span></p>
<p><span style="font-size: x-large"><strong>Wearable 미세먼지 측정 자전거 헬멧<br />
</strong></span></p>
<p><span style="font-size: x-large"><strong>Good! : Get out of Dust!<br />
</strong></span></p>
<p style="text-align: right"><strong>글 | 고려대학교 강병욱, 김도형, 송명근, 원준현, 장재현</strong></p>
<p>&nbsp;</p>
<p><span style="color: #008000"><strong>심사평</strong></span></p>
<p><span style="color: #33cccc"><strong>JK전자</strong> </span>작품 구현의 완성도는 좋아 보입니다. 하지만 미세먼지 측정을 자전거 헬멧에 구현하는 것이 실용적인지는 한 번 생각해보아야 할 것 같습니다. 스마트폰만 켜도 기상청에서 제공하는 데이터로 바로 미세먼지 농도를 알 수도 있고, 헬멧이 아니더라도 항상 휴대하기 간편한 형태로 구현을 했으면 어떨까 합니다.</p>
<p><span style="color: #33cccc"><strong>뉴티씨</strong> </span>매우 간단한 아이디어이지만 구현을 완료하였고, 또한 실용적으로 현재 매우 필요한 작품으로 보인다. 자전거 인구가 급증하고 있고, 또한 오토바이를 타는 사람들도 매우 많아져서, 현재의 미세먼지 농도를 안다면 적절히 조치하여 개인의 건강에 도움을 주게 될 것으로 생각한다.<br />
바로 상품화를 진행하여도 좋은 아이디어로 생각된다.</p>
<p><span style="color: #33cccc"><strong>칩센</strong> </span>아이디어는 재밌지만 미세먼지를 측정하는 순간 집으로 들어갈 것 같다. 운동을 시작하기 전 결정되어야 하지 않을까 싶다.</p>
<p><span style="color: #33cccc"><strong>위드로봇</strong> </span>전체적인 기술 구현에 필요한 난이도는 높지 않아도 하나의 동작하는 시스템으로 구현하는 전체적인 완성도가 무척 뛰어난 작품입니다. 헬맷으로 1차 인터페이스를 사용하고, 스마트폰을 2차 인터페이스로 택하여 필요에 따라 정보를 사용자가 선택할 수 있도록 한 점이 훌륭합니다. 평균 수치가 로깅이 되어 활용할 수 있도록 한 점도 추후 IoT 관점에서 다양하게 활용할 수 있을 것 같습니다.</p>
<p><span style="color: #008000"><strong>1. 작품 제목</strong> </span><br />
Wearable 미세먼지 측정 자전거 헬멧 Good! : Get out of Dust!</p>
<p><span style="color: #008000"><strong>2. 작품 개요</strong></span><br />
사용대상 : 자전거 운전자, 오토바이 운전자, 공사장 인부 등 헬멧을 착용하고 야외활동을 하는 사람.<br />
배경 : 다음 기사에서 볼 수 있듯이 최근 미세먼지 문제가 큰 이슈가 되고 있으며, 각종 질병을 유발하는 등 인체에 치명적인 것을 알 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-17-334.jpg" rel="lightbox[33392]"><img alt="Cap 2017-05-30 10-57-17-334" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-17-334.jpg" width="620" height="355" /></a></p>
<p>(자료1)에서 볼 수 있듯이, 최근 중국발 미세먼지에 의해서 한국의 미세먼지 수치가 세계기준의 두 배인 것을 알 수 있습니다. 또한 (자료2)에서 는 미세먼지로 인한 천식, 비염, 아토피의 연도별 유병률이 점점 증가하고 있는 것을 알 수 있습니다. 이런 상황에서도 건강을 위해 자전거를 이용하는 인구는 점차 증가하는 추세입니다. 이렇게 야외활동을 하는 사람들이 미세먼지를 흡입함으로서 피해를 입는 것을 줄이고자 아이디어를 제안하게 되었습니다.<br />
예상효과 및 활용방안 : 자전거 헬멧 뒤편에 미세먼지 센서를 부착하여 미세먼지의 농도를 측정하고 앞부분에 부착된 LED를 통해 운전자에게 현재 수치를 알려줍니다. 또한 스마트폰으로 데이터를 전송하여 실제 수치를 확인할 수 있으며, 미세먼지 농도가 나쁨 수치에 도달하였을 때 푸쉬 메시지와 알람이 울리도록 하였습니다.</p>
<p><strong><span style="color: #008000">3. 작품 설명</span> </strong><br />
<span style="color: #339966"><strong>3.1. 주요동작 및 특징</strong></span><br />
<span style="color: #33cccc"><strong>3.1.1. 주요기능</strong> </span><br />
하드웨어 시스템에서 미세먼지 센서로 미세먼지 농도를 측정하여 UART 통신으로 MCU로 데이터를 전송해 기상청 발표기준(0~30㎍/㎥인 경우 초록색, 31~80㎍/㎥인 경우 노란색, 81~150㎍/㎥인 경우 빨간색, 150㎍/㎥ 이상인 경우 2개의 빨간색) LED를 켜줍니다. 동시에 데이터를 블루투스 통신을 통해 스마트폰 어플리케이션으로 전송하여, 스마트폰에서 실제 수치를 확인하고, 나쁨 수치에서 푸쉬 알림을 통해 알려줍니다. 아래는 그림을 통하여 한 눈에 주요 기능을 파악할 수 있도록 나타낸 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-27-749.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33561" alt="Cap 2017-05-30 10-57-27-749" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-27-749.jpg" width="620" height="174" /></a></p>
<p>① 1단계에서는 MCU에서 미세먼지 센서로 측정값을 보내라는 command를 보내면, 센서에서 측정값을 Response합니다.<br />
② 2단계에서는 측정된 값에 따라 LED를 다르게 켜주고, 값을 Bluetooth 모듈로 전송합니다.<br />
③ 3단계에서는 Bluetooth에서 전송받은 데이터를 스마트폰 어플리케이션으로 전송합니다.<br />
④ 스마트폰 어플리케이션은 그 데이터를 전송받아서 화면에 표시해주고, 측정값이 일정값 이상으로 올라갔을 때 푸쉬 알림을 받게 하여 사용자에게 알립니다.</p>
<p><span style="color: #33cccc"><strong>3.1.2. 부가기능</strong></span><br />
부가기능으로 자전거를 타면서 필요한 정보, 예를 들면 날씨, 오존 농도, 자외선 농도를 함께 표시해주도록 하였습니다.</p>
<p><span style="color: #339966"><strong>3.2. 전체 시스템 구성</strong></span><br />
2개의 UART 통신이 가능한 하드웨어 보드인 ARM-Cortex M3와 미세먼지 센서를 활용하여 회로를 구성하였습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-39-249.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33562" alt="Cap 2017-05-30 10-57-39-249" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-39-249.jpg" width="620" height="265" /></a><br />
전체적인 시스템을 System Schematic로 그려 보았습니다. 미세먼지 센서에서 UART 통신을 통하여 MCU(ARM Cortex &#8211; M3)로 데이터를 전송하고, MCU는 UART 통신으로 Bluetooth 모듈로 전송합니다. 그리고 블루투스 통신을 통하여 스마트폰 어플리케이션으로 데이터를 전송하며, 그 정보를 데이터베이스 서버에 저장합니다. 이를 통해 부가적인 정보와 함께 미세먼지 수치를 알려주는 것입니다.</p>
<p><span style="color: #33cccc"><strong>3.2.1. ARM Cortex -M3 시스템</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-49-033.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33563" alt="Cap 2017-05-30 10-57-49-033" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-49-033.jpg" width="620" height="378" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-58-451.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33564" alt="Cap 2017-05-30 10-57-58-451" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-57-58-451.jpg" width="620" height="402" /></a></p>
<p>위 사진은 실제 테스트 중인 시스템을 찍은 사진으로, 사진 아래쪽에 향 연기를 피워 인위적으로 미세먼지 농도를 높여준 것을 볼 수 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-19-58-483.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33565" alt="Cap 2017-05-30 11-19-58-483" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-19-58-483.jpg" width="620" height="414" /></a><br />
착용하게 되면 위의 사진과 같이 현재의 미세먼지농도 수치를 LED를 통해 ‘좋음/보통/나쁨/매우 나쁨’의 4가지 상태로 알 수 있습니다. 자전거 운전자는 스마트폰을 이용하지 않고도 자신이 운전 중인 도로의 미세먼지수치를 파악할 수 있습니다. 스마트폰 어플리케이션에서 블루투스로 전송받은 측정 수치를 확인하는 것도 볼 수 있습니다.</p>
<p><span style="color: #33cccc"><strong>3.2.2. 스마트폰 어플리케이션</strong></span><br />
<strong></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-14-416.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33566" alt="Cap 2017-05-30 11-20-14-416" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-14-416.jpg" width="620" height="531" /></a></p>
<p><span style="color: #339966"><strong>3.3. 개발 환경</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-24-448.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33567" alt="Cap 2017-05-30 11-20-24-448" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-24-448.jpg" width="620" height="168" /></a></p>
<p><strong>Hardware</strong><br />
· MCU: ARM-Cortex M3<br />
· OS: Windows8<br />
· Tool: IAR Embedded Workbench<br />
· Language: C/C++</p>
<p><strong>Software</strong><br />
· OS: Windows10<br />
· Tool: Android Studio<br />
· Graphic: Photoshop<br />
· Language: JAVA(Android)</p>
<p><span style="color: #008000"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #339966"><strong>4.1. 하드웨어 회로 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-30-815.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33568" alt="Cap 2017-05-30 11-20-30-815" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-30-815.jpg" width="620" height="326" /></a></p>
<p><span style="color: #33cccc"><strong>4.1.1. ① 5V, 3.3V 출력 전원부 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-37-781.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33569" alt="Cap 2017-05-30 11-20-37-781" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-37-781.jpg" width="620" height="186" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-47-076.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33570" alt="Cap 2017-05-30 11-20-47-076" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-20-47-076.jpg" width="196" height="186" /></a><br />
위와 같이 회로를 구성하여 7V~40V 입력으로 5V를 출력하였습니다.<br />
1117C를 사용하여 5V입력으로 3.3V를 출력하였습니다.</p>
<p><span style="color: #33cccc"><strong>4.1.2. ARM Cortex M3 구성</strong></span><br />
블루투스 모듈에 UART1을 사용하기 위하여, TX/RX 각각 A포트 핀9번, 10번을 사용하였습니다.<br />
미세먼지 센서에 UART2를 사용하기 위하여 TX/RX 각각 A포트 핀2번, 3번을 사용하였습니다.<br />
4개의 LED에 신호를 주기 위하여, D포트 0번, 1번, 2번, 3번을 사용하였습니다.</p>
<p><span style="color: #33cccc"><strong>4.1.3. 블루투스 모듈 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-06-100.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33571" alt="Cap 2017-05-30 11-21-06-100" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-06-100.jpg" width="620" height="434" /></a><br />
1. GND<br />
2. VCC에 3.3V 연결<br />
3. STATUS에 LED 연결<br />
7. 블루투스 TX에 ARM- UART1 RX(A10)연결<br />
8. 블루투스 RX에 ARM- UART1 TX(A9)연결</p>
<p><span style="color: #33cccc"><strong>4.1.4. 미세먼지센서 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-12-315.png" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33572" alt="Cap 2017-05-30 11-21-12-315" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-12-315.png" width="620" height="325" /></a><br />
1. GND<br />
2. TX에 ARM- UART2 RX(A3)연결<br />
3. 5V<br />
5. RX에 ARM-UART2 TX(A2)연결</p>
<p><span style="color: #008000"><strong>5.참고문헌</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-18-115.jpg" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33573" alt="Cap 2017-05-30 11-21-18-115" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-18-115.jpg" width="620" height="284" /></a></p>
<p>위 3개의 도서와 구글에서 검색한 오픈 소스코드를 참고하여 시스템을 구현하고 안드로이드 어플리케이션을 개발하였습니다.</p>
<p><span style="color: #008000"><strong>6.부품목록</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-24-166.png" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33574" alt="Cap 2017-05-30 11-21-24-166" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-24-166.png" width="620" height="359" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-34-631.png" rel="lightbox[33392]"><img class="alignnone size-full wp-image-33575" alt="Cap 2017-05-30 11-21-34-631" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-21-34-631.png" width="620" height="141" /></a></p>
<p><span style="color: #008000"><strong>7. 소스코드</strong></span><br />
추가설명이 필요한 부분은 주석으로 설명을 달았습니다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include&lt;stm32f10x.h&gt;<br />
#include&lt;stdio.h&gt;<br />
#include&#8221;delay.h&#8221;<br />
#include&#8221;LCD.h&#8221;<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
/* USART_1 &amp; printf 관련 define*/<br />
#ifdef __GNUC__<br />
#define PUTCHAR_PROTOTYPE int __io_putchar(int ascii)<br />
#else<br />
#define PUTCHAR_PROTOTYPE int fputc(int ascii, FILE *f)<br />
#endif<br />
#define BUFFER_SIZE 200<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
// BlueTooth 수신 데이터 저장 변수<br />
volatile char control_data;<br />
u8 RxBuf[BUFFER_SIZE];<br />
u8 TxBuf[BUFFER_SIZE];<br />
u8 TxInCnt=0;<br />
u8 TxOutCnt=0;<br />
u8 RxCnt=0;<br />
// 먼지센서 수신 데이터 저장 변수<br />
int Dust_value[16]={9,};<br />
int Measured_value=0;<br />
int _Value;<br />
volatile u16 a=0;<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
void Rcc_Initialize(void) ;<br />
void Gpio_Initialize(void);<br />
void Nvic_Initialize(void);<br />
void UART1_Initialize(void);<br />
void USART1_IRQHandler(void);<br />
void UART2_Initialize(void);<br />
void Delay_ms(unsigned int Count);<br />
void Delay_us(unsigned int Count);<br />
void main(void){<br />
Rcc_Initialize( );<br />
Gpio_Initialize( );<br />
Nvic_Initialize( );<br />
UART1_Initialize( );<br />
USART1_IRQHandler( );<br />
UART2_Initialize( );<br />
while(1){<br />
Delay_us(2000);<br />
//to 미세먼지 센서 , send<br />
USART_SendData(USART2,0&#215;11);<br />
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);</p>
<p>USART_SendData(USART2,0&#215;01);<br />
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);</p>
<p>USART_SendData(USART2,0&#215;01);<br />
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);</p>
<p>USART_SendData(USART2,0xED);<br />
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);</p>
<p>Delay_us(3000); //from 미세먼지 센서 , recieve<br />
for(int temp=0; temp&lt;16;temp++){ //시작 패킷 00 16 0d 01<br />
Dust_value[temp]= USART_ReceiveData(USART2);<br />
Delay_ms(1);<br />
}<br />
USART_ClearITPendingBit(USART2, USART_IT_RXNE); //미세먼지값 계산.<br />
Measured_value=Dust_value[3]*256*256*256+Dust_value[4]*256*256+Dust_value[5]*256+Dust_value[6];<br />
_Value=(Measured_value*3528)/100000; //to 블루투스 send.<br />
printf(&#8220;{%d}&#8221;,_Value); //LED 색변경<br />
if(_Value&lt;=30)<br />
GPIOD-&gt;ODR = 0&#215;0001;<br />
else if((_Value&lt;=80)&amp;&amp;(_Value&gt;30))<br />
GPIOD-&gt;ODR = 0&#215;0002;<br />
else if((_Value&lt;=150)&amp;&amp;(_Value&gt;80))<br />
GPIOD-&gt;ODR = 0&#215;0004;<br />
else if(_Value&gt;150)<br />
GPIOD-&gt;ODR = 0x000C;<br />
}<br />
}<br />
RCC 설정&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
void Rcc_Initialize(void)<br />
{<br />
ErrorStatus HSEStartUpStatus;<br />
RCC_DeInit();<br />
RCC_HSEConfig(RCC_HSE_ON);<br />
HSEStartUpStatus = RCC_WaitForHSEStartUp();<br />
if (HSEStartUpStatus == SUCCESS)<br />
{<br />
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);<br />
FLASH_SetLatency(FLASH_Latency_2);<br />
RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK = SYSCLK</p>
<p>RCC_PCLK2Config(RCC_HCLK_Div1); // 72Mhz<br />
RCC_PCLK1Config(RCC_HCLK_Div4); // 72/4 x2 = 36Mhz<br />
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLL 설정8Mhz*9=72Mhz<br />
RCC_PLLCmd(ENABLE);</p>
<p>while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);<br />
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);<br />
while (RCC_GetSYSCLKSource() != 0&#215;08);<br />
}<br />
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //GPIO A에 clock허용<br />
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); //GPIO D에 clock허용<br />
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//UART1 clock허용.<br />
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); // 미세먼지 센서.<br />
}</p>
<p>GPIO 설정&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
void Gpio_Initialize(void)<br />
{<br />
GPIO_InitTypeDef GPIO_InitStructure;</p>
<p>//블루투스 TX<br />
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//핀 9추가<br />
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;<br />
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;<br />
GPIO_Init(GPIOA, &amp;GPIO_InitStructure);</p>
<p>//블루투스 RX<br />
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//핀 10추가<br />
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;<br />
GPIO_Init(GPIOA, &amp;GPIO_InitStructure);</p>
<p>//미세먼지 센서 TX<br />
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;<br />
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;<br />
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;<br />
GPIO_Init(GPIOA, &amp;GPIO_InitStructure);</p>
<p>//미세먼지 센서 RX<br />
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//핀 10추가<br />
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;<br />
GPIO_Init(GPIOA, &amp;GPIO_InitStructure);</p>
<p>//LED<br />
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;<br />
// 핀 0,1,2,3<br />
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;<br />
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;<br />
GPIO_Init(GPIOD, &amp;GPIO_InitStructure);<br />
}</p>
<p>Nvic 함수선언&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
void Nvic_Initialize(void)<br />
{<br />
NVIC_InitTypeDef NVIC_InitStructure;<br />
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);</p>
<p>//USART1_IRQ enable<br />
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn ;<br />
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;<br />
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;<br />
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;<br />
NVIC_Init(&amp;NVIC_InitStructure);<br />
}</p>
<p>Printf를 사용하기 위한 정의&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
PUTCHAR_PROTOTYPE<br />
{<br />
TxBuf[TxInCnt] = ascii;<br />
if(TxInCnt&lt;BUFFER_SIZE-1) TxInCnt++;<br />
else TxInCnt = 0;</p>
<p>//Enable the USART1 Transmit interrupt<br />
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);</p>
<p>return ascii;<br />
}</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
void UART1_Initialize(void){ //PCLK2를 사용한다.</p>
<p>USART_InitTypeDef USART_InitStructure;<br />
NVIC_InitTypeDef NVIC_InitStructure;</p>
<p>USART_InitStructure.USART_BaudRate = 9600;<br />
USART_InitStructure.USART_WordLength = USART_WordLength_8b;<br />
USART_InitStructure.USART_StopBits = USART_StopBits_1;<br />
USART_InitStructure.USART_Parity = USART_Parity_No;<br />
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;<br />
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;<br />
USART_Init(USART1, &amp;USART_InitStructure);<br />
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);<br />
USART_Cmd(USART1, ENABLE);</p>
<p>NVIC_InitStructure.NVIC_IRQChannel = 37; //USART1_IRQChannel<br />
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;<br />
NVIC_Init(&amp;NVIC_InitStructure);</p>
<p>}</p>
<p>(BLUETOOTH 통신)USART1 인터럽트 설정&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
void USART1_IRQHandler(void)<br />
{<br />
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)// 비트에 0이 아닐 경우에 데이터가 수신.<br />
{</p>
<p>control_data = USART_ReceiveData(USART1); //0이 아닐 경우에 데이터를 읽는다. control_data= 버퍼에 값을 저장하는 역할을 하는 변수.</p>
<p>/*Buffer룰 구현해야하는 이유.</p>
<p>수신시간에 비해 처리시간이 길어서 인터럽트 발생부분에서는 버퍼에 단순히 저장만하고 처리는 다른 곳에서 한다.<br />
*/<br />
USART_ClearITPendingBit(USART1, USART_IT_RXNE);<br />
// pending bit를 clear.(안해주면 인터럽트가 처리되었는지 알 수 없고 다시 인터럽트가 발생한것으로 인지해서 계속 핸들러 호출)</p>
<p>}</p>
<p>if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)//비트에 0이 아닐 경우에 데이터가 송신<br />
{</p>
<p>USART_SendData(USART1,TxBuf[TxOutCnt]);</p>
<p>if(TxOutCnt&lt;BUFFER_SIZE-1) TxOutCnt++; // Txoutcount가 buffer size 보다 작으면 +1씩 샌다.<br />
else TxOutCnt = 0;</p>
<p>if(TxOutCnt == TxInCnt)// Txoutcount가 Txincount가 되면 tx 끄고 RX 킨다.<br />
{<br />
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);<br />
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);<br />
}<br />
}<br />
}</p>
<p>//미세먼지 센서.<br />
void UART2_Initialize(void)<br />
{</p>
<p>USART_InitTypeDef USART_InitStructure;<br />
USART_InitStructure.USART_BaudRate = 9600 ;<br />
USART_InitStructure.USART_WordLength = USART_WordLength_8b;<br />
USART_InitStructure.USART_StopBits = USART_StopBits_1;<br />
USART_InitStructure.USART_Parity = USART_Parity_No;<br />
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;<br />
USART_InitStructure.USART_Mode =USART_Mode_Rx |USART_Mode_Tx;<br />
USART_Init(USART2, &amp;USART_InitStructure);<br />
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);<br />
USART_Cmd(USART2, ENABLE);<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
//딜레이 함수<br />
void Delay_us(unsigned int Count)<br />
{<br />
Count *= 12;<br />
for(; Count!=0; Count&#8211;);<br />
}<br />
void Delay_ms(unsigned int Count)<br />
{<br />
Count *= 12000;<br />
for(; Count!=0; Count&#8211;);<br />
}<br />
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/33392/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[41호]휴대용 미세 섬유 제작 장치</title>
		<link>http://www.ntrexgo.com/archives/33390</link>
		<comments>http://www.ntrexgo.com/archives/33390#comments</comments>
		<pubDate>Sat, 25 Mar 2017 01:25:10 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[41호]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[ict]]></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=33390</guid>
		<description><![CDATA[디바이스마트 매거진 41호 &#124; 전기 방사란 고분자용액에 고전압을 가하여 그 고분자의 성질을 갖는 미세 섬유를 제조하는 공정이고 이를 위한 장치가 전기 방사 장치다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain.png" rel="lightbox[33390]"><img class="alignnone size-large wp-image-31056" alt="2016 ictmain" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain-620x156.png" width="620" height="156" /></a></p>
<p><span style="font-size: large"><strong>2016 ICT 융합 프로젝트 공모전 입선</strong></span></p>
<p><span style="font-size: x-large"><strong>휴대용 미세 섬유 제작 장치<br />
</strong></span></p>
<p><span style="font-size: x-large"><strong>(Portable electrospinning device and fine fiber)</strong></span></p>
<p>&nbsp;</p>
<p style="text-align: right"><strong>글 | 충남대학교 홍성욱, 김일적, 이현우, 정진우</strong></p>
<p>&nbsp;</p>
<p><span style="color: #008000"><strong>심사평</strong></span></p>
<p><strong>뉴티씨</strong> 매우 생소한 분야라 평가하기 어려우나, 전기 방사를 통하여 미세 섬유를 제작 가능하다는 것을 확인하였다는데 의미가 있으며, 소형화된 휴대 장치를 만들어 응급지혈 등에 사용할 수 있도록 한 점이 돋보인다. 실제로 사용 가능하도록 기능을 개선하고, 좀 더 빠른 시간에 많은 양이 생성될 수 있도록 한다면 좋은 제품을 사용될 수 있을 것으로 보인다. 상대적으로 높은 점수를 주었다.</p>
<p><strong>칩센</strong> 보고서 상 내용처럼 지혈 등 응급조치에 사용할 수 있게 되면 큰 기대가 될만한 작품이다. 현실의 스파이더맨이 될 수 있지 않을까 싶다.</p>
<p><strong>위드로봇</strong> 제작한 작품에서 가장 중요한 부분 중에 하나가 고전압 증폭 회로인데 이 부분에 대한 설명은 보고서에서 찾기 어려웠습니다.</p>
<p><span style="color: #008000"><strong>1. 작품 제목</strong></span><br />
휴대용 미세 섬유 제작 장치 (Portable electrospinning device and fine fiber)</p>
<p><span style="color: #008000"><strong>2. 작품 개요</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-39-26-251.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33531" alt="Cap 2017-05-30 10-39-26-251" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-39-26-251.jpg" width="620" height="277" /></a></p>
<p>전기 방사란 고분자용액에 고전압을 가하여 그 고분자의 성질을 갖는 미세 섬유를 제조하는 공정이고 이를 위한 장치가 전기 방사 장치다. 전기 방사 장치는 &lt;그림 1&gt;에서 나타낸 것처럼 크게 고전압 전원, 원료 분출부 그리고 섬유를 수집하는 집진판의 3가지로 이루어진다. 고분자 용액 등 전기 방사의 원료 용액을 원료 분출부로 토출시키면 표면장력에 의해 오른쪽 그림과 같이 둥근 형태로 팁 끝에 맺히게 된다. 이때 팁에는 +, 집진판에는 -극을 연결해 고전압을 가하게 되면 둥근 모양이 뾰족한 테일러 콘(Taylor cone) 형태를 띠게 되면서 용액간의 전기적 반발력을 갖게 된다. 이때 반발력이 용액간의 표면장력보다 커지게 되면 용액이 삐져나와 방사되고 연신되어 섬유가 된다. 방사된 섬유는 반대 극성을 띤 집진판에 끌려가 모이게 된다.</p>
<p>전기 방사는 상대적으로 간단한 방법으로 수 마이크로미터에서 수십 나노미터 두께의 미세 섬유를 얻을 수 있는 장점을 가지고 있다. 전기 방사를 통해 얻은 미세 섬유는 필터, 의학 분야 등 다양한 분야에서 사용 가능하다.</p>
<p>하지만 기존의 전기 방사 장치는 장비의 부피와 무게가 크고 가격이 비싸며 유선 전력원을 필요로 하는 단점을 가지고 있다. 이 단점들의 원인이 되는 것은 고전압 전원 공급 장치(High-voltage power supply)이다. 고전압 전원 공급 장치는 질량과 부피가 크며, 가격이 비싸다. 다르게 말하면, 고전압 전원 공급 장치를 개조하거나 대체할 수 있다면 저렴하면서 작고 가벼운 전기 방사 장치를 만들 수 있다는 것이다.</p>
<p>이러한 문제를 해결하기 위하여 기존의 고전압 전원 공급 장치를 건전지와 고전압 증폭 회로로 대체하는 방법을 생각했다. 수 V의 전압을 수 kV의 전압까지 증폭시킬 수 있는 고전압 증폭 회로를 이용하여 건전지의 작은 전압을 전기 방사에 필요한 만큼 증폭시키는 방법이다. 건전지와 고전압 증폭 회로는 고전압 전원 공급 장치에 비해 크기나 무게가 현저히 작고 저렴하면서도 전기 방사에 필요한 만큼의 고전압을 얻을 수 있다. 또한 건전지를 이용하므로 휴대가 가능하고 단순히 건전지를 교체하는 방법으로 반영구적인 사용이 가능하기 때문에, 이 방법을 사용하면 기존 장치의 문제점들을 해결할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-39-46-868.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33532" alt="Cap 2017-05-30 10-39-46-868" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-39-46-868.jpg" width="620" height="332" /></a></p>
<p>가격이 저렴하고 휴대가 편리한 전기 방사 장치가 개발되면 일상생활에서 시간과 장소에 구애받지 않고 사용 가능할 것이다. 또, 응급 지혈 장치, 특수 환경에서 사용하는 자외선 차단제, 제습제 등 고분자용액의 종류와 특징에 따라 다양한 용도로 사용 가능할 것으로 예상된다. 또한 &lt;그림2&gt;에서 확인할 수 있듯이 선행 기술 검색결과 1910건의 전기 방사 관련 특허 중 전기 방사 장치에 관련된 특허는 174건(9%)으로 검색되었고, 이들을 세밀하게 조사했지만 휴대성과 관련된 특허는 발견되지 않았다. 휴대성과 관련된 전기 방사 장치에 대한 기술은 전무하므로 우리가 만든 이 장치는 상당한 독창성을 가지고 있다.</p>
<p><span style="color: #008000"><strong>3. 작품 설명</strong></span><br />
<span style="color: #339966"><strong>3.1. 주요 동작 및 특징</strong></span><br />
본 장치는 전기 방사 장치에 휴대성을 부여한 장치로서 아래와 같은 특징을 가진다.</p>
<p>1. 건전지와 고전압 증폭 회로를 사용하여 저렴하게 전기 방사 장치 제작 가능<br />
2. 건전지와 고전압 증폭 회로를 사용함으로써 부피와 무게가 작아 휴대 용이<br />
3. 건전지를 교체하여 반영구적으로 사용가능<br />
4. 고분자 용액의 종류와 특징에 따라 다양한 용도로 사용가능<br />
5. 점도를 조절하여 섬유의 두께 조절 가능<br />
6. 주사기를 탈착하는 방식으로 교체시 별도의 연결 과정이 없어 고분자 용액 변경 편리<br />
7. 저항을 이용해 전류가 몸을 흐르지 않으면서 몸이 콜렉터 역할을 하도록 함<br />
8. 사람의 손 크기에 맞춰 제작하여 손에 쥐기 편함<br />
9. 스위치로 간편하게 ON/OFF 가능</p>
<p><span style="color: #339966"><strong>3.2. 전체 시스템 구성</strong></span><br />
전체적인 시스템의 구성은 &lt;그림 3&gt;의 블록도로서 표현할 수 있다. 전체적으로 전원 장치, 고전압 증폭 장치, 원료 용기, 원료 방출부, 안전장치로 구성되어 있다. 우선 전원 장치에서 수 볼트의 전압이 공급된다. 이때 공급되는 전압은 전기 방사를 일으키기에 부족하므로 고전압 증폭 장치를 거쳐 5~10kV의 고전압으로 증폭된다. 증폭된 전압의 +극은 원료 방출부에, -극은 안전장치에 연결되고 안전장치를 통하여 사용자와 연결되게 된다. 사용자는 -전하를 가지고 있고 원료 방출부는 +전하를 가지고 있게 되므로 전기 방사의 조건은 충족되게 된다. 이때 원료 용기에서 원료 방출부로 원료가 방출되면, 원료는 고전압에 의해 테일러 콘(Taylor cone) 형상을 띠면서 전기적 반발력에 의해 방사되어 미세 섬유를 얻을 수 있게 된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-40-07-035.png" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33533" alt="Cap 2017-05-30 10-40-07-035" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-40-07-035.png" width="620" height="322" /></a></p>
<p><span style="color: #339966"><strong>3.3. 개발 환경</strong></span><br />
<strong>개발 프로그램</strong><br />
· SolidWorks 2014<br />
· COMSOL Multiphysics 5.0<br />
· ANSYS 15.0</p>
<p><strong>제작 장치</strong><br />
· 3D 프린터(PMS Engineering, MD-270)</p>
<p><strong>측정 장치</strong><br />
· Fluke-116 Multimeter<br />
· 80K-40 High voltage prove</p>
<p><span style="color: #008000"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #339966"><strong>4.1. 구상 단계</strong></span><br />
앞에서 설명했듯이 전기 방사 장치는 크게 고전압 전원, 원료 분출부 그리고 섬유를 수집하는 집진판의 3가지로 나누어진다. 우리는 기존의 장치에 휴대성을 부여하기 위해서 고전압 증폭장치, 전원 공급 장치, 원료 보관 용기, 안전장치로 장치를 구성하도록 설계하였다.<br />
고전압 증폭 장치로는 고전압 증폭 회로를 사용하기로 했고 여러 종류의 회로를 구매하고 실험을 통해 가장 전기 방사가 잘 이루어지는 회로로 채택하기로 하였다. 전원 공급 장치로는 가장 쉽게 구할 수 있으면서도 작고 가벼운 건전지를 선택했다. 부피를 작게 하기위해 AAA 건전지를 채택하였고 3V의 전압을 출력하기 위해 건전지 2개를 사용하도록 했다. 원료 보관 용기로는 1ml 주사기를 사용하였다. 전기 방사에 사용되는 고분자 용액의 특성상 용기와 바늘 팁을 자주 교체해주어야 하므로 용량이 작으며 저렴하고 쉽게 교체 가능한 1ml 주사기를 채택하였다. 안전장치는 전기적인 안전장치와 물리적인 안정장치 이렇게 두 가지를 고려해 설계하였다.</p>
<p><span style="color: #339966"><strong>4.2. 실험 단계</strong></span><br />
<strong>(1) 실험 방법</strong><br />
설계를 하는데 있어서 어떠한 고전압 증폭 회로를 사용할건지는 우리가 가지고 있던 큰 문제 중 하나였다. 우리는 이 문제점을 해결하기 위해서 시중에서 판매하는 다양한 고전압 증폭 회로를 직접 구입하여서 이것을 실험하는 방법으로 문제를 해결하였다.<br />
실험은 고전압 증폭 회로를 선택하기 위해서 고전압 증폭 회로의 스펙 상 전압과 실제로 3V를 가했을 때 실측 전압이 어떻게 다른지를 알아보는 실험A, 실험A의 결과로 선택한 고전압 증폭 회로를 이용하여 실제로 전체 회로를 구성하였을 때 전기 방사가 제대로 되는지 알아보는 실험B를 실시하였다.</p>
<p><strong>(2) 실험A &#8211; 고전압 증폭 회로 전압 측정 실험</strong><br />
실험에 들어가기에 앞서서 시중에서 파는 여섯 종류의 예비 후보 군을 선정하여서 구매한 후에 실험을 하였다. 예비 후보 군을 정한 기준은 고전압 증폭 회로의 크기와 출력 전압이다. &lt;그림 4&gt;와 같이 6종류의 회로에 대해 실험하였다. 스펙 상 출력 전압은 A. 7kV, B. 40kV, C. 60kV, D. 80kV, E. 400kV, F. 600kV이다. 건전지 2개가 약 3V의 전압을 낼 수 있을 것이라고 가정하여서 Power supply의 입력 전압은 3V로 하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-42-55-619.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33534" alt="Cap 2017-05-30 10-42-55-619" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-42-55-619.jpg" width="620" height="387" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-06-719.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33535" alt="Cap 2017-05-30 10-43-06-719" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-06-719.jpg" width="620" height="379" /></a><br />
&lt;그림 5&gt;와 같이 회로를 구성하였다. (a)는 실제 구성한 회로의 모습이고 이를 (b)와 같이 간단한 회로도로 나타내었다. 증폭 회로에 의해서 증폭된 고전압을 Fluke-116 Multimeter, 80K-40 High voltage prove를 이용하여서 측정하였다. Power supply 말고 실제로 사용할 건전지를 이용하여서도 위와 같은 회로를 구성하여서 실험을 해보았다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-13-252.png" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33536" alt="Cap 2017-05-30 10-43-13-252" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-13-252.png" width="620" height="264" /></a></p>
<p>실험 결과는 &lt;표 1&gt;과 같다. A회로를 제외하면 스펙 상 출력 전압과 실측 출력 전압이 크게 차이가 났으며 전원 공급 장치와 건전지의 차이도 컸다. 전원 공급 장치를 이용했을 때가 건전지를 이용했을 때보다 출력 전압이 더 컸다. F 증폭 회로의 경우 건전지로도 5kV의 출력 전압을 나타내어 전기 방사에 충분할 것이라 예상되었다.</p>
<p><strong>(3) 실험B &#8211; 회로 별 전기 방사 실험</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-22-302.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33537" alt="Cap 2017-05-30 10-43-22-302" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-22-302.jpg" width="620" height="364" /></a></p>
<p>&lt;그림 6&gt;과 같이 회로에 따른 전기 방사 여부를 알아보기 위한 실험을 진행하였다. 전원의 종류에 따른 차이점을 비교해보기 위해 안정된 전원 공급 장치인 경우(Power supply)와 AAA건전지 2개인 경우로 나누어 실험을 진행하였다. 입력 전압은 3V이며 방사 거리는 10cm이고 방사 시간은 30초로 정하였다. 실험결과는 아래와 같다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-42-190.jpg" rel="lightbox[33390]"><img class="alignnone size-large wp-image-33538" alt="Cap 2017-05-30 10-43-42-190" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-42-190-542x620.jpg" width="542" height="620" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-58-622.jpg" rel="lightbox[33390]"><img class="alignnone size-large wp-image-33539" alt="Cap 2017-05-30 10-43-58-622" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-43-58-622-533x620.jpg" width="533" height="620" /></a></p>
<p>회로별로 전기 방사한 모습을 &lt;표 2&gt;에 나타내었다. 전원 공급 장치로 전압을 증폭 시켰을 때 모든 회로가 전기 방사가 고르게 잘 되는 것을 볼 수 있다. 그리고 건전지를 이용했을 때는 F증폭 회로만 전기 방사가 제대로 되는 것을 볼 수 있었다. D와 E회로의 경우에는 건전지를 이용했을 때 용액이 직선으로 분출되며 제대로 방사가 되지 않는 것을 볼 수 있었다.<br />
고전압 증폭 회로 전압 측정, 전기 방사 두 가지 실험을 종합했을 때, 출력 전압이 5kV이상일 경우에 전기 방사가 되는 것을 알 수 있었다. 전원 공급 장치를 이용하였을 때는 모든 회로의 출력 전압이 5kV 이상이었고 전기 방사가 정상적으로 되었다. 하지만 건전지 이용 시 출력 전압이 5kV이하인 경우(회로 B, C) 전기 방사가 전혀 되지 않았고, 3~4kV일 경우(회로 D, E) 용액에 실처럼 분출되는 현상을 보이며 전기 방사가 제대로 되지 않았다. 또 출력 전압이 크면 클수록 방사 범위가 넓어지는 것을 알 수 있다(&lt;표 2&gt;의 전원 공급 장치 사용 시). 결론적으로, 회로 F가 AAA건전지 2개를 사용하는 휴대용 전기 방사 장치를 제작하기에 가장 알맞은 회로임을 알 수 있고 이를 이용하면 AAA건전지를 2개만 이용하는 휴대용 전기 방사 장치를 제작할 수 있다.</p>
<p><span style="color: #339966"><strong>4.3. 장치 설계 단계 (3D모델링)</strong></span><br />
Solidwork 2014를 이용해 휴대용 미세섬유 제작 장치를 만들기 위한 3D 모델링을 하였다. 각 구성부 부품의 크기를 고려해 최대한 작으면서 전기방사가 가능하도록 만들었다. 또한 이 단계에서 고려한 것은 3D 프린터의 제작 한계이다. 몇 번의 시행착오를 거친 결과 3D 프린터가 2mm 이하에서는 정확하게 제작이 힘들다는 것을 파악하였고 이를 항상 고려하면서 모델링을 하였다.<br />
본 단계에서는 각 파트를 3D 모델링 한 것을 소개함과 동시에 파트들의 부분적인 기능들에 대해서 설명하도록 하겠다.</p>
<p><span style="color: #33cccc"><strong>4.3.1. 전체적인 크기 및 디자인 설정</strong></span><br />
휴대용으로 활용하기 위해 20대 남성의 평균 손길이(손바닥직선 길이)를 고려하였다. 한국기술표준원의 “제5차 한국인 인체 치수조사사업 보고서”를 통해서 조사해보았을 때 우리가 예상 사용자로 설정하고 있는 20대 남성의 평균 손바닥직선 길이는 105.59mm이었다. 우리는 이러한 점을 고려하여 평균 손사이즈를 가진 사람은 물론 작은 손사이즈를 가진 사람도 한손에 쥘 수 있게 하기위하여 한 손에 쥘 수 있는 크기 68mm × 121mm × 50mm 로 CAD 디자인을 설계하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-44-12-135.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33540" alt="Cap 2017-05-30 10-44-12-135" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-44-12-135.jpg" width="620" height="339" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-44-25-123.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33541" alt="Cap 2017-05-30 10-44-25-123" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-44-25-123.jpg" width="303" height="387" /></a></p>
<p>&lt;그림 7&gt;에서 볼 수 있듯이 손으로 작동하기 편하도록 전체적으로 유선형 디자인을 채택하였으며 몇 번의 제작을 통하여 최적의 모델을 얻을 수 있었다. 케이스는 총 3가지 부분으로 분리하여서 &lt;그림 8&gt;에서 볼 수 있듯이 원료 용기가 들어가는 부분은 매번 교체가 필요한 부분이므로 케이스를 여닫이가 편하게 자석과 돌기를 이용하여 고정할 수 있게 하였고 나머지 부분은 케이스에 나사를 이용하여 고정할 수 있도록 설계하였다.</p>
<p><span style="color: #33cccc"><strong>4.3.2. 전원 장치</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-05-168.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33542" alt="Cap 2017-05-30 10-45-05-168" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-05-168.jpg" width="620" height="339" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-13-361.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33543" alt="Cap 2017-05-30 10-45-13-361" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-13-361.jpg" width="323" height="456" /></a></p>
<p>&lt;그림 9&gt;의 (a)는 전원 장치인 AAA건전지 2구 홀더를 도면으로 나타내고, (b)는 접지판의 도면, &lt;그림 10&gt;은 전체적인 구조를 나타낸다. 본 제품에서는 건전지 2개를 사용하여 3V의 전압을 출력하고, 이를 고전압 증폭장치에서 증폭하여 수 kV의 전압을 출력해 전기 방사를 일으키는 방법을 사용한다.</p>
<p>전원 장치로는 건전지, 이차전지, 슈퍼 캐패시터, 연료전지, 태양전지, 무선충전기술 등 여러가지 방식을 사용할 수 있지만, 이 모델은 최대한 간단하면서도 좋은 휴대성을 지닌 건전지를 이용하였다. 더 많은 건전지를 담을 수 있는 홀더를 사용하면 그만큼 더 높은 고전압을 사용할 수 있지만 그만큼 전체적으로 크기가 커지게 된다. 따라서 현재 모델은 AAA건전지를 2개만 사용함으로써 최대한 크기를 작게 하면서도 고전압 증폭 회로를 통해 원하는 만큼의 고전압을 얻을 수 있도록 하였다.</p>
<p>건전지를 이용하기 때문에 가벼워 휴대하기에 알맞다. 또 수시로 교체가 가능하기 때문에 여분의 건전지만 있다면 반영구적으로 사용 가능하다. &lt;그림9&gt;의 (b)에서 나타낸 접지판은 &lt;그림 10&gt;에서 나타낸 것과 같이 사용자의 손에 닿아 제품의 회로를 완성하고, 증폭된 전압의 -극을 접지시켜 전기 방사가 계속되도록 하는 역할을 한다. 접지판으로는 전도성이 좋은 금속 물질을 사용하거나 전도성이 좋은 물질로 포장된 다른 물체를 사용할 수 있다.</p>
<p><span style="color: #33cccc"><strong>4.3.3. 고전압 증폭 장치</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-23-634.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33544" alt="Cap 2017-05-30 10-45-23-634" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-23-634.jpg" width="620" height="271" /></a></p>
<p>&lt;그림 11&gt;은 앞에서 실험을 통하여 선정한 고전압 증폭 회로(下)를 도면과 사진으로 나타낸 것이다. 고전압 증폭 장치란 10V 미만의 전압을 1kV 이상의 전압으로 증폭시키는 장치를 말한다. 고전압 증폭 회로는 입력된 전압을 수백 내지 수천 배 증폭시킨다. 본 제품에서 사용하는 회로는 건전지로부터 3V의 전원을 공급받으면 고전압 증폭 회로 내에서 약 5kV 전압으로 증폭시킨다. 증폭된 전압은 +극은 원료 방출부에, -극은 안전장치에 연결되고 앞에서 설명한 것처럼 전기 방사가 이루어진다. 고전압이 흐르기 때문에 안전을 위해 플라스틱 케이스로 보호되어있다.</p>
<p><span style="color: #33cccc"><strong>4.3.4. 원료 용기</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-30-367.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33545" alt="Cap 2017-05-30 10-45-30-367" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-30-367.jpg" width="336" height="271" /></a></p>
<p>원료의 용기는 제작하고자 하는 섬유의 원료가 되는 용액을 보관하는 용기를 말한다. 원료의 용기로는 주사기, 플라스틱 용기, 금속 용기 등 다양한 용기가 사용될 수 있다. 원료가 고체일 경우에는 별도의 용기없이 바로 사용될 수 있지만 이 모델의 경우에는 고분자 용액을 사용하기 때문에 액상의 원료를 담을 수 있는 주사기를 이용한다. 주사기는 간단하게 용액을 담을 수 있고 교체가 용이하며 피스톤을 눌러 원료를 조금씩 방출해 팁 끝에 맺히도록 할 수 있기 때문에 적합한 용기라고 할 수 있다. &lt;그림 12&gt;는 원료 용기를 디자인한 그림이다.</p>
<p><span style="color: #33cccc"><strong>4.3.5. 원료 방출부 및 원료 방출부 안전장치</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-35-451.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33546" alt="Cap 2017-05-30 10-45-35-451" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-35-451.jpg" width="336" height="271" /></a></p>
<p>원료 방출부는 말 그대로 섬유의 원료가 방출되고 고전압이 연결되어 전기 방사가 이루어지는 부위를 말한다. 여러 가지 원료 방출부가 있을 수 있지만 이번 모델에서는 금속으로 이루어져 있으면서 원료가 맺힐 수 있는 구조로 이루어진 바늘 팁을 원료 방출부로 선택했다. 보통의 바늘은 끝이 뾰족한 형태로 되어 있는데 그렇게 될 경우 바늘 끝이 사선으로 되어 전기 방사의 방향을 컨트롤하기 어렵고 제대로 테일러 콘이 형성되지 않을 수 있기 때문에 끝이 평평한 바늘 팁을 사용한다. 주사기 피스톤을 눌러 바늘 끝에 약간의 원료가 맺히도록 하면 고전압에 의해 원료가 테일러 콘 형상을 띠고 전기적 반발력에 의해 전기 방사가 이루어지게 된다. &lt;그림 13&gt;은 원료 방출부를 디자인한 모델이다.</p>
<p>설계 과정에 있어서 원료 방출부 안전장치의 직경은 미세 섬유의 안정적인 출력을 위해서 중요하게 생각했던 요소였다. 초기 설계시 원료 방출부 안전장치의 지름을 2mm로 설계하였는데, 케이스로 구성될 재질의 플라스틱(PLA, Polylactide Acid)과 전기장 간섭이 일어나 안정장치가 없을 때의 전기방사보다 효율이 떨어지는 현상이 발생하였다. 그래서 &lt;그림 14&gt;에서 볼 수 있듯이 COMSOL 5.0을 활용해 안전장치가 있을 때와 없을 때의 전기장선분포를 파악, 전기장을 분석해 보았다.</p>
<p>위 해석은 큰 테두리 안에 자기력 등 절연을 하여 변수를 차단하고, 물성치는 공기를 집어넣어 일반적인 실험조건하에서 시뮬레이션을 실시하였다. 케이스에는 PLA(PolyLactide Acid) 전기유전율을 논문 등에서 찾아 유전율 값이 3.11임을 알게 되었고 물성치 값에 대입하였다. 그리고 주사기 팁 끝부분에 5kV의 전위를 가하고 밑판을 접지시켜 주사기 팁에서 밑판으로 전기장이 분포되도록 나타낸 것이다. 주사기 팁과 접지시켜준 판은 Stainless steel(상대유전율 : 1)로 설정하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-56-868.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33547" alt="Cap 2017-05-30 10-45-56-868" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-45-56-868.jpg" width="620" height="364" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-46-00-735.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33548" alt="Cap 2017-05-30 10-46-00-735" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-46-00-735.jpg" width="620" height="364" /></a></p>
<p>그 결과 &lt;표 3&gt;과 같이 전기장선이 간섭되어 영향이 미쳐지는 것을 파악할 수 있었고 내부 직경의 길이가 8mm일 때부터 -506.70V/m부근으로 전기장이 거의 일정하게 수렴하게 되어 내벽에 의한 영향을 받지 않았다는 결론을 얻었다.</p>
<p>따라서 내부 직경의 길이를 8mm로 하여서 안전하면서도 전기방사효율이 떨어지지 않는 장치를 설계하게 되었다. &lt;그림 15&gt;는 그러한 결과를 적용하여 설계한 모델링 모습이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-46-09-768.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33549" alt="Cap 2017-05-30 10-46-09-768" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-46-09-768.jpg" width="620" height="315" /></a></p>
<p><span style="color: #33cccc"><strong>4.3.6. 안전장치 설계</strong></span><br />
안전장치란 본 제품을 사용하는데 있어서 발생할 수 있는 위험 요소들을 사전에 차단하여 사용자를 보호하는 장치를 말한다. 이 모델에서는 전기적 안전장치와 물리적 안전장치 두 가지를 설계했다.</p>
<p>먼저 고전압을 이용하는 제품이기 때문에 전기적 안전장치가 필요하다. 본 제품에서는 캐패시터 또는 저항을 이용하여 사용 중 고전압이 흐르는 부분에 사용자의 인체가 닿더라도 인체에 유해한 만큼의 전류가 흐르지 않도록 설계하여 전기적 위험을 방지하는 방법을 이용하였다. 고전압 증폭 회로에서 출력된 고전압의 -극이 안전장치에 연결되고, 캐패시터나 저항 등을 이용해 통전을 막을 수 있는 안전회로를 만들어 안전을 도모할 수 있다.</p>
<p>물리적 안전장치는 고전압이 흐르는 원료 방출부 부분에 사용자가 닿지 않도록 하는 장치이다. 케이스로 바늘 팁 부분을 감싸서 사용자의 인체가 직접 닿기 힘들게 설계하였다. 바늘 끝과 케이스의 끝이 일치하도록 하고 케이스의 직경을 충분히 넓게 하여 케이스가 전기 방사를 방해하지 않으면서도 안전하도록 설계했다. &lt;그림 16&gt;은 이러한 설계 사상이 들어간 물리적 안전장치의 도면이다. 이 방법 이외에도 여러 가지 방법으로 물리적 안전장치를 설계할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-46-23-013.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33550" alt="Cap 2017-05-30 10-46-23-013" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-46-23-013.jpg" width="312" height="286" /></a></p>
<p><span style="color: #33cccc"><strong>4.4. 3D프린터 제작 및 작동</strong></span><br />
케이스 모델링을 완료한 후 교내에 설치된 3D 프린터(PMS Engineering, MD-270)를 사용하여서 케이스를 제작을 하였다. 3D프린터의 원료로는 Polylatic-acid(PLA)를 사용하여서 제작하였고, 케이스 제작을 완료한 후에는 전원 장치, 고전압 증폭 장치, 원료 용기, 원료 방출부, 안전장치를 장치 내에 설치한 후에 나사를 이용하여서 체결하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-54-57-316.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33551" alt="Cap 2017-05-30 10-54-57-316" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-54-57-316.jpg" width="620" height="315" /></a></p>
<p>체결까지 완료하고 장치를 손으로 잡은 모습은 &lt;그림 17&gt;과 같다. 이미지에서 볼 수 있듯이 한 손으로 편하게 조작이 가능한 것을 알 수 있다. 장치를 완성한 후에는 고분자 용액을 원료 용기에 넣은 후 전기 방사를 실시해 보았다. 이 실험에서 사용된 고분자 용액은 Poly-urethane(Pellethane 2363-80AE, Lubrizol, USA)이며, 이를 Tetra Hydro Furan(THF)와 Di Methyl Formamide(DMF)(60/40, v/v) 혼합 용액에 13wt%의 농도로 약 12시간여 동안 교반기를 이용하여 용해시켜 용액을 제조하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-55-08-117.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33552" alt="Cap 2017-05-30 10-55-08-117" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-55-08-117.jpg" width="620" height="349" /></a></p>
<p>&lt;그림 18&gt;은 제작된 장치를 이용해 5분 가량 전기방사를 한 모습이다. 장치는 한 번에 최대 1시간에서 1시간 30분 정도 작동 가능하였다. 첨부된 이미지에서 볼 수 있듯이, 금속 집진판이나 손바닥에서 모두 균일하게 미세 섬유가 제작되는 것을 확인할 수 있다.</p>
<p><span style="color: #008000"><strong>5. 결론</strong></span><br />
본 연구의 목표는 기존의 전기방사장치를 소형화하여 휴대 가능하도록 제작하는 것이며 그것에 유의하면서 설계와 실험을 진행하였다. 건전지(3V) 전압은 1600배인 최대 5kV로 안정적으로 증폭되었다. 고전압 증폭장치, 전원 공급 장치, 원료 보관 용기, 안전장치 등을 조립하여 최종 전기 방사 장치를 제작하였다. 제작된 장치는 한 손으로 충분히 조작 가능한 형태를 보였다. 제작된 전기방사 장치에 Poly-urethane 고분자 용액을 주입한 후 스위치를 켜고 작동하였을 때, 성공적으로 전기방사가 가능했으며 금속 콜렉터와 사람의 신체 부위에 미세 섬유를 균일하게 도포할 수 있었다. 휴대성을 부여함과 동시에 안정적인 미세 섬유 제작이 가능하게 되었으므로 이 프로젝트는 소정의 성과를 얻었다고 할 수 있다.<br />
이 장치는 일반인이 한 손으로 조작할 수 있는 시스템으로서 고분자 용액의 종류를 다른 것으로 교체해서 사용할 경우 응급 지혈 장치 등으로 의류 분야에서, 자외선 차단제 등으로 미용 분야에서 사용될 수 있을 것으로 기대된다. 이 뿐만이 아니라 기존에 전기 방사를 이용하던 분야인 필터, 코팅 분야에 다양하게 응용될 수 있을 것으로 기대된다.</p>
<p><span style="color: #008000"><strong>6. 기타</strong></span><br />
<span style="color: #339966"><strong>6.1. 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-55-40-749.jpg" rel="lightbox[33390]"><img class="alignnone size-full wp-image-33553" alt="Cap 2017-05-30 10-55-40-749" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-55-40-749.jpg" width="620" height="257" /></a></p>
<p><span style="color: #339966"><strong>6.2. 참고문헌</strong></span><br />
1.  Li, D. &amp; Xia, Y. Electrospinning of Nanofibers: Reinventing the Wheel? Adv. Mater. 16, 1151-1170 (2004).<br />
2.  Zucchelli, A., Focarete, M. L., Gualandi, C. &amp; Ramakrishna, S. Electrospun nanofibers for enhancing structural performance of composite materials. Polym. Adv. Technol. 22, 339-349 (2011).<br />
3.  Heo, J. et al. Enhanced cellular d istribution and infiltration in a wet electrospun three-dimensional fibrous scaffold using eccentric rotation-based hydrodynamic conditions. Sensors Actuators, B Chem. 226, 357-363 (2016).<br />
4.  Hong, S. K., Lim, G. &amp; Cho, S. J. Breathability Enhancement of Electrospun Microfibrous Polyurethane Membranes through Pore Size Control for Outdoor Sportswear Fabric. Sensors Mater. 27, 77-85 (2015).<br />
5.  Ramakrishna, S. An introduction to electrospinning and nanofibers. (2005).<br />
6. 한국 기술 표준원 “제 5차 한국인 인체 치수조사사업 보고서”, 2004</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/33390/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[41호] Project H &#8211; 스마트홈</title>
		<link>http://www.ntrexgo.com/archives/33386</link>
		<comments>http://www.ntrexgo.com/archives/33386#comments</comments>
		<pubDate>Sat, 25 Mar 2017 00:00:54 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[41호]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[ict]]></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=33386</guid>
		<description><![CDATA[디바이스마트 매거진 41호 &#124; 대기업들이 관심을 보이는 분야이고 국내 스마트홈시장은 매년 늘어갈 것이라는 전망이다. 대기업이 진출한다는 것은 그만큼 가치가 있는 종목이고 홈 오토메이션 이라는 것이 중요한 기술이 될 것임을 알 수 있다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain.png" rel="lightbox[33386]"><img class="alignnone size-large wp-image-31056" alt="2016 ictmain" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain-620x156.png" width="620" height="156" /></a></p>
<p><span style="font-size: large"><strong>2016 ICT 융합 프로젝트 공모전 입선</strong></span></p>
<p><span style="font-size: x-large"><strong>Project H &#8211; 스마트홈</strong></span></p>
<p>&nbsp;</p>
<p style="text-align: right"><strong>글 | 고려대학교 최윤형</strong></p>
<p>&nbsp;</p>
<p><span style="color: #008000"><strong>심사평</strong></span><br />
<span style="color: #339966"><strong>JK전자</strong></span> 모터로 제어되는 기구부와 집 모형, 마이크로컨트롤러와 안드로이드 앱 개발까지 다양한 분야의 지식이 필요한 작품이네요. 시스템적으로 구현이 어려운 기술들은 아니지만 서로 다른 분야의 기술들을 적절히 잘 활용하여 완성도도 높고, 곧 다가올 사물인터넷 시대의 한 분야인 홈 케어 시스템에서 필요로 하는 요소들을 1개의 작품에 잘 적용하였습니다.<br />
<span style="color: #339966"><strong>뉴티씨</strong></span> 스마트홈을 주제로 잡고 실제로 스마트한 환경을 구현하려 매우 노력한 흔적이 보여서 보고서 완성도면에서 20점을 주었으며, 전반적으로 좋은 점수를 받았다. 하지만, 아직 실용성이 부족하며, 조금만 더 창의적인 아이디어를 나만의 것으로 소화하여 만들었다면 더 좋은 점수를 받았을 것이다. 작품의 기대효과가 높지는 않으나, 전체적인 완성도나 기술성은 높은 점수를 주었다.<br />
<span style="color: #339966"><strong>칩센</strong></span> 20년 전부터 나오던 홈오토메이션이 IoT라는 개념으로 다시 나오는 것 같다. 그만큼 주제는 식상하다. 하지만 구현 완성도와 보고서의 내용이 뛰어나고 노력한 흔적이 보인다.<br />
<span style="color: #339966"><strong>위드로봇</strong></span> 모형으로 집을 만들고 그 안에서 발생할 수 있는 여러 상황을 시뮬레이션하여, 핸드폰으로 각 상황에 알맞게 조치를 취할 수 있음을 보여주는 재미있는 작품입니다. 다양한 센서를 인터페이스하는 측면에서 많은 공부가 되었을 것 같습니다. 작품 전체의 완성도가 높은 수작입니다.</p>
<p><span style="color: #008000"><strong>1. 작품 개요</strong></span></p>
<p><span style="font-family: 'andale mono', times"><em>지난해 국내 스마트 홈 시장 규모 6조9천억 원11.8%↑ -부산일보</em></span><br />
<span style="font-family: 'andale mono', times"><em>구글, &#8216;홈 오토메이션&#8217; 분야 신생 업체 32억 달러에 인수 -연합뉴스</em></span><br />
<span style="font-family: 'andale mono', times"><em>애플, 인텔리전트홈 원격제어&#8230;특허 -zdnet korea</em></span></p>
<p>뉴스에서 보도된 내용이다. 애플 구글같은 대기업들이 관심을 보이는 분야이고 국내 스마트 홈시장은 매년 늘어갈 것이라는 전망이다. 대기업이 진출한다는 것은 그만큼 가치가 있는 종목이고 홈 오토메이션이라는 것이 중요한 기술이 될 것임을 알 수 있다.<br />
홈 오토메이션은 스마트폰과 블루투스를 이용한 AVR과의 통신으로 모터및 센서 제어를 해보는 것이므로 JAVA를 이용한 APP개발, 또한 블루투스 통신 구현, AVR을 이용한 모터 및 센서 제어 등 기초적인 기술들이 대부분 사용되었다. 그래서 이 프로젝트의 경험을 바탕으로 할 수 있는 일들이 다양해질 것이라고 생각한다.</p>
<p><span style="color: #008000"><strong>2. 작품 설명</strong></span><br />
<span style="color: #339966"><strong>2.1. 전체 시스템 구성 &#8211; 시스템 구성도(Block diagram)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-05-14-551.jpg" rel="lightbox[33386]"><img alt="Cap 2017-05-30 10-05-14-551" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-05-14-551.jpg" width="620" height="415" /></a></p>
<p><span style="color: #339966"><strong>2.2. 주요 동작 및 특징</strong></span><br />
<strong></strong></p>
<p><span style="color: #33cccc"><strong>2.2.1. 조도량에 따라 커튼 열고 닫힘</strong></span></p>
<p>개요: 아침에는 햇볕이 들어오도록 자동으로 열리고 날씨가 좋지 않거나 밤에는 사생활 보호를 위해 자동으로 닫히도록 한다.<br />
작동:<em id="__mceDel"> GL5516(조도 센서)를 이용하여 빛의 양을 감지하고 빛의 양이 적으면 커튼을 닫히도록 하고 빛의 양이 많으면 커튼이 열리도록 한다.</em></p>
<p><span style="color: #33cccc"><strong>2.2.2. 썬루프 원격 조절</strong></span><br />
개요: 스마트폰을 이용하여 원격으로 썬루프를 조정한다.<br />
작동:<br />
1. 스마트폰으로 썬루프가 열리는 정도를 조절할 수 있게 한다.<br />
2. 날씨가 좋지 않을 시 어두운 정도를 GL5516(조도 센서)를 이용하여 측정하고 조도가 낮아 비가 오기 전 스마트폰으로 명령을 주지 않아도 자동으로 썬루프를 닫는다. 만약 구름이 있어도 썬루프를 열겠다는 신호를 보내면 “Warning: 썬루프를 여시겠습니까?”라는 문구를 띄우고 “예”를 누르면 작동한다.</p>
<p><span style="color: #33cccc"><strong>2.2.3. 방범 시스템</strong> </span><br />
개요 : 밤에 늦게 누군가가 집에 침입하였을 때 빠르게 112에 신고할 수 있다.<br />
작동 :<br />
1. 스마트폰으로 방범 시스템 작동 유무 설정<br />
2. 방범시스템을 작동시키면 GP2D120(광 센서)을 이용해 사람 유무 판단.<br />
3. 사람이 있다고 감지되었을 때 스마트폰으로 감지되었다고 메시지와 진동으로 표시. 그 후 112에 신고하시겠습니까?라는 문구를 띄우고 예를 누르면 112에 연결</p>
<p><span style="color: #33cccc"><strong>2.2.4. 우편함 알림 시스템</strong> </span><br />
개요: 밖에 있는 우편함에 우편이 있는지 없는지 직접 확인을 하지 않아도 센서를 통해 자동적으로 스마트폰 메일 알람 시스템으로 알려준다.<br />
작동:<br />
1. GP2D120(광 센서)를 우편함 아래쪽에서 거리를 잴 수 있도록 배치하고 우편이 놓였을 때 거리 값이 작아지는 것을 이용하여 우편 유무 확인<br />
2. 우편이 있을 때 스마트폰으로 우편이 왔다고 메일 알림으로 표시한다.</p>
<p><span style="color: #339966"><strong>2.3. 등각 외관도 및 작품 사진</strong></span></p>
<p><strong></strong><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-07-16-702.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33485" alt="Cap 2017-05-30 10-07-16-702" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-07-16-702.jpg" width="620" height="349" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-07-24-767.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33486" alt="Cap 2017-05-30 10-07-24-767" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-07-24-767.jpg" width="620" height="332" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-07-29-001.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33487" alt="Cap 2017-05-30 10-07-29-001" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-07-29-001.jpg" width="620" height="332" /></a></p>
<p><span style="color: #339966"><strong>2.4. 개발 환경(개발 언어, Tool, 사용 시스템 등)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-11-58-501.png" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33488" alt="Cap 2017-05-30 10-11-58-501" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-11-58-501.png" width="620" height="332" /></a></p>
<p><span style="color: #339966"><strong>2.5. 세부 구성</strong> </span><br />
<strong>기구부</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-01-118.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33489" alt="Cap 2017-05-30 10-13-01-118" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-01-118.jpg" width="620" height="241" /></a><br />
<strong> </strong></p>
<p><strong>회로부 및 센서부</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-06-286.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33490" alt="Cap 2017-05-30 10-13-06-286" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-06-286.jpg" width="620" height="416" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-16-004.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33491" alt="Cap 2017-05-30 10-13-16-004" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-16-004.jpg" width="620" height="546" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-16-004.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33491" alt="Cap 2017-05-30 10-13-16-004" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-16-004.jpg" width="620" height="546" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-27-335.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33492" alt="Cap 2017-05-30 10-13-27-335" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-13-27-335.jpg" width="620" height="282" /></a></p>
<p><span style="color: #339966"><strong>2.6. 소프트웨어 주요 코드</strong></span><br />
<span style="color: #33cccc"><strong>2.6.1. Atmega128 소프트웨어 주요 코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: 외부 인터럽트를 사용하기 위한 설정<br />
// Descriptions: 하강엣지일때 계속해서 발생<br />
==================================================<br />
DDRD &amp;= ~(_BV(DDD0)|_BV(DDD1)); //INT0(PD0), INT1(PD1) 핀을 디지털 입력 포트로 설정<br />
PORTD |= _BV(PD0)|_BV(PD1); //풀업저항 있는 입력<br />
// 하강 일시 작동 PD0 INT0 PD1 INT1 사용<br />
EICRA &amp;= ~(_BV(ISC00)|_BV(ISC01)|_BV(ISC10)|_BV(ISC11));<br />
// 하강 일시 계속 인터럽트 발생<br />
EIMSK |= _BV(INT0)|_BV(INT1); //개별적 인터럽트 허용</p>
<p><strong>창 리미트스위치를 눌렀을 때 인터럽트가 실행되도록 초기화 설정</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: adc 사용하기 위한 설정(GP2D120) 거리 센서 0~3.3출력<br />
// Descriptions: PF0(ADC0) ~PF7(ADC7)까지 있음<br />
==================================================<br />
DDRF=0; //풀업저항 없는 입력 사용<br />
PORTF =0;<br />
ADMUX |= _BV(REFS0); ADMUX &amp;= ~_BV(REFS1);<br />
//5v AVCC연결된 전압 AREF에 연결된 커패시터사용<br />
ADCSRA |= _BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0);<br />
//AVR 16000KHz 80 &lt;= X &lt;= 160설정해야함 따라서 분주비 128 설정 125KHz<br />
// ADC 클럭을 결정하는 비트입니다. 분주비가 작으면 변환이 빨리 되지만 사용상 문제가 없는 범위에서 최대한 느리게 변환 하는 것이 노이즈 영향이 줄어든다.<br />
ADCSRA |= _BV(ADEN); //인에이블비트</p>
<p><strong>거리 센서의 아날로그값을 디지털값으로 변화하기 위하여 ADC컨버터 초기값 설정</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: cds광전도셀에서 받은 op앰프 출력을 입력시킬때 쓰는 핀<br />
// Descriptions: cds셀 입1/0 상태 입력단자. 어두울 때 1 밝을 때 0<br />
==================================================<br />
DDRG &amp;= ~_BV(DDG4);//cds셀 상태 입력단자. 어두울 때 1 밝을 때 0<br />
PORTG &amp;= ~_BV(PG4);//풀업저항 없는 입력</p>
<p><strong>PD4에 CDS셀의 조도 값을 받아들이기 위하여 입력 설정</strong></p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: 연기 센서<br />
// Discriptions: 연기 센서 작동되면 PING2에서 5v 출력이 PING3 에 입력된다.<br />
==================================================<br />
DDRG |= _BV(DDG2); //출력으로 사용 사용된 곳 없음<br />
PORTG |= _BV(PG2);<br />
DDRG &amp;= ~_BV(DDG3); //풀업있는 입력 사용<br />
PORTG |= _BV(PG3);<br />
DDRG &amp;= ~_BV(DDG0)|_BV(DDG1); //리밋스위치용 풀업저항 있는 입력<br />
PORTG |= _BV(PG0)|_BV(PG1);<br />
//사용시 Pxn핀 HIGHT 전압 출력<br />
//PORTx 레지스터의 Pxn 비트를 1로<br />
DDRF |= _BV(DDF2);<br />
PORTF |= _BV(PF2);</p>
<p><strong>PG3에 연기센서값을 받아들이기 위하여 입력 설정</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: ch 0~7중 하나를 선택해 0~5V로 변환하는 함수<br />
// Descriptions: PF0(ADC0) ~PF7(ADC7)까지 있음<br />
// 예를 들어 ATmega128 ADC의 reference 전압을 2.5V로 만든다면,<br />
// ADC의 resolution은 1/1024<br />
// 2500mV / 1024 = 약 2.44 mV<br />
// 즉, ADC에 0V가 입력되면 0이라는 변환 값이 나오고,<br />
// 2.44mV가 입력되면 1,<br />
// 4.88mV가 입력되면 2, &#8230;..<br />
// 2500mV가 입력되면 1023 이라는 ADC 변환 값이 출력됩니다.<br />
==================================================<br />
uint16_t GetAdv(uint8_t ch) //ch 0~7중 하나를 선택해 A/D 변환하는 함수<br />
{<br />
uint16_t Ain;<br />
ADMUX = (ADMUX&amp;0xf8)|(ch&amp;0&#215;7); //하위 3비트로 채널 선택<br />
ADCSRA |= _BV(ADSC); //ADSC에 1을 넣어 S/H후 A/D 변환 시작<br />
while(!(ADCSRA&amp;_BV(ADIF))); //ADSC의 ADIF가 1이 되면 A/D변환 종료<br />
//val = ADC;<br />
//ADC로부터 변환된 값 저장<br />
///참고: 이렇게 하면 실제로는 ADIF가 0이됨<br />
Ain = ((uint32_t)ADC*50 + (1&lt;&lt;9))&gt;&gt;10; //Ain은 실제 전압의 10배<br />
//Ain = ADC *5.0/1023.0;<br />
ADCSRA |= _BV(ADIF);<br />
return Ain;<br />
}</p>
<p><strong>ADC n번을 이용하고 그 값을 10배하여 받아들임 ex) 100값을 받았다면 10V입력</strong></p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>//- Wireless Module를 통해 수신된 데이터 패킷이 있으면 받아서 데이터에 따라 모터 구동<br />
if (uwIsPacket()==UW_PACKET0)<br />
{<br />
if (uwGetData0(&amp;data))<br />
{<br />
mtrDrive0(data);<br />
lswPutLed(0&#215;1); //확인용 LED 점멸<br />
}<br />
t_prev = tm2Getms();<br />
}</p>
<p><strong>수신한 Data 값을 가지고 모터를 PWM 제어</strong></p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>if(data==PROTECTON) //방범기능용<br />
{<br />
protectflag=0;<br />
}<br />
if(data==PROTECTONOFF)<br />
{<br />
protectflag=1;<br />
}</p>
<p><strong>방범 기능 On/Off 기능 수행</strong></p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: DS_SD_002 연기 센서에 0&#215;30 데이터 전송<br />
// Discriptions: PING3 에서 5V입력이 확인되면<br />
==================================================<br />
if(!(PING &amp; _BV(PING3)))<br />
{<br />
if(DS_SD_002_Flag==0){<br />
uartPutc(DS_SD_002);<br />
lswPutLed(0&#215;2); //확인용 LED 점멸<br />
DS_SD_002_Flag=1;<br />
DS_SD_002_t_prev = tm2Getms();<br />
}<br />
}<br />
else if ((tm2Getms()-DS_SD_002_t_prev)&gt;6000) // 일정시간지나면 입력 받아들임<br />
{<br />
DS_SD_002_Flag=0;<br />
}</p>
<p><strong>연기 센서에 연기가 감지되면 그것을 확인하는 코드</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: cds광전도셀에서 받은 op앰프 출력을 입력시킬때 쓰는 핀<br />
// Discriptions: cds셀 입1/0 상태 입력단자. 어두울 때 1 밝을 때 0<br />
==================================================<br />
if(PING &amp; _BV(PING4))</p>
<p>{<br />
if(CDS_Flag==0){<br />
uartPutc(CDS);<br />
lswPutLed(0&#215;4); //확인용 LED 점멸<br />
CDS_Flag=1;<br />
CDS_t_prev = tm2Getms();<br />
mtrDrive0(0&#215;4); //아니면 ox2 닫기는 left<br />
}<br />
}</p>
<p><strong>CDS 셀에서 AVR로 입력된 값을 확인하여 선루프를 자동으로 열고 닫는다.</strong></p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: adc입력상태를 확인하여 출력 0번은 MAIL<br />
// Descriptions: 0번은 메일함 꼭대기까지 5cm 2.3정도 탐지 거리 7mm 물건이 있을 경우 1cm기준으로 잡는다. 1.8<br />
==================================================<br />
if(GetAdv(myAdc0)&gt;5) //adc0번이 입력 전압이 1.8V보다 작을때<br />
{<br />
if(GP2D120Mail_Flag==0){<br />
uartPutc(MAIL);<br />
lswPutLed(0&#215;8); //확인용 LED 점멸<br />
GP2D120Mail_Flag=1;<br />
GP2D120Mail_t_prev = tm2Getms();</p>
<p>}<br />
}</p>
<p><strong>우편함에서 우편이 감지되면 AVR로 신호를 준다.</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>if(protectflag==0)<br />
{<br />
lswPutLed(0xaa);<br />
==================================================<br />
// Function: adc 입력 상태를 확인하여 출력 GP2D120<br />
// Descriptions: 추후 감지 범위 바꿔가며 정밀하게 만들 예정<br />
==================================================<br />
if(GetAdv(myAdc1)&gt;20) //adc0번이 입력 전압이 2.5V보다 작을 때 30cm<br />
{<br />
if(GP2D120_1_Flag==0){<br />
uartPutc(GP2D120_0);<br />
lswPutLed(0&#215;81); //확인용 LED 점멸<br />
GP2D120_1_Flag=1;<br />
GP2D120_1_t_prev = tm2Getms();<br />
}<br />
}</p>
<p>==================================================<br />
if(GetAdv(myAdc2)&gt;15) //adc0번이 입력 전압이 2.5V보다 작을 때 우체통<br />
{<br />
if(GP2D120_2_Flag==0){<br />
uartPutc(GP2D120_1);<br />
lswPutLed(0&#215;90); //확인용 LED 점멸<br />
GP2D120_2_Flag=1;<br />
GP2D120_2_t_prev = tm2Getms();<br />
}<br />
}<br />
else if((tm2Getms()-GP2D120_2_t_prev)&gt;5000)<br />
{<br />
GP2D120_2_Flag=0;<br />
}<br />
==================================================<br />
if(GetAdv(myAdc3)&gt;15) //adc0번이 입력 전압이 2.5V보다 작을 때<br />
{<br />
if(GP2D120_3_Flag==0){<br />
uartPutc(GP2D120_2);<br />
lswPutLed(0&#215;84); //확인용 LED 점멸<br />
GP2D120_3_Flag=1;<br />
GP2D120_3_t_prev = tm2Getms();<br />
}<br />
}<br />
==================================================<br />
if(GetAdv(myAdc4)&gt;15) //adc0번이 입력 전압이 2.5V보다 작을 때<br />
{<br />
if(GP2D120_4_Flag==0){<br />
uartPutc(GP2D120_3);<br />
lswPutLed(0&#215;90); //확인용 LED 점멸<br />
GP2D120_4_Flag=1;<br />
GP2D120_4_t_prev = tm2Getms();<br />
}<br />
}</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-14-13-878.png" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33493" alt="Cap 2017-05-30 10-14-13-878" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-14-13-878.png" width="598" height="398" /></a></p>
<p><strong>각각의 센서에서 받은 값을 확인하여 방범 기능을 수행한다.</strong></p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: mtrDrive0<br />
// Descriptions: CP-RC가 전송한 Data에 따른 모터 구동<br />
==================================================<br />
void mtrDrive0(uint16_t Data)<br />
{<br />
if (Data&amp;MTR_LEFT)<br />
{<br />
if(!(PING&amp;_BV(PING0)))<br />
{<br />
pwmSet(PWM_CH0, 0);<br />
}<br />
else pwmSet(PWM_CH0, MTR0_HIGH); //CH_0모터 255 고속 값으로<br />
}<br />
else if (Data&amp;MTR_RIGHT)<br />
{<br />
if(!(PING&amp;_BV(PING1)))<br />
{<br />
pwmSet(PWM_CH0, 0);<br />
}<br />
else pwmSet(PWM_CH0, -MTR0_HIGH);<br />
}<br />
else if (Data&amp;MTR_GOLEFTALL)<br />
{<br />
while((PING&amp;_BV(PING0)))<br />
{<br />
pwmSet(PWM_CH0, MTR0_HIGH);//CH_0모터 255 고속 값으로<br />
}<br />
}<br />
else if (Data&amp;MTR_GORIGHTALL)<br />
{<br />
while((PING&amp;_BV(PING1)))<br />
{<br />
pwmSet(PWM_CH0, -MTR0_HIGH);//CH_0모터 255 고속 값으로<br />
}<br />
}<br />
else //모터 정지<br />
{<br />
pwmSet(PWM_CH0, 0);<br />
}<br />
}<br />
void pwmSet(uint8_t ch, int16_t Val)<br />
{<br />
if (Val&lt;-255) Val=-255;<br />
if (Val&gt;255) Val=255;</p>
<p>if (ch==PWM_CH0) // CH0 모터인 경우<br />
{<br />
#if PWM_EN_DIP_REVERSE<br />
if (lswGetSwitch() &amp; LSW_DIP1) Val = -Val;<br />
#endif<br />
if (Val&gt;0) // 정방향이면,<br />
{<br />
PORTE&amp;=~_BV(PE4); // L298 1A1를 LOW로<br />
OCR3A=Val;<br />
}<br />
else<br />
{<br />
PORTE|=_BV(PE4); // L298 1A1을 High로<br />
OCR3A=255+Val;<br />
}<br />
}<br />
}</p>
<p><strong>모터 제어를 위한 PWM 코드</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: uwGetData0<br />
// Description: 패킷으로부터 2바이트 데이터 추출<br />
==================================================<br />
uint8_t uwGetData0(uint16_t* data)<br />
{<br />
uint8_t sreg;<br />
uint16_t result=0;</p>
<p>if (((uwData[1]+uwData[2])&amp;0x7f)==uwData[3])<br />
{<br />
*data=uwData[1]+((uint16_t)uwData[2]&lt;&lt;8);<br />
result=1;<br />
}<br />
sreg=SREG;<br />
cli();<br />
uwFlag=0;<br />
SREG=sreg;</p>
<p>return result;<br />
}</p>
<p><strong>2바이트를 추출하기 위한 USART 소켓 통신 코드</strong></p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>==================================================<br />
// Function: uwIsPacket<br />
// Description: 패킷 전송 유무 확인, 패킷 전송시 1<br />
==========================<br />
uint8_t uwIsPacket(void)<br />
{<br />
uint8_t sreg, result;<br />
sreg=SREG;<br />
cli();<br />
result=uwFlag;<br />
SREG=sreg;<br />
return result;<br />
}</p>
<p><strong>패킷 전송 유무 확인, 패킷 전송 시 1 리턴</strong></p>
</div>
<p><span style="color: #33cccc"><strong>2.6.2. 스마트폰 안드로이드 소프트웨어 주요 코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>if(read()==&#8221;cloud&#8221;){<br />
Intent intent = new Intent(getApplicationContext(),<br />
Cloudalert.class);<br />
startActivity(intent);<br />
}</p>
<p>if(read()==&#8221;fire&#8221;){<br />
Intent intent = new Intent(getApplicationContext(),<br />
Firealert.class);<br />
startActivity(intent);<br />
}<br />
Button Call119 = (Button)findViewById(R.id.call119yesbtn);<br />
Call119.setOnClickListener(new OnClickListener(){<br />
public void onClick(View v){<br />
Intent in = new Intent(Intent.ACTION_CALL);<br />
in.setData(Uri.parse(&#8220;tel:01090577489&#8243;));<br />
startActivity(in);<br />
}<br />
});</p>
<p>if(read()==&#8221;protect&#8221;){<br />
Intent intent = new Intent(getApplicationContext(),<br />
Protectalert.class);<br />
startActivity(intent);<br />
}<br />
Button Call112 = (Button)findViewById(R.id.call112yesbtn);<br />
Call112.setOnClickListener(new OnClickListener(){<br />
public void onClick(View v){<br />
Intent in = new Intent(Intent.ACTION_CALL);<br />
in.setData(Uri.parse(&#8220;tel:01090577489&#8243;)); //암시적 인텐트로 전화를 건다. 매니페스트에 추가해줘야함<br />
startActivity(in);<br />
}<br />
});</p>
<p><strong>AVR에서 블루투스로 보내준 데이터에 따라 인텐트 생성하여 알림 창을 띄운다.</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>private class TransmitThread extends Thread {</p>
<p>int pauseCnt = 0;<br />
byte[] packet0 = new byte[4];</p>
<p>public void run() {<br />
setName(&#8220;RepeatThread&#8221;);<br />
while (true) {</p>
<p>if (mBtnStatusChanged==true)<br />
{<br />
if (mSerialService.getState() == BluetoothSerialService.STATE_CONNECTED) {<br />
packet0[0] = (byte) PACKET0_START;<br />
packet0[1] = (byte) (mBtnStatus&amp;0xff);<br />
packet0[2] = (byte) (mBtnStatus&gt;&gt;8);<br />
packet0[3] = (byte) ((packet0[1]+packet0[2]) &amp; 0xff);<br />
mSerialService.write(packet0);<br />
}<br />
if (mBtnStatus==0) {<br />
if (++pauseCnt &gt;= 10) {<br />
pauseCnt = 10;<br />
mBtnStatusChanged = false;<br />
}<br />
} else {<br />
pauseCnt = 0;<br />
}<br />
try {<br />
Thread.sleep(TRANSMIT_INTERVAL-1);<br />
} catch (InterruptedException e) {<br />
e.printStackTrace();<br />
}<br />
}</p>
<p>try {<br />
Thread.sleep(1);<br />
} catch (InterruptedException e) {<br />
e.printStackTrace();<br />
}<br />
}<br />
}<br />
}</p>
<p><strong>AVR에서 스마트폰으로 온 데이터를 받기 위한 통신 쓰레드</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>private String read() {<br />
int length = buffer.length();<br />
String data = buffer.substring(0, length);<br />
buffer.delete(0, length);<br />
return data;<br />
}</p>
<p><strong>스마트폰에 수신된 데이터를 buffer에 저장하고 읽어오는 함수</strong><br />
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>public void write(byte[] buffer) {<br />
try {<br />
mmOutStream.write(buffer);</p>
<p>// Share the sent message back to the UI Activity<br />
mHandler.obtainMessage(BluetoothSerial.MESSAGE_WRITE, -1, -1, buffer)<br />
.sendToTarget();<br />
} catch (IOException e) {<br />
Log.e(TAG, &#8220;Exception during write&#8221;, e);<br />
}<br />
}</p>
<p><strong>스마트폰에서 AVR로 데이터를 보내기 위한 함수</strong><br />
</div>
<p><span style="color: #339966"><strong>2.7. 스마트폰 제어 화면</strong></span><br />
<span style="color: #33cccc"><strong>2.7.1. 메인 화면</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-20-10-726.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33494" alt="Cap 2017-05-30 10-20-10-726" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-20-10-726.jpg" width="238" height="378" /></a><br />
ProjectH 앱을 실행하면 첫 화면에서 방범 시스템 On/Off, 썬루프 닫기/열기 기능을 설정할 수 있다.<br />
썬루프 닫기/열기는 누르고 있는 동안 열고 닫히는 버튼이고 썬루프 전부 닫기 / 전부 열기는 한번 누르면 전부 열고 닫는 버튼이다. 방범 시스템 On/Off기능은 GP2D120 센서로 움직이는 물체를 감지하여 켜고 끌 때 사용하는 버튼이다.<br />
그 외에 사용된 센서는 감지하는 신호를 받아 팝업 창을 띄우게 된다.</p>
<p><strong><span style="color: #33cccc">2.7.2. 화재알림기능_DS-SD-002(연기 센서) </span></strong></p>
<p><strong><span style="color: #33cccc"><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-20-16-341.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33495" alt="Cap 2017-05-30 10-20-16-341" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-20-16-341.jpg" width="239" height="377" /></a></span></strong><em id="__mceDel"><br />
</em>연기 센서는 제작 업체에 따르면 일반 화장실 크기의 공간에서 담배를 태우면 연기가 감지되도록 설계되었다고 한다. 연기가 감지되었을 때 릴레이의 접점을 이용하여 신호로 전달한다. 연기가 감지되었을 때는 AVR에서 신호를 받아들여 스마트폰으로 위험을 알리는 팝업 창을 띄우고 센서 부분에서 버져가 울리게 된다.<br />
“집에 연기가 감지되었습니다. 119에 신고하시겠습니까?”라는 문구에서 Yes를 누를 경우 바로 119에 전화가 걸리게 되고 아닐 경우 No를 누르면 메인화면으로 돌아가게 된다.</p>
<p><span style="color: #33cccc"><strong>2.7.3. 방범 기능_GP2D120</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-24-01-934.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33496" alt="Cap 2017-05-30 10-24-01-934" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-24-01-934.jpg" width="232" height="364" /></a><br />
GP2D120 센서의 거리에 따른 값을 0~3.3V 범위의 아날로그로 받아 AVR에서 0~5V의 디지털 값으로 바꾸어 어느 정도에 거리에 있는 물체들만 감지하도록 하였고, 화재 알림 기능과 동일하게 Yes를 누르면 112에 바로 통화가 가능하며 No를 누르면 빠져나가 메인화면으로 돌아가게 된다. 스마트폰 메인 화면에 Protect On/Off기능으로 켜고 끌 수 있다. 감지되는 위치에 따라 감지 위치 화면을 띄운다.<br />
아래 그래프는 거리에 따른 전압의 출력 값을 나타내는 데이터시트이다. 이것을 정리해보면 두번째 표와 같다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-24-12-395.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33497" alt="Cap 2017-05-30 10-24-12-395" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-24-12-395.jpg" width="242" height="284" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-25-00-310.png" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33498" alt="Cap 2017-05-30 10-25-00-310" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-25-00-310.png" width="615" height="122" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-25-06-145.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33499" alt="Cap 2017-05-30 10-25-06-145" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-25-06-145.jpg" width="617" height="356" /></a></p>
<p><span style="color: #33cccc"><strong>2.7.4. 우편 기능_GP2D120</strong></span><br />
우편이 우체통으로 들어왔을 때 센서를 가리게 된다. 그러면 GP2D120 센서의 출력 전압이 0V가 된다. 이 원리를 이용하여 전압이 0V가 되었을 때 AVR에서 스마트폰으로 신호를 전달하게 되고 노티피케이션을 통하여 사용자에게 보여주게 된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-25-11-114.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33500" alt="Cap 2017-05-30 10-25-11-114" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-25-11-114.jpg" width="431" height="351" /></a></p>
<p>1) 화면 노티피케이션을 누르면<br />
2) 화면이 뜨고 노티피케이션은 사라진다.</p>
<p>스마트폰에서 메시지가 오면 상단에 메시지 알림이 뜨고 클릭하면 메시지를 보는 동시에 상단 메세지알림이 사라진다. 이와 같이 최대한 메시지와 알림 및 확인 방식을 유사하게 해 직관적으로 알아볼 수 있도록 제작하였다.</p>
<p><span style="color: #33cccc"><strong>2.7.5. 조도감지센서(GL5516)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-26-33-052.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33501" alt="Cap 2017-05-30 10-26-33-052" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-26-33-052.jpg" width="620" height="380" /></a><br />
조도가 자신이 원하는 정도에 기준을 정하기 위해서 OP앰프를 사용했고, -쪽(Reference 전압)으로 들어가는 전압을 조절하기 위하여 10KΩ의 가변저항을 넣었다. 이 회로는 어느 정도 어두워지면 HIGHT 값을 AVR에 전달한다. 우리 시스템에서는 우천 시 집안으로 비나 눈이 들어오는 것을 방지하기 위해 어두워지면 자동으로 창을 닫는 것으로 설정하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-26-40-751.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33502" alt="Cap 2017-05-30 10-26-40-751" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-26-40-751.jpg" width="620" height="249" /></a><br />
위 회로에서 -쪽을 살펴보면 R1이 1.8k, R2가 0~10KΩ이다. 만약 CDS가 밝을 때 5KΩ이 나온다면 +에 들어가는 전압은 5/(10+5), 즉 VCC에 약 1/3 1.6V정도가 된다. 가변 저항의 값은 1.6 =&lt; 가변저항값/(1.8+가변저항값)으로 최소값을 결정해주면 된다.</p>
<p><span style="color: #33cccc"><strong>2.7.6. 썬루프 창 부분 (KGU-3429(DC 12V))</strong></span><br />
회전운동을 직선운동으로 바꾸어줄 리니어모터를 사용하였다. 메인 화면에서 썬루프 닫기나 썬루프 열기를 누르고 있을 때 닫히거나 열리게 되고, 썬루프 전부 닫기나 전부 열기를 한 번 눌렀을 시 전부 닫히거나 열리게 된다. 리니어모터가 지정된 범위에서만 움직이도록 양 끝단에 리밋스위치를 달아 범위를 제한했다.</p>
<p><span style="color: #008000"><strong>3. 단계별 제작 방법</strong></span><br />
<span style="color: #339966"><strong>3.1. 모터 기구부 제작</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-26-46-002.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33503" alt="Cap 2017-05-30 10-26-46-002" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-26-46-002.jpg" width="620" height="249" /></a><br />
모터가 일직선상으로 직선운동을 원활하게 하기 위해서 직선의 홈을 만들어 그 직선을 따라 이동하도록 제작하였다. 빨간색 부분에 파여진 홈에 모터의 신호에 따라 좌우로 작동을 한다. 파란색 사각형 부분은 리미트센서가 들어가도록 홈을 제작하였다. ‘썬루프 전체 열기’를 실행하면 모터가 이 두 리밋센서 사이에서만 움직이도록 제한하였다.</p>
<p><span style="color: #339966"><strong>3.2. 전체 외형 제작</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-06-184.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33504" alt="Cap 2017-05-30 10-29-06-184" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-06-184.jpg" width="620" height="237" /></a><br />
위와 같이 SolidWorks 2010으로 레이저 가공을 위한 1:1 도면을 만들었다. 나사 구멍과 지붕의 기울기를 고려하며 시스템상 충돌이 나지않고 어셈블리가 되도록 하였다. 어셈블리가 되지 않으면 도면을 따라 레이저 프린터 가공을 하였을 때 나사구멍이 맞지 않아 조립이 되지 않으므로, 신중을 가했다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-15-534.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33505" alt="Cap 2017-05-30 10-29-15-534" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-15-534.jpg" width="620" height="365" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-27-370.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33506" alt="Cap 2017-05-30 10-29-27-370" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-27-370.jpg" width="620" height="465" /></a></p>
<p>다음으로는 솔리드웍스의 1:1 도면을 각각 부품에 대하여 CAD 파일로 내보내기를 한다. 내가 사용한 레이저 가공기가 Solid Work는 지원하지 않고 AutoCAD를 통한 1:1 도면 프린트만 가능했기 때문이다. 아래는 실제로 레이저 프린터로 아크릴을 가공했을 때 사용했던 AutoCAD 도면이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-37-268.jpg" rel="lightbox[33386]"><img class="alignnone size-full wp-image-33507" alt="Cap 2017-05-30 10-29-37-268" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-29-37-268.jpg" width="620" height="440" /></a></p>
<p><span style="color: #339966"><strong>3.3. 소프트웨어</strong> </span><br />
안드로이드 앱 프로그래밍은 처음이라 참고할 도서를 선정하여 공부하며 따라했다. 대표적인 책으로 ‘Do it 안드로이드 앱 프로그래밍’ 책이 있었고 Bluetooth chat 부분의 통신 부분을 가지고 블루투스 부분을 구현하게 되었다. 블루투스를 구현한 후 AVR에서 스마트폰으로 넘어오는 데이터 값에 따라 서로 다른 화면을 띄워줄 필요가 있었고 그 화면 구성을 인텐트로 각각의 Layout을 지정해주었다. 송수신 데이터 값이 중간에 변경되지 않고 정확하게 전달하기 위해서 public static final int 값으로 지정하고 문자로 지정해줌으로써 쉽게 통신하도록 해주었다. 데이터 송수신을 소켓통신 방법을 사용하고 오류검정코드 packet0[3] = (byte) ((packet0[1]+packet0[2]) &amp; 0xff);를 통해 각각의 비트를 검사하며 데이터의 손실이 일어나도 그 데이터는 버리도록 만들어 통신 신뢰도를 높였다. AVR에서는 ADC 변환, 모터 제어를 위한 PWM, USART, 센서값 받기 등 센서 처리와 통신을 위한 코드를 만들었다.</p>
<p><span style="color: #008000"><strong>4. 참조 자료</strong></span><br />
• Do it 안드로이드 앱 프로그래밍 젤리빈 4.2.2판<br />
• 기적을 부르는 안드로이드 통신 프로그래밍</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/33386/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[41호]최대 흡기상태 측정 모듈</title>
		<link>http://www.ntrexgo.com/archives/33395</link>
		<comments>http://www.ntrexgo.com/archives/33395#comments</comments>
		<pubDate>Sat, 25 Mar 2017 00:00:54 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[41호]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[ict]]></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=33395</guid>
		<description><![CDATA[디바이스마트매거진 41호 &#124; 방사선사의 고충으로 고안되어 나온 작품으로 X-ray검사 중 가장 많이 촬영되어지는 흉부부위는 다른 부위와 다르게 방시선사와 피검자의 수신호로 촬영되어지는 X-ray촬영이다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain.png" rel="lightbox[33395]"><img class="alignnone size-large wp-image-31056" alt="2016 ictmain" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain-620x156.png" width="620" height="156" /></a></p>
<p><span style="font-size: large"><strong>2016 ICT 융합 프로젝트 공모전 입선</strong></span></p>
<p><span style="font-size: xx-large"><strong>최대 흡기상태 측정 모듈</strong></span></p>
<p style="text-align: right"><strong>글 | 고려대학교 강병욱, 김도형, 송명근, 원준현, 장재현</strong></p>
<p>&nbsp;</p>
<p><span style="color: #008000"><strong>심사평</strong></span></p>
<p><strong>뉴티씨</strong> 실제로 병원에서 X-ray 사진을 찍을 때에 좋은 위치에서 찍기 위한 실질적인 아이디어가 반영된 작품으로 판단되며, 좋은 어플리케이션이다. 잘 만들면 실용적으로 적용하는 것도 좋으리라 생각된다. 난이도는 어렵지 않으나, 실제 동작이 완료된 점, 실용적인 점 등은 좋은 점수를 받은 이유이다.</p>
<p><strong>칩센</strong> 상세한 관찰로 아이디어가 도출되어 높게 평가한다. 구현이 쉬울 수는 있어도 어려운 게 뛰어난 것은 아니다.</p>
<p><strong>위드로봇</strong> X-ray 검사 시 호흡을 멈추는 상태를 검출한다는 아이디어는 매우 재미있습니다. 단, 이 상태를 검출하기 위해 PSD를 이용하여 측정자의 어깨의 흔들림을 측정하는 부분은 조금 아쉽습니다. 최대 흡기 상태를 정의할 수 있는 다른 지표를 찾고, 그 지표를 검출할 수 있는 시스템을 개발하는 과정이 상세하게 드러나면 좋은 작품이 될 것 같습니다.</p>
<p><span style="color: #008000"><strong>작품 개요</strong></span></p>
<p>다소 생소할 수 있는 이 작품은 방사선사의 고충으로 고안되어 나온 작품으로, X-ray검사 중 가장 많이 촬영되어지는 흉부부위는 다른 부위와 다르게 방사선사와 피검자의 신호 교환으로 촬영 된다. 보통의 흉부선 X-ray 촬영은 아래와 같이 이루어지고 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-22-11-915.jpg" rel="lightbox[33395]"><img alt="Cap 2017-05-30 11-22-11-915" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-22-11-915.jpg" width="620" height="281" /></a></p>
<p>이 순간 방사선사는 피검자의 호흡 상태를 알지 못한 채로 X-ray 촬영버튼인 shoot 버튼을 누르며 촬영이 종료된다. 방사선사가 피검자에게 이러한 지시를 하는 이유는 피검사자의 최대 흡기 상태, 즉 최대한 숨을 들이마셔 폐의 부피를 가장 크게 하였을 때 횡격막의 양끝이 아래로 잘 내려가 흉강 내 구조물이 엑스선 영상에 이상적으로 나타나기 때문이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-22-19-717.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33581" alt="Cap 2017-05-30 11-22-19-717" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-22-19-717.jpg" width="620" height="328" /></a></p>
<p>물론 대부분의 X-ray 사진이 잘 나오는 편이지만, 그렇지 않을 경우 재촬영이 필요하게 되며, 이는 피검자에게 불필요한 방사선 피폭을 안겨주고 시간, 비용적인 문제 역시 따르게 된다. 또한 청력이 약한 노인이나 장애인분들 같은 경우 방사선사와의 신호 소통이 잘 이루어지지 않아 발생되는 문제점들이 생기는데 있어 구체적인 해결방법을 제시하고자 한다.</p>
<p>인체가 호흡을 할 때 흡기상태에서는 쇄골이 위로 올라가고, 횡격막은 내려가며 외관상으로는 가슴이 내밀어지고 어깨가 올라가게 된다. 즉, 가슴둘레가 커지고 어깨 높이가 높아지게 되는 것이다. 실제로 디텍터를 끌어안은 피검자는 가슴은 내밀지 못하므로 어깨가 더욱 상승하는 것을 관찰할 수 있지만 먼 거리에서 X-ray 버튼을 누르는 방사선사의 눈으로는 식별하가 쉽지 않다. 실제로 대부분의 경험 많은 방사선사는 피검자의 호흡 상태를 알아차리는 것보다 오랜 기간 숙달된 감각으로 X-ray 촬영을 한다고 한다.</p>
<p>우리는 인체가 흡기중일 때 어깨가 상승한다는 것을 이용하여, 어깨 높이에 따른 최대 흡기 상태가 측정이 가능하다면, 보다 정확한 측정 방식이 될 것으로 예상하여 보다 객관적으로, 그리고 정량적으로 최대 흡기 상태를 측정 할 수 있도록 본 모듈을 고안하였다.</p>
<p><span style="color: #008000"><strong>작품 설명</strong></span></p>
<p>프로젝트 진행 중 문득 X-ray가 모듈에 영향을 미치지 않을까? 의문점이 들었다. 하지만 잠깐의 조사로 괜찮다는 것을 금방 알 수 있었는데. X-ray는 공항검색, 화물검색, 전자장비 오류 검출 등으로 많은 분야에서 사용되고 있다. 여기서 전자장비의 검출은 X-ray가 전자장비에 영향을 미치지 않는다고 판단할 수 있으므로 다른 장비의 기기를 추가적으로 사용 가능하다는 것을 알 수 있다. 실제로 방사선사의 휴대폰 또한 온종일 X-ray에 노출되지만 오랜 시간 사용가능한 것 역시 확인할 수 있었다. 피검자의 최대 흡기 상태의 측정 방법은 어깨높이를 측정함으로써 간단히, 간접적으로 알 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-22-867.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33582" alt="Cap 2017-05-30 11-26-22-867" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-22-867.jpg" width="620" height="370" /></a></p>
[그림 5]와 같이 만들어진 모듈은 어깨의 상단에 배치된다. 모듈에서는 적외선을 쏘고 반사되어진 빛을 감지하여 시간을 측정하여 그 거리를 가늠하는 것이다. 실제 흉부 X-ray 상황을 가정해 보자. 모듈이 없을 때와 비슷한 상황으로 가겠지만 모듈을 사용한다면 방사선사는 피검자의 호흡 상태를 알 수 있는 상황이 될 것이다.</p>
<p>방사선사는 최대 흡기 상태 측정모듈의 LED의 ON/OFF로 피검자의 상태를 알 수 있다. 모듈의 마지막 Green_Led에 불이 들어오면 피검자의 최대 흡기 상태라고 판단하여 shoot 버튼을 누름으로써 보다 정확하게 흉부 X-ray 촬영이 가능하다.</p>
<p><span style="color: #339966"><strong>3.­1. 주요 동작 및 특징</strong></span></p>
<p>● 피검자의 유/무 검출<br />
● 피검자의 어깨 높이 측정<br />
● 피검자의 어깨 높이에 따른 LED 변화</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-30-649.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33583" alt="Cap 2017-05-30 11-26-30-649" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-30-649.jpg" width="620" height="362" /></a></p>
<p>적외선 거리 감지기의 Data에 의해서 각색의 LED로 상황을 알려주게 된다. [그림 9]는 이상적인 적외선 센서 그래프로, 피검자 감지를 하면 [그림 7]과 같이 노란색 LED에 불이 들어오게 되고, 호흡을 측정하여 최대 흡기 상태라고 판단되면 [그림 8]과 같이 녹색 LED까지 불이 들어오게 된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-38-516.png" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33584" alt="Cap 2017-05-30 11-26-38-516" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-38-516.png" width="620" height="375" /></a></p>
<p><span style="color: #339966"><strong>3.­2. 전체 시스템 구성</strong></span><br />
<span style="color: #33cccc"><strong>3.2.1. Hardware</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-44-299.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33585" alt="Cap 2017-05-30 11-26-44-299" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-44-299.jpg" width="620" height="348" /></a></p>
<p>하드웨어 구성은 비교적 간단하다. 거리를 측정할 적외선 감지모듈과 제어할 수 있는 마이크로컨트롤러 보드 그리고 System 상태를 알려주는 LED로 구성되어 있다. 적외선 거리 측정센서 모듈은 SHARP사의 GP2YOAO2YKOF로 20~150cm의 거리 측정이 가능하며 [그림 11]에서의 노란색 구간인 20~30cm의 전압 레벨의 차가 심하여, Data 값 분석에 있어서 보다 명확하게 판단할 수 있다. [그림 11]의 초록색 구간은 피검자 유무 검출 구간으로 사용되었다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-54-433.png" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33586" alt="Cap 2017-05-30 11-26-54-433" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-26-54-433.png" width="620" height="380" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-04-532.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33587" alt="Cap 2017-05-30 11-27-04-532" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-04-532.jpg" width="620" height="367" /></a></p>
<p><span style="color: #33cccc"><strong>3.2.2. Software</strong></span><br />
Software System의 전체 구성은 크게 2가지로 나뉘어진다. 노이즈 제거를 위한 Filtering System과 최대 흡기 상태를 찾는 Detecting System이다. Filtering System은 적외선 거리센서로부터 받아오는 Data의 노이즈를 줄여주는 System이고, 최대 흡기 상태 측정은 Detecting System이 담당한다.</p>
<p><strong>가. Filtering System</strong><br />
Filtering System은 [그림 14]와 같이 적외선 거리측정 센서의 Data 값이 연속적인 노이즈로 제어하기 힘들어 소프트웨어 필터링을 추가로 사용하였다. 부속적인 시스템이지만 기존에 사용되는 Filtering과는 조금 차별화를 두고 무엇보다 작은 시스템으로 큰 효과를 보는 후처리방식이며, 노이즈라 판단될 경우 보정치환을 하여 노이즈를 제거하게 된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-12-798.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33588" alt="Cap 2017-05-30 11-27-12-798" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-12-798.jpg" width="620" height="137" /></a><br />
후처리 System이기 때문에 Data를 Buffer에 잠시 묶어두어 노이즈를 찾아내게 된다. 한 번 Filtering 하는데 3개의 Buffer가 필요하다. 현재 5번의 Filtering을 하여 총 11개의 Data_buffer가 필요하며 하나의 Filtering영역에서 노이즈 신호라고 판단될 경우 이전의 정상적인 값을 치환하여 Data 값을 보정하게 된다. 후처리 방식으로 진행되는 Filtering이지만 실제 시간차이는 System이 동작하는 속도로 움직이기 때문에 사람의 체감으로는 잘 구분하지 못한다. Filtering Data는 Detecting System으로 활용된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-20-432.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33589" alt="Cap 2017-05-30 11-27-20-432" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-20-432.jpg" width="620" height="316" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-25-598.jpg" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33590" alt="Cap 2017-05-30 11-27-25-598" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-25-598.jpg" width="620" height="265" /></a></p>
[그림 16]은 Filtering되는 Data를 순차적으로 나타내고 있다. 실제 filtering이 되는 것을 확인할 수 있는 동시에 연속적인 filtering 사용은 Data 손실을 유발한다는 것을 알 수 있는데, 급격히 생겨난 굴곡 그래프가 깎여지는 현상이 발견될 수 있는 단점을 보이지만 적정선의 Filtering은 효과가 있는 것으로 보인다.</p>
<p><strong>나. Detecting System</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-38-949.png" rel="lightbox[33395]"><img class="alignnone size-full wp-image-33591" alt="Cap 2017-05-30 11-27-38-949" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-27-38-949.png" width="620" height="424" /></a></p>
<p>Detection System은 크게 네 가지 구간으로 나누어지는데 그 중 첫 번째 상태로 피검자를 감지하지 못한다면 System은 대기상태에 머물게 된다. 두 번째 상태로 피검자를 감지하였다면 이를 System 사용자에게 알려주게 된다. 세 번째 상태로는 최대 흡기 상태 측정상태로 방사선사에게 Shoot을 해도 좋다는 신호를 주는 상태이다. 네 번째 상태는 shoot 버튼을 누르게 되면 대기상태로 돌아간다. 하지만 이 네 번째 상태는 Shoot 버튼을 누른 상태로 가상의 상태를 시험하기 위해 만든 상태이다. 실제 시스템 구성에서는 사용되지 않고 대기상태로 돌아가게 된다.</p>
<p><span style="color: #339966"><strong>3­.3. 개발 환경(개발 언어, Tool, 사용 시스템 등)</strong></span></p>
<p>· C언어 개발<br />
· arduino sketch Tool 사용</p>
<p><span style="color: #008000"><strong>4. 단계별 제작 과정</strong></span></p>
<p>· 문제점을 발견하고 모듈을 구상 거리측정센서 및 보드 선정<br />
· 하드웨어 케이스제작 및 부착<br />
· 소프트웨어제작 1달 동안 Filtering 고안 및 Test.<br />
· 2주 Detecting system 제작 및 수치 값 조정</p>
<p><span style="color: #008000"><strong>5. 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>/***********************************************************<br />
1. micros() 함수를 이용한 dt 생성!<br />
2. dt를 이용한 미분값 확인!<br />
3. 배열 10개로의 평균값 구하기.<br />
************************************************************/<br />
#include &lt;TimerOne.h&gt;<br />
#define ts 0.001*0.001<br />
#define FlagOn 1<br />
#define FlagOff 0<br />
#define R_LED 9 // Red LED!!<br />
#define Y_LED 8 // Yellow LED!!<br />
#define Y_LED1 10 // Yellow LED!!<br />
#define Y_LED2 12 // Yellow LED!!<br />
#define G_LED 11 // Green LED!!</p>
<p>#define Filtering_y 4<br />
#define Filtering_diff_y 4<br />
#define matrix_SizeFory 99<br />
#define matrix_SizeForDiffy 99</p>
<p>#define Average_Value 10<br />
#define entry_value 0</p>
<p>#define high_filter 0&#215;00<br />
#define low_filter 0&#215;08</p>
<p>#define filter_buffer_number 4 // 필터링 개수 정하는 곳 &lt;&lt;&lt;&lt; 4가 적당한듯<br />
#define Low_number 1<br />
#define DatsFilterBufferNumber 5</p>
<p>&nbsp;</p>
<p>float tCount = entry_value;<br />
float tCountPre = entry_value;<br />
unsigned char i = 0, j = 0, k = 0, l = 0;</p>
<p>unsigned char DetectionFlag = 0&#215;00;<br />
unsigned char reference_Flag = 0&#215;00;<br />
unsigned char System_stats = 0&#215;00; // System Flag<br />
int SumCheckFlag = 0;<br />
int Count = 0;<br />
int refer_filter_value = 0;<br />
int band_pass_value = 0;<br />
int sum_y, sum_diff_y, y_filtering , value_filtering, diff_value, integ_value, integ_y, integ_y_filter;<br />
float t;<br />
int diff_y, diff_y_filtering , dt, diff_diff_y; // time, y_value, diff_Y, △t, diff_diff_Y<br />
int ch_t_value = entry_value;<br />
int diff_y_pre = entry_value;<br />
int y_filtering_pre = entry_value;<br />
int filter_value = entry_value;<br />
int pre_filter_value = entry_value;<br />
int diff_filter_value = entry_value;<br />
int mov_avr_value = entry_value;<br />
int reference_value = entry_value; // 사람이 들어왔을시 기준값 저장<br />
int Neates = entry_value;<br />
int Neates_ = entry_value;<br />
int Breath_Check_Time = entry_value;<br />
int detection_H_Check_Time = entry_value;<br />
float Breath_Ch_tCountPre = entry_value;<br />
float detection_H_Check_tCountPre = entry_value;</p>
<p>int y;<br />
int Start_Value = entry_value;<br />
int Replace_Out = entry_value;<br />
int BreathFlag = entry_value;<br />
int TimeCheckValue = entry_value;</p>
<p>int Data_buffer[2 * filter_buffer_number];<br />
int y_filter_buffer[matrix_SizeFory];<br />
int diff_filter_buffer[matrix_SizeForDiffy];<br />
int reference_buffer[0];<br />
int StartF = 1000;<br />
int DatsFilterBuffer[DatsFilterBufferNumber * 2];<br />
int HumenCHeckFlag[DatsFilterBufferNumber * 2];<br />
int out_value = 0;</p>
<p>unsigned int IR_output = entry_value; // ANALOG IN 0 PIN!!<br />
void PinModeSetup()<br />
{<br />
pinMode(R_LED, OUTPUT);<br />
pinMode(Y_LED, OUTPUT);<br />
pinMode(Y_LED1, OUTPUT);<br />
pinMode(Y_LED2, OUTPUT);<br />
pinMode(G_LED, OUTPUT);<br />
digitalWrite(R_LED, HIGH);<br />
digitalWrite(Y_LED, HIGH);<br />
digitalWrite(Y_LED1, HIGH);<br />
digitalWrite(Y_LED2, HIGH);<br />
digitalWrite(G_LED, HIGH);<br />
}</p>
<p>void saveStatesForNextStep() {<br />
tCountPre = tCount;<br />
diff_y_pre = diff_y;<br />
y_filtering_pre = y_filtering;<br />
pre_filter_value = filter_value;<br />
saveDataBufferForNextStep(filter_buffer_number); // Cation!! this funtion is macro<br />
}</p>
<p>void saveDataBufferForNextStep( int filter_num) { // 5번<br />
for (int i = filter_num &#8211; 1 ; i &gt;= 0; i&#8211;) {<br />
Data_buffer[(2 * i) + 2] = Data_buffer[(2 * i) + 1];<br />
Data_buffer[(2 * i) + 1] = Data_buffer[(2 * i)];<br />
}<br />
}<br />
void RealtimeProcessingForNextStep() {<br />
for (int i = DatsFilterBufferNumber &#8211; 1 ; i &gt;= 0; i&#8211;) {<br />
DatsFilterBuffer[(2 * i) + 2] = DatsFilterBuffer[(2 * i) + 1];<br />
DatsFilterBuffer[(2 * i) + 1] = DatsFilterBuffer[(2 * i)];<br />
}<br />
}</p>
<p>void printStates(int t) {<br />
Serial.print(t);<br />
Serial.print(&#8220;, &#8220;);<br />
}</p>
<p>int mov_avr_filter(int y_value) {<br />
sum_y = 0;<br />
y_filter_buffer[0] = y_value;<br />
for (int i = Filtering_y; i &gt;= 0; i&#8211;) {<br />
y_filter_buffer[i] = y_filter_buffer[i - 1];<br />
sum_y += y_filter_buffer[i];<br />
}<br />
value_filtering = sum_y / Filtering_y + 1;<br />
return value_filtering;<br />
}</p>
<p>int diff_buffer_filtering(int y_value) {<br />
sum_diff_y = 0;<br />
for (int i = Filtering_diff_y; i &gt;= 0; i&#8211;) {<br />
diff_filter_buffer[i + 1] = diff_filter_buffer[i];<br />
sum_diff_y += diff_filter_buffer[i];<br />
}<br />
diff_filter_buffer[0] = y_value;<br />
value_filtering = sum_diff_y / Filtering_diff_y;</p>
<p>return value_filtering;<br />
}</p>
<p>int diff_funtion(int value_pre, int value) {<br />
diff_value = (((value &#8211; value_pre) / dt));<br />
return diff_value;<br />
}</p>
<p>int integ_cacul(int value, int value_pre)<br />
{<br />
int tringle = 0;<br />
integ_value = (((value &#8211; value_pre) * dt));<br />
return integ_value;<br />
}<br />
/*<br />
compare_funtion 함수 (상 하위 필터 선택, 필터횟수, 과거의 과거의 값, 과거의 값, 현재 값)으로 구성, 필터횟수가 크면 클수록 급격히 변화되는 변화량에 영향을 미칠 수 있음!! 현재의 값과 과거의 값을 비교하여 과거의 값을 교정하는 방식의 필터링. 순간적인 noise에 적합하다.<br />
*/<br />
int compare_function( unsigned char high_low_filter, unsigned char HWNUM, int y, int after_y, int after_after_y) {<br />
unsigned char high_after_flag = 0&#215;00;<br />
unsigned char high_after_after_flag = 0&#215;00;<br />
unsigned char low_after_flag = 0&#215;00;<br />
unsigned char low_after_after_flag = 0&#215;00;</p>
<p>switch (high_low_filter) {<br />
case 0&#215;00 :<br />
if ((y &gt; after_after_y) &amp;&amp; (y &gt; after_y)) // y 의심<br />
{<br />
return after_after_y;<br />
}<br />
else {<br />
return y;<br />
}<br />
break;</p>
<p>case 0&#215;08 :<br />
if ((y &lt; after_after_y) &amp;&amp; (y &lt; after_y)) // y 의심<br />
{<br />
return after_after_y;<br />
}<br />
else {<br />
return y;<br />
}<br />
break;</p>
<p>case 0&#215;02 : if (high_low_filter == 0&#215;02 &amp;&amp; high_after_flag &gt; high_after_after_flag) {} break;<br />
case 0&#215;04 : if (high_low_filter == 0&#215;04 &amp;&amp; high_after_flag &lt; high_after_after_flag) {} break;<br />
}<br />
}<br />
int ReplaceFuction(int Pre_Pre_y, int Pre_y, int y) {<br />
if (Pre_Pre_y &lt; Pre_y) {<br />
return Pre_y;<br />
} else {<br />
return Pre_Pre_y;<br />
}<br />
}</p>
<p>void High_Compare_operation() {<br />
for (int i = 0 ; i &lt;= filter_buffer_number ; i++) {<br />
i = 2 * i;<br />
j = (2 * i) + 1;<br />
k = (2 * i) + 2;<br />
Data_buffer[k] = compare_function(high_filter, filter_buffer_number, Data_buffer[k], Data_buffer[j], Data_buffer[i]);<br />
}<br />
}</p>
<p>void Low_Compare_operation() {<br />
for (int i = (filter_buffer_number &#8211; (filter_buffer_number &#8211; Low_number)) ; i &lt;= filter_buffer_number ; i++) {<br />
i = 2 * i;<br />
j = (2 * i) + 1;<br />
k = (2 * i) + 2;<br />
Data_buffer[k] = compare_function(low_filter, filter_buffer_number, Data_buffer[k], Data_buffer[j], Data_buffer[i]);<br />
}<br />
}</p>
<p>void Time_Count() {<br />
tCount = micros();<br />
t = (float)(tCount) * ts;<br />
dt = (float)(tCount &#8211; tCountPre) * ts;</p>
<p>}</p>
<p>void Serial_out_put() {<br />
/* Serial out put*/<br />
// for(int j = 0 ; j &lt;= filter_buffer_number*2 ; j++){<br />
// printStates(Data_buffer[j]);<br />
// }<br />
printStates(Data_buffer[filter_buffer_number * 2]);<br />
printStates(Data_buffer[filter_buffer_number * 2]);<br />
printStates(mov_avr_value);<br />
Serial.print(&#8220;\r\n&#8221;);<br />
}</p>
<p>void System_opeation() {<br />
switch (System_stats) {<br />
case 0&#215;00 :<br />
digitalWrite(R_LED, LOW);<br />
digitalWrite(Y_LED, HIGH);<br />
digitalWrite(Y_LED1, HIGH);<br />
digitalWrite(Y_LED2, HIGH);<br />
digitalWrite(G_LED, HIGH);<br />
// Serial.println(&#8221; System operation&#8230; &#8220;);<br />
break;</p>
<p>case 0&#215;02 :<br />
digitalWrite(R_LED, LOW);<br />
digitalWrite(Y_LED, LOW);<br />
digitalWrite(Y_LED1, HIGH);<br />
digitalWrite(Y_LED2, HIGH);<br />
digitalWrite(G_LED, HIGH);<br />
// Serial.println(&#8221; Dection_humen&#8230; Take brethe&#8230;&#8221;);<br />
break;</p>
<p>case 0&#215;04 :<br />
digitalWrite(R_LED, LOW);<br />
digitalWrite(Y_LED, LOW);<br />
digitalWrite(Y_LED1, LOW);<br />
digitalWrite(Y_LED2, LOW);<br />
digitalWrite(G_LED, LOW);<br />
// Serial.println(&#8221; Ok. ready_shot &#8220;);<br />
break;<br />
}<br />
}</p>
<p>void System_timer(void)<br />
{<br />
System_opeation();<br />
}</p>
<p>void setup() {<br />
// put your setup code here, to run once:<br />
PinModeSetup();<br />
Serial.begin(115200); // error rate -3.5%<br />
Timer1.initialize(12000); // System_timer to run every 0.2 seconds<br />
Timer1.attachInterrupt(System_timer);<br />
delay(100);<br />
}</p>
<p>void loop() {<br />
Data_buffer[0] = analogRead(A0);<br />
Time_Count();</p>
<p>High_Compare_operation();<br />
// mov_avr_value = mov_avr_filter(Data_buffer[filter_buffer_number*2]);<br />
// Serial_out_put(); //화면 출력 for Test</p>
<p>/* 아래에 검출 이 들어와야함.*/<br />
if (Data_buffer[0] &lt; 265) {<br />
System_stats = 0&#215;00;<br />
}</p>
<p>/****************** System_stats = 0&#215;00 ******************/<br />
if (System_stats == 0&#215;00) {<br />
if ((Data_buffer[filter_buffer_number * 2]) &#8211; 50 &gt; 300) {<br />
detection_H_Check_tCountPre = tCount;<br />
System_stats = 0&#215;02;<br />
}<br />
}<br />
/****************** System_stats = 0&#215;02 ******************/<br />
if (System_stats == 0&#215;02) {<br />
Breath_Check_Time = 0;<br />
detection_H_Check_Time = (float)(tCount &#8211; detection_H_Check_tCountPre) * ts;<br />
if (detection_H_Check_Time == 1) {<br />
Neates = Data_buffer[filter_buffer_number * 2]; // 첫번째 조건 초기값 : Neates<br />
Neates_ = Data_buffer[filter_buffer_number * 2]; // 두번째 조건 초기값 : Neates_<br />
}<br />
if ((Data_buffer[filter_buffer_number * 2]) &gt; Neates + 2) { //Neates보다 큰 값이 들어오면 Neates는 더 커진다.<br />
Neates = Data_buffer[filter_buffer_number * 2];<br />
Breath_Ch_tCountPre = tCount;<br />
} else { // 위의 조건이 맞지 않으면 Breath_Ch_tCountPre 는 1초 .. 2초 세게된다.<br />
if (Neates &lt; Neates_ + 20) { // Nestes_ 보다 들어오는 값이 작다면 Breath_Ch_tCountPre 변동된다.<br />
Breath_Ch_tCountPre = tCount;<br />
}<br />
Breath_Check_Time = (float)(tCount &#8211; Breath_Ch_tCountPre) * ts;<br />
}<br />
if (Breath_Check_Time == 1) { // Breath_Check_Time이 1초가 되면 shoot 상태로 가고 0&#215;02 상태에서 벗어난다.<br />
System_stats = 0&#215;04;<br />
}<br />
}<br />
saveStatesForNextStep(); // 항상 마지막에 위치해야 함<br />
}</p>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/33395/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[41호]ABT_System(Automatic Bicycle Transmission System)</title>
		<link>http://www.ntrexgo.com/archives/33398</link>
		<comments>http://www.ntrexgo.com/archives/33398#comments</comments>
		<pubDate>Sat, 25 Mar 2017 00:00:28 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[41호]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[ict]]></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=33398</guid>
		<description><![CDATA[디바이스마트매거진 41호 &#124; 방사선사의 고충으로 고안되어 나온 작품으로 X-ray검사 중 가장 많이 촬영되어지는 흉부부위는 다른 부위와 다르게 방시선사와 피검자의 수신호로 촬영되어지는 X-ray촬영이다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain.png" rel="lightbox[33398]"><img class="alignnone size-large wp-image-31056" alt="2016 ictmain" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain-620x156.png" width="620" height="156" /></a></p>
<p><span style="font-size: large"><strong>2016 ICT 융합 프로젝트 공모전 입선</strong></span></p>
<p><span style="font-size: x-large"><strong>ABT_System(Automatic Bicycle Transmission System)<br />
</strong></span></p>
<p style="text-align: right"><strong>글 | 단국대학교 김승권, 서진욱, 이규호, 김영태, 최재호, 김재도</strong></p>
<p>&nbsp;</p>
<p><span style="color: #008000"><strong>심사평</strong></span></p>
<p><strong> JK전자</strong> 최근 자전거를 이용하는 인구가 급격하게 늘어난 것은 사실이다. 대부분이 건강을 위한 운동이 목적일 것이다. 특히 자전거 운동은 런닝보다 무릎관절 등에 무리가 덜 가는 운동으로 알려져 있어 높은 연령층에서도 많이 이용을 하고 있는 것 같다. 관절 건강을 위한 최적의 속도와 기어비를 자동으로 조정해서 패달을 밟는 최적의 강도를 자동으로 설정을 해주는 기능이 있는 자전거라면 많은 수요가 있을 수 있을 것 같다.</p>
<p><strong>뉴티씨</strong> 매우 실용적인 작품으로, 자전거가 외부에서 타는 것임을 감안하여 방수나 모터를 좀 더 튼튼한 것으로 사용하여 오랜기간 사용할 수 있도록 했으면 좋았을 것 같다. 충분히 실용화하여 사용할 수 있는 것으로 보이며, 재미있는 작품으로 보인다.</p>
<p><strong>칩센</strong> 점점 수요가 늘고 있는 자전거를 이용한 모티브가 돋보입니다. 케이스를 직접 제작하는 열의와 작품의 완성도 또한 높다고 판단됩니다. 세부적으로 제품의 안전과 관련된 부분을 고려하여 보완한다면 상용화된 작품으로도 진행될 여지가 있습니다.</p>
<p><strong>위드로봇</strong> 보고서의 내용 만으로는 잘 동작하였는지 판단하기 어렵습니다. 제작한 과정 뿐만 아니라 동작 상에서 발생하는 추가 문제점, 그 추가 문제점의 해결 방안에 대한 의견이 보고서에 첨부되면 더욱 좋겠습니다.</p>
<p><span style="color: #008000"><strong>1. 작품 제목</strong></span><br />
ABT(Automatic Bicycle Transmission)_System</p>
<p><span style="color: #008000"><strong>2. 작품 개요</strong></span><br />
자전거는 1800년대에 최초로 발명된 이래 인류 역사상 가장 멋진 발명품 중 하나이다. 2015년 기준으로 자전거 인구는 1200만명을 넘어섰으며 자동차와는 달리 연료없이 순수 인간의 동력으로만 구동 가능하다는 장점이 있어 친환경적이고 굉장히 경제적이다.<br />
자전거는 본래 단순한 이동수단이었지만 철인 3종경기나 트라이애슬론과 같은 큰 경기가 열릴 정도로 인기가 높아졌다. 점점 더 가볍고 튼튼한 자전거가 개발되고 있으며 최근에는 버튼만으로도 변속이 가능한 자전거가 개발되었다. 변속은 자전거 주행을 할 때 안전과 연관된 부분이기 때문에 현재 달리고 있는 속도와 경사에 맞게, 빠르게 변속을 해야한다. 자전거에 익숙하지 않은 사람들은 변속하는 시점을 잘 모르기 때문에 무리하게 자전거를 탈 경우 무릎손상을 초래할 수도 있다. 현재 시중에 판매되는 자전거 중에서는 편리하고 기능이 많이 들어간 자전거 일수록 매우 비싸다. “비싼 자전거만 좋고 튼튼해야 할까?”라는 편견을 깨고 어느 자전거에나 장착이 가능한, 누구나 쉽게 변속을 할 수 있는, 편리한 자전거를 만들고 싶었다. 그래서 ABT_System을 제작하게 된 것이다.</p>
<p><span style="color: #008000"><strong>3. 작품 설명</strong></span><br />
<span style="color: #339966"><strong>3.1. 개발환경</strong></span><br />
· 개발 언어 : C 언어, C++<br />
· 개발 Tool : Arduino Sketch<br />
· 사용 시스템 : 아두이노</p>
<p>현재 시중에 판매되고 있는 전자식 변속기는 크게 내장형 배터리 / 변속, 브레이크 레버 / 앞 변속기 / 뒷 변속기 / 통신케이블 / 배터리로 구성되어 있다. 물론 전자식 변속기를 장착하기 위해서는 장착할 수 있는 모델을 따로 구매해야하기 때문에 금전적인 문제가 상당히 크다. ABT_System을 장착하기 위해서는 자전거에 장착할 부분의 크기만 알면 되기 때문에 장착에 제한이 없다. 또한 구성품이 앞·뒤 변속기, LCD, 배터리, 컨트롤러, 스위치만 있으면 되기 때문에 구성품이 적으며, 장착이 간단하다.</p>
<p>ABT_System에는 LCD가 장착되어 있어 현재 변속기의 위치를 표시하며, 케이던스(1분당 페달을 밟는 횟수)와 속도를 동시에 확인할 수 있다. 바퀴와 페달에 장착된 마그네틱 스위치를 이용해 속도와 케이던스를 실시간으로 측정하며, 6축 가속도 센서를 이용하여 경사를 측정한다. 컨트롤러로 사용한 아두이노 나노를 통해 값을 계산한다. 이렇게 계산한 케이던스와 속도를 기준으로 적절한 기어비를 계산해 아두이노 메가로 기어를 변속하라는 명령을 전송한다. 전송받은 데이터를 기준으로 앞, 뒤 액추에이터 서보는 변속이 가능한 각도로 변경되며, 드레일러를 밀어 기어를 변속하게 된다.</p>
<p><span style="color: #339966"><strong>3.2. 주행모드</strong></span><br />
ABT_System에는 총 3가지 모드가 존재하여 사용자가 원하는대로 변속이 가능하다.</p>
<p><span style="color: #33cccc"><strong>3.2.1. One Finger Mode</strong></span><br />
One Finger Mode에서는 한 쪽 버튼만으로 변속이 가능하도록 소스코딩을 하였다. 이에 설정한 기어비는 앞, 뒤 변속기의 기어비를 계산하여 최적의 기어비로 변속이 가능하도록 설정하였다.<br />
가장 표준 자전거는 앞 기어는 3개, 뒷 기어는 7개의 기어로 구성되어 있으며, 총 21단으로 변속이 가능하다. 자전거의 기어는 앞, 뒤 기어를 적절히 변속해야 현재 달리고 있는 환경에 따라 원활하게 주행이 가능하다. 예를 들어 앞 기어의 가장 작은 톱니를 1번, 가장 큰 톱니를 3번이라고 가정하고, 뒷 기어의 가장 작은 톱니를 1번, 가장 큰 톱니를 7번이라고 가정하자. 앞 기어가 1번일 때는 경사를 오르거나 저속 주행을 할 때 사용하는 데 뒷 기어는 5, 6, 7번 기어를 사용하는 것이 가장 적절하다. 즉 뒷 기어의 1, 2, 3, 4번은 사용할 확률이 적다는 뜻이다. One Finger Mode에서는 가장 적절한 기어비로 변속을 하는 것을 목적으로 하기 때문에 앞, 뒤 기어의 기어비를 계산하여 11가지의 경우의 수로 변속을 하게 된다.</p>
<p><span style="color: #33cccc"><strong>3.2.2. Manual Mode</strong></span><br />
Manual Mode는 수동 변속 모드로 자동변속 기능을 필요로 하지 않고 사용자가 원하는 대로 즉각적으로 변속할 수 있는 설정이다. 좌측 버튼으로는 앞 기어의 변속을 담당하며, 우측 버튼으로는 뒷 기어의 변속을 담당한다. LCD에는 현재 변속 위치를 표시하기 때문에 사용자가 변속을 하고 싶을 때는 버튼을 눌러 실시간으로 변속이 가능하도록 설정하였다. 그렇다면 변속을 할 때 변속기의 위치는 고려하지 않을까? 일반 자전거의 변속기는 변속기 속선을 당기는 정도에 따라서 변속기의 위치를 세밀하게 조절이 가능하다. 변속기의 위치를 고려하지 않으면 체인이 대각선으로 연결되어 소음을 발생시키게 되는데 이 때 트리밍(Trimming)을 통해서 변속기의 위치를 조절해줘야 한다. 그래서 Manual Mode에서나, Automatic Mode, One Finger Mode에서도 트리밍이 가능하도록 코딩을 하여 변속을 할 때 소음이 발생하지 않도록 액추에이터가 이동한다. 트리밍을 하지 않으면 변속기의 플레이트가 닳아 손상되며, 체인에도 큰 영향을 미친다.</p>
<p><span style="color: #33cccc"><strong>3.2.3. Automatic Mode</strong></span><br />
Automatic Mode는 ABT_System에 장착된 기능을 모두 활용하는 모드로 주행각도, 주행속도, 케이던스를 측정하여 현재 페달링 속도와 주행속도, 노면의 기울기를 모두 고려하여 가장 적절한 기어비로 변속을 할 수 있도록 설정하였다. 1차로 기울기, 2차로 주행속도, 3차로 케이던스를 고려한다. 변속을 할 때 가장 중요한 것이 노면의 기울기이다. 주행속도와 케이던스를 먼저 고려하게 되면 노면의 기울기에 따라서 변속이 먼저 이뤄지지 않기 때문에 안정성이 낮아진다.<br />
만약 내리막을 주행하고 있으며 케이던스가 0인 상태에서는 어떻게 될까? 일정 수준의 케이던스를 넘지 않으면 변속을 하지 않으며, 변속을 하던 도중에 페달링을 멈추면 케이던스가 0이 되기 때문에 변속을 하지 않도록 설정하였다. 만약 케이던스가 0이더라도 주행 중이거나 정지하는 경우에는 이전에 유지한 변속 값을 유지하기 때문에 갑자기 변속이 되지 않는다.</p>
<p><span style="color: #339966"><strong>3.3. LCD 모듈</strong></span><br />
<span style="color: #33cccc"><strong>3.3.1. 부품리스트</strong></span><br />
<strong> </strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-28-51-031.png" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33601" alt="Cap 2017-05-30 11-28-51-031" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-28-51-031.png" width="620" height="187" /></a></p>
<p><span style="color: #33cccc"><strong>3.3.2. 부품 설명</strong></span><br />
캐릭터 LCD : 캐릭터 LCD는 그래픽 LCD와는 달리 문자 하나당 40개의 픽셀로 이뤄져 있으며, 아두이노나 Atmega128과 같은 MCU에서는 헤더파일에 기본적인 알파벳 코드가 작성되어 있어 함수를 호출하여 문자를 입력하면 바로 LCD에 글자를 띄울 수 있다.<br />
MC7805CT : MC7805CT는 회로에서 요구하는 전압이 있어 일정 수준 이하로 전압을 내릴 때 사용하는 리니어 레귤레이터이다. 정전압 레귤레이터에는 스위칭 방식인 SMPS, 가장 많이 사용되는 리니어 레귤레이터가 있다. 리니어 레귤레이터는 전위차를 열에너지로 소모하기 때문에 에너지 효율은 좋지 않지만 회로구성이 간단하고 요구전압과 입력전압의 차이가 많이 나지않을 때 사용된다. 모델명의 뒷자리 숫자, 즉 78XX는 변환하고자하는 전압을 의미하며 우리가 사용하는 7805는 5V로 전압을 내려주는 리니어 레귤레이터이다.</p>
<p>아두이노 나노 : 아두이노 나노는 아두이노 프로 미니 다음으로 작은 모델이다. 아두이노 우노나 메가와 같은 모델은 크기가 크기 때문에 한정된 크기에서 MCU를 요구할 때는 적합하지 않다는 단점이 있다. 때문에 아두이노 나노나 프로 미니, 마이크로와 같은 모델을 사용하며, Atmega328을 사용하여 아두이노 우노나 마이크로, 프로 미니와 다른 점이 거의 없다.</p>
<p>마그네틱 센서 : 마그네틱 센서는 비활성 가스를 충전한 유리관 속에 봉입된 스위치를 의미한다. 리드스위치는 다른 스위치와 달리 접점의 동작, 복귀가 빠르고 신뢰도가 높기 때문에 TACT 스위치보다 사용하기 편하다. 자전거에 장착하여 고속으로 회전하는 케이던스와 바퀴의 속도를 측정하기 위해서는 거리측정센서나 근접센서를 사용하기 어렵다. 때문에 자력에 의해 스위치가 On/Off되는 마그네틱 센서를 사용하는 것이 인식률이나 장착에 더 효율적이다.</p>
<p><span style="color: #339966"><strong>3.4. 앞·뒤 변속기 / 메인 컨트롤러</strong></span><br />
<span style="color: #33cccc"><strong> 3.4.1. 부품리스트</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-28-57-931.png" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33602" alt="Cap 2017-05-30 11-28-57-931" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-28-57-931.png" width="620" height="151" /></a></p>
<p><span style="color: #33cccc"><strong>3.4.2. 부품 설명</strong></span><br />
아두이노 메가 : 아두이노 메가는 Atmega2560을 사용하고 GPIO 포트가 다양하여 확장성이 좋다는 장점이 있다. 아두이노 나노 등을 사용해 소형화할 수 있었는데 아두이노 메가를 사용한 이유는 다음과 같다.<br />
아두이노 메가 이외의 아두이노 보드는 디지털/아날로그 포트, Hardware Serial Port가 적기 때문에 많은 GPIO 포트를 요구할 때는 적합하지 않다. ABT_System은 Hardware Serial Port가 총 3개 필요하다. AX-12A를 구동할 때 Serial 통신으로 Packet을 보내주는데 제작과정에서 SoftwareSerial 클래스를 사용하는 것이 되지 않아 Hardware Serial Port를 사용해야 했다. 그래서 불가피하게 Atmega2560을 선택했으며, 포트 부족 문제를 해결하였다.<br />
AX-12A : AX-12A 액추에이터 서보는 내부에 MCU가 장착되어 수신하는 Packet에 의해 동작한다. Robotics에서 제공하는 데이터시트를 보면 Instruction마다 기능을 다르게 설정할 수 있으며, ABT_System에는 360도 회전하는 주행모드보다는 각도 제어모드가 적합하기 때문에 AX-12A를 선택하였다. 일반 디지털 서보보다 비싼 가격대가 형성되어 있지만 토크, 허용전류, 빠른 응답속도, 정확한 명령 수행으로 인해 위 액추에이터를 선택하였다. 또한 일반 서보는 180도까지 제어가 가능하지만 액추에이터 서보는 330도까지 제어가 가능하기 때문에 더 넓은 제어각도를 처리할 수 있다.<br />
MMA8452 : MMA8452는 3축 가속도센서로 X, Y, Z축에서 기울어진 정도를 측정하여 각도로 표시를 해주기 때문에 기울기를 측정하기에 적합한 모듈이다. 보통 가속도, 자이로센서는 SPI, I2C 통신을 둘 다 지원하기 때문에 사용자가 원하는 대로 제어가 가능하다는 장점이 있다. 자이로 센서와 가속도 센서의 차이점은 측정하는 값에 차이가 있다. 가속도 센서는 X, Y, Z축의 중력가속도 성분을 분해하여 각각 각도로 나타내는 것이 가능하다. 자이로 센서는 각 축의 각속도를 측정하는 것이기 때문에 각도를 구하려면 적분을 해야한다. 때문에 ABT_System을 구현할 때는 가속도 센서를 사용하는 것이 적합하다고 판단하였다. ABT_System에서는 주행 각도를 측정하여 그에 알맞은 기어비로 기어를 변속하게 된다.</p>
<p><span style="color: #008000"><strong>4. 단계별 제작과정</strong></span><br />
<strong><span style="color: #339966">4.1. ABT_System 장착 위치별 지름, 세부크기 측정</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-07-383.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33603" alt="Cap 2017-05-30 11-29-07-383" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-07-383.jpg" width="620" height="374" /></a></p>
<p><strong><span style="color: #339966">4.2. 부품별 3D Modeling</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-14-800.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33604" alt="Cap 2017-05-30 11-29-14-800" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-14-800.jpg" width="620" height="511" /></a></p>
<p><strong><span style="color: #339966">4.3. 3D Printing</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-23-034.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33605" alt="Cap 2017-05-30 11-29-23-034" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-23-034.jpg" width="620" height="535" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-37-900.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33606" alt="Cap 2017-05-30 11-29-37-900" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-37-900.jpg" width="620" height="560" /></a></p>
<p><strong><span style="color: #339966">4.4. 2차, 3차 모델링 수정</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-43-344.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33607" alt="Cap 2017-05-30 11-29-43-344" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-43-344.jpg" width="322" height="350" /></a></p>
<p><strong><span style="color: #339966">4.5. 최종 출력 및 부품배치</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-51-766.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33608" alt="Cap 2017-05-30 11-29-51-766" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-51-766.jpg" width="620" height="457" /></a></p>
<p><strong><span style="color: #339966">4.6. 부품 조립 및 자전거 장착</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-59-365.jpg" rel="lightbox[33398]"><img alt="Cap 2017-05-30 11-29-59-365" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-29-59-365.jpg" width="620" height="193" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-08-785.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33610" alt="Cap 2017-05-30 11-30-08-785" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-08-785.jpg" width="620" height="811" /></a></p>
<p><strong><span style="color: #339966">4.7. 테스트</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-19-890.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33611" alt="Cap 2017-05-30 11-30-19-890" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-19-890.jpg" width="620" height="868" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-32-166.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33612" alt="Cap 2017-05-30 11-30-32-166" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-32-166.jpg" width="620" height="345" /></a></p>
<p><strong><span style="color: #339966">4.8. 회로도</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-38-619.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33613" alt="Cap 2017-05-30 11-30-38-619" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-38-619.jpg" width="620" height="753" /></a></p>
<p><strong><span style="color: #339966">4.9. 시험주행</span></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-45-783.jpg" rel="lightbox[33398]"><img class="alignnone size-full wp-image-33614" alt="Cap 2017-05-30 11-30-45-783" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-11-30-45-783.jpg" width="620" height="527" /></a></p>
<p><span style="color: #008000"><strong>5. 소스코드</strong></span><br />
<span style="color: #339966"><strong>5.1. FRONT CODE</strong></span></p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger"><strong>FRONT CODE</strong></h3><div class="symple-toggle-container">
<p>#include &lt;LiquidCrystal.h&gt;<br />
#include &lt;Wire.h&gt;<br />
#include &lt;SFE_MMA8452Q.h&gt;<br />
#include &lt;String.h&gt;</p>
<p>#define r_up 10<br />
#define r_down 11<br />
#define f_up 12<br />
#define f_down 13<br />
// Button Setting pin<br />
#define f_7 1<br />
#define f_6 2<br />
#define s_7 3<br />
#define s_6 4<br />
#define f_5 5<br />
#define t_7 6<br />
#define t_6 7<br />
#define s_5 8<br />
#define f_4 9<br />
#define t_5 10<br />
#define s_4 11</p>
<p>int mode_state=1;<br />
int m_after1, m_after2 = 0;<br />
int mode = 0;<br />
int mode_temp=0;<br />
int in[4] = {};<br />
float in_spd = 0;<br />
unsigned long time,time2, oldtime,oldtime2, delta,delta2;<br />
float spd1,spd2 = 0;<br />
float temp1, temp2 =0;<br />
int swpin=18,swpin2=19, swval=0,swval2=0, oldswval=0,oldswval2=0;<br />
LiquidCrystal lcd(7,6,5,4,3,2);<br />
int after[4], before[4] = {0};<br />
int f_state =1;<br />
int r_state = 1;<br />
int spd, rpm =0;<br />
int s_temp, r_temp = 0;<br />
char f_i2c;<br />
char r_i2c;<br />
char out[5]={};<br />
MMA8452Q accel;</p>
<p>void setup()<br />
{<br />
accel.init();<br />
lcd.begin(16,2);<br />
pinMode(swpin,INPUT);<br />
pinMode(swpin2,INPUT);<br />
pinMode(r_up, INPUT);<br />
pinMode(r_down,INPUT);<br />
pinMode(f_up, INPUT);<br />
pinMode(f_down, INPUT);<br />
Serial.begin(9600);<br />
}</p>
<p>void loop()<br />
{<br />
speed_sens(spd1, spd2);<br />
spd = (int)spd1;<br />
rpm = (int)spd2;<br />
switch(mode)<br />
{<br />
case 0:<br />
{<br />
lcd.setCursor(0,0);<br />
lcd.print(&#8220;Select Mode&#8221;);<br />
button();<br />
mode = mode_change(in[0],in[2], in[3]);<br />
break;<br />
}<br />
case 1:<br />
{<br />
button();<br />
Mode_1();<br />
lcd_cursor_mode1();<br />
break;<br />
}<br />
case 2:<br />
{<br />
button();<br />
Mode_2();<br />
lcd_cursor_mode2();<br />
break;<br />
}<br />
case 3:<br />
{<br />
button();<br />
Mode_3();<br />
lcd_cursor_mode3();<br />
break;<br />
}<br />
default:<br />
{}<br />
}</p>
<p>f_i2c = trans(f_state);<br />
r_i2c = trans(r_state);<br />
out[0] = f_i2c;<br />
out[1] = &#8216;+&#8217;;<br />
out[2] = r_i2c;<br />
out[3] = &#8216;\n&#8217;;<br />
out[4] = &#8221;;<br />
Serial.print(out);<br />
delay(150);<br />
if(mode_temp != mode)<br />
{<br />
lcd.clear();<br />
}<br />
mode_temp = mode;<br />
s_temp = spd;<br />
r_temp = rpm;<br />
}<br />
void lcd_spd()<br />
{</p>
<p>lcd.print(&#8220;SPD:&#8221;);<br />
if(spd&lt;10)<br />
{<br />
lcd.setCursor(5,1);<br />
lcd.print(&#8221; &#8220;);<br />
lcd.setCursor(4,1);<br />
lcd.print(spd);<br />
}<br />
else if(spd&gt;=10)<br />
{<br />
lcd.setCursor(6,1);<br />
lcd.print(&#8221; &#8220;);<br />
lcd.setCursor(4,1);<br />
lcd.print(spd);<br />
}<br />
lcd.setCursor(7,1);<br />
lcd.print(&#8221; RPM:&#8221;);<br />
if(rpm&gt;=10)<br />
{<br />
lcd.setCursor(14,1);<br />
lcd.print(&#8221; &#8220;);<br />
lcd.setCursor(12,1);<br />
lcd.print(rpm);<br />
}<br />
else if(rpm&lt;10)<br />
{<br />
lcd.setCursor(13,1);<br />
lcd.print(&#8221; &#8220;);<br />
lcd.setCursor(12,1);<br />
lcd.print(rpm);<br />
}<br />
else if(rpm&gt;99)<br />
{<br />
lcd.setCursor(12,1);<br />
lcd.print(rpm);<br />
}<br />
}<br />
void lcd_cursor_mode2()<br />
{<br />
//lcd.clear();<br />
lcd.setCursor(0,0);<br />
lcd.print(&#8220;MLM&#8221;);<br />
lcd.print(&#8221; Fr:&#8221;);<br />
lcd.print(f_state);<br />
lcd.print(&#8220;, Rr:&#8221;);<br />
lcd.print(r_state);<br />
lcd.setCursor(0,1);<br />
lcd_spd();<br />
}<br />
void lcd_cursor_mode1()<br />
{<br />
lcd.setCursor(0,0);<br />
lcd.print(&#8220;ATM&#8221;);<br />
lcd.print(&#8221; Fr:&#8221;);<br />
lcd.print(f_state);<br />
lcd.print(&#8220;, Rr:&#8221;);<br />
lcd.print(r_state);<br />
lcd.setCursor(0,1);<br />
lcd.print(&#8220;SPD:&#8221;);<br />
lcd.print(spd);<br />
lcd.print(&#8221; RPM:&#8221;);<br />
lcd.print(rpm);<br />
lcd_spd();</p>
<p>}<br />
void lcd_cursor_mode3()<br />
{<br />
lcd.setCursor(0,0);<br />
lcd.print(&#8220;OFM&#8221;);<br />
lcd.print(&#8221; Fr:&#8221;);<br />
lcd.print(f_state);<br />
lcd.print(&#8220;, Rr:&#8221;);<br />
lcd.print(r_state);<br />
lcd.setCursor(0,1);<br />
lcd.print(&#8220;SPD:&#8221;);<br />
lcd.print(spd);<br />
lcd.print(&#8221; RPM:&#8221;);<br />
lcd.print(rpm);<br />
lcd_spd();</p>
<p>}<br />
void button()<br />
{<br />
// int in[4] = {0};<br />
int i = 0;<br />
for(i=0;i&lt;4;i++)<br />
{<br />
in[i] = digitalRead(10+i);<br />
}<br />
if((in[0] == 1) &amp;&amp; (in[2] == 1))<br />
{<br />
mode = 0;<br />
}<br />
}</p>
<p>char trans(int state)<br />
{<br />
switch(state)<br />
{<br />
case 1:<br />
{<br />
return &#8217;1&#8242;;<br />
}<br />
case 2:<br />
{<br />
return &#8217;2&#8242;;<br />
}<br />
case 3:<br />
{<br />
return &#8217;3&#8242;;<br />
}<br />
case 4:<br />
{<br />
return &#8217;4&#8242;;<br />
}<br />
case 5:<br />
{<br />
return &#8217;5&#8242;;<br />
}<br />
case 6:<br />
{<br />
return &#8217;6&#8242;;<br />
}<br />
case 7:<br />
{<br />
return &#8217;7&#8242;;<br />
}<br />
default:<br />
{<br />
return &#8217;0&#8242;;<br />
}<br />
}<br />
}</p>
<p>int mode_change(int in1, int in2, int in3)<br />
{<br />
if(in1 == 1)<br />
{<br />
return 1;<br />
}<br />
if(in2 == 1)<br />
{<br />
return 2;<br />
}<br />
if(in3 == 1)<br />
{<br />
return 3;<br />
}<br />
}<br />
int Mode_1()<br />
{<br />
if(accel.x &lt; 15 &amp;&amp; accel.x&gt;=0)<br />
{</p>
<p>if(spd != 0 &amp;&amp; rpm &lt; 30)<br />
{<br />
spd = s_temp;<br />
rpm = r_temp;<br />
}</p>
<p>if(spd &gt;=0 &amp;&amp; spd&lt;=15)<br />
{<br />
if(rpm&lt;=30)<br />
{<br />
mode_state = 1;<br />
}<br />
else if(rpm &gt;30 &amp;&amp; rpm&lt;=60)<br />
{<br />
mode_state = 2;<br />
}<br />
else if(rpm &gt; 60 &amp;&amp; rpm&lt;= 90)<br />
{<br />
mode_state = 3;<br />
}<br />
}<br />
else if(spd &gt;15 &amp;&amp; spd&lt;=25)<br />
{<br />
if(rpm&lt;=30)<br />
{<br />
mode_state = 4;<br />
}<br />
else if(rpm &gt;30 &amp;&amp; rpm&lt;=60)<br />
{<br />
mode_state = 5;<br />
}<br />
else if(rpm &gt; 60 &amp;&amp; rpm&lt;= 90)<br />
{<br />
mode_state = 6;<br />
}<br />
else if(rpm &gt;90 &amp;&amp; rpm &lt;= 120)<br />
{<br />
mode_state = 7;<br />
}<br />
}<br />
else if(spd &gt; 25)<br />
{<br />
if(rpm&lt;=30)<br />
{<br />
mode_state = 8;<br />
}<br />
else if(rpm &gt;30 &amp;&amp; rpm&lt;=60)<br />
{<br />
mode_state = 9;<br />
}<br />
else if(rpm &gt; 60 &amp;&amp; rpm&lt;= 90)<br />
{<br />
mode_state = 10;<br />
}<br />
else if(rpm &gt;90 &amp;&amp; rpm &lt;= 120)<br />
{<br />
mode_state = 11;<br />
}<br />
}<br />
}<br />
else if(accel.x &gt;15)<br />
{<br />
if(spd &gt;=0 &amp;&amp; spd&lt;=15)<br />
{<br />
if(rpm&lt;=30)<br />
{<br />
mode_state = 1;<br />
}<br />
else if(rpm &gt;30 &amp;&amp; rpm&lt;=60)<br />
{<br />
mode_state = 2;<br />
}<br />
else if(rpm &gt; 60 &amp;&amp; rpm&lt;= 90)<br />
{<br />
mode_state = 3;<br />
}<br />
}<br />
}<br />
else if(accel.x &lt; 0 &amp;&amp; accel.x &gt;-15)<br />
{<br />
if(spd &gt;15 &amp;&amp; spd&lt;=25)<br />
{<br />
if(rpm&lt;=30)<br />
{<br />
mode_state = 4;<br />
}<br />
else if(rpm &gt;30 &amp;&amp; rpm&lt;=60)<br />
{<br />
mode_state = 5;<br />
}<br />
else if(rpm &gt; 60 &amp;&amp; rpm&lt;= 90)<br />
{<br />
mode_state = 6;<br />
}<br />
else if(rpm &gt;90 &amp;&amp; rpm &lt;= 120)<br />
{<br />
mode_state = 7;<br />
}<br />
}<br />
}<br />
switch(mode_state)<br />
{<br />
case 1:<br />
{<br />
f_state = 1;<br />
r_state = 7;<br />
return 0;<br />
}<br />
case 2:<br />
{<br />
f_state = 1;<br />
r_state = 6;<br />
return 0;<br />
}<br />
case 3:<br />
{<br />
f_state = 1;<br />
r_state = 5;<br />
return 0;<br />
}<br />
case 4:<br />
{<br />
f_state = 2;<br />
r_state = 6;<br />
return 0;<br />
}<br />
case 5:<br />
{<br />
f_state = 2;<br />
r_state = 5;<br />
return 0;<br />
}<br />
case 6:<br />
{<br />
f_state = 2;<br />
r_state = 4;<br />
return 0;<br />
}<br />
case 7:<br />
{<br />
f_state = 2;<br />
r_state = 3;<br />
return 0;<br />
}<br />
case 8:<br />
{<br />
f_state = 3;<br />
r_state = 5;<br />
return 0;<br />
}<br />
case 9:<br />
{<br />
f_state = 3;<br />
r_state = 4;<br />
return 0;<br />
}<br />
case 10:<br />
{<br />
f_state = 3;<br />
r_state = 3;<br />
return 0;<br />
}<br />
case 11:<br />
{<br />
f_state = 3;<br />
r_state = 2;<br />
return 0;<br />
}<br />
default:<br />
{<br />
}<br />
}<br />
}</p>
<p>void Mode_2()<br />
{<br />
int j=0;<br />
if(after[0] != 1)<br />
{<br />
if(in[2] == 1 &amp;&amp; r_state &lt; 7)<br />
{<br />
r_state += 1;<br />
}<br />
}<br />
if(after[1] != 1)<br />
{<br />
if(in[3] == 1 &amp;&amp; r_state &gt;1 )<br />
{<br />
r_state -= 1;<br />
}<br />
}<br />
if(after[2] != 1)<br />
{<br />
if(in[0] == 1 &amp;&amp; f_state &lt; 3)<br />
{<br />
f_state += 1;<br />
}<br />
}<br />
if(after[3] != 1)<br />
{<br />
if(in[1] == 1 &amp;&amp; f_state &gt; 1)<br />
{<br />
f_state -= 1;<br />
}<br />
}</p>
<p>for(j=0;j&lt;4;j++)<br />
{<br />
before[j] = in[j];<br />
after[j] = before[j];<br />
}<br />
}<br />
int Mode_3()<br />
{<br />
int Read1 = digitalRead(r_up);<br />
int Read2 = digitalRead(r_down);</p>
<p>if(m_after1 != 1)<br />
{<br />
if((mode_state &lt; 21) &amp;&amp; (in[2] == 1))<br />
{<br />
mode_state += 1;<br />
}<br />
}<br />
if(m_after2 != 1)<br />
{<br />
if((mode_state &gt; 1) &amp;&amp; (in[3] == 1))<br />
{<br />
mode_state -= 1;<br />
}<br />
}<br />
m_after1 = in[2];<br />
m_after2 = in[3];</p>
<p>switch(mode_state)<br />
{<br />
case 1:<br />
{<br />
f_state = 1;<br />
r_state = 7;<br />
return 0;<br />
}<br />
case 2:<br />
{<br />
f_state = 1;<br />
r_state = 6;<br />
return 0;<br />
}<br />
case 3:<br />
{<br />
f_state = 1;<br />
r_state = 5;<br />
return 0;<br />
}<br />
case 4:<br />
{<br />
f_state = 2;<br />
r_state = 6;<br />
return 0;<br />
}<br />
case 5:<br />
{<br />
f_state = 2;<br />
r_state = 5;<br />
return 0;<br />
}<br />
case 6:<br />
{<br />
f_state = 2;<br />
r_state = 4;<br />
return 0;<br />
}<br />
case 7:<br />
{<br />
f_state = 2;<br />
r_state = 4;<br />
return 0;<br />
}<br />
case 8:<br />
{<br />
f_state = 3;<br />
r_state = 5;<br />
return 0;<br />
}<br />
case 9:<br />
{<br />
f_state = 3;<br />
r_state = 4;<br />
return 0;<br />
}<br />
case 10:<br />
{<br />
f_state = 3;<br />
r_state = 3;<br />
return 0;<br />
}<br />
case 11:<br />
{<br />
f_state = 3;<br />
r_state = 2;<br />
return 0;<br />
}<br />
default:<br />
{<br />
}<br />
}<br />
}<br />
void speed_sens(float in1, float in2)<br />
{<br />
accel.read();<br />
swval = digitalRead(swpin);<br />
swval2 = digitalRead(swpin2);<br />
if(((oldswval2 == LOW) &amp;&amp; (swval2 == HIGH)))<br />
{<br />
time = millis();<br />
delta = millis() &#8211; oldtime;<br />
//26&#8243; * 25.4 * 3.141592 = 2.074m, 0.002174 km;<br />
// * 3600 = 7446.4 km/s<br />
in1 = 7600 / (float)delta;<br />
oldtime = time;<br />
// Serial.print((int)spd + &#8220;+&#8221; + (int)spd2);<br />
}<br />
if((oldswval == LOW) &amp;&amp; (swval == HIGH))<br />
{<br />
time2 = millis();<br />
delta2 = millis() &#8211; oldtime2;<br />
in2 = ((1.0 / (float)delta2) * 60000);<br />
oldtime2 = time2;<br />
}<br />
// if((spd != 0 || spd2 != 0) &amp;&amp; ((temp1 != spd )|| (temp2 != spd2)))<br />
//{<br />
// sprintf(buf, &#8220;%3ld+%3ld&#8221;, (long)spd, (long)spd2);<br />
// Serial.println(buf);<br />
// Serial.print(buf);<br />
//}</p>
<p>oldswval = swval;<br />
oldswval2 = swval2;<br />
temp1 = in1;<br />
temp2 = in2;<br />
}</p>
</div></div>
<p>&nbsp;</p>
<p><span style="color: #339966"><strong>5.2. REAR CODE</strong></span></p>
<div class="symple-toggle"><h3 class="symple-toggle-trigger"><strong>REAR CODE</strong></h3><div class="symple-toggle-container">
<p>&nbsp;</p>
<p>#include &lt;String.h&gt;</p>
<p>char Recv[5]={};<br />
byte rearD = 0&#215;02;<br />
byte frontD = 0&#215;01;<br />
int frontAngle, rearAngle = 0;<br />
char front_n,rear_n = &#8217;1&#8242;;<br />
char temp_f, temp_r = &#8217;1&#8242;;<br />
unsigned long time,time2, oldtime,oldtime2, delta,delta2;<br />
float spd,spd2 = 0;<br />
float temp1, temp2 =0;<br />
int swpin=8,swpin2=9, swval=0,swval2=0, oldswval=0,oldswval2=0;<br />
char buf[7] = {0};<br />
void setup() {</p>
<p>pinMode(2, OUTPUT);<br />
pinMode(swpin,INPUT);<br />
pinMode(swpin2,INPUT);<br />
digitalWrite(2,LOW);</p>
<p>Serial.begin(9600);<br />
Serial1.begin(1000000);<br />
Serial2.begin(1000000);</p>
<p>}<br />
//400 1단 , 540 7단<br />
void loop() {<br />
int i=0;<br />
while(Serial.available())<br />
{<br />
char data = SW.read();<br />
Recv[i] = data;<br />
i++;<br />
}<br />
change_value_f();<br />
change_value_r();<br />
Packet1(0&#215;01,frontAngle);<br />
Packet2(0&#215;01,rearAngle);</p>
<p>swval = digitalRead(swpin);<br />
swval2 = digitalRead(swpin2);<br />
if(((oldswval2 == LOW) &amp;&amp; (swval2 == HIGH)))<br />
{<br />
time = millis();<br />
delta = millis() &#8211; oldtime;<br />
//26&#8243; * 25.4 * 3.141592 = 2.074m, 0.002174 km;<br />
// * 3600 = 7446.4 km/s<br />
spd = 7600 / (float)delta;<br />
oldtime = time;<br />
}<br />
if((oldswval == LOW) &amp;&amp; (swval == HIGH))<br />
{<br />
time2 = millis();<br />
delta2 = millis() &#8211; oldtime2;<br />
spd2 = ((1.0 / (float)delta2) * 60000);<br />
oldtime2 = time2;<br />
}<br />
if((spd != 0 || spd2 != 0) &amp;&amp; ((temp1 != spd )|| (temp2 != spd2)))<br />
{<br />
sprintf(buf, &#8220;%3ld+%3ld&#8221;, (long)spd, (long)spd2);<br />
Serial.print(buf);<br />
}</p>
<p>oldswval = swval;<br />
oldswval2 = swval2;<br />
temp1 = spd;<br />
temp2 = spd2;<br />
delay(50);</p>
<p>}</p>
<p>void Packet1(unsigned char ID, int Angle)<br />
{<br />
unsigned char Check_Sum, Header = 0xFF;</p>
<p>Serial1.write(Header);<br />
Serial1.write(Header);<br />
Serial1.write(ID); // Motor ID<br />
Serial1.write(0&#215;05); // Data legnth<br />
Serial1.write(0&#215;03); // Instruction<br />
Serial1.write(0x1E); // Goal Position<br />
Serial1.write(Angle); // Set Goal Position<br />
Serial1.write(Angle&gt;&gt;8); //Clear Goal position 8bit<br />
Check_Sum = ~(ID + 0&#215;05 + 0&#215;03 + 0x1E + Angle + (Angle&gt;&gt;8)); // Send Data Error Check<br />
Serial1.write(Check_Sum);<br />
}<br />
void change_value_r()<br />
{<br />
if(rear_n != Recv[2])<br />
{<br />
rearAngle = rear_transferid(Recv[2]);<br />
}<br />
else<br />
{<br />
rearAngle = rear_transferid(rear_n);<br />
}<br />
//temp_r = rear_n;<br />
rear_n = Recv[2];<br />
// Recv[2] = temp_r;<br />
}</p>
<p>void change_value_f()<br />
{<br />
if(front_n != Recv[0])<br />
{<br />
frontAngle = front_transferid(Recv[0]);<br />
}<br />
else<br />
{<br />
frontAngle = front_transferid(front_n);<br />
}<br />
temp_f = front_n;<br />
front_n = Recv[0];<br />
// Recv[0] = temp_f;<br />
}<br />
void Packet2(unsigned char ID, int Angle)<br />
{<br />
unsigned char Check_Sum, Header = 0xFF;</p>
<p>Serial2.write(Header);<br />
Serial2.write(Header);<br />
Serial2.write(ID); // Motor ID<br />
Serial2.write(0&#215;05); // Data legnth<br />
Serial2.write(0&#215;03); // Instruction<br />
Serial2.write(0x1E); // Goal Position<br />
Serial2.write(Angle); // Set Goal Position<br />
Serial2.write(Angle&gt;&gt;8); //Clear Goal position 8bit<br />
Check_Sum = ~(ID + 0&#215;05 + 0&#215;03 + 0x1E + Angle + (Angle&gt;&gt;8)); // Send Data Error Check<br />
Serial2.write(Check_Sum);<br />
}<br />
void Default(unsigned char ID1)<br />
{<br />
Packet1(ID1, 512);<br />
delay(250);<br />
}<br />
int rear_transferid(char a)<br />
{<br />
switch(a){<br />
case &#8217;1&#8242;: {return 440;}<br />
case &#8217;2&#8242;: {return 500;}<br />
case &#8217;3&#8242;: {return 520;}<br />
case &#8217;4&#8242;: {return 540;}<br />
case &#8217;5&#8242;: {return 580;}<br />
case &#8217;6&#8242;: {return 610;}<br />
case &#8217;7&#8242;: {return 700;}<br />
default : {return 480;}<br />
}<br />
}</p>
<p>int front_transferid(char a)<br />
{<br />
switch(a){<br />
case &#8217;1&#8242;: {return 250;}<br />
case &#8217;2&#8242;: {return 530;}<br />
case &#8217;3&#8242;: {return 690;}<br />
default : {}<br />
}<br />
}</p>
<p>void First_front()<br />
{<br />
Packet1(0&#215;01,512);<br />
}<br />
void Second_front()<br />
{<br />
Packet1(0&#215;01,1023);<br />
delay(500);<br />
Packet1(0&#215;01,750);<br />
}<br />
void Third_front()<br />
{<br />
Packet1(0&#215;01,1023);<br />
}</p>
</div></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/33398/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[41호]Silence Quadcopter (Rotor&#8217;s Noise Canceling Quadcopter)</title>
		<link>http://www.ntrexgo.com/archives/33388</link>
		<comments>http://www.ntrexgo.com/archives/33388#comments</comments>
		<pubDate>Sat, 25 Mar 2017 00:00:12 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[41호]]></category>
		<category><![CDATA[Feature]]></category>
		<category><![CDATA[ict]]></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=33388</guid>
		<description><![CDATA[디바이스마트 매거진 41호 &#124; 조용한 쿼드콥터 즉, 로터의 소음을 없애(로터 소리의 역 주파수의 소리를 내보내어 상쇄시켜) 로터의 소리를 최소화 시킨 쿼드콥터이다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain.png" rel="lightbox[33388]"><img class="alignnone size-large wp-image-31056" alt="2016 ictmain" src="http://www.ntrexgo.com/wp-content/uploads/2016/05/2016-ictmain-620x156.png" width="620" height="156" /></a></p>
<p><span style="font-size: large"><strong>2016 ICT 융합 프로젝트 공모전 입선</strong></span></p>
<p><span style="font-size: x-large"><strong>Silence Quadcopter<span style="font-size: small">(Rotor&#8217;s Noise Canceling Quadcopter)</span></strong></span></p>
<p>&nbsp;</p>
<p style="text-align: right"><strong>글 | 단국대학교 정의동, 최진우</strong></p>
<p>&nbsp;</p>
<p><span style="color: #008000"><strong>심사평</strong></span></p>
<p><strong><span style="color: #008000">JK전자</span> </strong>현재 무인 항공기(드론)는 성능(기능), 안정성, 배터리 지속력에 초점이 맞추어져 개발이 진행되고 있는 것이 사실이다. 언젠가는 무인 항공기가 어느 정도 성능을 갖추고 실생활에 사용되기 시작하면 소음에 대한 이슈도 분명히 대두될 것이다. 본 작품에서 구현하고 있는 반대 주파수를 이용해서 소음을 감쇠하는 방법 외에도 모터, 프러펠러 개선 등의 다양한 방법으로 소음을 줄이려는 시도가 있을것이다.</p>
<p><span style="color: #008000"><strong>뉴티씨</strong></span> 매우 좋은 작품이며, 특히 DSP를 활용해 FFT 및 IFFT 등을 통하여 원하는 주파수를 찾고 역으로 주파수를 발생시켜 상쇄시키는, 예전에 공중전화 부스 등에서 적용되었던 아이디어를 개선해 현재의 실용적인 부분에서 적용한 점이 돋보인다. 드론의 중요성이 커지고있는 이 때에, 조용한 드론을 만들어야 하는 필요성도 매우 높아질 것으로 예상되는 바, 이 때문에 좋은 점수를 받았으며, 실제 일부 성공한 점 등도 좋은 점수를 받았다. 앞으로 더 연구에 매진하여 만점짜리 결과가 나오기를 바란다.</p>
<p><span style="color: #008000"><strong>칩센</strong></span> 재미있는 주제에 노이즈캔슬링 원리를 잘 적용하였다. 다른 분야에도 시도를 해보면 좋을 것 같다.</p>
<p><strong><span style="color: #008000">위드로봇</span> </strong>드론의 뜻이 원래 시끄럽게 붕붕거리다는 뜻인데, 이 소리를 없애는데 관심을 가진 재미있는 아이디어가 돋보이는 작품입니다. 노이즈 캔슬레이션 알고리즘을 좀 더 깊이 공부하고, 이를 구현했더라면 더 나은 결과가 나왔을 것 같습니다. 또한 정량적인 평가를 위해 노이즈를 측정할 수 있는 방법이 별도로 필요해 보입니다. 창의성과 기대효과 측면에 높은 점수를 드립니다.</p>
<p><strong><span style="color: #008000">1. 작품제목</span></strong><br />
작품의 제목은 Silence Quadcopter(Rotor&#8217;s Noise Canceling Quadcopter)입니다. 제목을 해석해 보자면 조용한 쿼드콥터 즉, 로터의 소음을 없애(로터 소리의 역 주파수의 소리를 내보내어 상쇄시켜) 로터의 소리를 최소화시킨 쿼드콥터라는 뜻입니다.</p>
<p><strong><span style="color: #008000">2. 작품 개요</span> </strong><br />
현재 드론(쿼드콥터, X콥터, UAV 등의 총칭) 분야는 중국, 미국 등의 방대한 투자 및 개발에 힘입어 더 이상의 발전은 없을 것이라 생각할 정도로 성장해 왔습니다. 하지만 그에 반해 몇몇 작지 않은 문제점들도 발견되었습니다. 그 중에서 크게 네 가지를 꼽아 보았습니다.</p>
<p>첫째, 안전 문제가 있습니다. 드론을 접해본 사람이라면 누구나 프로펠러의 위험성을 느낄 수 있습니다. 그리하여 만약, 드론이 비행 도중 주변의 물체 또는 사람 등과 부딪힐 경우 큰 사고로 번질 위험이 있습니다.</p>
<p>둘째, 최근 들어 크게 대두가 되고 있는 보안 및 사생활 문제가 있습니다. 드론 촬영을 하는 경우, 허가받지 않은 장소 촬영 또는 허가받지 않은 상태에서의 다른 사람 촬영 등은 사생활 침해 및 초상권 침해 등 법적인 문제를 야기할 수 있습니다. 또한 드론 관련 법안이 제대로 나와있지 않은 현재로서는 큰 문제를 야기할 수 있습니다.</p>
<p>셋째, 소음 문제가 있습니다. 드론을 접해 보았거나 드론에 가까이 가본 사람이라면 누구나 느낄 수 있는 것이 소리가 너무 크다는 것입니다. 드론산업 및 드론 취미가 많이 급증하고 있는 현재, 이 소음문제는 앞으로 더욱 커질 전망입니다.</p>
<p>넷째, 배터리 문제가 있습니다. 드론의 가장 큰 문제 중 하나로 생각되는 것이 바로 배터리 문제입니다. 완충 기준 거의 대부분의 드론들은 비행시간이 30분을 넘기지 못하고 있습니다.<br />
이러한 네 가지 문제를 해결하기 위해, 안전 문제는 물체 감지 및 정확한 제어 등으로 해결하고 있는 추세이고, 보안 및 사생활 문제는 법안이 만들어지고 있으며, 배터리 문제는 기업들의 배터리 개발 등으로 해결하고는 있지만 한계가 있을 것으로 보입니다. 반면 소음문제는 아직 전혀 해결되지 않고 있습니다.</p>
<p>그래서 소음 문제를 해결하기 위해 생각해낸 것이 ‘로터(모터 + 프로펠러) 소리의 반대되는 주파수로 상쇄시킴으로서 소음 문제를 해결하자’ 라는 것이고, 배터리 문제를 해결하기 위해 ‘모터에 자가 동력장치(주로 자전거 바퀴에 많이 설치되어 야간조명 등에 이용됨)를 설치하여 비행과 동시에 충전이 가능하게 설계를 하자’ 라는 것입니다.</p>
<p>처음 프로젝트 목표는 소음 및 배터리 문제, 이 두 가지를 해결하자는 것이었지만 자가 동력장치를 추가하면 결국에는 그 만큼의 모터 출력을 더 요구하게 되어 즉, 에너지 보존법칙에 의해 충전되는 양 이상의 에너지를 필요로 하기 때문에 효율성이 떨어지게 되어 배터리 문제는 좀 더 고민을 해보고, 우선 소음 문제부터 해결하기로 목표를 수정하였습니다.</p>
<p><span style="color: #008000"><strong>3. 작품 설명</strong></span><br />
<span style="color: #339966"><strong>3.1 주요 동작 및 특징</strong></span><br />
이 작품은 기존의 쿼드콥터에 로터의 소음을 없애는 기능을 추가시킨 쿼드콥터 입니다. 그래서 이 쿼드콥터는 크게 두 부분으로 나눌 수 있습니다. 하나는 제어부, 다른 하나는 센서부입니다.</p>
<p>우선 전체적인 하드웨어를 살펴보면 CPU + 제어부(모터, 프로펠러, ESC) + 센서부(마이크센서, 사운드센서, 증폭기, 핀 확장 소자, DAC 변환 소자) + 배터리 + 프레임으로 이루어져 있습니다.</p>
<p>소프트웨어를 살펴보면, 제어부 소스는 소스가 매우 짧고 간결하게 짜여 있다는 것을 알 수 있습니다. 외부 인터럽트를 이용해 주기적으로 모터 제어를 할 수 있게 하였는데, 모터 제어는 PID 제어 방식을 이용하였습니다. PID 오픈 소스들을 살펴보면 너무 자료가 많고, 다 다르고, 소스의 크기 또한 작지 않아 최대한 간편히 코딩을 해 보았습니다.</p>
<p>기본적인 개념인 P = 비례, I &#8211; 적분, D &#8211; 미분을 이용하여 PID 값 = (현재각도 * P게인값) + {이전 적분 누적값 + (I게인값 * 현재각도 * 0.01)} + {D게인값 * (현재각도 &#8211; 이전각도)} 이라는 공식을 세우고 그에 맞게 소스를 구현했습니다. 그리고 Roll 축, Pitch 축의 각도 값은 10개를 평균내 사용하였는데 그 이유는 최대한 쓰레기 값을 버리고, 최대한 정밀한 값을 사용하게 하기 위해서입니다. 예를 들어 10개의 각도값이 차례로 10 12 13 15 16 16 18 195 19 20 일때 18에서 195로 넘어가는 각도값의 차이는 177입니다. 하지만 10개의 각도를 평균내 사용하면 33.4 &#8211; 18 = 15.4로 오류를 최소한으로 줄일 수 있게 됩니다. P, I, D의 각 게인값 들은 직접 시소 테스트, 호버링 테스트 등을 하며 맞추었고, 외부 인터럽트의 주기는 가장 적합한 주기 네 가지 1ms, 2ms, 10ms, 20ms를 구상하여 테스트를 해 그 중에서도 가장 적합한 주기 20ms를 찾았습니다.</p>
<p>IMU 세 축 Yaw 축, Roll 축, Pitch 축 중 Pitch 축, Roll 축은 PID제어를 사용하였고, Yaw 축은 PI제어를 사용하였는데 Yaw 축만 다른 두 축과는 다르게 PI 제어를 사용한 이유는 Roll, Pitch 제어로 맞춘 평행을 Yaw 축 제어를 하면서 너무 많은 값이 더해지게 될 수 있는데, 이를 아래 예시를 통해 설명하겠습니다.</p>
<p>ex) 1motor_pwm = input_pwm + Pitch_pid_result + Yaw_pid_result 일 때 input_pwm은 공통이고, Pitch_pid_result는 맞추었다면 그 상태에서 Yaw_pid_result의 값이 너무 커지거나 너무 작아지게 되면 전체 pwm인 1motor_pwm의 값의 변화가 너무 커지게 됩니다. 그 결과 전체적인 자세제어에 문제가 생기게 되어 비행하는데 영항을 끼치게 되므로 영향을 최대한 덜 미치면서 방향 제어를 할 수 있는 제어 방식을 추구하다 보니 PI 제어가 가장 적합하다 생각하였습니다. 또한, Yaw 축 소스만은 Roll, Pitch 소스와는 다른 부분인</p>
<p>if(yawcnt == 1) yawerr = g_iq17yaw;<br />
else ;</p>
<p>라는 부분이 있는데 이는 초기 yaw 각도 값이 너무 크거나 작을 경우 모터 출력에 영향을 주게 되어 그것을 막기 위해 초기 에러 각도 값을 지정해 주어 각도에다 그 에러 값을 빼주어 현재 각도 값을 산출해 이용했습니다.</p>
<p>PID 게인 값을 맞춘 과정은 따로 설명을 하지 않았는데, 0부터 0.1 또는 0.01씩을 올려가며 자세 안정의 수렴, 발산 등을 맞추어 준 것입니다.<br />
그리고 쿼드콥터의 형태는 +형태로 하였습니다. +형태, x형태 둘 중 어떤 방식으로 할까 고민하다가 보다 테스트하기 간편하고, 그러면서 자세제어가 정확한 +형태로 하였습니다. +형태는 4개의 로터에 Yaw 축 제어가 공통으로 들어가 있는 상태에서 각각 대칭으로 한 쌍은 Pitch 축 제어, 또 다른 한 쌍은 Roll 축 제어를 하게 하여 각 모터 당 Yaw 축을 제외하고 하나의 축만을 제어해 테스트에 용이하였고, 한 축을 하나의 모터로만 제어하는 것에 비해 자세제어가 안정적으로 잘 되었습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-04-284.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33512" alt="Cap 2017-05-30 10-34-04-284" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-04-284.jpg" width="620" height="355" /></a></p>
<p>센서부 소스는 제어부 소스에 비해 소스의 길이가 상당히 길다는 점을 알 수 있습니다. 우선 센서부도 제어부와 마찬가지로 외부 인터럽트를 써서 센서 adc 값을 받아들이고, FFT 변환을 하고, 변환된 값의 반대되는 값을 보냅니다. FFT 변환 소스는 paulbourke.net에 있는 DFT &#8211; FFT 이론을 바탕으로 짜여진 것이고, 그 소스를 가져와 수정해 사용했습니다.</p>
<p>FFT는 Fast Fourier Transform 즉, 고속 푸리에 변환으로서 DFT (Discrete Fourier Transform &#8211; 이산 푸리에 변환)의 고속 모드라고 생각하면 될 것 같습니다. FFT에 대해 좀 더 자세히 설명을 해 보자면 FFT는 시간영역에서 변화하는 데이터 값을 주파수 영역에서의 데이터 값으로 변환시켜주는 알고리즘입니다. 즉, 보는 관점을 시간영역에서 주파수 영역으로 바꿔주어 값을 사용하는 것입니다.</p>
<p>그럼 왜 관점을 시간관점에서 주파수관점으로 바꿔서 계산을 하느냐하면, 우선 소리란 물체의 진동에 의하여 생긴 음파가 귀청을 울리어 귀에 들리는 것이라고 사전에 정의되어 있습니다. 즉, 소리는 진동수에 의해 크기가 결정되고, 진폭에 의해 세기가 결정됩니다. 그렇기 때문에 단위를 시간에서 주파수로 바꾸어준 후 그 값에 반대되는 값을 계산하고, 이를 다시 시간단위로 바꾼 후에 DAC변환을 통해 소리로 출력을 해야 하는 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-10-235.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33513" alt="Cap 2017-05-30 10-34-10-235" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-10-235.jpg" width="620" height="355" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-14-468.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33514" alt="Cap 2017-05-30 10-34-14-468" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-14-468.jpg" width="620" height="355" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-20-335.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33515" alt="Cap 2017-05-30 10-34-20-335" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-20-335.jpg" width="620" height="355" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-28-668.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33516" alt="Cap 2017-05-30 10-34-28-668" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-28-668.jpg" width="620" height="389" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-42-801.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33517" alt="Cap 2017-05-30 10-34-42-801" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-34-42-801.jpg" width="620" height="389" /></a></p>
<p>전체적인 신호처리 과정을 대략적으로 설명하자면, MIC센서를 이용한 아날로그값 받기 ▶ DAC변환소자를 이용한 디지털값으로 변환 ▶ 변환된 디지털값을 FFT 및 RFFT(Reverse FFT)처리 ▶ IFFT(Inverse FFT)처리 ▶ 디지털값 출력 ▶ DAC컨버터 구축 ▶ 아날로그값 변환 및 출력 ▶ 사운드센서로 소리 출력입니다. 여기서 RFFT는 말 그대로 FFT를 역 변환 해주는 것이고, IFFT는 FFT의 반대 즉, 시간 영역에서 주파수 영역으로 바뀌었던 데이터를 반대로 주파수 영역에서 시간 영역으로 바꿔주는 것을 의미합니다. 소리를 출력하여 로터의 소음과 상쇄시킨 결과 완벽히 소음이 줄지는 않았으나, 누가 봐도 소음이 줄었다는 것을 느낄 수 있을 정도까지는 되었습니다. 그래서 현재는 조금씩 주기, 출력 시간을 조정해가며 테스트하고 있습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-36-37-851.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33518" alt="Cap 2017-05-30 10-36-37-851" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-36-37-851.jpg" width="620" height="430" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-37-45-252.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33519" alt="Cap 2017-05-30 10-37-45-252" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-37-45-252.jpg" width="620" height="315" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-37-52-734.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33520" alt="Cap 2017-05-30 10-37-52-734" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-37-52-734.jpg" width="620" height="315" /></a></p>
<p><span style="color: #339966"><strong>3.2 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-00-568.png" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33521" alt="Cap 2017-05-30 10-38-00-568" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-00-568.png" width="620" height="455" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-10-334.png" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33522" alt="Cap 2017-05-30 10-38-10-334" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-10-334.png" width="620" height="430" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-16-352.png" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33523" alt="Cap 2017-05-30 10-38-16-352" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-16-352.png" width="619" height="430" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #339966"><strong>3.3 개발 환경(개발언어, Tool, 사용시스템 등)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-34-651.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33524" alt="Cap 2017-05-30 10-38-34-651" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-34-651.jpg" width="619" height="509" /></a></p>
<p><span style="color: #33cccc"><strong>언어 &#8211; C언어</strong></span><br />
개발 Tool에서 쓰이는 언어가 C언어이기 때문에, 자연스레 C언어를 이용하여 코딩 및 소스구현을 하게 되었습니다.</p>
<p><span style="color: #33cccc"><strong>Tool &#8211; Source Insight (Dsp전용 디버깅 프로그램)</strong></span><br />
DSP를 다룰 수 있는 툴을 찾다보니 Source Insight가 주변에 사용해 보았던 사람이 많아 쉽게 접근할 수 있었습니다.</p>
<p><span style="color: #33cccc"><strong>시스템 &#8211; DSP(tms320f2809, 제조사 : Texas Instrument)</strong></span><br />
DSP를 선정하게 된 이유는 많은 핀들을 보유함과 동시에 PWM이 잘 되고 처리속도가 빠른며 싼 값에 구할 수 있는 MCU를 찾다보니 DSP가 라즈베리파이, 아두이노, ATmega, 망고보드, cortex 시리즈 등 여러 MCU 중에서 가장 적합하다고 생각해서 메인 MCU로 선정을 하게 되었습니다.</p>
<p><span style="color: #33cccc"><strong>시스템 &#8211; 라즈베리파이2(Model B)</strong></span><br />
라즈베리파이를 선정하게 된 이유는 900MHz의 빠른 속도와, 1GB의 넉넉한 램 용량, 저렴한 가격 및 많은 GPIO 핀을 보유하고 있어서입니다. 물론 신호처리에 최적화된 DSP에 비해서는 살짝 부족하고 ADC 핀도 없어 불편한 감이 있기는 하지만, 모터 제어를 하는 동시에 신호처리를 하기 위해서는 두 개 이상의 MCU를 써야하는데 DSP를 메인 MCU로 쓰고 있기 때문에 서브 MCU로는 괜찮다고 생각된 라즈베리 파이를 선정하였습니다.</p>
<p><span style="color: #008000"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #339966"><strong>4.1. 계획 세우기 및 사전조사</strong></span><br />
프로젝트 주제를 정하고 그에 대한 사전조사를 인터넷 및 관련 사람들을 대상으로 조사하여 문제점, 주요특징, 앞으로의 전망 등을 충분히 조사하였습니다.</p>
<p><span style="color: #339966"><strong>4.2. 해당 작품 공부 및 제작 준비</strong></span><br />
쿼드콥터라는 것을 처음 해본만큼, 먼저 제작을 해 보았던 선배님들이나 RC 동호회 사람들, 인터넷 등을 이용해 작품 공부를 하였고, 필요한 부품 및 기자재 등을 준비하였습니다.</p>
<p><span style="color: #339966"><strong>4.3. 하드웨어 제작</strong></span><br />
기본적인 하드웨어(대각선길이-28cm)를 제작하였고, 블루투스 모듈(HC-06), 9축 센서(EBIMU-9DOF), BLDC모터(제조사-hobbyking), 변속기(제조사-hobbywing), MCU(DSP-tms320f2809) 등 각종 센서, 모터, cpu 등을 테스트 해 보았습니다.</p>
<p><span style="color: #339966"><strong>4.4. 시소테스트, 호버링 등 구동테스트</strong></span><br />
구동을 하기 위해 제어기(PID 제어 이용)를 설계하여 직접 코딩 및 테스트하여 각의 게인값들을 맞추고, 9축센서와 CPU 및 PC를 연동시켜 각 축(Roll, Pitch, Yaw)에 대한 제어가 잘 되는지 시소테스트(Roll, Pitch 축)와 줄 매달아놓고 테스트(Yaw 축), 그리고 호버링 테스트를 하면서 확인 및 수정 하였습니다.</p>
<p><span style="color: #339966"><strong>4.5. 마이크센서와 라즈베리파이와 스피커센서를 거친 신호처리</strong></span><br />
로터(모터 + 프로펠러) 근처에 스피커센서를 두어 로터의 소리의 값을 받아와 라즈베리파이의 ADC핀(ADC변환소자 이용)에 연결 및 디지털 데이터를 뽑아냈고, FFT(Fast Fourier Transform) 알고리즘을 거쳐 변환 데이터를 걸러낸 후 그에 반대되는 위상을 가진 역 주파수를 계산 및 출력해 냈으며, DAC과정(CPU의 GPIO핀과 핀 확장소자인 74HC595과 증폭기인 UILM358을 이용)을 거쳐 스피커 센서로 소리를 내보내기 위한 센서소스를 직접 짜고, 테스트 및 쿼드콥터에 설치하여 구동테스트를 하였습니다.</p>
<p><span style="color: #339966"><strong>4.6. 안드로이드 연동 및 전체 구동테스트</strong></span><br />
작품에 안드로이드를 올려 PC와 쿼드콥터와의 통신 및 컨트롤이 아닌 핸드폰 등 스마트기기와의 통신 및 컨트롤을 계획하여 앱을 만들고 기능들을 추가하여 편의성을 더할 예정이고, 안드로이드 스튜디오를 이용해 어플리케이션을 만들 생각입니다. 또한, 적외선센서를 이용해 장애물 감지 및 피해가는 알고리즘을 구성할 것이고, 고도센서를 이용해 보다 정확한 자세제어를 할 수 있게 할 것입니다.</p>
<p><span style="color: #008000"><strong>5. 기타(회로도, 소스코드, 참고문헌 등)</strong></span><br />
<span style="color: #339966"><strong>5.1. 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-48-968.jpg" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33525" alt="Cap 2017-05-30 10-38-48-968" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-48-968.jpg" width="620" height="359" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-58-733.png" rel="lightbox[33388]"><img class="alignnone size-full wp-image-33526" alt="Cap 2017-05-30 10-38-58-733" src="http://www.ntrexgo.com/wp-content/uploads/2017/03/Cap-2017-05-30-10-38-58-733.png" width="620" height="277" /></a></p>
<p><span style="color: #339966"><strong>5.2. 소스코드</strong></span><br />
<span style="color: #33cccc"><strong>5.2.1. 제어 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>##############################################################<br />
// FILE : Motor.c<br />
// TITLE : Motor c file.<br />
// Author : Jeong Eui Dong<br />
// Company : Maze &amp; Hz<br />
############################################################<br />
// $Release Date: 2016.02.12 $<br />
############################################################</p>
<p>#define _MOTOR_<br />
#include &#8220;DSP280x_Device.h&#8221;<br />
#include &#8220;DSP280x_Examples.h&#8221; // DSP280x Examples Include File<br />
#include &#8220;Main.h&#8221;<br />
#include &#8220;Motor.h&#8221;<br />
#pragma CODE_SECTION(control_ISR , &#8220;ramfuncs2&#8243;);<br />
//motor interrupt motor pid , Kalmanfilter 구상하기.<br />
interrupt void control_ISR( void )<br />
{<br />
StopCpuTimer0();<br />
//TxPrintf(&#8220;motor_check\n&#8221;);<br />
yawcnt ++ ;<br />
i++;</p>
<p>// g_iq17roll = imu roll, g_iq17pitch = imu pitch , g_iq17yaw = imu yaw<br />
//g_iq17errsum = g_iq17errsum + g_iq17ki * 0.01 * g_iq17angles1;<br />
// g_iq17pidresult = g_iq17kp * 오차 + g_iq17ki * g_iq17errsum + kd * (g_iq17angles1 &#8211; g_iq17angles2); // 오차 = ki * 0.01 * angles1</p>
<p>/////////////////////////////////////////////////////////////////////<br />
//roll, pitch축 제어는 PID제어 사용</p>
<p>Rollerr = _IQ17(-3.0);<br />
Rollnowangle = g_iq17roll &#8211; Rollerr; //Roll</p>
<p>for(i=0; i&lt;9; i++)<br />
Rollangle[i+1] = Rollangle[i];<br />
Rollangle[0] = Rollnowangle;<br />
Rollanglesum = Rollangle[0] + Rollangle[1] + Rollangle[2] + Rollangle[3] + Rollangle[4] + Rollangle[5] + Rollangle[6] + Rollangle[7] + Rollangle[8] + Rollangle[9];<br />
Rollangleresult = _IQ17mpy(Rollanglesum, _IQ17(0.1));<br />
Rollerrsum = Rollerrsum + _IQ17mpy(Rollki, _IQ17mpy(0.01, Rollangleresult));<br />
Rollpidresult = _IQ17mpy(Rollkp, Rollangleresult) + Rollerrsum + _IQ17mpy(Rollkd, (Rollangleresult &#8211; Rollpreangle));<br />
Rollhalf = _IQ17mpy(Rollpidresult,_IQ17(0.5));<br />
Rollpreangle = Rollangleresult;</p>
<p>Pitcherr = _IQ17(1.0);<br />
Pitchnowangle = g_iq17pitch &#8211; Pitcherr; //Pitch</p>
<p>for(i=0; i&lt;9; i++)<br />
Pitchangle[i+1] = Pitchangle[i];<br />
Pitchangle[0] = Pitchnowangle;<br />
Pitchanglesum = Pitchangle[0] + Pitchangle[1] + Pitchangle[2] + Pitchangle[3] + Pitchangle[4] + Pitchangle[5] + Pitchangle[6] + Pitchangle[7] + Pitchangle[8] + Pitchangle[9];<br />
Pitchangleresult = _IQ17mpy(Pitchanglesum, _IQ17(0.1));<br />
Pitcherrsum = Pitcherrsum + _IQ17mpy(Pitchki, _IQ17mpy(0.01, Pitchangleresult));<br />
Pitchpidresult = _IQ17mpy(Pitchkp, Pitchangleresult) + Pitcherrsum + _IQ17mpy(Pitchkd, (Pitchangleresult &#8211; Pitchpreangle));<br />
Pitchhalf = _IQ17mpy(Pitchpidresult,_IQ17(0.5));<br />
Pitchpreangle = Pitchangleresult;</p>
<p>// yaw축 제어는 다른방식 사용 ▶ PI제어 사용 ▶ 최대한 roll, pitch 제어에 영항을 미쳐서는 안된다.</p>
<p>if(yawcnt == 1) Yawerr = g_iq17yaw; //Yaw<br />
else ;<br />
Yawnowangle = g_iq17yaw &#8211; Yawerr;<br />
if(Yawnowangle &gt;= _IQ17(180))<br />
Yawnowangle = Yawnowangle &#8211; _IQ17(360);<br />
if(Yawnowangle &lt; _IQ17(-180))<br />
Yawnowangle = Yawnowangle + _IQ17(360);<br />
Yawerrsum = Yawerrsum + _IQ17mpy(Yawki, _IQ17mpy(0.01, Yawnowangle));<br />
//Yawpidresult = _IQ17mpy(Yawkp, Yawnowangle) + Yawerrsum + _IQ17mpy(Yawkd, (Yawnowangle &#8211; Yawpreangle));<br />
Yawpidresult = _IQ17mpy(Yawkp, Yawnowangle) + Yawerrsum;<br />
Yawpreangle = Yawnowangle;</p>
<p>//운동방향 &#8211; 전진 : front high , 후진 : back high , 우측 : right high , 좌측 : left high , 고도상승 : all high , 고도하강 : all low<br />
//1번 모터 시계 ▶ 반대 red &#8211; yellow<br />
Bldc1pwmRegs.CMPA.half.CMPA = ( ( g_int32pwm_output + ( Pitchpidresult &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16)(g_int32pwm_output + ( Pitchpidresult &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 ) + frontgo); // -<br />
//2번 모터 반시계<br />
Bldc2pwmRegs.CMPA.half.CMPA = ( ( g_int32pwm_output &#8211; ( Rollpidresult &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16) ( g_int32pwm_output &#8211; ( Rollpidresult &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 ) + rightgo); // +<br />
//3번 모터 시계 -&gt; 반대 red &#8211; yellow<br />
EPwm5Regs.CMPA.half.CMPA = ( ( g_int32pwm_output &#8211; ( Pitchpidresult &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16)( g_int32pwm_output &#8211; ( Pitchpidresult &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 ) + backgo); // -<br />
//4번 모터 반시계<br />
EPwm6Regs.CMPA.half.CMPA = ( ( g_int32pwm_output + ( Rollpidresult &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16)( g_int32pwm_output + ( Rollpidresult &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 ) + leftgo); // +</p>
<p>//////////////////////// X-Copter //////////////////////////////</p>
<p>// 4번 ▶ 1번, 3번 ▶ 4번, 2번 ▶ 3번, 1번 ▶ 2번<br />
/*<br />
//1번 모터 반시계 ▶ 반대 red &#8211; yellow 연결 Dir : Front<br />
Bldc2pwmRegs.CMPA.half.CMPA = ( ( g_int32pwm_output &#8211; ( Rollhalf &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 ) + ( Pitchhalf &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16) ( g_int32pwm_output &#8211; ( Rollhalf &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 ) + ( Pitchhalf &gt;&gt; 17 ) + frontgo ); // +</p>
<p>//2번 모터 시계 Dir : Right<br />
// EPwm5Regs.CMPA.half.CMPA = ( ( g_int32pwm_output &#8211; ( Pitchhalf &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 ) &#8211; ( Rollhalf &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16)( g_int32pwm_output &#8211; ( Pitchhalf &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 ) &#8211; ( Rollhalf &gt;&gt; 17 ) + rightgo ); // +</p>
<p>//3번 모터 반시계 ▶ 반대 red &#8211; yellow 연결 Dir : Back<br />
EPwm6Regs.CMPA.half.CMPA = ( ( g_int32pwm_output + ( Rollhalf &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 ) &#8211; ( Pitchhalf &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16)( g_int32pwm_output + ( Rollhalf &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 ) &#8211; ( Pitchhalf &gt;&gt; 17 ) + backgo ); // -</p>
<p>// 4번 모터 시계 Dir : Left<br />
// Bldc1pwmRegs.CMPA.half.CMPA = ( ( g_int32pwm_output + ( Pitchhalf &gt;&gt; 17 ) + ( Yawpidresult &gt;&gt; 17 ) + ( Rollhalf &gt;&gt; 17 )) &gt; 5000 )? (Uint16)5000 : (Uint16)(g_int32pwm_output + ( Pitchhalf &gt;&gt; 17 ) &#8211; ( Yawpidresult &gt;&gt; 17 ) + ( Rollhalf &gt;&gt; 17 ) + leftgo ); // -</p>
<p>*/<br />
//test motor pwm<br />
// EPwm5Regs.CMPA.half.CMPA = g_int32pwm_output;<br />
}<br />
</div>
<p><span style="color: #33cccc"><strong>5.2.2. 센서 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>//라즈베리파이에서는 소스 복사가 안되어 DSP로 테스트한 소스를 올렸다./////##############################################################<br />
// FILE : Sensor.c<br />
// TITLE : Senser c file.<br />
// Author : Jeong Eui Dong<br />
// Company : Maze &amp; Hz<br />
//############################################################<br />
// $Release Date: 2016.02.12 $<br />
//############################################################<br />
#include &#8220;DSP280x_Device.h&#8221;<br />
#include &#8220;DSP280x_Examples.h&#8221; // DSP280x Examples Include File<br />
#include &#8220;Main.h&#8221;<br />
#include &#8220;Sensor.h&#8221;<br />
#define PI 3.14159264</p>
<p>void FFT_Algorithm(volatile int16 dir,volatile int16 m,volatile float32 *Real,volatile float32 *Imagine);</p>
<p>void Initsensor_ADC( void )<br />
{<br />
memset( ( void * )&amp;Sound1real, 0, sizeof( Sound1real ) );<br />
memset( ( void * )&amp;Sound2real, 0, sizeof( Sound2real ) );<br />
memset( ( void * )&amp;Sound3real, 0, sizeof( Sound3real ) );<br />
memset( ( void * )&amp;Sound4real, 0, sizeof( Sound4real ) );</p>
<p>memset( ( void * )&amp;Sound1change, 0, sizeof( Sound1change ) );<br />
memset( ( void * )&amp;Sound2change, 0, sizeof( Sound2change ) );<br />
memset( ( void * )&amp;Sound3change, 0, sizeof( Sound3change ) );<br />
memset( ( void * )&amp;Sound4change, 0, sizeof( Sound4change ) );</p>
<p>memset( ( void * )&amp;Sound1imagine, 0, sizeof( Sound1imagine ) );<br />
memset( ( void * )&amp;Sound2imagine, 0, sizeof( Sound2imagine ) );<br />
memset( ( void * )&amp;Sound3imagine, 0, sizeof( Sound3imagine ) );<br />
memset( ( void * )&amp;Sound4imagine, 0, sizeof( Sound4imagine ) );<br />
memset( ( void * )&amp;Soundcheck, 0, sizeof( Soundcheck) );<br />
}</p>
<p>interrupt void sensor_ADC( void )<br />
{<br />
static Uint16 tick = 0;<br />
static Uint16 check = 0;<br />
static Uint16 cnt = 0;<br />
static _iq17 iqSound1real = _IQ17(0), iqSound2real = _IQ17(0), iqSound3real = _IQ17(0), iqSound4real = _IQ17(0);<br />
static _iq17 iqSound1imagine = _IQ17(0), iqSound2imagine = _IQ17(0), iqSound3imagine = _IQ17(0), iqSound4imagine = _IQ17(0);<br />
static _iq17 iqSound1change = _IQ17(0), iqSound2change = _IQ17(0), iqSound3change = _IQ17(0), iqSound4change = _IQ17(0);</p>
<p>StopCpuTimer2();</p>
<p>PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;</p>
<p>//TxPrintf(&#8220;adc_check\n&#8221;);<br />
CpuTimer0Regs.PRD.all=100*7;<br />
check++;</p>
<p>CpuTimer0Regs.PRD.all=100*30;<br />
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;<br />
Soundcheck[0] = AdcMirror.ADCRESULT0;</p>
<p>CpuTimer0Regs.PRD.all=100*30;<br />
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;<br />
Soundcheck[2] = AdcMirror.ADCRESULT2;</p>
<p>CpuTimer0Regs.PRD.all=100*30;<br />
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;<br />
Soundcheck[1] = AdcMirror.ADCRESULT1;</p>
<p>CpuTimer0Regs.PRD.all=100*30;<br />
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;<br />
Soundcheck[3]= AdcMirror.ADCRESULT3;</p>
<p>AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;</p>
<p>Sound1real[Adcsound] = (float32)Soundcheck[0];<br />
Sound2real[Adcsound] = (float32)(Soundcheck[2] &gt;&gt; 1);<br />
Sound3real[Adcsound] = (float32)(Soundcheck[1] &gt;&gt; 1);<br />
Sound4real[Adcsound] = (float32)(Soundcheck[3] &gt;&gt; 1);</p>
<p>if(Sound1real[Adcsound] &lt; 0) Sound1real[Adcsound] = (float32)0;<br />
if(Sound2real[Adcsound] &lt; 0) Sound2real[Adcsound] = (float32)0;<br />
if(Sound3real[Adcsound] &lt; 0) Sound3real[Adcsound] = (float32)0;<br />
if(Sound4real[Adcsound] &lt; 0) Sound4real[Adcsound] = (float32)0;</p>
<p>if(Adcsound == 128)<br />
{</p>
<p>FFT_Algorithm((int16)1, (int16)8, Sound1real, Sound1imagine);<br />
FFT_Algorithm((int16)1, (int16)8, Sound2real, Sound2imagine);<br />
FFT_Algorithm((int16)1, (int16)8, Sound3real, Sound3imagine);<br />
FFT_Algorithm((int16)1, (int16)8, Sound4real, Sound4imagine);</p>
<p>for(cnt = 0; cnt &lt; Adcsound; cnt++)<br />
{</p>
<p>iqSound1real = _IQ17(Sound1real[cnt]);<br />
iqSound2real = _IQ17(Sound2real[cnt]);<br />
iqSound3real = _IQ17(Sound3real[cnt]);<br />
iqSound4real = _IQ17(Sound4real[cnt]);<br />
iqSound1imagine = _IQ17(Sound1imagine[cnt]);<br />
iqSound2imagine = _IQ17(Sound2imagine[cnt]);<br />
iqSound3imagine = _IQ17(Sound3imagine[cnt]);<br />
iqSound4imagine = _IQ17(Sound4imagine[cnt]);</p>
<p>iqSound1change = _IQsqrt(_IQmpy(iqSound1real, iqSound1real) + _IQmpy(iqSound1imagine, iqSound1imagine));<br />
iiqSound2change = _IQsqrt(_IQmpy(iqSound2real, iqSound2real) + _IQmpy(iqSound2imagine, iqSound2imagine));<br />
iiqSound3change = _IQsqrt(_IQmpy(iqSound3real, iqSound3real) + _IQmpy(iqSound3imagine, iqSound3imagine));<br />
iiqSound4change = _IQsqrt(_IQmpy(iqSound4real, iqSound4real) + _IQmpy(iqSound4imagine, iqSound4imagine));</p>
<p>iSound1change[cnt] = _IQtoF(iqSound1change);<br />
iSound2change[cnt] = _IQtoF(iqSound2change);<br />
iSound3change[cnt] = _IQtoF(iqSound3change);<br />
iSound4change[cnt] = _IQtoF(iqSound4change);<br />
}</p>
<p>Max_arr = Sound1change[0];</p>
<p>for(cnt = 1; cnt &lt; Adcsound; cnt++)<br />
{<br />
if(Max_arr &lt; Sound1change[cnt]) Max_arr = Sound1change[cnt];<br />
else;</p>
<p>if(Max_arr &lt; Sound2change[cnt]) Max_arr = Sound2change[cnt];<br />
else;</p>
<p>if(Max_arr &lt; Sound3change[cnt]) Max_arr = Sound3change[cnt];<br />
else;</p>
<p>if(Max_arr &lt; Sound4change[cnt]) Max_arr = Sound4change[cnt];<br />
else;<br />
}</p>
<p>for(tick = 0; tick &lt; 128; tick++)<br />
{<br />
Sound1real[tick] = Sound1real[tick+1];<br />
Sound2real[tick] = Sound2real[tick+1];<br />
Sound3real[tick] = Sound3real[tick+1];<br />
Sound4real[tick] = Sound4real[tick+1];<br />
}<br />
Adcsound = 127;<br />
Sound1real[128] = 0;<br />
Sound2real[128] = 0;<br />
Sound3real[128] = 0;<br />
Sound4real[128] = 0;</p>
<p>}<br />
Adcsound++;<br />
//AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;<br />
StopCpuTimer0();<br />
StartCpuTimer2();</p>
<p>}</p>
<p>void FFT_Algorithm(volatile int16 dir,volatile int16 m,volatile float32 *Real,volatile float32 *Imagine)</p>
<p>{<br />
/* Calculate the number of points */</p>
<p>static float32 tx = 0, ty = 0, i2 = 0, k = 0, l1 = 0, l2 = 0, u1 = 0, u2 = 0;<br />
static float32 t1 = 0, t2 = 0;<br />
static int16 i1 = 0, b = 0, l = 0, n = 1, j = 0, i = 0;<br />
static _iq17 iqn = _IQ17(1), iqReal = _IQ17(0), iqImagine = _IQ17(0), iqT1 = _IQ17(0), iqT2 = _IQ17(0), iqU1 = _IQ17(0), iqU2 = _IQ17(0);<br />
static _iq17 c1 = _IQ17(0), c2 = _IQ17(0), z = _IQ17(0);</p>
<p>for (b = 0; b &lt; m; b++)<br />
{<br />
iqn = _IQmpy(iqn, _IQ17(2));<br />
}<br />
n = (Uint16)(_IQtoF(iqn));<br />
/* Do the bit reversal */<br />
i2 = (float32)(n &gt;&gt; 1);</p>
<p>for (i = 0; i &lt; n-1; i++)<br />
{<br />
if (i &lt; j)<br />
{<br />
tx = Real[i];<br />
ty = Imagine[i];<br />
Real[i] = Real[j];<br />
Imagine[i] = Imagine[j];<br />
Real[j] = tx;<br />
Imagine[j] = ty;<br />
}<br />
k = i2;<br />
while (k &lt;= j)<br />
{<br />
j = j &#8211; k;<br />
k = (float32)((Uint16)(k) &gt;&gt; 1);<br />
}<br />
j = j + k;<br />
}</p>
<p>/* Compute the FFT */<br />
c1 = _IQ17(-1.0);<br />
c2 = _IQ17(0.0);<br />
l2 = 1;<br />
for (l = 0; l &lt; m; l++)<br />
{<br />
l1 = l2;<br />
l2 = (float32)((Uint16)(l2) &lt;&lt; 1);<br />
iqU1 = _IQ17(1.0);<br />
iqU2 = _IQ17(0.0);</p>
<p>for (j = 0; j &lt; l1; j++)<br />
{<br />
for (i = j; i &lt; n; i = i + 12)<br />
{<br />
i1 = i + l1;<br />
iqReal = _IQ17(Real[i1]);<br />
iqImagine = _IQ17(Imagine[i1]);<br />
iqT1 = _IQmpy(iqU1, iqReal) &#8211; _IQmpy(iqU2, iqImagine);<br />
iqT2 = _IQmpy(iqU1, iqImagine) &#8211; _IQmpy(iqU2, iqReal);<br />
t1 = _IQtoF(iqT1);<br />
t2 = _IQtoF(iqT2);<br />
Real[i1] = Real[i] &#8211; t1;<br />
Imagine[i1] = Imagine[i] &#8211; t2;<br />
Real[i] += t1;<br />
Imagine[i] += t2;<br />
}<br />
z = _IQmpy(iqU1, c1) &#8211; _IQmpy(iqU2, c2);<br />
iqU2 = _IQmpy(iqU1, c2) &#8211; _IQmpy(iqU2, c1);<br />
iqU1 = z;<br />
}<br />
c2 = _IQsqrt(_IQmpy((_IQ17(1.0) &#8211; c1), _IQ17(0.5)));<br />
if (dir == 1)<br />
c2 = -c2;<br />
c1 = _IQsqrt(_IQmpy((_IQ17(1.0) + c1), _IQ17(0.5)));<br />
}</p>
<p>/* Scaling for forward transform */<br />
if (dir == 1) {<br />
for (i = 0; i &lt; n; i++)<br />
{<br />
iqReal = _IQ17(Real[i1]);<br />
iqImagine = _IQ17(Imagine[i1]);<br />
iqReal = _IQdiv(iqReal, iqn);<br />
iqImagine = _IQdiv(iqImagine, iqn);<br />
Real[i1] = _IQtoF(iqReal);<br />
Imagine[i1] = _IQtoF(iqImagine);<br />
}<br />
}<br />
}<br />
</div>
<p>&nbsp;</p>
<p><span style="color: #33cccc"><strong>5.2.3. FFT 역변환 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>///////C++로 코딩함.///////</p>
<p>template&lt;class T&gt; inline void swap(T &amp;x, T&amp;y)<br />
{<br />
T z;<br />
z = x; x = y; y = z;<br />
}<br />
void DoFFTInternal(jdouble* data, jint nn) {</p>
<p>unsigned long n, mmax, m, j, istep, i;<br />
jdouble wtemp, wr, wpr, wpi, wi, theta;<br />
jdouble tempr, tempi;</p>
<p>// reverse-binary reindexing</p>
<p>n = nn&lt;&lt;1;<br />
j=1;</p>
<p>for (i=1; i&lt;n; i+=2) {<br />
if (j&gt;i) {<br />
swap(data[j-1], data[i-1]);<br />
swap(data[j], data[i]);<br />
}<br />
m = nn;<br />
while (m&gt;=2 &amp;&amp; j&gt;m) {<br />
j -= m;<br />
m &gt;&gt;= 1;<br />
}<br />
j += m;<br />
};</p>
<p>// Danielson-Lanczos section</p>
<p>mmax=2;</p>
<p>while (n&gt;mmax) {<br />
istep = mmax&lt;&lt;1;<br />
theta = -(2*M_PI/mmax);<br />
wtemp = sin(0.5*theta);<br />
wpr = -2.0*wtemp*wtemp;<br />
wpi = sin(theta);<br />
wr = 1.0;<br />
wi = 0.0;</p>
<p>for (m=1; m &lt; mmax; m += 2) {<br />
for (i=m; i &lt;= n; i += istep) {<br />
j=i+mmax;<br />
tempr = wr*data[j-1] &#8211; wi*data[j];<br />
tempi = wr * data[j] + wi*data[j-1];</p>
<p>data[j-1] = data[i-1] &#8211; tempr;<br />
data[j] = data[i] &#8211; tempi;<br />
data[i-1] += tempr;<br />
data[i] += tempi;<br />
}</p>
<p>wtemp=wr;<br />
wr += wr*wpr &#8211; wi*wpi;<br />
wi += wi*wpr + wtemp*wpi;<br />
}</p>
<p>mmax=istep;<br />
}<br />
}</p>
</div>
<p><span style="color: #339966"><strong>5.3. 참고문헌</strong></span></p>
<p>· 프로젝트로 배우는 라즈베리 파이, 도날드 노리스 지음, 한빛미디어 출판<br />
· Data Manual &#8211; TMS320F2809, Texas Instruments 출판<br />
· http://paulbourke.net/miscellaneous//dft/, written by paul bourke<br />
· 그 外 네이버 지식인, 네이버 카페 “당근이의 AVR 갖구 놀기”</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/33388/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
