<?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; Feature</title>
	<atom:link href="http://www.ntrexgo.com/archives/tag/feature-2/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>[58호]자동회전, 자동신고 기능이 있는 소화기 거치대 및 소화기 경보기</title>
		<link>http://www.ntrexgo.com/archives/37994</link>
		<comments>http://www.ntrexgo.com/archives/37994#comments</comments>
		<pubDate>Thu, 20 Feb 2020 00:00:54 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[58호]]></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>
		<category><![CDATA[참가상]]></category>
		<category><![CDATA[프로젝트]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=37994</guid>
		<description><![CDATA[디바이스마트매거진 58호 &#124; ‘한달 주기로 분말형 소화기를 섞어주는 장치’와 ‘화재를 인식하여 자동으로 119신고가 이루어지는 시스템’을 접목한 아이템을 제작한다. ]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-1.png" rel="lightbox[37994]"><img class="alignnone size-large wp-image-38084" alt="58 ict 자동화소화전 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-1-620x194.png" width="620" height="194" /></a></p>
<p><strong>2019 ICT 융합 프로젝트 공모전 참가상</strong></p>
<p><span style="font-size: x-large"><strong>자동회전, 자동신고 기능이 있는</strong></span></p>
<p><span style="font-size: x-large"><strong>소화기 거치대 및 소화기 경보기</strong></span></p>
<p style="text-align: right">글 | 전남대학교 이정원, 정수연, 정찬환</p>
<p style="text-align: right">
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 창의적 발상과 시제품의 제작 완성도가 높아 보입니다. 또한 무선 통신을 통한 경보기와 소화기 거치대간의 효율적 사용 부분도 아이디어가 돋보입니다. 개발 작품에 있어 화재시 소방기관에 알려주는 기능에 있어 설명이 부족하여 이 부분에 대하여 구성을 어떻게 진행한 것인지 궁금증이 남아 있네요. 소화기 거치대의 동작과 관련한 시연 동영상등이 있었으면 더 좋았을듯 합니다.<br />
<strong>뉴티씨</strong> 평소에 직접 뒤집어서 흔들어주고 했었는데, 이것을 자동으로 해줄수 있다니 참 좋은 아이디어 같습니다. 매우 간단하면서도 좋은 아이템으로, 소방기구로 활용이 될 수 있는 가능성이 매우 높다고 생각되며 각 아파트 단지나, 주요한 건물 등에서도 반드시 구비하였으면 좋겠습니다. 이에 높은 점수를 드립니다.<br />
<strong>위드로봇</strong> 소화기의 수명 연장을 위해 자동 회전 기능을 구현하였기에 부분을 실용성 측면에서 높은 점수를 부여하였습니다. 반면 구현한 결과에 대한 분석이 보고서에 나타나지 않은 점이 아쉽습니다.<br />
<strong>펌테크</strong> 단순한 구성이지만 세심한 관찰력이 반영된 실생활과 밀접한 아이디어와 독창성 및 실용성이 아주 뛰어난 작품이라고 생각합니다. 단 일반적인 소화기 무게가 통상 3KG 이상인 점은 감안한다면 이를 감안한 구동모터 선정과 감속기어 박스 구성이 우선적으로 고려되어 할 것으로 판단이 되는데 이 부분은 작품에 반영이 되지 않은 것 같습니다. 또한 제출된 문서 내용을 감안해 볼 때 최종적인 작품의 완성은 되지는 않은 것으로 판단됩니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
<span style="color: #33cccc"><strong>2.1. 발명 목적</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-2.png" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38086" alt="58 ict 자동화소화전 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-2.png" width="620" height="280" /></a></p>
<p>1) 화재에 대한 안전불감증이 만연한 우리 사회에서 안전에 대한 관심도를 높이고자 한다.<br />
2) 화재 발생 시, 원활하게 화재를 진압하고 신속한 초기대응을 통하여 인적·물적 피해를 최소화하고자 한다.<br />
3) 분말소화기의 적절한 보관방법을 사용하여 소화기의 수명을 늘리는 동시에 폐소화기를 줄여 환경 보호에 기여하고자 한다.<br />
4) 분말소화기의 점유율은 71%로 국내 소화기 중 가장 많은 점유율을 차지하고 있으며, 이를 기반으로 한 창업 아이템은 충분히 수요가 있을 것으로 판단한다.</p>
<p><span style="color: #33cccc"><strong>2.2. 발명아이템의 선정동기 및 배경</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-3.png" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38088" alt="58 ict 자동화소화전 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-3.png" width="620" height="616" /></a></p>
<p>분말소화기의 경우 관리방법 중에 ‘한달에 한번 위아래로 흔들어주어야 함.’이라는 항목이 존재한다. 이는 소화 약제가 굳지 않도록 하기 위함인데, 많은 사람들은 이러한 관리방법에 대해 무지하다. 실제로 분말이 굳어 기능을 상실한 소화기 때문에 화재 진압에 어려움을 겪은 수많은 사례는 우리에게 경각심을 일깨워주었다. 한편, 화재 발생 시 골든타임은 5분이며 이후에는 심각한 인명피해와 재산피해가 발생할 수 있다. 실제로 골든타임을 놓쳐 연마다 4000건 이상의 화재가 일어나고 있고, 2000명 이상의 인명피해가 발생하고 있다. 따라서 제대로 된 소화기의 작동과 신속한 119신고를 통한 화재 초기대응의 필요성을 느끼게 되었고, 앞서 언급한 문제점을 해결하기 위해 ‘한달 주기로 분말형 소화기를 섞어주는 장치’와 ‘화재를 인식하여 자동으로 119신고가 이루어지는 시스템’을 접목한 아이템을 구상하게 되었다.</p>
<p><span style="color: #33cccc"><strong>2.3. 발명아이템의 독창성</strong></span><br />
소방산업의 발전이 정체되어있는 탓에 시장에 유사제품이 존재하지 않다. 잘 인식하지 못하는 부분에서 불편함을 해소해주는 소방 신기술을 갖춘 제품이며, 디자인 측면에서도 우수하다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong>3.1. 주요 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-1.jpg" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38083" alt="58 ict 자동화소화전 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-1.jpg" width="620" height="294" /></a></p>
<p>· 소화기의 수명연장을 위해 1달 주기로 한번씩 자동으로 소화기를 회전 시킨다<br />
· 화재경보기가 감지할 만큼의 큰 불이 나면 소화기 터너와 화재경보기가 상호 블루투스 통신으로 화재를 인지하고 소화기의 위치를 식별시켜줌과 동시에 Telematics기술을 활용하여 가까운 소방기관에 자동으로 신고한다.<br />
· 화재 시 소화기 거치대의 부저, 네오픽셀이 켜져 소화기의 위치를 쉽게 파악할 수 있어서 더 큰 화재로 번지는 것을 막아줄 수 있다.<br />
· 벽걸이형 거치대로 제작하여 장소에 영향을 받지 않고 어디든지 설치가 가능하다.<br />
· 화재경보기와 소화기 거치대가 서로 블루투스 기술을 활용 상호 통신하여 소화기의 위치를 빠르게 식별할 수 있어 빠른 진압이 가능하다.<br />
· 자동회전 기능으로 소화기 분말을 섞어줘 소화기의 수명을 크게 연장시킬 수 있다.<br />
· 화재가 발생하면 자동신고, 수동신고 기능으로 가까운 소방기관에 빠른 신고가 가능해 빠른 진압이 가능하다.</p>
<p><span style="color: #33cccc"><strong>3.2. 전체 시스템 구성</strong></span><br />
알고리즘</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-4.png" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38090" alt="58 ict 자동화소화전 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-4.png" width="620" height="463" /></a></p>
<p><span style="color: #33cccc"><strong>3.3. 개발 환경</strong></span><br />
· 개발언어 : C++(아두이노), C#(어플 개발)<br />
· 회로도 소스 개발 Tool : 아두이노<br />
· 어플 개발 Tool : Unity</p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong>4.1. 아이템 기획 및 기획서 작성</strong></span></p>
<p><strong style="color: #33cccc">4.2. 개발자 소스코딩, 기구제작자 모델링</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-2.jpg" rel="lightbox[37994]"><img class="alignnone size-large wp-image-38085" alt="58 ict 자동화소화전 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-2-590x620.jpg" width="590" height="620" /></a></p>
<p><span style="color: #33cccc"><strong>4.3. 개발자 회로제작, 기구제작자 모델 조립</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-3.jpg" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38087" alt="58 ict 자동화소화전 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-3.jpg" width="620" height="329" /></a></p>
<p><span style="color: #33cccc"><strong>4.4. 디자이너 모델 디자인 </strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-4.jpg" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38089" alt="58 ict 자동화소화전 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-4.jpg" width="620" height="329" /></a></p>
<p><span style="color: #33cccc"><strong>4.5. 소화기 거치대 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-5.png" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38091" alt="58 ict 자동화소화전 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-5.png" width="620" height="486" /></a></p>
<p><span style="color: #33cccc"><strong>4.6. 소화기 거치대 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;Stepper.h&gt; //스텝모터 라이브러리<br />
#include &lt;SoftwareSerial.h&gt; //블루투스 라이브러리<br />
#include &lt;Adafruit_NeoPixel.h&gt; //네오픽셀 라이브러리 시작<br />
#ifdef __AVR__ //네오픽셀 라이브러리 시작<br />
#include &lt;avr/power.h&gt;<br />
#endif //네오픽셀 라이브러리 끝</p>
<p>#define PIN 6 //네오픽셀 핀번호<br />
#define NUMPIXELS 60 //사용할 네오픽셀 수<br />
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);<br />
//네오픽셀을 위한 객체 선언</p>
<p>const int stepsPerRevolution = 8; //스텝모터 스텝수<br />
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11); //스텝모터 객체선언</p>
<p>SoftwareSerial phoneSerial(4, 5); //핸드폰 Master 블루투스의 Tx. Rx핀을 4번 5번핀으로 설정<br />
SoftwareSerial alarmSerial(2, 3); //화재경보기 Slave 블루투스의 Tx, Rx핀을 2번 3번핀으로 설정</p>
<p>int sirenPin = 13; //부저 핀번호<br />
int buttonPin = 7; //버튼 핀번호<br />
int buttonData; //버튼 데이터<br />
bool motorTrigger = false; //화재, 진압 trigger<br />
char serialData; //통신데이터<br />
int oneTimeFlag = 0;<br />
int oddEvenFlag = 0;</p>
<p>void setup()<br />
{</p>
<p>pinMode(buttonPin, INPUT);<br />
pinMode(sirenPin, OUTPUT);</p>
<p>// 네오픽셀 라이브러리 사용 시작<br />
#if defined (__AVR_ATtiny85__)<br />
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);<br />
#endif<br />
strip.begin();<br />
strip.show();</p>
<p>myStepper.setSpeed(60);</p>
<p>Serial.begin(9600); // 시리얼 통신의 속도를 9600으로 설정<br />
alarmSerial.begin(9600); //거치대 블루투스만 연결<br />
phoneSerial.begin(9600);</p>
<p>}<br />
void loop () {</p>
<p>motorEvenOdd(); //모터회전함수<br />
buttonValue(); //수동신고 함수</p>
<p>//화재, 진압 통신<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
serialData = alarmSerial.read();<br />
Serial.write(serialData);<br />
fireAlarmBT(); //블루투스 통신 함수<br />
}</p>
<p>}<br />
void alarmData() { //블루투스 데이터 값 받기<br />
serialData = alarmSerial.read();<br />
Serial.write(serialData);<br />
fireAlarmBT();<br />
}</p>
<p>void fireAlarmBT() { //화재,진압 통신<br />
if (serialData == ‘F’) { //화재시<br />
fireWork();<br />
}<br />
if (serialData == ‘E’) { //진압시<br />
exWrok();<br />
}<br />
oneTimeFlag = 1;<br />
}</p>
<p>void fireWork() { //화재시 행동<br />
motorTrigger = true;<br />
fire();<br />
buzzerOn();<br />
oneTimeFlag = 1;<br />
}<br />
void exWrok() { //진압시 행동<br />
motorTrigger = true;<br />
extinguish();<br />
motorTrigger = false;<br />
oneTimeFlag = 0;<br />
}</p>
<p>void buttonValue() { //수동신고 함수<br />
buttonData = digitalRead(buttonPin);<br />
if (buttonData == HIGH) { //수동신고<br />
delay(500);<br />
motorTrigger = true;<br />
selfFire();<br />
buzzerOn();<br />
}<br />
}<br />
void buzzerOn() { //부저, 네오픽셀 On<br />
theaterChase(strip.Color(0, 255, 0), 0); //네오픽셀, 부저<br />
}<br />
void buzzerOff() { //부저, 네오픽셀 Off<br />
noTone(sirenPin);<br />
}</p>
<p>void theaterChase(uint32_t c, uint8_t wait) { //부저,네오픽셀 On 함수<br />
for (int j = 0; j &lt; 30; j++) {<br />
tone(sirenPin, 262);<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
alarmData();<br />
noTone(sirenPin);<br />
break;<br />
}<br />
for (int q = 0; q &lt; 3; q++) {<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
alarmData();<br />
noTone(sirenPin);<br />
break;<br />
}<br />
for (int i = 0; i &lt; strip.numPixels(); i = i + 3) {<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
alarmData();<br />
noTone(sirenPin);<br />
break;<br />
}<br />
strip.setPixelColor(i + q, c); //turn every third pixel on</p>
<p>strip.show();<br />
}<br />
}<br />
}<br />
}</p>
<p>void theaterChase_(uint32_t c, uint8_t wait) { //부저,네오픽셀 Off 함수<br />
for (int q = 0; q &lt; 3; q++) {<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
alarmData();<br />
noTone(sirenPin);<br />
break;<br />
}<br />
for (int i = 0; i &lt; strip.numPixels(); i = i + 3) {<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
alarmData();<br />
noTone(sirenPin);<br />
break;<br />
}<br />
strip.setPixelColor(i + q, 0);<br />
}<br />
strip.show();<br />
}<br />
}</p>
<p>void fire() { //화재함수<br />
phoneSerial.listen();<br />
char data = “화재가 발생하였습니다.”;<br />
phoneSerial.write(data);<br />
}</p>
<p>void selfFire() { //수동 신고 화재<br />
alarmSerial.listen();<br />
char data = ‘f’;<br />
alarmSerial.write(data);<br />
phoneSerial.listen();<br />
char data_ = “화재가 발생하였습니다.”;<br />
phoneSerial.write(data_);<br />
}</p>
<p>void extinguish() { //진압함수<br />
phoneSerial.listen();<br />
char data = “화재가 진압되었습니다.”;<br />
phoneSerial.write(data);<br />
theaterChase_(strip.Color(0, 0, 0), 0); //네오픽셀 끔<br />
buzzerOff();<br />
oneTimeFlag = 0;<br />
}</p>
<p>void motorEvenOdd() { //모터회전<br />
for (int i = 0; i &lt;= 10; i++) {<br />
if(oddEvenFlag == 1)break;<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
alarmData();<br />
oddEvenFlag = 1;<br />
break;<br />
}<br />
myStepper.step(stepsPerRevolution);<br />
}<br />
for (int i = 0; i &lt;= 10; i++) {<br />
if(oddEvenFlag == 1)break;<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
alarmData();<br />
oddEvenFlag = 1;<br />
break;<br />
}<br />
myStepper.step(-stepsPerRevolution);<br />
}<br />
oddEvenFlag = 0;<br />
Serial.println(“bluetooth Ready”);<br />
}<br />
</div>
<p><span style="color: #33cccc"><strong>4.7. 화재경보기 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-6.png" rel="lightbox[37994]"><img class="alignnone size-full wp-image-38092" alt="58 ict 자동화소화전 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-자동화소화전-6.png" width="620" height="411" /></a></p>
<p><span style="color: #33cccc"><strong>4.8. 화재경보기 소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;SoftwareSerial.h&gt; //블루투스 라이브러리</p>
<p>SoftwareSerial alarmSerial(2, 3); //블루투스의 Tx, Rx핀을 2번 3번핀으로 설정<br />
char serialData; //블루투스 통신 변수<br />
int temSensor = A0; //온도센서 핀번호<br />
int sirenPin = 4; //부저 핀번호</p>
<p>void setup() {<br />
// 시리얼 통신의 속도를 9600으로 설정<br />
Serial.begin(9600);<br />
alarmSerial.begin(9600);<br />
pinMode(temSensor, INPUT);<br />
}</p>
<p>void loop() {</p>
<p>double temValue = 0; //센서 데이터 값 초기화</p>
<p>while (1) //온도가 올라갈 때까지 기다림<br />
{<br />
int readVal = analogRead(temSensor);<br />
double temValue = Thermistor(readVal);<br />
delay(500);</p>
<p>if (temValue &gt;= 50.0) { //큰 화재 발생<br />
break;<br />
}<br />
alarmSerial.listen();<br />
if (alarmSerial.available()) {<br />
Serial.write(alarmSerial.read());<br />
byte serialData = alarmSerial.read();<br />
if (serialData == 255) //수동신고<br />
{<br />
selfFire();<br />
}<br />
}<br />
}<br />
fire();</p>
<p>while (1)<br />
{<br />
int readVal = analogRead(temSensor);<br />
double temValue = Thermistor(readVal);<br />
delay(500);</p>
<p>if (temValue &lt;= 20) { //진압신호 올때까지 기다림<br />
break;<br />
}<br />
}<br />
extinguish();</p>
<p>}</p>
<p>void selfFire() { //수동신고<br />
buzzerOn();<br />
delay(8000);<br />
extinguish();<br />
}</p>
<p>void fire() { //화재 함수<br />
for(int i=0; i &lt; 50; i++){<br />
char data = ‘F’;<br />
alarmSerial.write(data);<br />
}<br />
buzzerOn();<br />
}</p>
<p>void extinguish() { //진압 함수<br />
for(int i =0; i &lt; 50; i++){<br />
char data = ‘E’;<br />
alarmSerial.write(data);<br />
}<br />
buzzerOff();<br />
}</p>
<p>void buzzerOn() { //부저 On<br />
tone(sirenPin, 262);<br />
}</p>
<p>void buzzerOff() { //부저 Off<br />
noTone(sirenPin);<br />
}</p>
<p>double Thermistor(int RawADC) //온도센서 섭씨 변환<br />
{<br />
double temValue;<br />
temValue = log(10000.0 * ((1024.0 / RawADC &#8211; 1)));<br />
temValue = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * temValue * temValue )) * temValue );<br />
temValue = temValue &#8211; 273.15; // convert from Kelvin to Celsius<br />
return temValue;<br />
}<br />
</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/37994/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[58호]Battleship 2인용 게임기</title>
		<link>http://www.ntrexgo.com/archives/37988</link>
		<comments>http://www.ntrexgo.com/archives/37988#comments</comments>
		<pubDate>Thu, 20 Feb 2020 00:00:28 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[Feature]]></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=37988</guid>
		<description><![CDATA[디바이스마트매거진 58호 &#124; battleship 보드게임 원리에 착안하여 시중에서 판매되는 게임기와 비슷한 외형의 디지털 게임기를 제작한다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-15.png" rel="lightbox[37988]"><img class="alignnone size-large wp-image-38064" alt="58 ict 배틀쉽 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-15-620x176.png" width="620" height="176" /></a></p>
<p><strong>2019 ICT 융합 프로젝트 공모전 참가상</strong></p>
<p><strong><span style="font-size: x-large">Battleship 2인용 게임기</span></strong></p>
<p style="text-align: right">글 | 국민대학교 오재홍, 이강민</p>
<p style="text-align: right">
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 보드게임을 디지털화하였다는 것에서 재미있는 발상이라 생각합니다. 하드웨어 구성에 있어서 게임기 조작부는 기성 조이스틱 등을 사용하여 조금 더 심플한 방법을 추구하고, Display 부분에 dot/character 보다 더 유려한 형태의 구성으로 했다면 재미있어 보이지 않았을까 합니다. 모듈 문제로 적용하지 못한 블루투스 기능 또한 아쉬움으로 남습니다.<br />
<strong>뉴티씨</strong> 한때 유행하던 8비트 임베디드 게임기를 상상하게 만든 작품이었습니다. 실제로 블루투스를 넣어서 서로 통신하여 게임할 수 있도록 된 점도 잘된 점이라고 생각합니다. 다만, 스마트폰을 LCD 표현용으로 사용하고 스마트폰과 연결하여 게임기로 쓸 수 있도록 하였다면, 보조장치로 더 좋지 않을까 생각합니다.<br />
<strong>위드로봇</strong> 보드 게임을 임베디드 시스템으로 구현한 부분이 재미있는 작품입니다.<br />
<strong>펌테크</strong> 과거 오락실 게임을 연상시키는 흥미로운 작품이라고 생각합니다. 단순해 보이지만 프로그래밍 과정을 통해 게임 구성에 관한 Algorithm 구현, GLCD를 통한 상태 표시 등은 기술적 구현이 쉽지는 않았을 것으로 예상됩니다. 비록 2대의 게임기기 상호 간 무선통신을 통한 구현을 최종 완성시키지 못했지만 유선상의 구현만으로도 충분히 가치가 있는 작품이라고 생각합니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
· 2대의 ATmega128을 이용한 유선 통신 기능 구현<br />
· 기존의 종이나 장난감으로 하는 보드게임을 디지털화하여 시중에서 판매되는 게임기와 비슷한 외형의 디지털 게임기 제작</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-1.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38043" alt="58 ict 배틀쉽 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-1.png" width="610" height="344" /></a></p>
<p>이 작품은 battleship 보드게임 원리에 착안해 만들었다. 기존의 battleship 보드게임은 10&#215;10의 보드에서 이루어지고, 우선 각자 자신의 보드에 각각 크기가 5,4,3,3,2인 다섯 개의 배(종류는 4종류, 각각 Aircraft(크기 5), Battleship(크기 4), Cruiser(크기 3), Destroyer(크기 2))를 가로 혹은 세로로 겹치지 않게 배열한다. 그리고 서로 돌아가며 상대의 배의 위치를 추측한다. 한 번씩 돌아가며 상대의 배가 있을 걸로 예상되는 위치(게임 보드 위의 한 점)를 지목한 뒤, 그 결과를 듣고 다시 그 결과를 바탕으로 추측하여 먼저 상대의 배가 있는 위치를 모두 맞춘 쪽이 승리하는 게임이다. 이 작품은 기존 battleship 보드게임과 달리 상대방의 5칸 크기의 배를 파괴하거나 5칸 크기의 배가 아닌 배를 3척 파괴하는 것이 승리조건이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-2.png" rel="lightbox[37988]"><img class="size-full wp-image-38045 aligncenter" alt="58 ict 배틀쉽 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-2.png" width="412" height="491" /></a><br />
차이점은 이 작품에서는 크기가 5,4,3,2인 배가 있고 한 칸 크기의 함정이 있다는 것이다. 이 함정은 배와 겹치지 않게 배열하고 상대방이 함정을 공격했을 때 배를 공격했다고 착각하게 만드는 역할을 하여 배의 모양을 쉽게 예측하지 못하게 만들었다는 것이다. 마지막으로 스캔 기능이 추가되었다. 자신이 공격에 성공한 배가 어떤 배인지 알기 위한 기회가 3번이 주어진다. 자신의 공격 턴에 지정한 좌표에 스캔 버튼을 누르면 배의 종류를 알려준다.<br />
이러한 게임 규칙의 변화, 아이템 사용 효과 추가, 아날로그 게임의 디지털화를 통해서 기존 battleship 보드게임에서 보다 더 재미의 요소를 추가하였다.</p>
<p><span style="color: #33cccc"><strong>3.1. 주요 동작 및 특징</strong></span><br />
<span style="color: #339966"><strong>가. 스위치 동작</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-1.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38042" alt="58 ict 배틀쉽 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-1.jpg" width="610" height="163" /></a><br />
(1) 리셋 스위치<br />
(2) 상하좌우 스위치<br />
(3) 포격/확인 스위치<br />
(4) 회전/스캔 스위치</p>
<p><span style="color: #339966"><strong>나. 게임 진행 순서</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-3.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38047" alt="58 ict 배틀쉽 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-3.png" width="610" height="276" /></a></p>
<p>① 게임기 상단에 부착된 스위치를 이용해 각자의 배 배치를 완료한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-4.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38049" alt="58 ict 배틀쉽 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-4.png" width="610" height="278" /></a></p>
<p>② 배 배치가 완료된 후 한 사람씩 공격을 하게 되는데 상대방의 배 위치를 맞췄을 때는 X표시가 되며 한 번 더 차례를 진행하고 공격에 실패했을 때는 *표시가 되며 상대방의 턴으로 넘어간다. 특정 알파벳 배의 모양을 완전히 파괴하게 되면 화면 하단에 있는 알파벳 현황판 숫자가 달라진다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-2.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38044" alt="58 ict 배틀쉽 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-2.jpg" width="610" height="239" /></a></p>
<p>③ 게임기 스위치 좌측 상단에 LED는 자신의 턴일 때는 초록색, 상대방의 턴일 때는 빨간색에 불이 들어온다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-3.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38046" alt="58 ict 배틀쉽 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-3.jpg" width="610" height="131" /></a></p>
<p>④ 공격 시 파란색 버튼을 이용하여 스캔 기능을 사용함으로써 상대방 특정 위치의 배 종류를 알 수 있다. 스캔 기능은 각 플레이어에게 3번의 사용 기회가 주어진다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-5.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38051" alt="58 ict 배틀쉽 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-5.png" width="610" height="131" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-6.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38053" alt="58 ict 배틀쉽 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-6.png" width="610" height="131" /></a></p>
<p>&nbsp;</p>
<p>⑤ 게임 진행 중 승리조건이 달성되면 승리 문구가 표시되고 흰색 버튼을 눌러 새로운 게임을 시작할 수 있다.</p>
<p><span style="color: #33cccc"><strong>3.2. 전체 시스템 구성</strong></span><br />
<span style="color: #339966"><strong>가. 스위치 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-7.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38055" alt="58 ict 배틀쉽 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-7.png" width="610" height="431" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-8.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38057" alt="58 ict 배틀쉽 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-8.png" width="620" height="261" /></a></p>
<p>한 대의 게임기 안에 있는 7개 스위치는 모두 풀업 저항 회로로 구성되어 있고 스위치를 누를 때 연결된 포트의 HIGH 신호를 LOW 신호로 바꾸어 입력 신호를 변경한다. 스위치는 모두 폴링(Polling)방식으로 동작되며 RESET 단자에 연결된 스위치를 제외한 나머지는 모두 PORTD에 연결하였다.</p>
<p><span style="color: #339966"><strong>나. 사운드</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-9.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38058" alt="58 ict 배틀쉽 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-9.png" width="620" height="240" /></a></p>
<p>게임의 효과음은 전기 신호를 소리로 변환시켜 주는 부저(Buzzer)를 통해서 제작하였다.<br />
부저에는 내부에 전자석과 진동을 일으키는 판으로 이루어져 있으며, 전자석이 진동판을 아주 빠르게 흔들어 소리를 발생 시키는 원리를 가지고 있어 타이머/카운터를 이용하여 주파수를 정해주어 소리를 발생시켰다.<br />
하나의 효과음은 여러 가지 주파수의 배열로 만들었고 타이머/카운터 레지스터를 조절하는 함수의 인자로 사용하였다.</p>
<p><span style="color: #339966"><strong>다. 통신 방법</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-10.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38059" alt="58 ict 배틀쉽 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-10.png" width="620" height="353" /></a></p>
<p>게임기의 통신은 USART(Universal Synchronous and Asynchronous Receive and Transmitter) 통신 방식을 사용한다. USART 통신을 하기 위해서 2대의 ATmega128 Tx/Rx 포트를 서로 교차하여 선을 연결하고 양쪽 ATmega128 모두 송수신 속도, 전송 문자의 데이터 비트수 등 데이터를 송수신 하는데 필요한 레지스터들을 동일하게 설정한다.<br />
정보를 보낼 때 UDR0에 데이터를 넣어 인터럽트를 발생시키고 그 데이터를 받을 때는 미리 선언한 flag 값만 변경시켜 인터럽트를 통해 실시간으로 정보를 주고받는다.</p>
<p><span style="color: #339966"><strong>라. 배터리</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-4.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38048" alt="58 ict 배틀쉽 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-4.jpg" width="300" height="357" /></a></p>
<p>게임기의 GLCD 백라이트와 부저에 전원을 공급하기 위해서 약 5V의 전압이 필요하다. 따라서 게임기의 하단부에 AA배터리 소켓을 4개 부착하였고 1.5V AA건전지 4개를 직렬 연결하여 총 6V의 전압을 공급할 수 있도록 설계하였다.</p>
<p><span style="color: #339966"><strong>마. 게임 알고리즘</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-11.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38060" alt="58 ict 배틀쉽 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-11.png" width="620" height="467" /></a></p>
<p><span style="color: #33cccc"><strong>3.3. 개발 환경(개발 언어, Tool, 사용 시스템 등)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-12.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38061" alt="58 ict 배틀쉽 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-12.png" width="620" height="148" /></a></p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong>4.1. 코드 제작</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-13.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38062" alt="58 ict 배틀쉽 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-13.png" width="620" height="512" /></a></p>
<p>① Visual Studio와 Code Vision AVR 모두 C언어를 기반으로 한 플랫폼이기 때문에 먼저 Visual Studio로 게임 알고리즘을 제작한 후 Code Vision AVR에 부합하는 코드로 변환하여 GLCD에 영상을 띄웠다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-5.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38050" alt="58 ict 배틀쉽 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-5.jpg" width="620" height="424" /></a></p>
<p>② ATmega128간의 USART 유선통신의 데이터 송수신을 간단한 스위치 동작으로 확인하였다.</p>
<p><span style="color: #33cccc"><strong>4.2. 하드웨어 제작</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-6.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38052" alt="58 ict 배틀쉽 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-6.jpg" width="620" height="149" /></a></p>
<p>① 스위치와 리드선을 글루건으로 고정시키고 스티로폼에 스위치만 보이게 하여 실제 게임기 스위치 같은 외형을 제작하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-14.png" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38063" alt="58 ict 배틀쉽 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-14.png" width="620" height="276" /></a></p>
<p>② 아크릴판으로 틀을 제작하고 게임기의 윗면에 GLCD와 스위치를 아랫면에는 ATmega128, 부저, 브레드보드를 위치시켰다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-7.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38054" alt="58 ict 배틀쉽 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-7.jpg" width="620" height="201" /></a></p>
<p>③ 2대의 게임기를 붙여 게임기 하단에 배터리를 넣으면 게임이 작동하도록 제작하였다.</p>
<p><span style="color: #0000ff"><strong>5. 기타</strong></span><br />
<span style="color: #33cccc"><strong>5.1. 소스코드</strong></span><br />
<span style="color: #339966"><strong>가. 배 배치 알고리즘</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>void print_ship(int x, int y, int ship_length, char ship_name)<br />
{<br />
if(turn==0)<br />
for (i = 0; i &lt; ship_length; i++)<br />
board_char[y][x+i] = ship_name;</p>
<p>else<br />
{<br />
for (i = 0; i &lt; ship_length; i++)<br />
board_char[y+i][x] = ship_name;<br />
}<br />
}</p>
<p>print_ship 함수는 x,y 좌표, 배의 길이, 배 이름을 인수로 받아 전역변수 turn이 0이면<br />
배의 이름을 board_char 배열에 가로로 넣고 turn이 1이면 board_char 배열에 세로로 넣는다.</p>
<p>void MapDraw(void)<br />
{<br />
for(i = 0; i &lt; 10; i++)<br />
{<br />
for(j = 0; j &lt;10; j++)<br />
{<br />
GLCD_TextGoTo(i,j);<br />
GLCD_WriteChar(board_char[j][i]);<br />
}<br />
}<br />
}</p>
<p>MapDraw 함수는 board_char 배열에 저장된 데이터를 GLCD에 찍어주는 역할을 한다.</p>
<p>switch(PIND)<br />
{<br />
case 0xfd: // 아래로 움직이는 키를 눌렀을 때 (PORTD1)<br />
if (turn == 0 &amp;&amp; player_y != 9)<br />
{<br />
player_x+=0; player_y+=1;<br />
_delay_ms(3000);<br />
}<br />
if (turn == 1)<br />
{<br />
if(board_char[player_y + ship_length][9] == ‘.’){<br />
player_x+=0; player_y+=1;<br />
_delay_ms(3000);<br />
}<br />
}<br />
</div>
<p>배를 이동하기 코드의 일부를 발췌한 부분이다.<br />
turn이 0이면 배가 가로로 되어있는 상태이고 1이면 세로로 되어있는 상태이기 때문에 turn이 0이고 y좌표가 (x,9) 가 아닌 경우에 한 칸 내려갈 수 있고,<br />
turn이 1이고 y좌표와 배의 길이를 더한 좌표에 있는 문자가. 맵의 기본 모양이라면 한 칸 내려갈 수 있기 때문에 y좌표에 1을 더해주었다. GLCD의 좌표는 첫 번째 줄의 y좌표는 0이고 아래로 내려갈수록 +1씩 된다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>void enter_ship(int x, int y, int ship_length, char ship_name)<br />
{<br />
if (turn == 0)<br />
for (i = 0; i&lt;ship_length; i++)<br />
{<br />
grid[y][x + i] = ship_name;<br />
}<br />
else<br />
for (i = 0; i&lt;ship_length; i++)<br />
{<br />
grid[y + i][x] = ship_name;<br />
}<br />
placement_cnt++;<br />
enter_cnt++;<br />
}<br />
</div>
<p>enter_ship 함수는 turn의 값을 통해 배의 방향을 판단하고 반복문을 이용해 grid 배열에 배치할 배의 이름을 넣어주는 함수이다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>void erase_ship(int x, int y, int ship_length)<br />
{<br />
if (turn == 0)<br />
for (i = 0; i &lt; ship_length; i++)<br />
board_char[y][x + i] = grid[y][x + i];</p>
<p>else<br />
for (i = 0; i &lt; ship_length; i++)<br />
board_char[y + i][x] = grid[y + i][x];<br />
}<br />
</div>
<p>erase_ship 함수는 x,y 좌표, 배의 길이를 인수로 받아 board_char 배열에 grid 배열을 넣어준다. 이 함수는 좌표값을 이동시켰을 때 이전에 print_ship 함수로 board_char 배열에 넣어주어 Mapdraw 함수로 GLCD에 배열을 표현했을 때 잔상이 남는 것을 지워주는 역할을 한다. board_char 배열에 넣어주는 grid 함수는 배를 배치했을 때 배열 안에 값이 저장된다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>while(1)<br />
{<br />
print_ship<br />
-&gt; MapDraw<br />
-&gt; swich case 문을 이용하여 버튼 눌렀을 때 좌표 이동 및 배 배치<br />
-&gt; erase_ship<br />
}</p>
</div>
<p><span style="color: #339966"><strong>나. 부저 사운드 함수</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>float start3[]= {329.6, 329.6, 329.6, 293.7, 329.6, 0, 329.6, 329.6 ,329.6, 293.7, 392.0, 349.2, 329.6,-1}; // start 사운드<br />
float end_win[] = {261.6, 329.6, 392.0, 523.3, -1}; // 승리 사운드<br />
float end_lose[] = {277.2, 261.6, 246.9, 223.1,-1}; // 패배 사운드<br />
float fire[]= {261.6, -1}; // 포격 성공 사운드<br />
float wrecked[] = {130.8, 123.5, -1}; // 침몰사운드<br />
float miss[] = {392.0 ,-1}; // miss 사운드<br />
float scan2[] = {440.0, -1}; // scan 사운드<br />
void Buzzer(float arr[])<br />
{<br />
int i = 0;<br />
DDRB |=(1&lt;&lt;DDB4); //5번 핀으로 소리 출력<br />
TCCR0 = 0x1D;<br />
TCCR1A = 0&#215;00;<br />
TCCR1B = 0&#215;04;<br />
TCNT0 = 0;<br />
TCNT1 = 65536 &#8211; 55000;</p>
<p>while(arr[i] != -1)<br />
{<br />
OCR0 = (int)(8000000/(arr[i]*256));<br />
while((TIFR &amp; 0&#215;04) == 0);<br />
TIFR |= 0&#215;04;<br />
TCNT1 = 61250;<br />
//=====================<br />
OCR0 = 0;<br />
while((TIFR &amp; 0&#215;04) == 0);<br />
TIFR |= 0&#215;04;<br />
TCNT1 = 55000;<br />
i++;<br />
}<br />
TCCR0 = 0;<br />
}<br />
</div>
<p>타이머/카운터 레지스터를 설정하고 while문의 인자에는 arr[i] 배열의 인자(주파수)를 하나씩 실행 시키는데 -1이 나오면 효과음이 끝나도록 설정 하였고 하나의 효과음이 모두 나온 후에 다음 동작(화면이 바뀌거나 스위치를 작동하는 행위)이 실행된다.<br />
빠른 게임 진행을 위해서 게임 시작, 게임 종료를 나타내는 효과음 이외의 배열(arr[i])의 길이를 짧게 설정하였다.</p>
<p><span style="color: #339966"><strong>다. 통신 방법</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>void Init_interrupt_usart(void) // 인터럽트 레지스터 설정<br />
{<br />
UCSR0A = 0&#215;00;<br />
UCSR0C = 0&#215;06;<br />
UCSR0B = 0xd8; // 1101 1000</p>
<p>UBRR0H = 0&#215;00;<br />
UBRR0L = 0&#215;07; // 115200bps<br />
SREG|=0&#215;80;<br />
}<br />
ISR(USART0_TX_vect) // led 제어, 끝나는거 제어<br />
{<br />
tx_done=0;<br />
}</p>
<p>ISR(USART0_RX_vect)<br />
{<br />
data = UDR0;</p>
<p>if(data==1) ////////////////////////<br />
led_turn=1;<br />
if(data==0) ////////////////////////<br />
led_turn=0;</p>
<p>if(data==Game_set)<br />
{<br />
end_flag=1;<br />
loss_cnt++;<br />
}<br />
if(data == re_game)<br />
re_game_flag2=1;</p>
<p>if(data == C_zero)<br />
C_zero_flag=1;</p>
<p>if(data == B_zero)<br />
B_zero_flag=1;</p>
<p>if(data == S_zero)<br />
S_zero_flag=1;</p>
<p>if(data == M_zero)<br />
M_zero_flag=1;</p>
<p>if(data == D_zero)<br />
D_zero_flag=1;<br />
}<br />
</div>
<p>인터럽트 ISR(USART0_TX_vect)은 메인문에서 UDR0 값을 넣어줬을 때 tx_done=0 으로 만들면서 ISR을 빠져나가게 되면서 while(tx_done);을 다음 코드로 진행할 수 있게 구성하였다.<br />
인터럽트 ISR(USART0_TX_vect)에서 정보는 최소화 하였고 보내는데 필요한 정보들은 flag 변수를 이용하여 주로 처리하였다.<br />
인터럽트 ISR(USART0_RX_vect)은 UDR0 값을 받아 변수 data에 저장 후 필요한 flag를 1로 set 하는 용도로 쓰였다.</p>
<p><span style="color: #33cccc"><strong>5.2. 아쉬운 점</strong></span><br />
<strong>블루투스 페어링(pairing) 오류</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-8.jpg" rel="lightbox[37988]"><img class="alignnone size-full wp-image-38056" alt="58 ict 배틀쉽 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-배틀쉽-8.jpg" width="620" height="459" /></a></p>
<p>기존 작품 설계 방향은 무선통신을 이용한 2인용 게임기를 만드는 것 이 목표였기 때문에 아두이노를 이용하여 블루투스를 페어링 하려 했지만 블루투스 모듈 문제로 페어링이 되지 않아 유선통신을 하게 되었다. 그림은 블루투스 모듈인 hc-05와 hc-06을 페어링 하고 있는 모습이다.<br />
<strong></strong></p>
<p><strong>휴대하기에는 큰 부피</strong><br />
기존에 보유하고 있던 큰 크기의 브레드보드를 기준으로 회로를 설계하고 게임기 외형을 제작하였기 때문에 휴대하기에는 큰 부피로 작품이 제작되었다.<br />
<strong></strong></p>
<p><strong>시간제한 기능 미사용</strong><br />
타이머 인터럽트를 사용해서 사용자가 공격하는데 30초의 시간제한을 두려 하였지만 여러 개의 인터럽트를 동시에 사용하여 충돌이 생겨 타이머가 제대로 작동하지 않았다.<br />
아래 내용은 타이머 인터럽트만을 사용하여 GLCD에 30초 타이머 기능을 구현한 코드와 코드의 설명이다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>ISR(TIMER0_COMP_vect) // 타이머 ISR (30초 카운트)<br />
{<br />
total_count++;<br />
if ( total_count == 1000 ) // total_cound는 1ms<br />
{<br />
if(++sec_first&gt;9){ s=0; // 1초 단위<br />
if(++sec_second&gt;2){ s1=0; //10초 단위<br />
}<br />
}<br />
//sec_first와 sec_second는 전역변수<br />
GLCD_TextGoTo(2,1); GLCD_WriteChar(sec_first+’0’); // GLCD에 1초 단위 표기<br />
GLCD_TextGoTo(1,1); GLCD_WriteChar(sec_second+’0’); // GLCD에 10초단위 표기<br />
_delay_ms(1);</p>
<p>total_count = 0;<br />
}<br />
}</p>
<p>void Init_Timer(void) // 타이머/카운터0 레지스터 설정을 통한 타이머 Init<br />
{<br />
TCCR0 |= (1&lt;&lt;CS02); // 프리스케일러로 64를 선택<br />
TCCR0 |= (1&lt;&lt;WGM01); // CTC 모드<br />
TCNT0 = 0; // 카운터 초기화<br />
OCR0 = 249; // TOP 정의<br />
TIMSK |= (1&lt;&lt;OCIE0); // 타이머/카운터0 Compare Match 인터럽트 활성화<br />
sei(); // 전역 인터럽트 활성화<br />
total_count = 0; // total_count 초기화<br />
}</p>
<p>void Quit_Timer(void) // Timer 레지스터 설정을 통한 Timer Quit<br />
{<br />
TIMSK = 0&#215;00; // 타이머/카운터의 interrupt를 비활성화<br />
sec_first = 0; // sec_first를 초기화<br />
sec_second = 0; // sec_second를 초기화<br />
total_count = 0; // total_count를 초기화<br />
}<br />
</div>
<p>타이머 기능: Init_Timer에서 타이머/카운터0의 레지스터 설정을 통해 1ms마다 total_count가 1씩 증가하는 타이머를 만들었다. 각 레지스터의 설정은 다음과 같다. Init_Timer함수의 주석을 통해서 설명되어 있다.<br />
Init_Timer를 통해서 타이머/카운터0이 활성화 되면 TCNT가 OCR과 같아지는 순간 타이머0 ISR(TIMER0_COMP_vect)로 진입하여total_count가 1ms마다 증가하며, total_count가 1000이 되는 순간 sec_first를 1씩 증가시킨다. sec_fisrt가 10이 되는순간 sec_first는 0으로 초기화되고, sec_second가 1씩 증가한다. sec_second가 3이되는 순간 sec_second는 0으로 초기화 된다.<br />
코드를 통해, 위 내용을 확인할 수 있으며, sec_first와 sec_second는 각각 1초 단위 10초 단위를 의미한다.<br />
종합 의견 : 완성된 작품에서 무선통신과 타이머 기능을 추가하고 작은 크기의 브레드보드를 사용하여 외형을 제작한다면 보다 편리하고 직관적인 게임기의 기능을 갖추게 될 것이다.</p>
<p><span style="color: #33cccc"><strong>5.3. 참고문헌</strong></span><br />
· 뉴티씨 (newtc) : http://www.newtc.co.kr/dpshop/bbs/board.php?bo_table=m41&amp;wr_id=745&amp;page=5<br />
· 인터럽트 레지스터 설정 : https://webnautes.tistory.com/984<br />
· USART 통신 : https://blog.naver.com/xisaturn/220750649418<br />
· 그림 1,2 battleship 보드게임 예시 : https://en.wikipedia.org/wiki/Battleship_(game)<br />
· 그림 3. ATmega128 data sheet : http://www.siphec.com/item/AVR-ATmega128-ATmega1281-ATmega2561.html<br />
· 그림 6. 주파수와 피에조 부저의 음계 : https://kocoafab.cc/tutorial/view/626<br />
· 그림 7. ATmega USART Tx/Rx 연결 회로도 : https://blog.naver.com/iintuition_/220587315291</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/37988/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[58호]세이프티 볼라드</title>
		<link>http://www.ntrexgo.com/archives/37996</link>
		<comments>http://www.ntrexgo.com/archives/37996#comments</comments>
		<pubDate>Thu, 20 Feb 2020 00:00:17 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[58호]]></category>
		<category><![CDATA[Feature]]></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=37996</guid>
		<description><![CDATA[디바이스마트매거진 &#124; 신호에 따라 올라가고 내려가는 시스템으로 장애인분들의 이동권을 보장 해 줄 수 있을 뿐만 아니라 일반인들의 무단횡단을 줄여 안전사고를 예방할 수 있다.]]></description>
				<content:encoded><![CDATA[<p><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-1.png" rel="lightbox[37996]"><img class="alignnone size-large wp-image-38097" alt="58 ict 세이브티볼라드 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-1-620x196.png" width="620" height="196" /></a></strong></p>
<p><strong>2019 ICT 융합 프로젝트 공모전 참가상</strong></p>
<p><span style="font-size: x-large"><strong>세이프티 볼라드</strong></span></p>
<p style="text-align: right">글 | 경북대학교 김도훈, 박선우, 박은빈</p>
<p style="text-align: right">
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 횡단보도등에서 발생하는 사고소식을 접할때마다 늘 생각이 들던 시스템이고, 간혹 주차장 입출입구 등에 유사한 시스템이 적용되어 있는 것을 본적이 있는듯 하다. 하지만 여러가지 현실적인 문제로 인하여 아직까지도 적용이 되지 않는게 아닐까 하는 막연한 추측을 하고 있다. Mechanic적인 요소를 적용한 것이 매우 흥미로우며, 시제품의 완성도도 생각보다는 높게 평가할수 있을듯 하다. 앞서 설명한것과 같이 실제 시스템을 적용하기 위한 현실적인 문제에 대하여 조금 더 고민하여 개선된 제품이 나온다면 아파트 단지등과 같은 변수고려가 적은 환경에 있어 적용가능할 것으로 보인다.<br />
<strong>뉴티씨</strong> 법적으로 근거가 있는 아이디어이며, 또한, 많은 특허들도 등록되어 있습니다. 실용화가 가능한 것으로, 이미 국내 및 일본 등에서 실용화가 되어 있는 곳도 있는것으로 알고 있습니다. 장소에 따라서는 사고를 막기위하여 매우 중요한 시설로 사용될 수 있다고 생각됩니다. 학생으로 스스로 이런 생각을 해내었다는 점에서 박수를 보냅니다.<br />
<strong>위드로봇</strong> 아이디어가 독보이는 작품입니다. 실용성 측면을 좀 더 고민하면 더욱 좋은 작품이 될 것 같습니다.<br />
펌테크 작품의 하우징 구성은 상당히 깔끔하고 훌륭하게 구성이 되었으나, 작품의 구성 측면에서는 너무 단순하고 심플한 느낌을 받았습니다. 작품전 출전이라는 것을 감안한다면 현재의 작품에 아디디어를 좀 더 반영한 형태로 출품이 되었다면 좋지 않았을까 생각합니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 동기 및 개요</strong></span><br />
<span style="color: #33cccc"><strong>2.1. 동기</strong></span><br />
[랩해서남줄랩]이라는 TV프로그램의 주제 중 ‘나는 장애를 극복하지 않았다.’라는 편을 보았습니다. 이 프로그램에서는 지체장애인분들이 일상생활에서 많은 불편함을 겪고 있고, 이것을 해결하기위해 직접 나서는 모습을 담고 있었습니다. 특히 차가 들어오는 것을 막기 위해 설치를 해둔 볼라드 때문에 휠체어가 지나가지 못하거나, 걸린다는 것을 알게 되었습니다. 이런 불편사항을 보안하기 위해 ‘자동으로 움직이는 볼라드는 어떨까?‘라는 생각을 하게 되었고 주로 횡단보도에 설치되어있는 볼라드에 적용해보기로 했습니다.<br />
볼라드가 올라오고 내려오는 과정을 토의하면서 주의할 점을 파악해 나갔습니다. 무턱대고 볼라드가 땅에서 올라오면 횡단보도에 서있던 보행자가 다칠 위험이 클 것이라고 생각했습니다. 그래서 볼라드를 윈기둥 형태가 아닌 ‘π’자 형태로 만들기로 했습니다. 세이프티 볼라드의 윗부분은 일반 보행자들에게 잘 보이는 색상으로 구성하였고, 지체장애인 분들도 볼라드의 위치를 알도록 들어갔을 때도 약간 볼록한 형태로 구상을 했습니다.<br />
또한, 이 볼라드는 지체장애인분들 뿐만 아니라 보호구역에서도 유용하게 사용될 수 있을 것이라고 판단했습니다. 어린이 보호구역에 세이프티 볼라드가 설치된다면 아이들에게 신호체계를 보다 정확하게 알려 줄 수 있을 것이라고 생각합니다. 더불어 빨간불일 때 횡단보도에서 무단횡단을 하는 사람들이 줄어들어 보다 나은 교통질서를 제공할 것입니다. 결과적으로 안전사고를 예방하는데 큰 도움이 되는 시스템이라고 자부합니다.</p>
<p><span style="color: #33cccc"><strong>2.2. 개요</strong></span><br />
이 세이프티 볼라드는 신호에 따라 올라가고 내려가는 시스템을 가지고 있다. 이것은 장애인분들의 이동권을 보장 해 줄 수 있을 뿐만 아니라 일반인들의 무단횡단을 줄여 안전사고를 예방할 수 있다. 또한 어린이 보호구역에 설치하여 초록어머니를 대신하는 횡단보도 지킴이가 될 것이다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong>3.1. 구상도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-2.png" rel="lightbox[37996]"><img class="alignnone size-large wp-image-38099" alt="58 ict 세이브티볼라드 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-2-614x620.png" width="614" height="620" /></a></p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-3.png" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38101" alt="58 ict 세이브티볼라드 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-3.png" width="620" height="231" /></a></p>
<p>차량이 지나다니지 않아도 신호등이 빨간불이 되면 볼라드에 신호를 주어 땅에서 올라와 보행자가 지나가지 못하도록 길을 막습니다. 마찬가지로 신호등이 파란불이 되면 볼라드에 신호를 주어 땅으로 들어가서 보행자가 길을 다닐 수 있도록 합니다.</p>
<p><span style="color: #33cccc"><strong>3.2. 결과물 사양</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-4.png" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38103" alt="58 ict 세이브티볼라드 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-4.png" width="620" height="531" /></a></p>
<p><span style="color: #0000ff"><strong>4. 제작과정</strong></span><br />
<span style="color: #33cccc"><strong>4.1. 단계별 제작과정</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-1.jpg" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38096" alt="58 ict 세이브티볼라드 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-1.jpg" width="620" height="241" /></a></p>
<p>도로의 안, 즉 땅 속을 나타낼 틀을 제작합니다. 이 때 볼라드가 만들어질 위치에 모터와 볼라드를 설치할 지지대를 만들어 줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-2.jpg" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38098" alt="58 ict 세이브티볼라드 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-2.jpg" width="620" height="241" /></a></p>
<p>볼라드 지지대를 만들어 올라가고 내려갈 수 있도록 기존의 지지대에 설치해 줍니다. 이는 모터에 부착된 톱니바퀴가 회전을 하면 아래, 위로 움직여주는 역할을 합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-3.jpg" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38100" alt="58 ict 세이브티볼라드 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-3.jpg" width="620" height="241" /></a></p>
<p>모터를 볼라드와 연결된 부분에 연결시켜 주어 모터가 돌아가면 볼라드가 올라가고 내려가도록 설정해줍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-4.jpg" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38102" alt="58 ict 세이브티볼라드 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-4.jpg" width="620" height="241" /></a></p>
<p>시스템 상단에 도로를 구현해 줍니다. 분홍색부분은 인도 부분이며 검은색부분은 차도로 횡단보도만 나타냈습니다. 빨간색 LED와 초록색LED를 연결한 신호등을 설치해 줍니다.<br />
볼라드를 설치할 구멍을 뚫어 볼라드가 내려가고 올라가도록 합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-5.png" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38104" alt="58 ict 세이브티볼라드 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-5.png" width="620" height="241" /></a></p>
<p>빨간불 일 때는 볼라드가 올라오도록 모터가 정방향 회전을 합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-6.png" rel="lightbox[37996]"><img class="alignnone size-full wp-image-38095" alt="58 ict 세이브티볼라드 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2020/02/58-ict-세이브티볼라드-6.png" width="620" height="241" /></a></p>
<p>초록불 일 때는 볼라드가 내려가도록 모터가 후방향 회전을 합니다.</p>
<p><span style="color: #33cccc"><strong>4.2. 주요 동작 및 특징</strong></span><br />
전체적인 동작 내용은 신호등과 횡단보도를 표현하고 신호등 신호에 맞게 볼라드를 위아래로 움직여 주는 것이다. 이를 위해 아두이노 보드와 모터 쉴드를 이용해 모터의 동작과 LED 깜박임을 제어하도록 구성하였다. 먼저 신호등 빨간불에서 초록불로 바뀌는 경우에 LED-green에 전압을 인가하고 LED-red의 전압을 차단하는 동시에 두 모터에 동작명령을 주어 횡단보도 양측 볼라드가 같이 내려가도록 설계하였다. 초록불 시간이 거의 다 끝나갈 때 즈음 LED-green이 깜박이도록 명령을 주어 신호가 거의 끝나간다는 것을 표현하였다. 이후 시간이 다 되면 LED-green의 불이 꺼짐과 동시에 LED-red의 불이 켜지면서 볼라드가 올라오도록 설계하였다.<br />
상하로 움직일 수 있는 볼라드로 인해 볼라드의 주 기능인 차량 통제의 역할을 수행할 수 있는 동시에 볼라드로 인해 발생했던 보행자의 통행 불편함을 해소할 수 있게 되었다.<br />
또한 제작 과정에서 볼라드가 내려갈 때와 올라갈 때의 모터 구동 시간을 다르게 설정하여 중력으로 인한 모터의 부하로 발생하는 볼라드의 높이 오차를 해결하였다.</p>
<p><span style="color: #33cccc"><strong>4.3. 전체 시스템 구성</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;AFMotor.h&gt;</p>
<p>AF_DCMotor motor1(3); // M3에 연결<br />
AF_DCMotor motor2(2); // M2에 연결</p>
<p>void setup() {<br />
Serial.begin(9600); // set up Serial library at 9600 bps<br />
Serial.println(“Motor test!”);</p>
<p>// turn on motor<br />
motor1.setSpeed(0); // 모터 회전속도 설정<br />
motor2.setSpeed(0);<br />
motor1.run(RELEASE);<br />
motor2.run(RELEASE);</p>
<p>// analog input pin을 output으로 초기화<br />
pinMode(A0, OUTPUT); // RED<br />
pinMode(A5, OUTPUT); // GREEN<br />
}</p>
<p>void loop() {<br />
uint8_t i;</p>
<p>delay(1000);</p>
<p>Serial.print(“tick”);</p>
<p>// 정방향 회전<br />
motor1.run(FORWARD);<br />
motor2.run(FORWARD);<br />
digitalWrite(A0, LOW); // RED off<br />
digitalWrite(A5, HIGH); // GREEN on</p>
<p>// 모터 구동 시작<br />
for (i=0; i&lt;60; i++) {<br />
motor1.setSpeed(180);<br />
motor2.setSpeed(180);<br />
delay(10);<br />
}</p>
<p>// 모터 정지<br />
motor1.run(RELEASE);<br />
motor2.run(RELEASE);<br />
delay(5000);</p>
<p>Serial.print(“tock”);</p>
<p>// 초록불 점멸<br />
for (i=0; i&lt;5; i++) {<br />
digitalWrite(A5, LOW);<br />
delay(200);<br />
digitalWrite(A5, HIGH);<br />
delay(200);<br />
}</p>
<p>Serial.print(“tech”);</p>
<p>// 역방향 회전<br />
motor1.run(BACKWARD);<br />
motor2.run(BACKWARD);<br />
digitalWrite(A0, HIGH); // RED on<br />
digitalWrite(A5, LOW); // GREEN off</p>
<p>// 모터 구동 시작<br />
for (i=0; i&lt;80; i++) {<br />
motor1.setSpeed(200);<br />
motor2.setSpeed(200);<br />
delay(10);<br />
}</p>
<p>// 모터 정지<br />
motor1.run(RELEASE);<br />
motor2.run(RELEASE);<br />
delay(7000);<br />
}<br />
</div>
<p>위는 스마트 볼라드의 모형을 구동시키기 위한 소스 코드이다. 상하로 왕복운동을 하는 구조는 과학상자로 만들었으며, 이에 필요한 두 개의 모터를 제어하기 위한 장치로 아두이노(UNO R3 ATmega328)와 아두이노 모터 쉴드(Adafruit L293D Motor Shield)를 선택하였다. 아두이노의 코드는 C++을 기반으로 만들어졌다. 따라서 코드의 문법은 모두 C++과 동일하다. 아두이노에서 모터쉴드를 제어하기 위한 헤더파일(AFMotor.h)이 제공되고 있으므로 이를 활용하였다. 아두이노의 코드는 크게 두 부분으로 구분된다. LED, 모터 등의 객체를 생성하고 객체들의 초기 설정을 해주는 부분인 void setup() 함수와 무한 반복되며 하드웨어의 실질적인 동작을 기술하는 부분인 void loop() 함수로 이루어진다. 먼저, 가장 첫 부분은 다음과 같다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include &lt;AFMotor.h&gt;</p>
<p>AF_DCMotor motor1(3); // M3에 연결<br />
AF_DCMotor motor2(2); // M2에 연결</p>
</div>
<p>#include &lt;AFMotor.h&gt;는 Adafruit L293D Motor Shield를 활용하기 위한 라이브러리를 추가하는 부분이다. 미리 만들어져있는 헤더파일을 통해 모터 객체를 쉽게 생성하고, 다양한 메소드를 편리하게 사용할 수 있게 된다. 아래의 두 줄은 AFMotor 라이브러리에 정의되어있는 AF_DCMotor 클래스를 사용해 두 개의 모터를 제어하기 위해 각각 motor1, motor2 라는 모터 객체를 생성한다. 이때 생성자의 매개변수로 각각 3, 2를 넘겨주었는데, 이는 모터 쉴드의 4개의 모터 연결 포트 중 motor1은 3번 포트에, motor2는 2번 포트에 연결하겠다는 의미이다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>void setup() {<br />
Serial.begin(9600); // set up Serial library at 9600 bps<br />
Serial.println(“Motor test!”);</p>
<p>// turn on motor<br />
motor1.setSpeed(0); // 모터 회전속도 설정<br />
motor2.setSpeed(0);<br />
motor1.run(RELEASE);<br />
motor2.run(RELEASE);</p>
<p>// analog input pin을 output으로 초기화<br />
pinMode(A0, OUTPUT); // RED<br />
pinMode(A5, OUTPUT); // GREEN<br />
}</p>
</div>
<p>Serial.begin(speed)는 아두이노가 시리얼 통신을 사용하게 만드는 메소드이다. Serial은 시리얼 통신과 관련된 메소드들이 포함되어있는 정적(static) 클래스이다. 메소드의 인자로 넘겨주는 speed 초당 몇 비트의 속도로 통신을 할지 설정하는 값이다. 이는 컴퓨터 쪽의 시리얼 통신 속도와 일치하여야 시리얼 모니터에 정상적으로 출력이 된다. 다음은 모터와 LED를 초기화하는 부분이다. setup() 함수 이전에 생성한 두 개의 모터 객체의 속도와 현재 구동 상태를 각각 0과 RELEASE 상태로 초깃값을 설정해 준다. 아두이노 보드에는 12개의 출력 핀과 6개의 아날로그 인풋 포트가 있다. 그런데 Adafruit L293D Motor Shield는 2번, 13번 핀을 제외하고는 모두 사용하는 방식으로 아두이노 보드에 장착된다. 따라서 모터를 구동시키는 것 외에 신호등을 구현하기 위한 두 개의 LED의 출력을 제어하기 위해서는 아날로그 인풋 포트를 디지털 아웃풋 핀으로 사용할 필요가 있었다. 그 설정을 해주는 부분이 pinMode() 함수이다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>void loop() {<br />
uint8_t i;</p>
<p>delay(1000);<br />
</div>
<p>loop() 함수는 setup() 함수가 실행된 후 프로그램이 종료될 때까지 함수 내부의 내용이 무한 반복되며 실행된다. 먼저 uint8_t i; 는 loop() 함수 내부의 반복문에서 계속 사용할 지역변수 i를 선언하는 코드이다. 자료형 uint8_t 는 &lt;stdint.h&gt;에 정의되어있는 자료형으로, 8비트의 부호가 없는 정수형의 자료형을 나타낸다. 즉, 정수 0에서부터 255까지 표현할 수 있다. 아두이노 UNO R3 ATmega328는 8-bit의 프로세서를 가지고 있어 8비트 보다 큰 자료를 한 번에 처리하지 못하므로 해당 자료형을 사용한다. delay() 함수는 의미 그대로 코드를 실행하는데 시간을 지연시키는 역할을 한다. 함수의 인자로 전달받는 시간의 단위는 ms(밀리세컨드) 이므로 위의 예처럼 1000 을 넘기면 1000ms 즉 1초를 지연시킨다. 이 delay() 함수를 통해 신호등의 빨간불, 초록불이 켜지는 시간과 모터를 동작시키는 반복문의 시간을 제어할 수 있다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>Serial.print(“tick”);</p>
<p>// 정방향 회전<br />
motor1.run(FORWARD);<br />
motor2.run(FORWARD);<br />
digitalWrite(A0, LOW); // RED off<br />
digitalWrite(A5, HIGH); // GREEN on</p>
<p>// 모터 구동 시작<br />
for (i=0; i&lt;60; i++) {<br />
motor1.setSpeed(180);<br />
motor2.setSpeed(180);<br />
delay(10);<br />
}</p>
<p>// 모터 정지<br />
motor1.run(RELEASE);<br />
motor2.run(RELEASE);<br />
delay(5000); Serial.print(“tick”);</p>
<p>// 정방향 회전<br />
motor1.run(FORWARD);<br />
motor2.run(FORWARD);<br />
digitalWrite(A0, LOW); // RED off<br />
digitalWrite(A5, HIGH); // GREEN on</p>
<p>// 모터 구동 시작<br />
for (i=0; i&lt;60; i++) {<br />
motor1.setSpeed(180);<br />
motor2.setSpeed(180);<br />
delay(10);<br />
}</p>
<p>// 모터 정지<br />
motor1.run(RELEASE);<br />
motor2.run(RELEASE);<br />
delay(5000);</p>
</div>
<p>Serial.print(“tick”) 메소드는 아두이노 개발환경의 시리얼 모니터에 “tick”이라는 문자열을 출력한다. 이를 통해 loop() 함수 내부에서 해당 메소드까지 소프트웨어적으로 문제없이 실행되고 있음을 확인하기 위한 목적으로 활용한다. 초록불이 되고 모터가 정방향으로 구동되기 시작할 때 “tick”을, 초록불이 깜빡거리기 시작할 때 “tock”을, 빨간불이 되고 모터가 역방향으로 구동되기 시작할 때 “tock”을 출력하도록 하였다.<br />
motor1.run(FORWARD); 는 모터를 회전시키기 위하여 모터 객체(motor1, motor2) 의 상태를 정지(RELEASE)에서 정방향 회전(FORWARD)로 변경시켜 주는 부분이다. digitalWrite(pin, value); 함수는 HIGH 또는 LOW 값을 디지털 핀에 출력하는 함수이다. setup() 함수에서 아날로그 입력 단자 A0, A5를 pinMode() 함수를 통해 디지털 출력 핀으로 설정해 주었기 때문에 A0, A5 단자에 대해서 HIGH, LOW의 값을 출력할 수 있다. A0 단자에는 빨간색의 LED를 연결하고, A5 단자에는 초록색의 LED를 연결할 것이므로, 빨간색 신호등은 끈 상태로, 초록색 신호등은 켜진 상태로 만들기 위해 digitalWrite() 함수의 value 인자를 각각 LOW, HIGH로 설정하였다.<br />
초록불이 켜지고 난 다음은 올라가 있던 스마트 볼라드가 땅으로 내려올 차례이다. AF_DCMotor클래스의 메소드인 .setSpeed(speed) 메소드는 모터의 속력을 설정한다. speed 인자의 값으로 0에서 255까지의 값을 받을 수 있으며, 0은 꺼진 상태를, 255는 최대 속력을 나타낸다. 우리가 설정한 speed 값인 180은 어떤 정확한 수치를 나타내는 것이 아니다. DC 모터의 응답이 일반적으로 선형적이지 않으므로, 실제 RPM이 설정된 값인 180에 비례하게 나타나지는 않는다. 다양한 값으로 구동을 시켜본 결과 볼라드 구조물의 무게와 부하를 이겨내기 위한 적절한 속도를 구한 것이 180이다.<br />
반복문의 한 루프에 10ms씩의 시간 지연이 들어가 있어 총 60번의 반복을 하므로 이론적으로는 총 0.6초가 걸리겠지만, 모터가 구동되는 시간으로 인해 시간이 조금 더 걸려 1초 내외로 동작을 마친다. 반복문의 실행을 마치고 나면 양쪽의 볼라드가 하강하여 땅으로 완전히 내려와 있는 상태가 된다. motor1.run(RELEASE); 메소드는 볼라드가 정지한 이후 두 개의 모터의 동작 상태를 정방향 구동 중에서 정지로 바꿔주는 부분이다. 또한, 초록불이 점멸하기 시작하기 전까지 5초 동안의 시간 지연을 준다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>Serial.print(“tock”);</p>
<p>// 초록불 점멸<br />
for (i=0; i&lt;5; i++) {<br />
digitalWrite(A5, LOW);<br />
delay(200);<br />
digitalWrite(A5, HIGH);<br />
delay(200);<br />
}</p>
</div>
<p>초록불이 일정 시간이 지나 빨간불로 바뀌기 전 깜빡이는 기능을 수행하는 부분이다. 따라서 위에서 말한 대로 초록불이 점멸하기 전 Serial.print() 메소드를 통해 “tock”을 시리얼 모니터에 출력하여 프로그램이 정상 작동하고 있는지 확인한다. 초록색 LED가 연결된 A5 포트의 출력을 LOW, HIGH로 0.2초의 시간 지연을 두고 번갈아 가면서 5번 바꾼다. 다시 말해서, 초록불이 다섯 번 깜빡이고 끝난다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>Serial.print(“tech”);</p>
<p>// 역방향 회전<br />
motor1.run(BACKWARD);<br />
motor2.run(BACKWARD);<br />
digitalWrite(A0, HIGH); // RED on<br />
digitalWrite(A5, LOW); // GREEN off</p>
<p>// 모터 구동 시작<br />
for (i=0; i&lt;80; i++) {<br />
motor1.setSpeed(200);<br />
motor2.setSpeed(200);<br />
delay(10);<br />
}</p>
<p>// 모터 정지<br />
motor1.run(RELEASE);<br />
motor2.run(RELEASE);<br />
delay(7000);<br />
</div>
<p>초록불이 깜빡거리기를 끝내고 빨간불로 바뀌면서 모터가 작동하여 볼라드가 올라가는 동작을 시키는 부분이다. 초록불이 되고 볼라드가 내려가는 동작을 하는 loop() 함수의 첫 번째 블록과 거의 같은 코드 구성을 하고 있다. 하지만 세세한 설정은 정반대이다. 모터가 구동되는 방향이 반대여야 하므로 이전에 FORWARD로 설정하였던 값을 BACKWARD로 바꾸고, 초록불과 빨간불의 켜지고 꺼짐도 반대로 바뀌었다. 모터 구동 부분의 반복문의 경우 반복 횟수가 위의 블록과 같지 않다. 같은 구조로 코드를 작성하여 실행시켜 보았을 때, 볼라드 구조물의 무게로 인해 볼라드가 내려가는 길이에 비해 올라가는 길이가 적었다. 따라서 반복문의 횟수를 더 크게 설정하여 올라가고 내려오는 길이가 거의 같도록 조절하였다. 또한, 모터의 상태를 정지(RELEASE)로 변경한 후 주는 시간 지연이 더 긴 것은 초록불과는 다르게 깜빡거리는 시간을 고려하지 않았기 때문이다.</p>
<p><span style="color: #33cccc"><strong>4.4. 기대효과 및 예상되는 장애요인과 해결방안</strong></span><br />
스마트 볼라드가 실제로 도입된다면 필요에 따라 볼라드를 설치 및 제거함으로써 차량 통제가 필요한 곳에 널리 쓰일 수 있을 것이다. 예를 들어 주차장에서의 차량 통제나 인도의 불법 주정차 예방에도 사용될 수 있고, 큰 행사로 인해 넓은 지역의 대규모 차량 통제가 필요한 경우 손쉽게 스마트 볼라드를 이용하여 차량 진입을 막을 수 있다.<br />
또한 스마트 볼라드는 횡단보도에서 지하철의 스크린 도어와 비슷한 역할을 해줄 수 있기 때문에 무단횡단 예방의 효과가 있고, 횡단보도에서의 교통사고 발생 위험을 상당히 낮출 수 있을 것으로 기대된다.<br />
특히, 어린이 보호 구역이나 보행 약자가 많은 지역에서 스마트 볼라드가 빛을 발할 수 있는데 사람 없이도 24시간 교통 약자의 보행을 보호해줄 수 있어 교통 상황을 관리해주는 교통 경찰이나 경비원, 녹색 어머니회의 역할을 대신할 수 있다.<br />
스마트 볼라드를 제작하는 과정에서 여러 좋은 아이디어가 나왔지만 직접 제작하는 데까지는 이르지 못하였다. 예를 들어 볼라드에 LED를 설치하여 야간에 어두운 길을 밝혀 주는 역할을 할 수도 있고, 센서를 부착해 사람을 인식하여 차가 없으면 신호가 바뀌고 자동으로 내려가게 하는 기능과 시간대 별로 보행자와 차량의 통행량 정보를 측정해 교통 정보도 수집할 수 있도록 할수 있을것이다. 그리고 볼라드가 움직이기 전에 음성안내를 해주어 보행자에게 미리 알려주는 기능도 추가되면 좋을 것 같다.<br />
스마트 볼라드에서 예상되는 장애요인으로는 갑자기 움직이는 볼라드로 인한 보행자 피해와 볼라드의 설치 및 유지 관리 문제가 있다.<br />
하지만 이런 문제는 향후 발전 방향에서 언급한 것처럼 볼라드가 움직이기 전에 LED점멸이나 음성 안내 메시지를 통해 보행자가 볼라드의 움직임을 미리 예측할 수 있도록 한다면 보행자가 볼라드의 움직임을 인지하지 못해 생기는 사고를 예방할 수 있을 것이다. 또한 스마트 볼라드는 땅 밑에 장치를 설치하여 볼라드가 올라오는 방식이므로 설치가 비교적 쉬운 편이고 외부 충격으로 인한 파손이 있다 하더라도 볼라드 기둥만 교체해 주면 되기 때문에 수리하기도 편리할 것이다. 또한 컴퓨터로 볼라드를 제어할 수 있기 때문에 볼라드 관리도 간편할 것으로 예상된다.</p>
<p><span style="color: #0000ff"><strong>5. 참고</strong></span><br />
· 아두이노 코드 및 구동방법: https://youtu.be/V-MXQN3CjEE https://www.youtube.com/watch?v=D5JX2N-7zWo</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/37996/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[49호]실시간 영상처리 방식 졸음운전 방지 블랙박스</title>
		<link>http://www.ntrexgo.com/archives/35889</link>
		<comments>http://www.ntrexgo.com/archives/35889#comments</comments>
		<pubDate>Mon, 20 Aug 2018 00:00:57 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[blog-posts]]></category>
		<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[49호]]></category>
		<category><![CDATA[Feature]]></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=35889</guid>
		<description><![CDATA[디바이스마트매거진 49호 &#124; 졸음운전시스템은 고급차량의 옵션으로 붙어있거나 33~55만원 사이의 비싼 가격에 팔리고 있다. 그렇기 때문에 하드웨어의 성능을 조금 낮추고 졸음운전을 판단하는 기술력을 상승시킴으로써 싼 가격에 많은 사람들이 이용할 수 있도록 구현한다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440.png" rel="lightbox[35889]"><img class="alignnone size-large wp-image-35589" alt="Cap 2018-07-12 14-10-54-440" src="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440-620x210.png" width="620" height="210" /></a></p>
<p><span style="background-color: #000000; font-size: medium; color: #ffffff;"><strong>  2018 ICT 융합 프로젝트 공모전 최우수상  </strong></span></p>
<p><span style="font-size: x-large; color: #000000; background-color: #ffffff;"><strong>실시간 영상처리 방식 졸음운전 방지 블랙박스</strong></span></p>
<p style="text-align: right;">글 | 성결대학교 오태식, 여규성, 김성중, 이정희</p>
<p>&nbsp;</p>
<p><span style="color: #339966;"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 보고서가 아주 훌륭합니다. 실제 동일한 기대효과를 가지는 개발이 많이 진행되고 있지만, 블랙박스와 같이 별도 구매 제품에 적용하려고 한 시도가 좋습니다.</p>
<p><strong>뉴티씨</strong> 자율 주행이나 ADAS와 같은 시스템처럼, 여기에 필요한 기반기술인 차선인식이나 눈 깜빡임 인식으로, 안전을 보장하는 기능도 최근 블랙박스 등에 많이 탑재되고 있는 핫한 기술입니다. 이를 학생이 직접 세부적인 기술 구현을 통하여, 가능하게 하였다는 점에서 높은 점수를 주었으며, 조금 더 안정성있게 시간을 가지고 개발한다면, 실제 제품으로까지 개발이 가능할 것으로 생각됩니다. 문서작성도 매우 잘하여서, 엔지니어들의 부족한 점인 문서작성 부분에서도 높은 점수를 주었습니다. 최근 졸음운전으로 인한 교통사고가 급증하고 있는 바, 매우 실용적인 작품으로 생각됩니다.</p>
<p><strong>위드로봇</strong> 목표, 연구 진행 및 결과에 대한 분석 등이 잘 작성된 프로젝트입니다. 눈 깜박임의 판별의 경우는 편광 필터 사용 및 추가 카메라(적외선) 적용을 추천하며, 차량의 주행 방향은 GPS 정보가 추가로 필요할 것으로 보입니다.</p>
<p><span style="color: #339966;"><strong>2. 작품 개요</strong></span><br />
최근 고속도로 교통사고 사망률 조사에 따르면 졸음운전에 의한 사고가 1위를 향하고 있다. 졸음운전에 의한 사고는 내 주변 가족, 친척, 친구 등 얼마든지 일어날 수 있는 사고이다. 사람들은 졸음운전에 대한 위험성과 그에 따른 피해가 얼마나 심각한지 너무나 잘 알고 있기 때문에 기업과 국가에서는 졸음운전에 의한 사고를 예방하고자 하는 여러 제품들과 정책을 세우고 홍보를 하고 있다. 그럼에도 불구하고 졸음운전에 의한 사고는 좀처럼 나아지지 않고 있다.<br />
졸음운전에 의한 사고는 우리나라에서 뿐만 아니라 전 세계 곳곳에서도 일어나고 있다. 졸음은 생물학적인 생리현상이기 때문에 정신을 붙잡는다고 해서 이길 수 있는 것은 아니다. 미국의 도로교통안전국(NHTSA)에 따르면 2005~2009년 사이 전체 사망사고 중 2.2%~2.6%가 졸음운전과 관리되어 있다고 한다. 졸음운전은 운전자의 주의력을 낮추고, 반응시간을 느리게 하며, 운전자의 판단능력에 영향을 주어 심각한 사고를 유발할 가능성이 높기 때문에 미국에서도 다양한 대책이 적용되어왔다.</p>
<p><span style="color: #339966;"><strong>3. 작품 목표</strong></span><br />
<strong>1. 졸음운전 사망사고율을 1%미만으로 낮춘다.</strong><br />
졸음운전에 의한 사고를 1%미만으로 줄임으로서 많은 사람들이 졸음운전을 예방할 수 있도록 한다.</p>
<p><strong>2. 고급승용차 뿐만 아니라 택시, 버스, 대형 화물차, 지하철 등과 같은 차량에도 설치하여 대중화를 목표로 한다.</strong><br />
현재 시중에 나와 있는 졸음운전시스템은 고급차량의 옵션으로 붙어있거나 33~55만원 사이의 비싼 가격에 팔리고 있다. 그렇기 때문에 하드웨어의 성능을 조금 낮추고 졸음운전을 판단하는 기술력을 상승시킴으로써 싼 가격에 많은 사람들이 이용할 수 있도록 구현한다.</p>
<p><strong>3. 스마트폰과 라즈베리파이를 연동하여 사용함으로서 단일 제품가격을 저렴하게 한다.</strong><br />
한 기기에서만 처리하던 기존 제품들과는 달리 누구나 가지고 있는 스마트폰과 연동하여 처리함으로서 하드웨어적 성능을 낮추고 제품 가격을 저렴하게 한다.<br />
4. OpenCV 방식 영상처리 기술을 통해 정확도 향상시킨다.<br />
영상처리 기술을 통해 차선과 눈 깜빡임을 처리, 정확도를 높이고 하드웨어적인 성능 한계를 소프트웨어 기술을 통해 향상시킨다.</p>
<p><span style="color: #339966;"><strong>4. 작품 설명</strong></span><br />
<strong>1. 블랙박스의 차선검출 시스템 제작</strong><br />
라즈베리파이의 카메라 센서를 활용하여 차선을 검출한다. 운전자의 차량이 차선을 벗어나게 되면 졸음운전을 하고 있음을 판단한다. 다음의 차선검출을 통한 졸음운전 판단은 1차적인 판단기준에 속한다.</p>
<p><strong>2. 스마트폰을 이용한 눈 깜빡임 검출</strong><br />
최근 스마트폰의 네비게이션 어플리케이션을 활용하는 사람들이 많아지고 있다. 그래서 스마트폰의 카메라를 이용하여 카메라에 사용자의 눈을 인식하도록 하고 만약 사용자가 눈을 감고 있으면 졸음운전을 하고 있음을 판단한다. 다음의 눈 깜빡임을 통한 졸음운전 판단은 2차적인 판단기준에 속한다.</p>
<p><strong>3. 2, 3차사고 방지를 위한 GPS센서 활용과 서버제작</strong><br />
2, 3차 사고를 방지하기 위해 사용자간의 운전 상태에 대한 정보를 공유한다. 하지만 다음의 기능은 졸음운전 방지시스템을 사용하는 사용자가 많아지면 서버를 개방하여 사용할 수 있도록 한다.</p>
<p><strong>4. 사용자의 Application사용 편의성을 위한 NFC(Near Field Communication)기능 제공</strong><br />
매번 차에 앉아서 사람들은 네비게이션을 켜고 또 졸음운전방지 어플리케이션을 켜서 사용해야한다는 불편함을 가지고 있다. 그래서 이러한 불편함을 해소하고자 NFC기능을 추가하여 거치대에 스마트폰을 거치하면 자동으로 어플리케이션이 실행되도록 한다.</p>
<p><span style="color: #339966;"><strong>5. 주요 동작 및 특징</strong></span><br />
<span style="color: #3366ff;"><strong>5.1. 스마트폰 운전자 얼굴 감지</strong></span><br />
<span style="color: #00ccff;"><strong>5.1.1. 눈깜빡임 검출 연구 (얼굴 검출)</strong></span><br />
<strong>준비사항</strong><br />
· 사용 기기 : 스마트폰 (SM-G930S 삼성 갤럭시S7)<br />
· 프로그래밍 언어 : 자바<br />
· 영상처리 api : OpenCV 3.0.0_android</p>
<p><strong>개요</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-1.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35893" alt="2018 ict _ 최우수상 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-1.png" width="127" height="87" /></a></p>
<p>· 얼굴로서의 특징을 모두 가지고 있다.<br />
· 처음부터 종료시까지 계속 눈을 감고 있지 않는다.<br />
<strong>설계 과정</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-2.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35894" alt="2018 ict _ 최우수상 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-2.png" width="545" height="491" /></a></p>
<p><strong>눈깜빡임 검출 </strong><strong>구현 알고리즘</strong></p>
<p>1. 흑백 변환<br />
CvCameraViewFrame 객체의 프레임을 흑백으로 저장하는 gray 메소드 사용<br />
2. lbp cascade를 이용하여 얼굴 검출<br />
detectMultiScale 메소드를 이용하여 검출 감지된 얼굴 좌표는 MatOfRect형 변수로 저장된다.<br />
3. 눈 영역 추출<br />
얼굴 좌표에서 ( 얼굴의 위 좌표 + 얼굴 높이 / 4.5 ) ~ ( 얼굴 위 좌표 + 얼굴 높이 / 3.0 ) 에 눈이 있다고 가정<br />
4. harrcascade를 이용 하여 눈 검출<br />
detectMultiScale 메소드를 검출 신뢰성을 향상시키기 위해 여러번 검출 후 정렬하여 가장 크고 작은 값들(오검출이라 예상되는 값)을 제외하고 평균을 내서 눈의 위치를 확정 얼굴의 위치와 각도등의 변경을 대처하기 위해 옵티컬 플로우(루카스 카나데)를 사용하여 눈의 위치 추적 사용하는 메소드 calcOpticalFlowPyrLK()<br />
5. 눈주변을 canny 변환<br />
canny 메소드를 이용하여 canny 변환 Mat형 변수로 저장된다.<br />
6. 허프 변환으로 기울기 계산<br />
HoughLines 메소드를 이용하여 허프 변환 얼굴의 너비에 따라서 최소 선분 길이 지정 기울기에 따라 다른 값 저장</p>
<p><span style="color: #00ccff;"><strong>5.1.2. 처리 이미지 크기 조정</strong></span><br />
<strong>개요</strong><br />
처리 이미지를 960 X 비율에 맞는 세로로 resize해 사용함으로서 초당 프레임 상승을 기대한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-3.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35895" alt="2018 ict _ 최우수상 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-3.png" width="182" height="168" /></a></p>
<p><strong>설계 과정</strong><br />
얼굴 검출을 제외한(얼굴 검출 시에는 480 X (비율에 맞는 세로 크기) 사용) 얼굴 추적, 눈 검출, 눈 깜빡임 검출에 쓰이는 이미지를 960 X (비율에 맞는 세로 크기)로 맞춘다.</p>
<p><strong>구현</strong></p>
<p><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-5.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35898" alt="2018 ict _ 최우수상 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-5.png" width="545" height="177" /></a></strong><br />
<strong> 결과</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-4.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35896" alt="2018 ict _ 최우수상 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-4.png" width="537" height="172" /></a></p>
<p>초당 프레임이 2~3 프레임에서 5~6 프레임 증가하였다</p>
<p><span style="color: #00ccff;"><strong>5.1.3. 얼굴 크기 및 회전 보정</strong></span><br />
<strong>개요</strong><br />
처리할 얼굴 이미지를 (480 X 비율에 맞는 세로)로 resize하고 회전을 보정받음으로서 눈 검출 및 템플릿 매칭, 개폐판단을 보완한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-1.jpg" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35897" alt="2018 ict _ 최우수상 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-1.jpg" width="286" height="140" /></a></p>
<p><strong>설계 과정</strong><br />
얼굴 이미지를 새로 만들어 (480 X (비율에 맞는 세로 크기) )로 resize 후 회전 보정한다.</p>
<p><strong>구현</strong><br />
1. 랜드마크의 각도를 정렬하고 오차라 판단하는 앞뒤 각각 3개씩을 제외한 값을 평균을 내어 저장한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-6.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35899" alt="2018 ict _ 최우수상 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-6.png" width="546" height="396" /></a></p>
<p>2. getRotationMatrix2D를 통해 2D 변환식을 저장한 후 warpAffine을 통해 회전 변환을 적용한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-7.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35900" alt="2018 ict _ 최우수상 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-7.png" width="544" height="248" /></a></p>
<p>3. 크기를 보정한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-8.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35901" alt="2018 ict _ 최우수상 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-8.png" width="546" height="83" /></a></p>
<p><strong>결과</strong><br />
·크기 고정 및 회전 보정을 하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-9.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35902" alt="2018 ict _ 최우수상 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-9.png" width="311" height="178" /></a></p>
<p><span style="color: #00ccff;"><strong>5.1.4. 얼굴 배경 제거</strong></span><br />
<strong>개요</strong><br />
히스토그램 평활화를 할 때 외부 배경의 밝기에 영향을 받지 않고 외부가 밝든 어둡든 얼굴 밝기를 항상 비슷하게 유지하기 위하여 배경을 제거한다. 또한 눈 검출 및 매칭, 기울기 판단 시에도 좋은 영향을 준다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-2.jpg" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35903" alt="2018 ict _ 최우수상 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-2.jpg" width="269" height="137" /></a></p>
<p><strong>설계과정</strong><br />
얼굴 윤곽 안쪽만 투명한 이미지와 원본 이미지를 배열곱하여 배경을 제거한다.</p>
<p><strong>구현</strong><br />
1. 얼굴 윤곽을 잡아낸다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-10.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35904" alt="2018 ict _ 최우수상 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-10.png" width="547" height="224" /></a></p>
<p>2. fillConexPoly 함수로 얼굴 영역만 투명한 8비트 4채널 이미지와 원본을 8비트 4채널로 변환한 이미지를 준비한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-11.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35905" alt="2018 ict _ 최우수상 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-11.png" width="547" height="201" /></a></p>
<p>3. 배열곱을 한 후 1채널 gray로 변환한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-12.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35906" alt="2018 ict _ 최우수상 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-12.png" width="546" height="104" /></a></p>
<p>4. 얼굴 영역만 깊은복사를 하고 평활화를 한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-13.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35907" alt="2018 ict _ 최우수상 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-13.png" width="546" height="80" /></a></p>
<p><strong>결과</strong><br />
얼굴 이미지의 배경을 제거 히스토그램 평활화</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-14.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35908" alt="2018 ict _ 최우수상 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-14.png" width="304" height="141" /></a></p>
<p><span style="color: #00ccff;"><strong>5.1.5. 눈 검출 후 템플릿 수집</strong></span><br />
<strong>개요</strong><br />
눈 템플릿을 만든 후 각도와 좌표를 저장한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-15.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35909" alt="2018 ict _ 최우수상 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-15.png" width="280" height="145" /></a></p>
<p><strong>설계 과정</strong><br />
Harr 검출로 눈을 검출한 후 템플릿을 수집하고 템플릿들을 히스토그램 비교를 이용하여 오류를 배제, 템플릿들의 좌표와 각도를 수집하여 템플릿 매칭에 쓰일 템플릿, 템플릿 매칭 오류를 보정해줄 눈 좌표, 눈 깜빡임 판별을 위해 눈을 떴을 경우 각도를 정한다.</p>
<p><strong>구현</strong><br />
1. 눈을 검출한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-24.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35920" alt="2018 ict _ 최우수상 (24)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-24.png" width="549" height="153" /></a></p>
<p>2. 템플릿을 20개 정도 수집한다. 이때 정규화한 히스토그램 값과 중심 좌표 값을 같이 저장한다.<br />
3. 각 값들에 대한 히스토그램을 비교한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-17.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35913" alt="2018 ict _ 최우수상 (17)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-17.png" width="552" height="131" /></a><br />
좌표값과 각도의 평균, 가장 유사도가 높은 템플릿을 저장한다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-18.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35914" alt="2018 ict _ 최우수상 (18)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-18.png" width="548" height="279" /></a></p>
<p><strong>결과</strong><br />
눈의 템플릿을 만들었다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-19.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35915" alt="2018 ict _ 최우수상 (19)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-19.png" width="306" height="142" /></a></p>
<p><span style="color: #00ccff;"><strong>5.1.6. 눈의 각도 측정</strong></span><br />
<strong>개요</strong><br />
눈의 각도를 측정한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-20.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35916" alt="2018 ict _ 최우수상 (20)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-20.png" width="191" height="89" /></a></p>
<p><strong>설계 과정</strong><br />
가우시안 블러로 잡음을 제거한 후 케니엣지를 통해 엣지를 구한다. 허프라인을 통해 선을 찾은 후 각도를 측정한다.</p>
<p><strong>구현</strong><br />
1. 잡음 제거 후 케니엣지로 엣지를 구하고 허프라인으로 선 반환을 받는다. 그 후 각도를 저장한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-21.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35917" alt="2018 ict _ 최우수상 (21)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-21.png" width="550" height="130" /></a><br />
2. 저장한 각도를 0 ~ 90도 사이로 변환하고 각도를 정렬 후 앞 10% 뒤 10%를 제외한 값을 평균을 내어 저장한다.</p>
<p><strong>결과</strong><br />
각도를 측정, 저장하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-22.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35918" alt="2018 ict _ 최우수상 (22)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-22.png" width="160" height="137" /></a></p>
<p><span style="color: #00ccff;"><strong>5.1.7. 템플릿 매칭</strong></span><br />
<strong>개요</strong><br />
템플릿 매칭을 이용하여 눈을 찾는다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-23.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35919" alt="2018 ict _ 최우수상 (23)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-23.png" width="263" height="153" /></a></p>
<p><strong>설계 과정</strong><br />
템플릿 매칭은 회전과 크기, 조명 변화에 민감하지만 회전과 크기 보정, 배경 제거 후 히스토그램 평활화를 하였기 때문에 검출률을 상당히 높일 수 있었다. 나머지 잔 오검출을 제외하기 위하여 템플릿 선정에서 얻은 좌표값을 이용하여 보정하여 눈의 검출을 완벽히 한다.</p>
<p><strong>구현</strong><br />
1. TM_SQDIFF 방식으로 유사 템플릿을 찾는다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-24.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35920" alt="2018 ict _ 최우수상 (24)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-24.png" width="549" height="153" /></a><br />
2. 좌표값의 차이가 너무 클 경우 (눈을 감을 경우 템플릿 유사도가 크게 달라지기 때문에 오검출이 일어날 경우가 있음) 기존 템플릿의 위치에 의존하여 눈을 찾는다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-25.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35921" alt="2018 ict _ 최우수상 (25)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-25.png" width="545" height="444" /></a></p>
<p><strong>결과</strong><br />
템플릿 매칭을 이용해 눈을 찾았다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-26.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35922" alt="2018 ict _ 최우수상 (26)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-26.png" width="219" height="120" /></a></p>
<p><span style="color: #0000ff;"><strong>5.2. 블랙박스 &#8220;도로 차선 감지&#8221;</strong></span><br />
<span style="color: #00ccff;"><strong>5.2.1. 차선 이탈 감지 시스템 구현</strong></span><br />
<strong>1. 차선 인식</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-27.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35923" alt="2018 ict _ 최우수상 (27)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-27.png" width="545" height="198" /></a></p>
[차선의 종류] (경부고속도로 상부)<br />
① : 흰색 차선(일반)<br />
② : 황색 차선(중앙/끝)<br />
③ : 청색 차선(버스전용)<br />
차선을 인식하기 위해서는 먼저 차선의 특징을 알 필요가 있다. 졸음운전이 일어나기 쉬운 고속도로에 존재하는 차선은 흰색, 황색, 청색이 있다. 3가지 종류의 차선을 특정하기 위하여 영상에서 흰색, 황색, 청색 영역을 추출한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-28.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35924" alt="2018 ict _ 최우수상 (28)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-28.png" width="261" height="152" /></a></p>
[흰색 영역 추출]
·흰 영역을 추출하였을 때 차선이 아닌 다른 부분도 추출됨을 볼 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-29.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35925" alt="2018 ict _ 최우수상 (29)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-29.png" width="265" height="151" /></a></p>
[차선 특정]
·색 영역을 추출하여 얻어낸 데이터를 바탕으로 차선으로 추정되는 객체를 특정한다.</p>
<p><span style="color: #00ccff;"><strong>5.2.2. 차선 검출 구현</strong></span><br />
<strong>준비 사항</strong><br />
· 사용 기기 : RaspberryPi 3, Logitech Webcam C270<br />
· 프로그래밍 언어 : C++<br />
· 영상처리 api : OpenCV 3.1.0</p>
<p><strong>개요</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-3.jpg" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35926" alt="2018 ict _ 최우수상 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-3.jpg" width="549" height="203" /></a></p>
<p>위와 같은 풍경이 펼쳐지고 있을 때, 차선만을 검출하는 방법에 대하여 설명한다.<br />
· 일반적인 도로의 모습에서 차선의 특징을 정의 한다.<br />
· 차선의 색은 흰색, 노란색이고, 도로의 색(아스팔트)과 큰 차이가 난다.<br />
· 차선은 일정한 두께가 있다.<br />
· 차선들은 하나의 소실점에서 만난다.</p>
<p><strong>설계 과정</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-30.png" rel="lightbox[35889]"><img class="alignnone size-large wp-image-35927" alt="2018 ict _ 최우수상 (30)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-30-446x620.png" width="446" height="620" /></a></p>
<p><strong>차선 검출 구현 알고리즘</strong></p>
<p>1. Gray Scale 변환<br />
·cv::cvtColor 사용 Gray Scale 변환<br />
·0~1(float)scale cv::Mat.convertTo 사용</p>
<p>2. edge 크기 검출<br />
· cv::Sobel 함수로 x축, y축으로 미분<br />
·cv::cartToPolar 함수에 x/y축으로 미분한 값을 넣어 edge의 크기(magnitude)와 방향(orientation)을 구한다.</p>
<p>3. 객체 최대치 검출<br />
·magnitude의 정보가 담긴 값 중에left &lt; middle &gt; right 가 되는 middle 값만 추출</p>
<p>4. 차선 후보 검출<br />
·영상의 아래쪽으로 갈수록 커지고 위로 갈수록 작아지는 최저 차선폭을 지정<br />
· 같은 y값을 가지는 인접한 두 지점간 거리와 해당되는 y축의 최저 차선폭을 비교.<br />
· 두 지점의 magnitude값이 유사 검사.<br />
· 위 조건을 만족 시 두 지점의 orientation값이 160~200도 차이가 나는지 비교한다.<br />
· 모든 조건을 만족하면 두 지점의 중심점을 차선 후보 점으로 지정한다.</p>
<p>5. 선 검출<br />
· cv::HoughLinesP 함수에 이전 연산의 결과로 나온 객체를 입력하여 직선 좌표값을 뽑아낸다.</p>
<p>6. 소실점 계산<br />
· RANSAC 알고리즘으로 소실점을 찾는다.<br />
· 소실점으로 향하는 직선만 차선으로 인정.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-4.jpg" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35911" alt="2018 ict _ 최우수상 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-4.jpg" width="546" height="315" /></a></p>
<p><span style="color: #00ccff;"><strong>5.2.3. 차선 검출 속도 향상을 위한 관심영역 지정</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-31.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35929" alt="2018 ict _ 최우수상 (31)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-31.png" width="543" height="173" /></a><br />
<strong>개요</strong><br />
차선 검출 시에 연산하는 영역을 촬영 영상 중 실제 도로가 속해 있는 영역으로만 강제 하여(관심 영역 지정) 연산 속도를 향상시킨다.</p>
<p><strong>설계 과정</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-32.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35930" alt="2018 ict _ 최우수상 (32)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-32.png" width="485" height="249" /></a></p>
<p>영상의 상단 30%는 지평선의 윗부분으로 간주한다.<br />
영상의 하단 10%는 차량의 본넷 부분으로 간주한다.<br />
나머지 중간 영역을 관심 영역으로 지정하여 연산한다.</p>
<p><strong>구현</strong><br />
관심 영역의 사각형 객체를 이용하여 일부분만 다룬다. 차선 검출 속도 향상을 위한 관심 영역 지정</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-33.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35931" alt="2018 ict _ 최우수상 (33)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-33.png" width="549" height="103" /></a></p>
<p><strong>결과</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-34.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35932" alt="2018 ict _ 최우수상 (34)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-34.png" width="280" height="334" /></a><br />
상단 : 원본, 하단 : 관심 영역<br />
원본에서 관심 영역을 설정한 것을 알 수 있다.<br />
차선 검출 속도 향상을 위한 관심 영역 지정</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-35.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35933" alt="2018 ict _ 최우수상 (35)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-35.png" width="549" height="220" /></a></p>
<p>좌측 : 영역을 연산 시 소비클록, 우측 : 관심 영역을 연산 시 소비클록(약 1/3의 연산 시간의 절약이 있었다.)</p>
<p><strong>문제점</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-36.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35934" alt="2018 ict _ 최우수상 (36)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-36.png" width="549" height="202" /></a><br />
좌측 : 정상 각도, 우측 : 비정상 각도<br />
관심 영역 도로가 들어올 수 있게 카메라의 각도를 조정</p>
<p><span style="color: #00ccff;"><strong>5.2.4. 차량의 차선 이탈 감지</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-37.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35935" alt="2018 ict _ 최우수상 (37)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-37.png" width="328" height="194" /></a><br />
<strong>개요</strong><br />
올바른 주행이 아닌 상태는 두 가지로 볼 수 있다.<br />
① 좌측 상황 : 차량이 차선 내부에 있지만 차량의 주행 방향과 차선의 방향이 일치하지 않다.<br />
② 우측 상황 : 차량이 차선을 밟고 있다.</p>
<p><strong>설계 과정</strong><br />
① 상황을 감지하기 위해서 필요한 요소는 아래와 같다.<br />
1. 차량의 주행 방향 2. 차선의 방향<br />
나머지 요소인 차량의 주행 방향을 알기 위해서 다양한 방식을 적용할 수 있다.<br />
· 차량 전륜의 방향을 알아낸다.<br />
· 자이로스코프 센서를 부착하여 데이터를 분석한다.<br />
· 영상처리로 알아낸다.<br />
이 중 2가지 방법은 추가 하드웨어 요소를 필요로 한다,</p>
<p>② 상황을 감지하기 위해서 필요한 요소는 아래와 같다.<br />
1. 차선의 위치 2. 차량의 위치<br />
사전에 영상에서 차선을 검출하였기 때문에 차선의 위치는 쉽게 알 수 있다.<br />
· 차량의 위치를 촬영하고 있는 블랙박스의 위치이다.<br />
· 우리는 상대적으로 어렵다고 예상되는 ②번 상황을 우선적으로 구현하기로 하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-38.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35936" alt="2018 ict _ 최우수상 (38)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-38.png" width="548" height="156" /></a></p>
<p>②번 영역의 중앙에 특별한 영역(노란색 영역)을 만든다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-39.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35937" alt="2018 ict _ 최우수상 (39)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-39.png" width="542" height="152" /></a></p>
<p>영상에서 차선객체의 중점(파란색 점)을 가져온다.<br />
· 노이즈 객체들을 분별하기 위하여 길이를 정의한다.<br />
· 관심 영역의 절반의 대각선 길이(노란선의 길이)를 100%로 잡고 비교하여 20% 이상의 길이를 가지는 객체를 차선으로 인정한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-41.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35939" alt="2018 ict _ 최우수상 (41)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-41.png" width="550" height="232" /></a><br />
· 지정한 특별 영역에 있는 객체들의 길이를 알아 낸 뒤,<br />
합이 20% 이상이 되면 차량이 경고를 판별한다.<br />
(예시 : 노란색 영역에 중점이 있는 차선 객체 길이의 합이 28%(20% 이상) 차량이 차선을 밟았다고 판별함)</p>
<p><strong>구현</strong><br />
관심영역에 특별영역을 만들고 100%의 기준이 되는 선의 길이를 구한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-42.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35940" alt="2018 ict _ 최우수상 (42)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-42.png" width="547" height="298" /></a></p>
<p>특별영역에 들어온 차선을 판별한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-43.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35941" alt="2018 ict _ 최우수상 (43)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-43.png" width="546" height="420" /></a></p>
<p>길이의 총합이 20%가 넘는 경우가 연속해서 5번 생기면, BlueTooth가 연결된 기기에 detect 신호를 송신한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-44.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35942" alt="2018 ict _ 최우수상 (44)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-44.png" width="545" height="398" /></a></p>
<p><strong>결과</strong><br />
관심 영역의 차선이 중앙에 있을 시에 감지를 한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-45.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35943" alt="2018 ict _ 최우수상 (45)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-45.png" width="329" height="226" /></a></p>
<p><span style="color: #0000ff;"><strong>5.3. 스마트폰 거치(NFC)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-46.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35944" alt="2018 ict _ 최우수상 (46)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-46.png" width="547" height="289" /></a></p>
<p><span style="color: #00ccff;"><strong>5.3.1. 네트워크 통신 구현</strong></span><br />
<strong>준비 사항</strong><br />
· 사용 기기 : 스마트폰<br />
· 프로그래밍 언어 : 자바<br />
· 통신 방식 : FCM (FireBase Cloud Message)</p>
<p><strong>개요</strong><br />
라즈베리파이와 안드로이드 간의 통신 연구로 새로운 통신 방식을 조사하여 데이터를 주고 받아본다. FCM이라는 클라우드 메시지 방식을 테스트해본다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-47.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35945" alt="2018 ict _ 최우수상 (47)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-47.png" width="268" height="148" /></a></p>
<p><strong>FCM 설명</strong><br />
메시지를 무료로 안정적으로 전송해줄 수 있는 하나의 메시지 전송 시스템의 장점으로는 1. 서버를 따로 만들 필요 없이 클라이언트만 제작하여 메시지를 주고받을 수 있는 시스템, 2. 쉽고 빠르게 구현, 3. 앱의 사용자가 많아진다면 서버코드를 확장하지 않고도 알아서 처리가 있다.</p>
<p><strong>특징</strong><br />
· 저장된 양의 데이터를 통계적으로 볼 수 있다.<br />
· 테스트 메시지를 보낼 수 있어 테스트가 편리하다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-48.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35946" alt="2018 ict _ 최우수상 (48)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-48.png" width="564" height="193" /></a></p>
<p><strong>설계과정</strong><br />
1. 안드로이드 app에 firebase를 추가한다. (패키지 이름, 앱 닉네임, 빈칸)<br />
2.자동적으로 google-services.json이 다운로드되면 프로젝트의 메니페스트가 있는 경로에 복사한다.<br />
3.서버에 프로젝트를 등록하고 sener ID와 server KEY를 얻는다. (Project &gt; Settings &gt; Cloud Messaging에서 체크)<br />
4. 프로젝트 수준과 앱 수준의 gradle을 전부 설정해준다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-49.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35947" alt="2018 ict _ 최우수상 (49)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-49.png" width="550" height="208" /></a><br />
5. 각 기기가 서버에 접속할 수 있게 토큰을 생성해준다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-50.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35948" alt="2018 ict _ 최우수상 (50)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-50.png" width="553" height="111" /></a><br />
6. 메시지 수신 시 이벤트로 노티피케이션과 진동을 준다.<br />
7. 메시지 송신 시 서버로 메시지를 전송한다.</p>
<p><span style="color: #00ccff;"><strong>5.3.2. FCM 구현 알고리즘</strong></span><br />
<strong>1. 토큰 생성</strong><br />
· 서버에서 해당 프로젝트의 어플 사용자임을 인증하고 토큰을 받는다.<br />
· FirebaseInstanceId.getInstance().getToken() 메소드 이용 해당 기기의 토큰을 생성한다.<br />
· okhttp3의 Request 메소드를 이용하여 토큰을 서버에 전송한다.<br />
<strong>2. msg수신</strong><br />
· notificationManager.메소드를 이용하여 받은 메시지를 띄운다<br />
· Vibrator로 진동을 준다.<br />
<strong>3. msg송신</strong><br />
· databaseReference.메소드를 이용하여 서버의 데이터베이스에 메시지를 쓴다.</p>
<p><span style="color: #00ccff;"><strong>5.3.3. 라즈베리파이(블랙박스)와 안드로이드간의 블루투스 통신</strong></span><br />
<strong> 구현</strong><br />
· 라즈베리파이의 라이언트를 accept, 정보를 상시 수신한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-51.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35949" alt="2018 ict _ 최우수상 (51)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-51.png" width="549" height="495" /></a></p>
<p>· 차선 이탈을 감지시, 클라이언트에 detect 신호 송신한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-52.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35950" alt="2018 ict _ 최우수상 (52)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-52.png" width="550" height="394" /></a></p>
<p>· 안드로이드 어플리케이션에서 사전에 페어링된 기기 리스트를 받아서, Spinner에 배치한다. Spinner에서 선택된 블루투스 기기(라즈베리파이)에 접속을 준비한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-53.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35951" alt="2018 ict _ 최우수상 (53)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-53.png" width="549" height="448" /></a></p>
<p>· 서버(라즈베리파이)에 접속, I/OStream을 열고 통신한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-54.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35952" alt="2018 ict _ 최우수상 (54)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-54.png" width="550" height="398" /></a></p>
<p>· 스레드를 생성 후 서버에서 보내는 값을 항상 체크한다.<br />
· 서버에서 detect 신호를 보내주면 알람(진동)을 울린다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-55.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35928" alt="2018 ict _ 최우수상 (55)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-55.png" width="548" height="598" /></a></p>
<p><strong>결과</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-5.jpg" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35953" alt="2018 ict _ 최우수상 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-5.jpg" width="545" height="172" /></a><br />
라즈베리파이(서버)에서 소켓을 만들고 listen, accept하는 것을 볼 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-56.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35954" alt="2018 ict _ 최우수상 (56)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-56.png" width="555" height="166" /></a><br />
안드로이드 어플리케이션(클라이언트)에서 1. 접속할 기기를 선택 2. 서버(라즈베리파이)에 접속 3. detect 신호를 수신하여 텍스트로 출력한다.</p>
<p><span style="color: #00ccff;"><strong>5.3.4. 서버와 통신 &#8211; 알림</strong></span><br />
<strong>개요</strong><br />
졸음운전 판단 시 알림을 준다.</p>
<p><strong>설계과정</strong><br />
1. 사용자가 졸음운전을 하고 있다고 판단이 되는 경우 알림을 재생한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-57.png" rel="lightbox[35889]"><img alt="2018 ict _ 최우수상 (57)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-57.png" width="547" height="179" /></a><br />
2. 사용자가 알람을 들을 경우 버튼을 눌러서 알람을 중지한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-58.png" rel="lightbox[35889]"><img alt="2018 ict _ 최우수상 (58)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-58.png" width="548" height="199" /></a></p>
<p>&nbsp;</p>
<p><strong>구현</strong><br />
이벤트가 발생할 때마다 알람이 울려야 되기 때문에 이벤트 발생 지점으로부터 Media Player를 생성한다.<br />
GPS가 동작하지 않거나 GPS 신호를 받을 수 없더라도 졸음운전이라는 판단이 날 경우 알람을 울리도록 구현한다.<br />
1. 사용자가 졸음운전을 하고 있다고 판단이 되는 경우 알림 재생한다.<br />
2. 사용자가 알람을 들을 경우 버튼을 눌러서 알람을 중지한다.</p>
<p><span style="color: #00ccff;"><strong>5.3.5. FCM 서버등록</strong></span><br />
<strong> 개요</strong><br />
졸음운전의 2, 3차 사고방지를 위하여 FCM을 이용하여 서버를 구축하고 졸음운전자가 있다는 메시지를 실시간으로 알려주기 위해 사용한다.</p>
<p><strong>구현</strong><br />
[1] Firebase홈페이지에서 프로젝트를 생성</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-59.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35957" alt="2018 ict _ 최우수상 (59)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-59.png" width="547" height="228" /></a></p>
[2] android앱에 Firebase를 추가하기 위한 작업을 수행한다.<br />
(1) 안드로이드의 패키지 이름을 등록 한다.<br />
(2) google-service.json을 다운로드받고 파일을 안드로이드에 복사한다.<br />
(3) App수준의 build.gradle에 아래 문구를 추가한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-61.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35959" alt="2018 ict _ 최우수상 (61)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-61.png" width="548" height="153" /></a><br />
(4) project수준의 build.gradle에 다음과 같이 추가</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-62.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35960" alt="2018 ict _ 최우수상 (62)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-62.png" width="547" height="154" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-63.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35961" alt="2018 ict _ 최우수상 (63)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-63.png" width="550" height="125" /></a><br />
Firebase를 사용하기 위한 서버를 구축하였다.</p>
<p><span style="color: #00ccff;"><strong>5.3.6. FCM DataBase sating &amp; GPS, Date</strong></span><br />
<strong> 개요</strong><br />
FCM서버와 클라이언트가 서로 통신하기 위해서 Database가 필요하다 이곳의 Database에는 졸음운전자의 위치와 시간정보를 받아 다른 사용자들에게 실시간으로 메시지를 전송해 준다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-64.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35962" alt="2018 ict _ 최우수상 (64)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-64.png" width="572" height="260" /></a></p>
<p><strong>구현</strong><br />
[1] Database를 사용하기 위해 규칙을 설정한다.</p>
[2]데이터베이스에 내용을 전송하기 위해 어플리케이션에서 소스코드를 작성한다.<br />
(1) 데이터베이스에 내용을 보낼 빈 생성자를 만든다. 이때 생성자 안에는 GPS의 정보와 날짜와 시간의 정보가 담겨있다.<br />
(2) GPS 위치정보 받아오기 위한 소스코드</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-65.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35963" alt="2018 ict _ 최우수상 (65)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-65.png" width="548" height="274" /></a></p>
<p>(3) 날짜와 시간정보를 받아오기 위한 소스코드</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-66.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35964" alt="2018 ict _ 최우수상 (66)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-66.png" width="546" height="125" /></a><br />
(4) 위치정보와 시간정보를 데이터베이스에 전송하기 위한 소스코드</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-67.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35965" alt="2018 ict _ 최우수상 (67)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-67.png" width="543" height="126" /></a></p>
<p>&nbsp;</p>
[3] firebase에 올린 데이터 정보를 받기 위해서 수신 메시지 소스를 작성한다.</p>
<p><strong>문제점</strong><br />
위도와 경도의 정보를 그대로 사용할 수 없다. 또한 GPS를 켜지 않은 상태에서 메시지를 전송할 경우 Database에 잘못된 정보가 올라가게 되어 앱이 설치되어있는 모든 앱이 다운되는 현상이 발생한다.</p>
<p><strong>결과</strong><br />
스마트폰의 상단 바에 졸음운전자가 있음을 알리는 메시지를 전송한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-68.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35966" alt="2018 ict _ 최우수상 (68)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-68.png" width="555" height="262" /></a></p>
<p><span style="color: #339966;"><strong>6. 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-69.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35967" alt="2018 ict _ 최우수상 (69)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-69.png" width="558" height="436" /></a><br />
<span style="color: #3366ff;"><strong> 6.1. 눈 깜빡임 검출 연구 결과</strong></span><br />
<span style="color: #00ccff;"><strong> 6.1.1. 문제점 분석 및 해결방안</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-70.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35968" alt="2018 ict _ 최우수상 (70)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-70.png" width="548" height="260" /></a></p>
<p><span style="color: #00ccff;"><strong>6.1.2. 차선 검출 연구 결과</strong></span><br />
실제 Webcam을 사용한 실험 결과</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-71.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35969" alt="2018 ict _ 최우수상 (71)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-71.png" width="547" height="163" /></a></p>
<p><span style="color: #3366ff;"><strong>6.2. 스마트폰 어플리케이션 연구 결과</strong></span><br />
<span style="color: #00ccff;"><strong> 6.2.1. 오버레이 뷰 구현</strong></span><br />
<strong>개요</strong><br />
운전중에 스마트폰 네비게이션앱을 사용자하는 운전자가 많다.<br />
타사 앱 위 오버레이 창을 올려 앱의 유연성을 높인다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-72.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35970" alt="2018 ict _ 최우수상 (72)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-72.png" width="244" height="190" /></a></p>
<p><strong>설명</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-73.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35971" alt="2018 ict _ 최우수상 (73)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-73.png" width="377" height="144" /></a></p>
<p>· 좌측 영역 : 전면카메라의 프리뷰<br />
· 경고 수치 : 경고 정보 스택. 오버플로우시 경고가 울린다.<br />
· 차선이탈 : 블랙박스에서 받은 차선이탈 정보 알림<br />
· 눈 감음 : 전면카메라를 영상 처리한 결과 눈 감음 알림<br />
· BT 연결 : 블랙박스와의 연결 상태<br />
· 차선인식 : 블랙박스의 차선인식 원활상태<br />
· 카메라 : 전면카메라의 사용자 얼굴 인식 상태<br />
· 연결된 기기 : 블루투스로 연결된 기기의 이름</p>
<p><strong>구현</strong><br />
· 서비스 매니저를 불러서 뷰의 권한을 가지고 온다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-74.png" rel="lightbox[35889]"><img class="alignnone size-large wp-image-35972" alt="2018 ict _ 최우수상 (74)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-74-439x620.png" width="439" height="620" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-75.png" rel="lightbox[35889]"><img class="alignnone  wp-image-35973" alt="2018 ict _ 최우수상 (75)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-75.png" width="439" /></a></p>
<p><strong>결과</strong><br />
다른 어플리케이션 위에 오버레이 뷰가 실행된다.<br />
오버레이 뷰를 터치시 여러 기능이 실행된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-76.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35974" alt="2018 ict _ 최우수상 (76)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-76.png" width="550" height="377" /></a></p>
<p>· 더블클릭 : 앱으로 복귀한다.<br />
· 롱 크릭 &amp; 드래그 : 오버레이 뷰를 이동한다.</p>
<p><span style="color: #00ccff;"><strong>6.2.2. 오버레이 뷰를 통한 전면 카메라 영상처리 백그라운드 화</strong></span><br />
<strong> 개요</strong><br />
안드로이드에서 카메라를 사용하려면 카메라 프리뷰가 활성화 되어 있어야 하는데, 액티비티가 백그라운드화 되면 프리뷰가 활성화 되지 않아 카메라를 사용할 수가 없다. 이에 백그라운드에서 돌아가는 기존의 오버레이 뷰 서비스에 카메라 기능을 추가하여 카메라를 언제나 사용할수 있게 한다.</p>
<p><strong>설계 과정</strong><br />
오버레이 뷰 서비스에 카메라 사용, 영상처리 기능을 추가하여 프리뷰를 오버레이 뷰 또는 프리뷰를 감추어 놓고 카메라를 이용하게 한다.</p>
<p><strong>구현</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-77.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35975" alt="2018 ict _ 최우수상 (77)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-77.png" width="547" height="223" /></a><br />
카메라 초기 설정을 마친 뒤 프리뷰를 뿌려줄 뷰 클래스를 지정하여 프리뷰를 시작한다.<br />
프리뷰가 갱신될 때 실행되는 PreviewCallback 클래스를 생성한다. 받아온 영상정보를 영상처리를 위한 Mat 객체로 만든다. 이후에 영상처리 과정을 시작한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-78.png" rel="lightbox[35889]"><img class="alignnone  wp-image-35976" alt="2018 ict _ 최우수상 (78)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-78-359x620.png" width="547" /></a></p>
<p><strong>결과</strong><br />
카메라를 서비스에서 실행하여 액티비티와 무관하게 실행한다. 설정을 주어 카메라 프리뷰를 보이지 않아도 카메라를 사용할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-79.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35977" alt="2018 ict _ 최우수상 (79)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-79.png" width="549" height="193" /></a></p>
<p><span style="color: #00ccff;"><strong>6.2.3. 차선이탈 감지 / 눈 감음 감지 정보의 융합</strong></span><br />
<strong> 개요</strong><br />
블랙박스에서 받은 차선이탈 감지 정보, 전면카메라 영상처리에서 얻은 눈 감음 감지 정보를 적절히 융합하여 졸음운전을 판단하여야 한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-80.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35978" alt="2018 ict _ 최우수상 (80)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-80.png" width="340" height="140" /></a></p>
<p><strong>설계 과정</strong><br />
두 가지의 정보가 생길 때 마다 변수의 값을 더한다.<br />
주기적으로 변수를 확인하여 일정 수치를 넘으면 졸음운전이라고 판단한다. 주기적으로 변수를 확인할 때 일정 수치를 깎아서 시간이 지나면 경고를 멈추게 한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-81.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35979" alt="2018 ict _ 최우수상 (81)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-81.png" width="289" height="279" /></a></p>
<p><strong>구현</strong><br />
차선 이탈 감지 정보, 눈 감음 정보가 생길 때 count_계열 변수를 증가시킨다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-82.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35980" alt="2018 ict _ 최우수상 (82)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-82.png" width="547" height="493" /></a><br />
일정 시간마다 count_total을 체크하여 5가 넘을 시 경고를 준다. 그 후 일정 수치만큼 count_total을 감소시킨다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-83.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35981" alt="2018 ict _ 최우수상 (83)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-83.png" width="548" height="495" /></a></p>
<p><span style="color: #00ccff;"><strong>6.2.4. 안전운전 수치 그래프 만들기</strong></span><br />
<strong>개요</strong><br />
사용자가 어플리케이션을 사용하여 운전을 할 때 감지되는 졸음운전 횟수를 저장하여 이를 바탕으로 운전자의 안전운전 수치 기록 그래프를 만든다.<br />
이를 통하여 사용자는 자신의 운전습관을 간접적으로 알 수 있으며 보다 안전한 운전을 할 수 있다.</p>
<p><strong>설계과정</strong><br />
졸음이 감지될 때마다 그 횟수를 파일에 저장, 횟수는 일별로 저장, 저장된 내용을 사용하여 그래프를 만든다.</p>
<p><strong>구현</strong><br />
해당 일자의 졸음운전 감지 횟수를 텍스트 파일에 “년 월 일 &#8211; 감지횟수”로 저장한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-84.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35982" alt="2018 ict _ 최우수상 (84)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-84.png" width="547" height="200" /></a><br />
파일에 기록된 정보를 불러와서 label : 날짜, entry : 감지 횟수를 저장한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-85.png" rel="lightbox[35889]"><img class="alignnone size-large wp-image-35983" alt="2018 ict _ 최우수상 (85)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-85-491x620.png" width="491" height="620" /></a><br />
lineDataSet에 정보를 저장한 뒤에 lineChart객체(그래프 객체)의 설정값을 변경한 뒤에 그래프를 그려준다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-86.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35984" alt="2018 ict _ 최우수상 (86)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-86.png" width="553" height="446" /></a></p>
<p><strong>결과</strong><br />
사용자의 안전운전 수치 그래프가 만들어졌다.<br />
그래프의 수치는 사용자의 졸음운전 횟수이다.<br />
졸음운전 횟수가 많을수록 안전하지 않은 운전을 했기에 그래프가 낮아진다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-87.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35985" alt="2018 ict _ 최우수상 (87)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-87.png" width="544" height="291" /></a></p>
<p><span style="color: #339966;"><strong>7. 개발 환경</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-88.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35986" alt="2018 ict _ 최우수상 (88)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-88.png" width="515" height="108" /></a><br />
· 차선 검출 : Visual studio 2010 c++, OpenCV, Raspberry Pi<br />
· 운전자 얼굴 검출 : Android Studio<br />
· 네트워크 환경 : Firebase<br />
· 사용시스템 및 S/W크기(Mbyte)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-89.png" rel="lightbox[35889]"><img class="alignnone size-full wp-image-35987" alt="2018 ict _ 최우수상 (89)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-89.png" width="305" height="338" /></a></p>
<p><span style="color: #339966;"><strong>8. 단계별 제작 과정</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-90.png" rel="lightbox[35889]"><img class="alignnone size-large wp-image-35988" alt="2018 ict _ 최우수상 (90)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/2018-ict-_-최우수상-90-514x620.png" width="514" height="620" /></a></p>
<p><span style="color: #339966;"><strong>9. 참고문헌</strong></span><br />
· <a href="http://link.springer.com/article/10.1007/s10209-011-0256-6" target="_blank">눈 깜빡임 관련 알고리즘</a><br />
· <a href="http://romanhosek.cz/android-eye-detection-and-tracking-with-opencv/" target="_blank">안드로이드 눈깜빡임 감지</a><br />
· <a href="http://me10.sblo.jp/article/88289624.html" target="_blank">옵티컬플로우 예제</a><br />
· <a href="http://mycpp.blog.me/120110317337" target="_blank">옵티컬플로우 함수 설명</a><br />
· <a href="http://blog.naver.com/hms4913/220126252051" target="_blank">opencv에서 옵티컬플로우</a><br />
· <a href="http://cafe.naver.com/opencv/38181" target="_blank">옵티컬플로우 사용예제</a><br />
· <a href="http://carstart.tistory.com/188" target="_blank">canny edge 기초설명</a><br />
· <a href="http://stackoverflow.com/questions/24174868/edge-detection-using-opencv-canny" target="_blank">자바에서 canny edge 사용</a><br />
· <a href="http://blog.naver.com/dusrb2003/220290145675" target="_blank">허프변환 기초설명</a><br />
· <a href="https://blog.zaven.co/opencv-advanced-android-development-edge-detection/" target="_blank">허프변환 사용예제</a><br />
· <a href="http://stackoverflow.com/questions/7925698/android-opencv-drawing-hough-lines" target="_blank">허프변환 사용예제</a><br />
· <a href="http://www.ntrexgo.com/archives/25916" target="_blank">차선 이탈 시스템 이론</a><br />
· <a href="http://blog.daum.net/pg365/200" target="_blank">설계/구현 과정</a><br />
· <a href="http://webnautes.tistory.com/916" target="_blank">환경 구축</a><br />
· <a href="http://lispro06.woweb.net/?mid=app&amp;page=21" target="_blank">언어간 함수변환</a><br />
· <a href="https://console.firebase.google.com/" target="_blank">구글 firebase</a><br />
· <a href="https://corikachu.github.io/" target="_blank">파이썬 채팅 앱 to firebase</a><br />
· <a href="http://blog.naver.com/PostView.nhn?blogId=chandong83&amp;logNo=220931445463&amp;categoryNo=22&amp;parentCategoryNo=0&amp;viewDate=&amp;currentPage=1&amp;postListTopCurrentPage=1&amp;from=postView" target="_blank">안드로이드 UDP이용 메시지 전송예제 </a><br />
<a href="http://blog.naver.com/PostView.nhn?blogId=cosmosjs&amp;logNo=220739141098&amp;categoryNo=0&amp;parentCategoryNo=56&amp;viewDate=&amp;currentPage=1&amp;postListTopCurrentPage=1&amp;from=search" target="_blank">· FCM으로 메시지 전송 구현</a><br />
·<a href="http://blog.naver.com/zic325/220719729251" target="_blank"> 안드로이드 FCM 샘플</a><br />
· <a href="http://blog.naver.com/yoonhok_ 524/220918425133" target="_blank">FireBase DataBase 기초</a><br />
· <a href="https://ko.wikipedia.org/wiki/%EC%8A%A4%EC%BC%80%EC%B9%98%EC%97%85" target="_blank">스케치업 위키백과</a><br />
<a href="http://print3dison.cafe24.com/board/free/read.html?no=816&amp;board_no=1" target="_blank">· Creator K 사용자 가이드</a><br />
<a href="https://ko.wikipedia.org/wiki/3ds_%EB%A7 %A5%EC%8A%A4" target="_blank">· 3ds 맥스 위키백과</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/35889/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[49호]영상인식을 통한 졸음 운전 추돌 사고 방지 소프트웨어</title>
		<link>http://www.ntrexgo.com/archives/36038</link>
		<comments>http://www.ntrexgo.com/archives/36038#comments</comments>
		<pubDate>Mon, 20 Aug 2018 00:00:28 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[49호]]></category>
		<category><![CDATA[Feature]]></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=36038</guid>
		<description><![CDATA[디바이스마트매거진 49호 &#124; 졸음운전으로 인한 사고를 방지하기 위해서 아이디어를 구상하였는데, 영상 처리 및 이미지 내 대상 인식을 통해 졸음운전을 미연에 인지하고 대처하자는 요지로 프로젝트를 추진하게 되었다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440.png" rel="lightbox[36038]"><img class="alignnone size-large wp-image-35589" alt="Cap 2018-07-12 14-10-54-440" src="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440-620x210.png" width="620" height="210" /></a></p>
<p><span style="background-color: #000000;font-size: medium;color: #ffffff"><strong>  2018 ICT 융합 프로젝트 공모전 우수상  </strong></span></p>
<p><span style="font-size: x-large;color: #000000;background-color: #ffffff"><strong>영상인식을 통한 졸음 운전 추돌 사고 방지 소프트웨어 </strong></span></p>
<p style="text-align: right">글 | 단국대학교 정의동</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 아쉽게도 동일한 목표를 더 훌륭하게 구현한 팀이 있었습니다. open cv를 활용한 안면인식만으로 구현한 부분이 아쉽습니다. 보고서의 완성도 부분에서도 먼저 제출한 팀과 비교되는 점이 아쉽습니다.<br />
<strong>뉴티씨</strong> 눈감음이나 얼굴인식 등을 통하여, 졸음운전시 경보음을 줘서, 졸음운전을 예방하는 것은 요즘 매우 중요한 이슈입니다. 인식도 잘 되고, 매우 실용적으로 잘 제작하신 것으로 보입니다. 다만, 운전하는 상황이 매우 위험하므로, 인식 후 경보까지 시간을 조금 더 줄여서 빠르게 경보를 해주면 좀 더 좋을 것 같습니다. 조금만 더 다듬으면, 실제 판매 가능한 제품으로도 만들 수 있을 것으로 생각되어 매우 좋은 점수를 드립니다.<br />
<strong>위드로봇</strong> 전체적인 완성도가 높은 작품입니다. 다만 기존 제품과의 차별성이 없는 부분이 아쉽습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-1.png" rel="lightbox[36038]"><img class="alignnone size-full wp-image-36042" alt="49 ict 영상 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-1.png" width="620" height="416" /></a><br />
2012~2014년 3년간의 통계에 따르면, 졸음운전으로 인한 교통 사고는 7560건이 있었고, 하루에 약 7건이 발생하며 14명의 사상자가 발생하였다. 또한 전체 교통사고에 비하면 졸음운전으로 인한 사고는 1% 남짓에 불과하지만, 교통사고 치사율을 살펴보았을 때 전체 교통사고에 비하여 약 10배의 치사율을 보였다.<br />
위와 같이 위험한 졸음운전으로 인한 사고를 방지하기 위해서 아이디어를 구상하였는데, 영상 처리 및 이미지 내 대상 인식을 통해 졸음운전을 미연에 인지하고 대처하자는 요지로 프로젝트를 추진하게 되었다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #6c90ff"><strong>3.1. 주요 동작 및 특징</strong></span><br />
졸음 인식을 위해 얼굴 인식을 사용한 후 (p 입력 시 인식 시작) 눈의 특징 점을 추출하여 눈꺼풀 사이의 간격 비율을 이용해 졸고 있는지를 판단한다. 그 후 졸음이 인식될 경우 2.5초 후 알람음을 발생시키고 이용자가 알람을 해제할 때까지 지속시킨다. (s 입력 시 알람 해제) 정면을 응시하지 않아 얼굴이 인식되지 않을 경우 위험을 감지, 4.5초 후 알람을 출력한다. 정면을 다시 응시할 경우 알람은 자동으로 종료된다. 얼굴 인식을 다시 시작하고 싶은 경우 p를 눌러 재시작을 할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-2.png" rel="lightbox[36038]"><img class="alignnone size-full wp-image-36043" alt="49 ict 영상 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-2.png" width="620" height="199" /></a></p>
<p>시중에 많이 사용되는 얼굴인식 라이브러리 OpenCV는 눈 부위를 인식하는 기능이 있으나 인식률이 현저히 떨어진다. 이 부분을 보완하기 위해 dlib 이라는 라이브러리에 포함된 Face Landmark Detection 이라는 Trained Data Set 라이브러리를 사용했다. 데이터 셋 적용 후, 인식률도 크게 상향되었고 인식 속도 또한 딜레이가 거의 없을 정도로 발전하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-3.png" rel="lightbox[36038]"><img class="alignnone size-full wp-image-36044" alt="49 ict 영상 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-3.png" width="620" height="257" /></a></p>
<p>그러나 Face Landmark Detection에 한계가 있다. 얼굴의 각도가 변할 경우 얼굴의 특징점을 추출하는 데 정확성이 크게 떨어진다. 때문에 이 프로젝트에선 이중 얼굴 인식 시스템을 이용하였다. 한번 인식한 얼굴에서 얼굴의 위치와 각도를 계산하고 얼굴 부분만 회전하여 정면으로 바꿔준 뒤 다시 인식하는 방식이다. 이 시스템을 이용하여 기존 라이브러리의 단점을 크게 보완하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-4.png" rel="lightbox[36038]"><img class="alignnone size-full wp-image-36045" alt="49 ict 영상 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-4.png" width="620" height="247" /></a></p>
<p>눈이 감기는 것을 인식하는 부분에서 눈 사이의 거리만 계산한 것이 아니라 가로와 세로의 비율로 계산을 하였기 때문에 카메라에서 멀어진다 해도 눈이 감겨진 정도를 거리에 따른 오차 없이 계산할 수 있었다.</p>
<p><span style="color: #6c90ff"><strong>3.2. 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-5.png" rel="lightbox[36038]"><img class="alignnone size-large wp-image-36046" alt="49 ict 영상 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-5-502x620.png" width="502" height="620" /></a><br />
<span style="color: #6c90ff"><strong>3.3. 개발 환경</strong></span><br />
Operation System : Windows 10<br />
Programming Language : Python<br />
Used IDE Tool : Anaconda3 Python 3.6<br />
Used Libraries :OpenCV, Dlib, numpy, scipy, winsound, time</p>
<p><span style="color: #3366ff"><strong>3.4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong>3.4.1. 눈 감김 비율 계산</strong></span></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>video_capture = cv2.VideoCapture(0)<br />
face_detector = dlib.get_frontal_face_detector()<br />
shape_predictor = dlib.shape_predictor(&#8220;shape_predictor_68_face_landmarks.dat&#8221;)<br />
#비디오를 불러옴, dlib에서 frontal face detector, shape predictor를 불러옴<br />
def eye_ratio(eyepoint):<br />
A = dist.euclidean(eyepoint[1],eyepoint[5])<br />
B = dist.euclidean(eyepoint[2],eyepoint[4])<br />
C = dist.euclidean(eyepoint[0],eyepoint[3])<br />
ER = (A+B) / (2.0*C)</p>
<p>return ER<br />
#눈 비율 값 계산 define<br />
</div>
<p><strong><span style="color: #33cccc">3.4.2. 얼굴 재정렬 -점 회전 함수 선언</span></strong></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>def rotate (brx,bry):<br />
crx = brx &#8211; midx<br />
cry = bry &#8211; midy<br />
arx = np.cos(-angle)*crx &#8211; np.sin(-angle)*cry<br />
ary = np.sin(-angle)*crx + np.cos(-angle)*cry<br />
rx = int (arx + midx)<br />
ry = int (ary + midy)</p>
<p>return(rx,ry)<br />
#점 회전 define<br />
</div>
<p><strong><span style="color: #33cccc">3.4.3. 동영상 좌우반전 후 gray화 및 clahe 후 face detector</span></strong></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>while True:<br />
ret, frame = video_capture.read()<br />
flip_frame = cv2.flip(frame,1)<br />
gray = cv2.cvtColor(flip_frame, cv2.COLOR_BGR2GRAY)<br />
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))<br />
clahe_image = clahe.apply(gray)<br />
detection = face_detector(clahe_image)<br />
</div>
<p><strong><span style="color: #33cccc">3.4.4. 화면 내 인터페이스 작성 (메시지 팝업)</span></strong></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>key = cv2.waitKey(10) &amp; 0xFF<br />
# 키 입력</p>
<p>if message_popup == True:<br />
if print_counter == 0:<br />
cv2.putText(flip_frame, &#8220;&#8221;, (230, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
if print_counter == 1:<br />
cv2.putText(flip_frame, &#8220;Try again&#8221;, (260, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
if print_counter == 2:<br />
cv2.putText(flip_frame, &#8220;Gaze the camera&#8221;, (230, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
if print_counter == 3:<br />
cv2.putText(flip_frame, &#8220;Program starts in : 3&#8243;, (200, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)<br />
if print_counter == 4:<br />
cv2.putText(flip_frame, &#8220;Program starts in : 2&#8243;, (200, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)<br />
if print_counter == 5:<br />
cv2.putText(flip_frame, &#8220;Program starts in : 1&#8243;, (200, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)<br />
if print_counter == 6:<br />
cv2.putText(flip_frame, &#8220;CALCULATING&#8221;, (240, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)<br />
</div>
<p><strong><span style="color: #33cccc">3.4.5. 프로그램 시작 분기문</span></strong></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>if key == ord(&#8220;p&#8221;):<br />
if not eye_cap == True:</p>
<p>eye_open_done = False</p>
<p>#p 눌렸을 때 인식 측정 시작<br />
else :<br />
eye_open_done = True<br />
eye_cap = False<br />
cv2.destroyWindow(&#8220;image2&#8243;)<br />
program_switch = False<br />
eye_ratio_limit = 0.00<br />
left_ar = [0,]
right_ar = [0,]
<p>count_ar = 0<br />
winsound.PlaySound(None, winsound.SND_ASYNC)<br />
txt_switch = False<br />
alarm = False</p>
<p>#다시 누르면 이미지창 제거 메세지창 제거<br />
if eye_open_done == False:<br />
# 측정 시작<br />
for fd in detection:<br />
eye_open_shape = shape_predictor(clahe_image, fd)</p>
<p>eye_open_landmarks = np.matrix([[p.x, p.y] for p in eye_open_shape.parts()])</p>
<p>eye_open_left_eye = eye_open_landmarks[left_eye_points]
eye_open_right_eye = eye_open_landmarks[right_eye_points]
<p>eye_open_ER_left = eye_ratio(eye_open_left_eye)<br />
eye_open_ER_right = eye_ratio(eye_open_right_eye)</p>
<p># ER값 측정 시작<br />
if(count_ar &lt; 100):<br />
count_ar += 1</p>
<p>for i in range(36,41):<br />
cv2.line(flip_frame,(eye_open_shape.part(i).x, eye_open_shape.part(i).y),(eye_open_shape.part(i+1).x, eye_open_shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(eye_open_shape.part(41).x, eye_open_shape.part(41).y),(eye_open_shape.part(36).x, eye_open_shape.part(36).y),(255,0,0),1)<br />
for i in range(42,47):<br />
cv2.line(flip_frame,(eye_open_shape.part(i).x, eye_open_shape.part(i).y),(eye_open_shape.part(i+1).x, eye_open_shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(eye_open_shape.part(47).x, eye_open_shape.part(47).y),(eye_open_shape.part(42).x, eye_open_shape.part(42).y),(255,0,0),1)<br />
print_counter = 2<br />
message_popup = True</p>
<p>if(30&lt;count_ar&lt;=60):<br />
left_ar.append(eye_open_ER_left)<br />
right_ar.append(eye_open_ER_right)<br />
print_counter = 6<br />
if(60&lt;count_ar&lt;=70):<br />
print_counter = 0<br />
Max_ER_left = max(left_ar)<br />
Max_ER_right = max(right_ar)<br />
eye_ratio_limit = (Max_ER_left + Max_ER_right)/2*0.65<br />
if(70&lt;count_ar&lt;=80):<br />
print_counter = 3<br />
if(80&lt;count_ar&lt;=90):<br />
print_counter = 4<br />
if(90&lt;count_ar&lt;100):<br />
print_counter = 5</p>
<p>#얼굴이 인식되는 동안 count_ar이 올라가면서 어레이에 저장후 최대값으로 설정, 메시지 팝업</p>
<p>if(count_ar == 100):<br />
eye_open_done = True<br />
eye_cap = True<br />
program_switch = True<br />
print_counter = 0<br />
count_ar = 0<br />
count_time = time.time()</p>
<p>#count_ar이 최대일떄 측정 중단, 프로그램 시작<br />
</div>
<p><strong><span style="color: #33cccc">3.4.6. 얼굴 인식 범위 지정 및 얼굴 재정렬</span></strong></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>if program_switch == True:<br />
#프로그램 시작<br />
face_reco = False<br />
face_reco_n = True</p>
<p>for d in detection:</p>
<p>face_reco = True<br />
fnd_count = 0<br />
count_time2 = time.time()</p>
<p>if txt_switch2 == True:<br />
winsound.PlaySound(None, winsound.SND_ASYNC)<br />
face_alarm = False<br />
txt_switch2 = False<br />
#얼굴 인식 불가 알람이 ON일때 알람을 끔</p>
<p>x = d.left()<br />
y = d.top()<br />
x1 = d.right()<br />
y1 = d.bottom()<br />
#d 값 저장<br />
bdx = x-(x1-x)/2<br />
bdy = y-(y1-y)/2<br />
bdx1 = x1+(x1-x)/2<br />
bdy1 = y1+(y1-y)/2<br />
# 큰 d값 저장<br />
midx = (x+x1)/2<br />
midy = (y+y1)/2<br />
# d의 가운데 포인트 저장</p>
<p>shape = shape_predictor(clahe_image, d)</p>
<p>rex = shape.part(45).x<br />
rey = shape.part(45).y<br />
lex = shape.part(36).x<br />
ley = shape.part(36).y</p>
<p>mex = int (lex + (rex-lex)/2)<br />
mey = int (ley + (rey-ley)/2)<br />
#눈의 양끝점 좌표 설정 및 눈 사이 가운데 점 설정</p>
<p>tanx = mex &#8211; lex<br />
tany = ley &#8211; mey<br />
tan = tany/tanx<br />
#tan 값 계산<br />
angle = np.arctan(tan)<br />
degree = np.degrees(angle)<br />
#각도 계산</p>
<p>rsd_1 = rotate(x,y)<br />
rsd_2 = rotate(x1,y)<br />
rsd_3 = rotate(x,y1)<br />
rsd_4 = rotate(x1,y1)<br />
d2_1 = rotate(bdx,bdy)<br />
d2_2 = rotate(bdx1,bdy)<br />
d2_3 = rotate(bdx,bdy1)<br />
d2_4 = rotate(bdx1,bdy1)<br />
#좌표 회전</p>
<p>pts1 = np.float32([[d2_1[0],d2_1[1]],[d2_2[0],d2_2[1]],[d2_3[0],d2_3[1]],[d2_4[0],d2_4[1]]])<br />
pts2 = np.float32([[0,0],[400,0],[0,400],[400,400]])<br />
M = cv2.getPerspectiveTransform(pts1,pts2)<br />
dst = cv2.warpPerspective(flip_frame,M,(400,400))<br />
#회전된 좌표를 이용하여 새로운 창으로 프린트<br />
</div>
<p><strong><span style="color: #33cccc">3.4.7. 회전된 d2에서 얼굴 인식 실행</span></strong></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>d2gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)<br />
d2clahe_image = clahe.apply(d2gray)<br />
d2detections = face_detector(d2clahe_image)</p>
<p>for d2 in d2detections:<br />
xx = d2.left()<br />
yy = d2.top()<br />
xx1 = d2.right()<br />
yy1 = d2.bottom()<br />
d2shape = shape_predictor(d2clahe_image, d2)<br />
<br />
 cv2.rectangle(dst, (xx, yy), (xx1, yy1), (0, 255, 255), 1)<br />
 for i in range(1,68):<br />
cv2.circle(dst, (d2shape.part(i).x, d2shape.part(i).y), 1, (255,0,255), thickness=1)<br />
for i in range(36,41):<br />
cv2.line(dst,(d2shape.part(i).x, d2shape.part(i).y),(d2shape.part(i+1).x, d2shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(dst,(d2shape.part(41).x, d2shape.part(41).y),(d2shape.part(36).x, d2shape.part(36).y),(255,0,0),1)<br />
for i in range(42,47):<br />
cv2.line(dst,(d2shape.part(i).x, d2shape.part(i).y),(d2shape.part(i+1).x, d2shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(dst,(d2shape.part(47).x, d2shape.part(47).y),(d2shape.part(42).x, d2shape.part(42).y),(255,0,0),1)</p>
<p>landmarks = np.matrix([[p.x, p.y] for p in d2shape.parts()])</p>
<p>right_eye = landmarks[left_eye_points]
left_eye = landmarks[right_eye_points]
ER_right = eye_ratio(right_eye)<br />
ER_left = eye_ratio(left_eye)<br />
if ER_left &lt;= eye_ratio_limit and ER_right &lt;= eye_ratio_limit:<br />
open_eye = False<br />
if ER_left &gt; eye_ratio_limit and ER_right &gt; eye_ratio_limit:<br />
open_eye = True<br />
# 눈 감았을때 open eye가 꺼짐, 눈 뜨면 다시 켜짐</p>
<p>if open_eye == True:<br />
count_time = time.time()<br />
#눈이 감겨있으면 그 순간 count_time 측정 기록, 떠있으면 계속 갱신</p>
<p>cv2.line(flip_frame,rsd_1,rsd_2,(100,255,100),1)<br />
cv2.line(flip_frame,rsd_1,rsd_3,(100,255,100),1)<br />
cv2.line(flip_frame,rsd_4,rsd_2,(100,255,100),1)<br />
cv2.line(flip_frame,rsd_4,rsd_3,(100,255,100),1)<br />
#회전된 작은 d 프린트</p>
<p>for i in range(0,67):<br />
cv2.circle(flip_frame, (shape.part(i).x, shape.part(i).y), 1, (0,0,255), thickness=1)<br />
for i in range(36,41):<br />
cv2.line(flip_frame,(shape.part(i).x, shape.part(i).y),(shape.part(i+1).x, shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(shape.part(41).x, shape.part(41).y),(shape.part(36).x, shape.part(36).y),(255,0,0),1)<br />
for i in range(42,47):<br />
cv2.line(flip_frame,(shape.part(i).x, shape.part(i).y),(shape.part(i+1).x, shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(shape.part(47).x, shape.part(47).y),(shape.part(42).x, shape.part(42).y),(255,0,0),1)</p>
<p>cv2.putText(flip_frame, &#8220;Left : {:.2f}&#8221;.format(ER_left), (450, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 200, 200), 2)<br />
cv2.putText(flip_frame, &#8220;Right : {:.2f}&#8221;.format(ER_right), (450, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 200, 200), 2)<br />
cv2.putText(flip_frame, &#8220;Degree : {:.2f}&#8221;.format(degree), (450, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 200, 200), 2)<br />
cv2.putText(flip_frame, &#8220;Eye ratio limit: {:.2f}&#8221;.format(eye_ratio_limit), (10, 430), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)<br />
#라인 그리기 및 값 표현<br />
</div>
<p><strong><span style="color: #33cccc">3.4.8. 알람 기준 지정 및 알람 재생 및 종료</span></strong></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>if time.time()-count_time &gt; 2.5:<br />
txt_switch = True</p>
<p>if alarm == False:<br />
winsound.PlaySound(&#8220;school_alarm.wav&#8221;, winsound.SND_LOOP + winsound.SND_ASYNC)<br />
print(&#8220;alarm on&#8221;)<br />
alarm = True</p>
<p>#2.5초 후 알람 한번 출력, 메시지 스위치 온<br />
if face_reco == False:<br />
face_reco_n = False<br />
fnd_count += 1<br />
if fnd_count &gt;= 10:<br />
cv2.putText(dst, &#8220;FACE NOT DETECTED&#8221;, (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
cv2.putText(flip_frame, &#8220;FACE NOT DETECTED&#8221;, (10, 460), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
count_time = time.time()<br />
if txt_switch == False and time.time()-count_time2 &gt; 4.5:<br />
txt_switch2 = True<br />
if txt_switch2 == True:<br />
cv2.putText(flip_frame, &#8220;NO FACE ALARM!!!&#8221;, (10, 60),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
if face_alarm == False:<br />
winsound.PlaySound(&#8220;school_alarm.wav&#8221;, winsound.SND_LOOP + winsound.SND_ASYNC)<br />
print(&#8220;face alarm on&#8221;)<br />
face_alarm = True</p>
<p>#얼굴 인식이 안될 경우 눈 감는 카운트 초기화, 4.5 초 후 알람 및 메시지 출력<br />
if face_reco == True and face_reco_n == True:<br />
face = 2<br />
#얼굴 인식이 되는 도중<br />
if face_reco == False and face_reco_n == False:<br />
face = 1<br />
#얼굴 인식이 안되는 중<br />
if face_reco == False and face_reco_n == True:<br />
face = 0<br />
#프로그램 시작 값</p>
<p>if txt_switch == True:<br />
cv2.putText(flip_frame, &#8220;ALARM!!!&#8221;, (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)</p>
<p>#눈 감으면 알람<br />
if face == 2 and key == ord(&#8220;s&#8221;):<br />
txt_switch = False<br />
alarm = False<br />
winsound.PlaySound(None, winsound.SND_ASYNC)</p>
<p>#알람 울릴 때 (얼굴 인식이 되는 경우에만 알람 종료)<br />
</div>
<p><span style="color: #3366ff"><strong>3.5. 소스코드</strong></span></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>import cv2<br />
import dlib<br />
import numpy as np<br />
from scipy.spatial import distance as dist<br />
import winsound<br />
import time</p>
<p>video_capture = cv2.VideoCapture(0)<br />
face_detector = dlib.get_frontal_face_detector()<br />
shape_predictor = dlib.shape_predictor(&#8220;shape_predictor_68_face_landmarks.dat&#8221;)</p>
<p>right_eye_points = list(range(36, 42))<br />
left_eye_points = list(range(42, 48))</p>
<p>count_ar = 0<br />
left_ar = 30*[]
right_ar = 30*[]
<p>eye_ratio_limit = 0.00</p>
<p>count_time = 0<br />
count_time2 = 0</p>
<p>eye_cap = False<br />
eye_open_done = True<br />
program_switch = False<br />
message_popup = False<br />
print_counter = 0<br />
txt_switch = False<br />
txt_switch2 = False<br />
alarm = False</p>
<p>face_alarm = False<br />
face_reco = False</p>
<p>face_reco = False<br />
face_reco_n = True<br />
face = 0<br />
fnd_count = 0</p>
<p>open_eye = True</p>
<p>def eye_ratio(eyepoint):<br />
A = dist.euclidean(eyepoint[1],eyepoint[5])<br />
B = dist.euclidean(eyepoint[2],eyepoint[4])<br />
C = dist.euclidean(eyepoint[0],eyepoint[3])<br />
ER = (A+B) / (2.0*C)</p>
<p>return ER</p>
<p>def rotate (brx,bry):<br />
crx = brx &#8211; midx<br />
cry = bry &#8211; midy<br />
arx = np.cos(-angle)*crx &#8211; np.sin(-angle)*cry<br />
ary = np.sin(-angle)*crx + np.cos(-angle)*cry<br />
rx = int (arx + midx)<br />
ry = int (ary + midy)</p>
<p>return(rx,ry)</p>
<p>while True:<br />
ret, frame = video_capture.read()<br />
flip_frame = cv2.flip(frame,1)<br />
gray = cv2.cvtColor(flip_frame, cv2.COLOR_BGR2GRAY)<br />
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))<br />
clahe_image = clahe.apply(gray)<br />
detection = face_detector(clahe_image)</p>
<p>key = cv2.waitKey(10) &amp; 0xFF</p>
<p>if message_popup == True:<br />
if print_counter == 0:<br />
cv2.putText(flip_frame, &#8220;&#8221;, (230, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
if print_counter == 1:<br />
cv2.putText(flip_frame, &#8220;Try again&#8221;, (260, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
if print_counter == 2:<br />
cv2.putText(flip_frame, &#8220;Gaze the camera&#8221;, (230, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
if print_counter == 3:<br />
cv2.putText(flip_frame, &#8220;Program starts in : 3&#8243;, (200, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)<br />
if print_counter == 4:<br />
cv2.putText(flip_frame, &#8220;Program starts in : 2&#8243;, (200, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)<br />
if print_counter == 5:<br />
cv2.putText(flip_frame, &#8220;Program starts in : 1&#8243;, (200, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)<br />
if print_counter == 6:<br />
cv2.putText(flip_frame, &#8220;CALCULATING&#8221;, (240, 450), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)</p>
<p>if key == ord(&#8220;p&#8221;):<br />
if not eye_cap == True:<br />
eye_open_done = False<br />
else :<br />
eye_open_done = True<br />
eye_cap = False<br />
cv2.destroyWindow(&#8220;image2&#8243;)<br />
program_switch = False<br />
eye_ratio_limit = 0.00<br />
left_ar = [0,]
right_ar = [0,]
<p>count_ar = 0<br />
winsound.PlaySound(None, winsound.SND_ASYNC)<br />
txt_switch = False<br />
alarm = False</p>
<p>if eye_open_done == False:<br />
for fd in detection:<br />
eye_open_shape = shape_predictor(clahe_image, fd)<br />
eye_open_landmarks = np.matrix([[p.x, p.y] for p in eye_open_shape.parts()])<br />
eye_open_left_eye = eye_open_landmarks[left_eye_points]
eye_open_right_eye = eye_open_landmarks[right_eye_points]
eye_open_ER_left = eye_ratio(eye_open_left_eye)<br />
eye_open_ER_right = eye_ratio(eye_open_right_eye)</p>
<p>if(count_ar &lt; 100):<br />
count_ar += 1</p>
<p>for i in range(36,41):<br />
cv2.line(flip_frame,(eye_open_shape.part(i).x, eye_open_shape.part(i).y),(eye_open_shape.part(i+1).x, eye_open_shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(eye_open_shape.part(41).x, eye_open_shape.part(41).y),(eye_open_shape.part(36).x, eye_open_shape.part(36).y),(255,0,0),1)<br />
for i in range(42,47):<br />
cv2.line(flip_frame,(eye_open_shape.part(i).x, eye_open_shape.part(i).y),(eye_open_shape.part(i+1).x, eye_open_shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(eye_open_shape.part(47).x, eye_open_shape.part(47).y),(eye_open_shape.part(42).x, eye_open_shape.part(42).y),(255,0,0),1)<br />
print_counter = 2<br />
message_popup = True<br />
if(30&lt;count_ar&lt;=60):<br />
left_ar.append(eye_open_ER_left)<br />
right_ar.append(eye_open_ER_right)<br />
print_counter = 6<br />
if(60&lt;count_ar&lt;=70):<br />
print_counter = 0<br />
Max_ER_left = max(left_ar)<br />
Max_ER_right = max(right_ar)<br />
eye_ratio_limit = (Max_ER_left + Max_ER_right)/2*0.65<br />
if(70&lt;count_ar&lt;=80):<br />
print_counter = 3<br />
if(80&lt;count_ar&lt;=90):<br />
print_counter = 4<br />
if(90&lt;count_ar&lt;100):<br />
print_counter = 5</p>
<p>if(count_ar == 100):<br />
eye_open_done = True<br />
eye_cap = True<br />
program_switch = True<br />
print_counter = 0<br />
count_ar = 0<br />
count_time = time.time()</p>
<p>if program_switch == True:<br />
face_reco = False<br />
face_reco_n = True<br />
for d in detection:</p>
<p>face_reco = True<br />
fnd_count = 0<br />
count_time2 = time.time()</p>
<p>if txt_switch2 == True:<br />
winsound.PlaySound(None, winsound.SND_ASYNC)<br />
face_alarm = False<br />
txt_switch2 = False</p>
<p>x = d.left()<br />
y = d.top()<br />
x1 = d.right()<br />
y1 = d.bottom()<br />
bdx = x-(x1-x)/2<br />
bdy = y-(y1-y)/2<br />
bdx1 = x1+(x1-x)/2<br />
bdy1 = y1+(y1-y)/2<br />
midx = (x+x1)/2<br />
midy = (y+y1)/2</p>
<p>shape = shape_predictor(clahe_image, d)</p>
<p>rex = shape.part(45).x<br />
rey = shape.part(45).y<br />
lex = shape.part(36).x<br />
ley = shape.part(36).y</p>
<p>mex = int (lex + (rex-lex)/2)<br />
mey = int (ley + (rey-ley)/2)</p>
<p>tanx = mex &#8211; lex<br />
tany = ley &#8211; mey<br />
tan = tany/tanx<br />
angle = np.arctan(tan)<br />
degree = np.degrees(angle)</p>
<p>rsd_1 = rotate(x,y)<br />
rsd_2 = rotate(x1,y)<br />
rsd_3 = rotate(x,y1)<br />
rsd_4 = rotate(x1,y1)<br />
d2_1 = rotate(bdx,bdy)<br />
d2_2 = rotate(bdx1,bdy)<br />
d2_3 = rotate(bdx,bdy1)<br />
d2_4 = rotate(bdx1,bdy1)</p>
<p>pts1 = np.float32([[d2_1[0],d2_1[1]],[d2_2[0],d2_2[1]],[d2_3[0],d2_3[1]],[d2_4[0],d2_4[1]]])<br />
pts2 = np.float32([[0,0],[400,0],[0,400],[400,400]])</p>
<p>M = cv2.getPerspectiveTransform(pts1,pts2)</p>
<p>dst = cv2.warpPerspective(flip_frame,M,(400,400))</p>
<p>d2gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)<br />
d2clahe_image = clahe.apply(d2gray)<br />
d2detections = face_detector(d2clahe_image)</p>
<p>for d2 in d2detections:<br />
xx = d2.left()<br />
yy = d2.top()<br />
xx1 = d2.right()<br />
yy1 = d2.bottom()<br />
d2shape = shape_predictor(d2clahe_image, d2)</p>
<p>cv2.rectangle(dst, (xx, yy), (xx1, yy1), (0, 255, 255), 1)<br />
for i in range(1,68):<br />
cv2.circle(dst, (d2shape.part(i).x, d2shape.part(i).y), 1, (255,0,255), thickness=1)<br />
for i in range(36,41):<br />
cv2.line(dst,(d2shape.part(i).x, d2shape.part(i).y),(d2shape.part(i+1).x, d2shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(dst,(d2shape.part(41).x, d2shape.part(41).y),(d2shape.part(36).x, d2shape.part(36).y),(255,0,0),1)<br />
for i in range(42,47):<br />
cv2.line(dst,(d2shape.part(i).x, d2shape.part(i).y),(d2shape.part(i+1).x, d2shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(dst,(d2shape.part(47).x, d2shape.part(47).y),(d2shape.part(42).x, d2shape.part(42).y),(255,0,0),1)<br />
landmarks = np.matrix([[p.x, p.y] for p in d2shape.parts()])<br />
right_eye = landmarks[left_eye_points]
left_eye = landmarks[right_eye_points]
ER_right = eye_ratio(right_eye)<br />
ER_left = eye_ratio(left_eye)</p>
<p>if ER_left &lt;= eye_ratio_limit and ER_right &lt;= eye_ratio_limit:<br />
open_eye = False</p>
<p>if ER_left &gt; eye_ratio_limit and ER_right &gt; eye_ratio_limit:<br />
open_eye = True</p>
<p>if open_eye == True:<br />
count_time = time.time()</p>
<p>cv2.line(flip_frame,rsd_1,rsd_2,(100,255,100),1)<br />
cv2.line(flip_frame,rsd_1,rsd_3,(100,255,100),1)<br />
cv2.line(flip_frame,rsd_4,rsd_2,(100,255,100),1)<br />
cv2.line(flip_frame,rsd_4,rsd_3,(100,255,100),1)</p>
<p>for i in range(0,67):<br />
cv2.circle(flip_frame, (shape.part(i).x, shape.part(i).y), 1, (0,0,255), thickness=1)<br />
for i in range(36,41):<br />
cv2.line(flip_frame,(shape.part(i).x, shape.part(i).y),(shape.part(i+1).x, shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(shape.part(41).x, shape.part(41).y),(shape.part(36).x, shape.part(36).y),(255,0,0),1)<br />
for i in range(42,47):<br />
cv2.line(flip_frame,(shape.part(i).x, shape.part(i).y),(shape.part(i+1).x, shape.part(i+1).y),(255,0,0),1)<br />
cv2.line(flip_frame,(shape.part(47).x, shape.part(47).y),(shape.part(42).x, shape.part(42).y),(255,0,0),1)<br />
cv2.putText(flip_frame, &#8220;Left : {:.2f}&#8221;.format(ER_left), (450, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 200, 200), 2)<br />
cv2.putText(flip_frame, &#8220;Right : {:.2f}&#8221;.format(ER_right), (450, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 200, 200), 2)<br />
cv2.putText(flip_frame, &#8220;Degree : {:.2f}&#8221;.format(degree), (450, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 200, 200), 2)<br />
cv2.putText(flip_frame, &#8220;Eye ratio limit: {:.2f}&#8221;.format(eye_ratio_limit), (10, 430), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)</p>
<p>if time.time()-count_time &gt; 2.5:<br />
txt_switch = True</p>
<p>if alarm == False:<br />
winsound.PlaySound(&#8220;school_alarm.wav&#8221;, winsound.SND_LOOP + winsound.SND_ASYNC)<br />
print(&#8220;alarm on&#8221;)<br />
alarm = True</p>
<p>if face_reco == False:<br />
face_reco_n = False<br />
fnd_count += 1<br />
if fnd_count &gt;= 10:<br />
cv2.putText(dst, &#8220;FACE NOT DETECTED&#8221;, (100, 200), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
cv2.putText(flip_frame, &#8220;FACE NOT DETECTED&#8221;, (10, 460), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)</p>
<p>count_time = time.time()</p>
<p>if txt_switch == False and time.time()-count_time2 &gt; 4.5:<br />
txt_switch2 = True<br />
if txt_switch2 == True:<br />
cv2.putText(flip_frame, &#8220;NO FACE ALARM!!!&#8221;, (10, 60),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)</p>
<p>if face_alarm == False:<br />
winsound.PlaySound(&#8220;school_alarm.wav&#8221;, winsound.SND_LOOP + winsound.SND_ASYNC)<br />
print(&#8220;face alarm on&#8221;)<br />
face_alarm = True</p>
<p>if face_reco == True and face_reco_n == True:<br />
face = 2<br />
if face_reco == False and face_reco_n == False:<br />
face = 1<br />
if face_reco == False and face_reco_n == True:<br />
face = 0</p>
<p>if txt_switch == True:<br />
cv2.putText(flip_frame, &#8220;ALARM!!!&#8221;, (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)<br />
cv2.imshow(&#8220;image2&#8243;, dst)</p>
<p>if face == 2 and key == ord(&#8220;s&#8221;):</p>
<p>txt_switch = False<br />
alarm = False<br />
winsound.PlaySound(None, winsound.SND_ASYNC)<br />
cv2.imshow(&#8220;Frame&#8221;, flip_frame)<br />
print(&#8220;time = &#8220;,time.time()-count_time)<br />
print(&#8220;time2 = &#8220;,time.time()-count_time2)<br />
print(&#8220;face = &#8220;,face)</p>
<p>if key == ord(&#8220;q&#8221;):<br />
eye_ratio_limit = 0.00<br />
winsound.PlaySound(None, winsound.SND_ASYNC)<br />
break<br />
cv2.destroyAllWindows()<br />
video_capture.release()<br />
</div>
<p><span style="color: #0000ff"><strong>4. 실행영상</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-6.png" rel="lightbox[36038]"><img class="alignnone size-full wp-image-36047" alt="49 ict 영상 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-6.png" width="620" height="400" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-7.png" rel="lightbox[36038]"><img class="alignnone size-full wp-image-36048" alt="49 ict 영상 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-7.png" width="620" height="400" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-8.png" rel="lightbox[36038]"><img alt="49 ict 영상 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ict-영상-8.png" width="620" height="400" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/36038/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[49호]장애인 주차구역 불법단속 시스템</title>
		<link>http://www.ntrexgo.com/archives/35995</link>
		<comments>http://www.ntrexgo.com/archives/35995#comments</comments>
		<pubDate>Mon, 20 Aug 2018 00:00:12 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[49호]]></category>
		<category><![CDATA[Feature]]></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=35995</guid>
		<description><![CDATA[디바이스마트매거진 49호 &#124; 장애인 전용주차구역에 장애인 차량 외의 차량이 주차할 경우 경보음을 내고, 차량의 번호판을 관리자 서버에 바로 전송한다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440.png" rel="lightbox[35995]"><img class="alignnone size-large wp-image-35589" alt="Cap 2018-07-12 14-10-54-440" src="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440-620x210.png" width="620" height="210" /></a></p>
<p><span style="background-color: #000000;font-size: medium;color: #ffffff"><strong>  2018 ICT 융합 프로젝트 공모전 우수상  </strong></span></p>
<p><span style="font-size: x-large;color: #000000;background-color: #ffffff"><strong>장애인 주차구역 불법단속 시스템</strong></span></p>
<p style="text-align: right">글 | 경상대학교 박주형</p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span></p>
<p><strong>칩센</strong> 실용적인 아이디어로 판단됩니다. 사실 주차장에 대한 초음파 감지 장치와 주차관리를 위한 번호판독기는 모두 구현되어 있는 기술이지만, 공공질서를 위한 형태로 융합한 형태가 좋다고 판단됩니다.<br />
<strong></strong></p>
<p><strong>뉴티씨</strong> 장애인 주차구역에 등록되지 않은 비장애인 차량이 주차할 경우, 경보를 일으킨다는 컨셉으로 만들어졌는데 차량 번호판 인식, 차량 접근 인식, 경보 울림 등의 여러가지 기술들을 잘 구현한 듯 합니다. 다만, 보고서의 완성도가 많이 부족하여, 실제 구현을 잘 한 것이라는 부분에 대한 인식을 확실히 하기 어렵습니다. 잘 만드는 것도 중요하지만, 보고서로 다른 사람들도 잘 이해할 수 있도록 하는 부분도 매우 중요하다는 점을 인식하셔서, 다음에는 꼭 보고서도 잘 작성하시기 바랍니다. 전반적으로 높은 점수를 드렸습니다.<br />
<strong></strong></p>
<p><strong>위드로봇</strong> 불법 주차 단속을 무인으로 할 수 있다는 점에서 작품성이 높다고 생각합니다. 서버에서 문자 인식을 하도록 되어 있는데, 이럴 경우라면 단순히 사진을 찍어서 압축한 뒤 서버에서 처리하는 것이 나으며, 더 좋은 방법은 라즈베리파이에서 직접 문자 인식을 수행하도록 구성하면 완성도가 높은 작품이 될 것 같습니다. 보고서 내용 만으론 어느 정도 인식률로 동작했는지 알 수가 없어 완성도 부분에서 점수가 차감되었습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span><br />
<span style="color: #33cccc"><strong>2.1. 작품 소개</strong></span><br />
장애인 전용주차구역에 장애인 차량 외의 차량이 주차할 경우 경보음을 내고, 차량의 번호판을 관리자 서버에 바로 전송합니다.<br />
<span style="color: #5bd6d6"><strong>2.1.1. 기획의도</strong></span><br />
· 매년 장애인 구역에 불법주차차량증가<br />
· 장애인 전용주차 구역에 불법주차 된 차량이 보여도 애플리케이션을 다운받아서 신고해야하는 번거로움이 있어 대부분 그냥 보고 넘김<br />
· 장애인 전용주차구역에 불법 주차된 차량의 수들을 감소시키고, 장애인 분들의 편의 제공을 목표로 함<br />
· 불법주차를 할 수 없게 만들어 주차를 할 수 없는 문화로 만들어서 시민의식을 높여 선진국으로 발전</p>
<p><span style="color: #33cccc"><strong>2.2. 작품의 개발 배경 및 필요성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-1.png" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36000" alt="49 ICT_불법단속 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-1.png" width="475" height="282" /></a><br />
장애인 주차구역은 걷기가 불편한 사람들을 위해 만들어진 주차시설로 일반 주차 구역에 비해 약 1.5배가 크다. 크기가 넓은 이유는 걷기가 불편한 사람들이 목발이나 휠체어를 이용하는 경우 차를 타고 내릴 때 더 많은 공간을 필요로 하며, 보행 안전 통로가 확보되어야 하기 때문이다. 하지만 다리가 불편한 사람들을 위한 장애인 전용 주차구역에 위반사례들이 매년 급증하고 있다. 대구 지역에서만 보더라고 2014년에는 3,687건, 2015년에는 6,990건, 그리고 2016년에는 10,502건으로 해가 지날수록 거의 2배의 값으로 증가하고 있다.<br />
일일이 단속하는 것에도 어려움이 있다. 장애인 주차 표지를 대여하거나 위변조한 차량은 일일이 근접해서 관찰하지 않으면 식별하기 어렵다. 인력 부족 또한 심각하다. 지난 18일부터 오는 5월 20일까지 실시하는 올 상반기 장애인전용주차구역 집중 점검 기간동안 불법주차 단속에 나서는 복지부 소속 장애인정책과 직원은 8명이 전부다.<br />
현재 시행되고있는 장애인 주차구역신고에 대한 행정망 또한 비효율적이다. 장애인 주차구역 위반 차량을 신고하기 위해서는 생활불편 신고 앱을 다운 받아서 글을 쓰고 사진과 위치까지 올려야 한다. 이것을 올린다 해도 바로 처리되는 것이 아니라 행정업무의 분할로 1건을 처리하는 20~60분 걸린다. 그러면 처리되는 시간동안 그 차량이 빠져나갈 수가 있다. 따라서 이런 현재의 문제상황을 인식하고 증가하는 불법주차 사례를 감소시키기 위해 프로젝트를 하게 되었다.</p>
<p><span style="color: #33cccc"><strong>2.3. 작품의 특징 및 장점</strong></span><br />
<strong>가. 단속 신고 자동화</strong><br />
장애인을 위한 주차 관리 시스템은 장애인 주차 구역 내 차량 주차 시 차량 번호를 추출하고 기존 데이터베이스와 대조하여 장애인 차량인지 확인한다. 미등록 차량일 경우 즉시 데이터를 전송하여 신고를 자동화한다.</p>
<p><strong>나. 장애인 차량 주차증 불필요</strong><br />
기존의 장애인 주차 구역 단속은 장애인 등록 차량이라도 장애인 주차증을 분실하거나 부착하지 않을 경우 단속의 대상이 된다. 또한 주차증의 허점을 이용해 차량 번호와 장애인 자동차 스티커에 새겨진 번호가 다른 경우나 주차증을 위변조하여 부착하는 등 단속을 피한 장애인 주차 구역 주정차 위반 사례가 발견되고 있다.<br />
하지만 장애인을 위한 주차 관리 시스템은 장애인 주차 구역에 차량 주차 시 장애인 차량인지 확인하고 미등록 차량임을 인식하는 즉시 신고하기 때문에 스티커 부착 유무나 위변조와 관련 없이 정확한 단속을 할 수 있다.</p>
<p><strong>다. 일반 주차 관리 시스템과 차이</strong><br />
기존에 상용화된 주차 관리 시스템은 주차장 입구에서 차량 번호 영상을 인식하는 것에 비해 장애인을 위한 주차 관리 시스템은 장애인 주차 구역 내 주차 시 데이터를 추출한다. 이로 인해 현재 특정 차량이 어느 구역에 주차되어 있는지를 알 수 있다.</p>
<p><strong>라. 장애인 주차 구역 관리 시스템 부재 해결</strong><br />
장애인 주차 구역에 대해서는 대수롭지 않다는 인식이 만연하여 주차 위반에 대한 문제점 또한 크게 의식되지 않고 있기 때문인지 장애인 주차 구역 통제 시스템이 제대로 마련되어 있지 않다. 장애인을 위한 주차 관리 시스템은 이러한 부재를 메꿀 새로운 시스템이다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #33cccc"><strong>3.1. 주요 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-1.jpg" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36001" alt="49 ICT_불법단속 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-1.jpg" width="480" height="310" /></a></p>
<p>차량이 들어오면 일단 인지를 하고, 카메라를 이용하여 차량 번호 판을 인식하여 이 차량이 장애인 차량인지 비장애인 차량인지 구별을 한다. 만약 비장애인 차량이라면 경보음을 울리고 데이터가 관리자에게 전송된다.<br />
<span style="color: #33cccc"><strong>3.2. 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-2.png" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36002" alt="49 ICT_불법단속 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-2.png" width="481" height="272" /></a></p>
<p>차량이 들어오면 일단 인지를 하고, 카메라를 이용하여 차량 번호판을 인식하여 이 차량이 장애인 차량인지 비장애인 차량인지 구별을 한다. 만약 비장애인 차량이라면 경보음을 울리고 데이터가 관리자에게 전송된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-3.png" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36003" alt="49 ICT_불법단속 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-3.png" width="479" height="343" /></a></p>
<p><span style="color: #33cccc"><strong>3.3. 개발 환경</strong></span></p>
<p><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-4.png" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36004" alt="49 ICT_불법단속 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-4.png" width="478" height="383" /></a></strong><br />
<span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<strong>초음파센서 알고리즘</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-5.png" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36005" alt="49 ICT_불법단속 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-5.png" width="489" height="255" /></a></p>
<p><strong>쉘스크립트 알고리즘</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-6.png" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36006" alt="49 ICT_불법단속 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-6.png" width="472" height="327" /></a></p>
<p><strong>데이터베이스 저장화면</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-2.jpg" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36007" alt="49 ICT_불법단속 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-2.jpg" width="480" height="331" /></a></p>
<p><strong>번호판 인식화면</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-3.jpg" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36008" alt="49 ICT_불법단속 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-3.jpg" width="479" height="380" /></a></p>
<p><strong>홈페이지 저장화면</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-7.png" rel="lightbox[35995]"><img class="alignnone size-full wp-image-36009" alt="49 ICT_불법단속 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/08/49-ICT_불법단속-7.png" width="482" height="320" /></a></p>
<p><span style="color: #0000ff"><strong>5. 기타</strong></span><br />
<span style="color: #33cccc"><strong>5.1. 작품의 기대효과</strong></span><br />
가. 단속 인력 최소화 및 효율적 행정 처리<br />
장애인을 위한 주차 관리 시스템은 단속 신고 자동화를 내세우고 있어 단속 관련 업무를 최소화하고 업무 처리에 소비되는 시간을 단축시킬 수 있다. 또한 신고 자동화로 인한 항시 단속으로 단속 인력 부족에 대한 문제를 해결할 수 있으며 단속 신고 포상과 관련된 비용을 축소할 수 있다.</p>
<p><strong>나. 인식 개선</strong><br />
단속 업무 자동화로 인해 불법 주차 차량에 대한 확실한 증거를 확보하게 되고, 확증이 생긴 단속 대상은 결격 사유에 해당하지 않기 때문에 자동으로 과태료 부과 대상이 된다. 항시 단속하여 불법 주차 차량이 신속히 적발되어 처벌되면 장애인 주차 구역에 대한 인식 개선을 노릴 수 있다.</p>
<p><strong>다. 불법 주차 감소</strong><br />
수시로 단속하여 쉽게 처벌 대상이 되고 주차 구역 위반에 대한 인식이 변화하면 불법 주차 차량의 감소를 기대할 수 있다. 이로 인해 장애인 전용 주차 구역이 필요한 이들이 마땅한 자리를 얻을 수 있다.</p>
<p><strong>라. 시민의식 함양</strong><br />
불법 주차 감소함에 따라 불법에 대하여 하지 못하도록 사회 인식을 바꾸고 대한민국 사회에서 불법을 하지 않는 나라로 바뀌어 시민의식을 깨우치고 조금 더 선진국으로 나아가는 방향을 기대하여 본다.</p>
<p><strong>마. 불법 주차 처리성</strong><br />
지금 현재 불법 주차 시에 어플리케이션으로 신고를 하게 되면 신고를 처리하면 신고처리를 하는 시간이 1시간정도의 시간이 걸리는 데 주차공간에 있는 차량이 빠져나오는데 이렇게 오랜 시간이 걸리게 되면 정작 주차를 하려고 하였던 장애인 차량은 기다리기만 할 수도 없는 노릇이다. 하지만 이 시스템을 사용하게 되면 불법 주차로 간주되는 즉시 바로 경고음과 주차관리자 및 교통과 관리자에게 통보가 되므로 불법주차 차량을 바로 빠져나오게 할 수 있다. 이렇게 되면 기다리는 사람도 발생하지 않아 고생하지 않아도 된다.</p>
<p><span style="color: #33cccc"><strong>5.2. 프로젝트를 통해 배우거나 느낀 점</strong></span><br />
<strong>비효율적인 행정 처리</strong><br />
민원은 많지만 이를 수용할 인력도 효율적인 프로세스도 없다. 또한 20%가량의 민원은 정보가 부족하다는 이유로 처리되지 않는다. 이러한 문제점은 민원이 민원을 만들어 낸다고 생각했다. 즉각 단속이 가능해 진다면 처리 속도는 물론이고 단속 인원도 필요없다. 무엇보다 중요한 것은 정보가 부족하다는 이유로 민원이 처리 되지 않는 일은 없을 것이다.</p>
<p><strong>인식 개선</strong><br />
많은 기사를 통해 놀라운 문구를 접했다.<br />
“장애인 구역에 주차하면 어때서?”, “장애인 주차 구역에 주차한 시장”, “장애인 주차 구역 주차 후 과태료 물자 도리어 화를 낸다.” 이렇듯 많은 사람들이 장애인 주차공간에 주차하는 것을 별것 아니라고 생각한다. 이런 생각들이 쌓여서 현재 수많은 민원과 민원에 따른 행정 업무가 필요해졌다. 불법 주차 시 즉각 단속을 할 수 있다면 장애인 주차 구역에 주차를 하지 않을 것이며 추후에는 인식 개선으로 이어질 것이다. 장애인 주차 구역뿐만 아니라 무단 행단과 음주 운전 같이 쉽게 어겨지는 행위들도 즉각 단속을 통한 인식 개선이 필요하다고 느낀다.<br />
<strong></strong></p>
<p><span style="color: #33cccc"><strong>5.3. 영상처리 소스코드</strong></span></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include &lt;opencv2/opencv.hpp&gt;</p>
<p>#include &lt;iostream&gt;<br />
#include &lt;cstdlib&gt;<br />
#include &lt;stack&gt;</p>
<p>using namespace cv;<br />
using namespace std;</p>
<p>int main()<br />
{<br />
Mat image, image1, image2, image3, drawing;<br />
Rect rect, temp_rect;<br />
vector&lt;vector&lt;Point&gt; &gt; contours;<br />
vector&lt;Vec4i&gt; hierarchy;<br />
double ratio, delta_x, delta_y, gradient;<br />
int select, plate_width, count, friend_count = 0, refinery_count = 0;<br />
stack&lt;int&gt; Stack;<br />
stack&lt;int&gt; Stack2;<br />
image = imread(&#8220;C:\\Users\\aucun\\Documents\\Visual Studio 2018\\Projects\\opencv_basic\\Plates\\3.JPG&#8221;); // 이미지 읽기</p>
<p>imshow(&#8220;Original&#8221;, image);<br />
waitKey(0);</p>
<p>image.copyTo(image2); // 이미지 복사<br />
image.copyTo(image3);</p>
<p>cvtColor(image2, image2, CV_BGR2GRAY); // 회색으로 변환<br />
imshow(&#8220;Original-&gt;Gray&#8221;, image2);<br />
waitKey(0);</p>
<p>Canny(image2, image2, 100, 300, 3); // 외각선 추출<br />
imshow(&#8220;Original-&gt;Gray-&gt;Canny&#8221;, image2);<br />
waitKey(0);</p>
<p>&nbsp;</p>
<p>// Finding contours.<br />
findContours(image2, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point());<br />
vector&lt;vector&lt;Point&gt; &gt; contours_poly(contours.size());<br />
vector&lt;Rect&gt; boundRect(contours.size());<br />
vector&lt;Rect&gt; boundRect2(contours.size());</p>
<p>for (int i = 0; i&lt; contours.size(); i++) {<br />
approxPolyDP(Mat(contours[i]), contours_poly[i], 1, true);<br />
boundRect[i] = boundingRect(Mat(contours_poly[i]));<br />
}</p>
<p>drawing = Mat::zeros(image2.size(), CV_8UC3);</p>
<p>for (int i = 0; i&lt; contours.size(); i++) {</p>
<p>ratio = (double)boundRect[i].height / boundRect[i].width;</p>
<p>if ((ratio &lt;= 2.5) &amp;&amp; (ratio &gt;= 0.5) &amp;&amp; (boundRect[i].area() &lt;= 700) &amp;&amp; (boundRect[i].area() &gt;= 100)) {</p>
<p>drawContours(drawing, contours, i, Scalar(0, 255, 255), 1, 8, hierarchy, 0, Point());<br />
rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), Scalar(255, 0, 0), 1, 8, 0);</p>
<p>boundRect2[refinery_count] = boundRect[i];<br />
refinery_count += 1;<br />
}<br />
}</p>
<p>boundRect2.resize(refinery_count);</p>
<p>imshow(&#8220;Original-&gt;Gray-&gt;Canny-&gt;Contours&amp;Rectangles&#8221;, drawing);<br />
waitKey(0);</p>
<p>// Bubble Sort accordance with X-coordinate.<br />
for (int i = 0; i&lt;boundRect2.size(); i++) {<br />
for (int j = 0; j&lt;(boundRect2.size() &#8211; i); j++) {<br />
if (boundRect2[j].tl().x &gt; boundRect2[j + 1].tl().x) {<br />
temp_rect = boundRect2[j];<br />
boundRect2[j] = boundRect2[j + 1];<br />
boundRect2[j + 1] = temp_rect;<br />
}<br />
}<br />
}<br />
for (int i = 0; i&lt; boundRect2.size(); i++) {<br />
rectangle(image3, boundRect2[i].tl(), boundRect2[i].br(), Scalar(0, 255, 0), 1, 8, 0);<br />
count = 0;<br />
// Snake moves to right, for eating his freind.<br />
for (int j = i + 1; j&lt;boundRect2.size(); j++) {</p>
<p>delta_x = abs(boundRect2[j].tl().x &#8211; boundRect2[i].tl().x);</p>
<p>if (delta_x &gt; 150) // Can&#8217;t eat snake friend too far ^-^.<br />
break;<br />
delta_y = abs(boundRect2[j].tl().y &#8211; boundRect2[i].tl().y);<br />
if (delta_x == 0) {<br />
delta_x = 1;<br />
}<br />
if (delta_y == 0) {<br />
delta_y = 1;<br />
}<br />
gradient = delta_y / delta_x;<br />
//cout &lt;&lt; i &lt;&lt; endl;</p>
<p>if (gradient &lt; 0.25) {<br />
count++;</p>
<p>if (!Stack.empty()) {<br />
if ((boundRect2[j].tl().x &gt; (boundRect2[Stack.top()].tl().x + (boundRect2[Stack.top()].width / 2)))) {<br />
Stack.push(j);<br />
}<br />
}<br />
else {<br />
Stack.push(j);<br />
}<br />
}<br />
}<br />
if (count &gt; friend_count) {<br />
while (!Stack2.empty()) Stack2.pop();<br />
while (!Stack.empty()) {<br />
Stack2.push(Stack.top());<br />
Stack.pop();<br />
cout &lt;&lt; Stack2.top() &lt;&lt; endl;<br />
}<br />
select = i;<br />
friend_count = count;<br />
rectangle(image3, boundRect2[select].tl(), boundRect2[select].br(), Scalar(255, 0, 0), 1, 8, 0);<br />
plate_width = delta_x;<br />
}<br />
while (!Stack.empty()) Stack.pop(); //스택 비우기<br />
} // 네모칸을 이미지에 표시<br />
rectangle(image3, boundRect2[select].tl(), boundRect2[select].br(), Scalar(0, 0, 255), 2, 8, 0);<br />
line(image3, boundRect2[select].tl(), Point(boundRect2[select].tl().x + plate_width, boundRect2[select].tl().y), Scalar(0, 0, 255), 1, 8, 0);</p>
<p>imshow(&#8220;Rectangles on original&#8221;, image3);<br />
waitKey(0);<br />
image(Rect(boundRect2[select].tl().x, boundRect2[select].tl().y , boundRect2[select].width, boundRect2[select].height)).copyTo(image1);//차번호판 부분만 복사<br />
resize(image1, image1, Size(image1.cols*4, image1.rows*4), 0, 0, CV_INTER_LINEAR);//크기 조정</p>
<p>int k;<br />
for (int i = 0; i &lt; friend_count-1; i++) {<br />
if (!Stack2.empty()) {<br />
k = Stack2.top();<br />
Stack2.pop();<br />
image(Rect(boundRect2[k].tl().x, boundRect2[k].tl().y, boundRect2[k].width, boundRect2[k].height)).copyTo(image1);//숫자나 문자 하나씩 추출<br />
resize(image1, image1, Size(image1.cols * 4, image1.rows * 4), 0, 0, CV_INTER_LINEAR);//크기 조정<br />
imwrite(&#8220;C:\\Users\\aucun\\Desktop\\test\\&#8221; + to_string(i + 2) + &#8220;.JPG&#8221;, image1);//잘려진 사진을 저장<br />
}<br />
}<br />
// Shows license plate, and save image file.<br />
imshow(&#8220;Region of interest&#8221;, image1);<br />
waitKey(0);<br />
//imwrite(&#8220;C:\\Users\\aucun\\Desktop\\test\\1.JPG&#8221;, image1);<br />
exit(0);<br />
}</p>
<p>ㅇ라즈베리파이 쉘스크립트<br />
#/!/bin/bash</p>
<p>flag=1<br />
for((;;))</p>
<p>do<br />
echo $flag<br />
check=`./test`<br />
echo $check</p>
<p>if [ $check = "carin" -a ${flag} == 1 ]
then<br />
flag=0<br />
raspistill -o car.jpg</p>
<p>var=`curl -F myfile=@/home/pi/test/car.jpg http://han.mysterlee.com/a.jsp`</p>
<p>echo $var</p>
<p>if [ $var = "8" ]
then<br />
echo &#8220;장애인차&#8221;<br />
echo $var</p>
<p>else<br />
echo &#8220;비장애인차&#8221;<br />
echo $var<br />
./jong</p>
<p>#else if [ $var = "1" ]
#echo &#8220;인식안됨 or 오류&#8221;<br />
#./jong</p>
<p>fi</p>
<p>fi<br />
if [ $check = "carout" ]
then<br />
flag=1<br />
fi<br />
done</p>
<p>exit 0<br />
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/35995/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[49호]Smart Baby Helper</title>
		<link>http://www.ntrexgo.com/archives/36014</link>
		<comments>http://www.ntrexgo.com/archives/36014#comments</comments>
		<pubDate>Mon, 20 Aug 2018 00:00:05 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[49호]]></category>
		<category><![CDATA[Feature]]></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=36014</guid>
		<description><![CDATA[디바이스마트매거진 49호 &#124; 비 부착형으로 센싱을 한 스마트한 Baby Helper를 만들고자 하였다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440.png" rel="lightbox[36014]"><img class="alignnone size-large wp-image-35589" alt="Cap 2018-07-12 14-10-54-440" src="http://www.ntrexgo.com/wp-content/uploads/2018/06/Cap-2018-07-12-14-10-54-440-620x210.png" width="620" height="210" /></a></p>
<p><span style="background-color: #000000;font-size: medium;color: #ffffff"><strong>  2018 ICT 융합 프로젝트 공모전 우수상  </strong></span></p>
<p><span style="font-size: x-large;color: #000000;background-color: #ffffff"><strong>Smart Baby Helper</strong></span></p>
<p style="text-align: right">글 | 단국대학교 정의동</p>
<p style="text-align: right">
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 실생활에서 얻은 아이디어와 통계자료 및 시장조사를 이용한 프로젝트 시작에 높은 평가를 줍니다. 실제 생각보다 흔하게 일어나는 영유아 질식사고를 예방한다는 컨셉에 많이 공감하였습니다. 실용성과 창의성등 대부분의 항목에서 높은 점수를 주었으나 보고서의 정리와 시스템 구성도 등이 좀 더 보완해야될 부분 같습니다.</p>
<p><strong>뉴티씨</strong> 아기와 관련된 여러가지 상태를 IoT 환경에서 감시하고, 영상을 전송하는 등으로 아기를 원격지에서도 살펴볼 수 있도록 한 점은 좋은 응용이라고 생각됩니다. 또한, IoT를 학습하는 데도 좋은 작품이 되었습니다. 다만, 완성도를 조금 높여서 실제로 사용이 가능하도록 아이디어를 첨부하면 좀 더 좋은 작품이 되리라고 생각됩니다<br />
<strong></strong></p>
<p><strong>위드로봇</strong> 3D 프린터로 목업을 제작하고, 이 크기에 맞춰 보드를 제작한, 실제 실용적인 측면을 많이 고려한 작품입니다. 전반적으로 완성도가 높으며, 동영상 데모가 있으면 더욱 좋을 것 같습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span></p>
<p><span style="color: #0000ff"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-1.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36026" alt="49 ict_smart babyhelper (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-1.png" width="620" height="467" /></a></strong></span><br />
평소 기사, 뉴스, TV 등으로 워킹맘들이 육아를 하는데 큰 어려움을 겪고 있다고 알고 있어서 이를 어떻게 디바이스 해결할 수 있을지에 대해 고민을 많이 했었습니다.<br />
우선 워킹맘들이 가장 어려움을 겪는 부분이 어디인지 조사한 결과 예상대로 육아부분 이였고, 육아하는데 가장 큰 걱정이 무엇인지 조사한 결과 영유아의 수면이 제일 걱정된다고 했습니다. 그 원인을 찾아보았더니 수면 중 아기의 호흡곤란 등으로 사고가 많이 일어났다는 것을 알 수 있었습니다. 이런 Desk Research 뿐만 아니라 직접 아기를 키우고 계시는 육아맘들을 직접 인터뷰 및 질의응답을 진행하였고, Field Research를 조사했더니 Desk Research와 비슷한 결과를 얻을 수 있었습니다.<br />
즉, 자녀 양육이 부모들의 가장 큰 스트레스로 작용하였고 그 원인을 파헤쳐본 결과 아기의 건강, 수유, 목욕, 양육비 등이 있었습니다.<br />
저는 이러한 문제를 해결하고자 스마트 디바이스를 제작하고자 하였고 만들기 전에 앞서 시장에 나와있는 비슷한 제품들을 조사하였습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-2.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36027" alt="49 ict_smart babyhelper (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-2.png" width="620" height="396" /></a></p>
<p>위의 제품들의 공통적으로 가장 큰 문제라고 생각되는 점이 몸에 부착하여야만 사용이 가능한 불편한 형태로 제작된 제품이라 생각되어 이를 해결한, 부착형이 아닌 비 부착형으로 센싱을 한 스마트한 Baby Helper를 만들고자 하였습니다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #537eff"><strong>3.1. 주요 동작 및 특징</strong></span><br />
본 작품은 크게 두 부분으로 나눌 수 있습니다. 젖병 모듈과 건강관리(허브) 모듈로 나눌 수 있는데 젖병 모듈에서는 아기의 적정 수유량, 수유온도, 수유시간을 제공 및 알람을 해 줍니다.<br />
건강관리 모듈에서는 아기의 호흡 및 맥박수를 체크하고, 아기 주변환경의 온습도 및 공기질 상태를 체크하며, 카메라 센서를 이용해 실시간 아기 모니터링이 가능하게 하였습니다.</p>
<p><span style="color: #33cccc"><strong>3.1.1. 젖병 모듈 Part</strong></span></p>
<p><span style="color: #33cccc"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-1.jpg" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36028" alt="49 ict_smart babyhelper (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-1.jpg" width="620" height="422" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-3.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36029" alt="49 ict_smart babyhelper (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-3.png" width="620" height="334" /></a></strong></span><br />
<strong>동작 및 특징</strong><br />
· 적외선 온도센서를 통한 젖병 내부 온도 체크<br />
· 압력센서를 통한 수유량 체크<br />
· VFD를 통한 실시간 젖병 내부온도 및 수유시간 확인<br />
· 서버 및 DB를 구축하여 권장 수유량, 수유시간을 제공 및 알람<br />
· 쌓여가는 사용자의 DATA에 맞춰 수유량, 수유시간 Update</p>
<p><span style="color: #33cccc"><strong>3.1.2. 건강관리(허브) 모듈 Part</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-4.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36030" alt="49 ict_smart babyhelper (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-4.png" width="620" height="380" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-2.jpg" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36031" alt="49 ict_smart babyhelper (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-2.jpg" width="620" height="344" /></a></p>
<p><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/Cap-2018-11-20-10-10-29-470.jpg" rel="lightbox[36014]"><img alt="49 ict_smart babyhelper 555" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/Cap-2018-11-20-10-10-29-470.jpg" width="620" height="348" /></a></strong><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-6.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36016" alt="49 ict_smart babyhelper (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-6.png" width="620" height="345" /></a></p>
<p>위 테스트 사진은 실제 와이파이 센서를 이용하여 맥박수 및 호흡측정을 테스트하고 그래프로 나타낸 사진입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-7.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36017" alt="49 ict_smart babyhelper (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-7.png" width="619" height="430" /></a></p>
<p>위 과정도의 우측 아기사진은 MIT에서 실제 와이파이 센서를 이용하여 아기 수면중 호흡 및 맥박 측정을 테스트한 사진입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-8.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36018" alt="49 ict_smart babyhelper (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-8.png" width="619" height="508" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-9.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36019" alt="49 ict_smart babyhelper (9)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-9.png" width="619" height="323" /></a><br />
간단하게 설명하자면 와이파이 센서에서 신호를 송수신 하는데 TV, 책상 등의 사물은 송수신의 Time 변화율이 0이고, 아기의 Time 변화율은 상수이므로 이 차이를 이용하여 다른것들은 배제한채 순수한 아기의 거리값을 구할 수 있습니다. 거리값에는 아기와 모듈간의 거리값이 나오는데 여기서 Time축을 더 쪼개면 아기의 호흡량을 구할 수 있고, 호흡량 그래프 안에서도 떨림이 보이는 그래프 모양이 발생하는데 바로 이 부분이 맥박(심박)입니다.<br />
이를 이용하여 아기의 호흡량 및 맥박수를 구할 수 있습니다.<br />
하지만 여기에서 아직 보완 및 발전해야 하는 부분은 여러명의 사람이 있을 때 각각의 사람의 호흡 및 맥박수를 분리하여 구분해서 구해야 합니다.<br />
현재 개발중인 부분인데, 와이파이센서 여러개를 병렬(어레이 구조)로 만들어 사물의 위치를 파악하게 하여 분리합니다. 여러개의 와이파이 센서는 각각의 방위각 및 같은 사물에 대한 거리차를 구할 수 있어 실제 모듈과 대상간의 벡터 거리값을 구할 수 있습니다.</p>
<p><strong>동작 및 특징</strong><br />
· 와이파이 센서를 통한 호흡 및 맥박수 측정<br />
· 온습도 센서, 공기질 센서를 통한 주변 환경 체크<br />
· 카메라 센서를 통한 아기 상황 실시간 모니터링<br />
· 아기의 상황에 변화가 있을시 즉시 알람기능</p>
<p><span style="color: #33cccc"><strong>3.2.3. 안드로이드 &#8211; 모듈 연동 Part</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-15.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36025" alt="49 ict_smart babyhelper (15)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-15.png" width="321" height="262" /></a></p>
<p><strong>아기 상태 정보</strong><br />
· UWB 센서를 통한 호흡, 맥박수 측정<br />
· 마이크 센서를 통한 아기 울음소리 감지<br />
· 공기질, 온습도 센서를 통한 주변환경 감지<br />
· 웹캠을 통한 아기 상태 확인<br />
· 응급상황 알림 서비스</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-10.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36020" alt="49 ict_smart babyhelper (10)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-10.png" width="375" height="262" /></a></p>
<p><strong>아기 성장 정보</strong><br />
· 아기의 성장 상태 확인<br />
· 아기의 현재 상태 확인</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-14.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36024" alt="49 ict_smart babyhelper (14)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-14.png" width="298" height="262" /></a></p>
<p><strong>실시간 아이 식사량 체크</strong><br />
· 비접촉 온도센서를 통한 수유 온도 확인<br />
· 압력센서를 통한 수유 먹은 양 체크<br />
· 자동으로 다음 먹을 시간 계산</p>
<p><span style="color: #537eff"><strong>3.2 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-11.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36021" alt="49 ict_smart babyhelper (11)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-11.png" width="620" height="396" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-12.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36022" alt="49 ict_smart babyhelper (12)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-12.png" width="620" height="457" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-13.png" rel="lightbox[36014]"><img class="alignnone size-full wp-image-36023" alt="49 ict_smart babyhelper (13)" src="http://www.ntrexgo.com/wp-content/uploads/2018/11/49-ict_smart-babyhelper-13.png" width="620" height="446" /></a></p>
<p><span style="color: #537eff"><strong>3.3 개발 환경(개발언어, Tool, 사용시스템 등) </strong></span><br />
<span style="color: #33cccc"><strong>3.3.1. 개발언어 &#8211; C, C++, Java, Php, Python</strong></span><br />
개발 Tool : Arduino IDE, Vim, Andriod Studio<br />
사용 시스템 : Wemos-Wifi 보드<br />
사용 시스템 : 라즈베리파이3(Model B)</p>
<p>젖병모듈에는 아두이노 기반의 Wemos-Wifi보드가 올라가는데 c, c++기반입니다. 건강관리(젖병) 모듈은 라즈베리파이3를 쓰는데 c,python을 기반으로 작업하였습니다. 또한 안드로이드에서는 java로 작업하였고, 서버를 위해 php를 사용했습니다.<br />
Wemos-wifi보드를 위한 Arduino IDE, 라즈베리파이를 위한 Vim, 어플제작을 위한 Android Studio를 썼습니다.<br />
Wemos-Wifi를 선정한 이유는 기타 보드보다 아주 사이즈가 작으면서, 와이파이 쉴드가 내장되어 있고, gpio, adc, i2c, sci, spi 등 다양한 통신기능도 있어서 모듈로 제작하기에 아주 적합하였습니다.<br />
라즈베리파이를 선정하게 된 이유는 900MHz의 빠른 속도와, 1GB의 넉넉한 램용량, 저렴한 가격 및 많은 GPIO핀을 보유하고 있어서입니다. 또한, 서버 환경을 구축하기에 아주 적합하고 호환성 또한 매우 훌륭합니다.</p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #33cccc"><strong>4.1.1. 계획 세우기 및 사전조사(2017.09.02 ~ 2017.09.30)</strong></span><br />
대상을 정하고 대상의 가장 큰 관심사를 조사, 그에 따른 프로젝트 작품을 선정하고 기술적 차별성은 어떻게 할것인지 등을 조사합니다.</p>
<p><span style="color: #33cccc"><strong>4.1.2. 해당 작품 공부 및 제작 준비(2017.10.01 ~ 2017.10.31)</strong></span><br />
와이파이 신호를 어떻게 받아오는지, 받아온 신호를 어떻게 처리를 해 야 하는지, 서버를 어떻게 구축하고, 어떻게 데이터를 송수신 하는지 등을 공부하고 하드웨어는 어떻게 제작할 것인지 등 준비를 합니다.</p>
<p><span style="color: #33cccc"><strong>4.1.3. 센서 테스트(2017.11.01. ~ 2018.01.31)</strong></span><br />
와이파이 센서, 적외선 온도 센서, 압력 센서, 온습도 센서, 공기 질 센서, 카메라 센서를 각각 테스트합니다. 센서가 많고 센싱이 어려운 만큼 전체 기간중 가장 큰 비중을 차지합니다.</p>
<p><span style="color: #33cccc"><strong>4.1.4. 젖병모듈 제작(2018.02.01. ~ 2018.02.14)</strong></span><br />
이전에 테스트 했던 온도, 압력센서를 이용하여 젖병 모듈을 만듭니다. 또한, 실제 분유를 타 온도, 무게값이 잘 나오는지 에러를 처리 합니다.</p>
<p><span style="color: #33cccc"><strong>4.1.5. 건강관리(허브) 모듈 제작(2018.02.15. ~ 2018.03.07)</strong></span><br />
이전에 테스트했던 와이파이, 온습도, 공기질, 카메라 센서를 전체적으로 합병하고 모듈로 제작하고 호흡, 맥박수가 잘 측정되는지, 주변 환경이 모니터링이 잘 되는지 다시 에러 처리합니다. 또한 서버에 데이터가 잘 넘어가고 받아지는지 테스트 합니다.</p>
<p><span style="color: #33cccc"><strong>4.1.6. 어플 제작 및 연동(2018.03.07. ~ 2018.03.29)</strong></span><br />
안드로이드 스튜디오를 이용한 어플을 제작하고 젖병, 건강관리 모듈과의 서버를 통한 데이터 통신을 하게 합니다. 또한, 어플을 통해 사용자에게 알림 및 정보를 제공해 줍니다.</p>
<p><span style="color: #33cccc"><strong>4.1.7. 보완 및 Develop(2018.03.30. ~ )</strong></span><br />
와이파이 센서를 병렬구조로 제작 및 테스트하여 다수의 사람인 경우에도 구분 및 센싱이 가능하게 하고, 와이파이 센서를 넘어 마이크 센서로 제작하여 비가청 주파수를 이용해 센싱을 하여 전자파의 위험성을 해결해 주려 합니다.</p>
<p><span style="color: #0000ff"><strong>5. 기타(소스코드, 참고문헌 등)</strong></span><br />
<span style="color: #537eff"><strong>5.1. 소스코드</strong></span><br />
<span style="color: #33cccc"><strong>5.1.1. 젖병 모듈 전체 소스</strong></span></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>#include &lt;ESP8266WiFi.h&gt;</p>
<p>#include &lt;font5x7.h&gt;<br />
#include &lt;LedDisplay.h&gt;<br />
#include &lt;Adafruit_MLX90614.h&gt;</p>
<p>#define dataPin D0 // connects to the display&#8217;s data in<br />
#define registerSelect D4 // the display&#8217;s register select pin<br />
#define clockPin D6 // the display&#8217;s clock pin<br />
#define enable D5 // the display&#8217;s chip enable pin<br />
#define reset 0 // the display&#8217;s reset pin<br />
#define displayLength 8 // number of characters in the display<br />
#define Weight A0 // Weight sensor</p>
<p>int brightness = 15;<br />
LedDisplay myDisplay = LedDisplay(dataPin, registerSelect, clockPin,<br />
enable, reset, displayLength);<br />
Adafruit_MLX90614 temp = Adafruit_MLX90614();</p>
<p>const char *ssid = &#8220;dongdong&#8221;;<br />
const char *password = &#8220;hello4826&#8243;;<br />
const char *host = &#8220;192.168.1.13&#8243;; //서버 주소 입력<br />
WiFiServer server(80);</p>
<p>void setup() {<br />
Serial.begin(115200);<br />
myDisplay.begin();<br />
// set the brightness of the display:<br />
myDisplay.setBrightness(brightness);<br />
temp.begin();</p>
<p>Serial.print(&#8220;Connecting to &#8220;);<br />
Serial.println(ssid);</p>
<p>WiFi.begin(ssid, password);</p>
<p>while (WiFi.status() != WL_CONNECTED) {<br />
delay(500);<br />
Serial.print(&#8220;.&#8221;);<br />
}<br />
Serial.println(&#8220;&#8221;);<br />
Serial.println(&#8220;WiFi connected&#8221;);</p>
<p>// Start the server<br />
server.begin();<br />
Serial.println(&#8220;Server started&#8221;);</p>
<p>// Print the IP address<br />
Serial.println(WiFi.localIP());<br />
}</p>
<p>void loop() {</p>
<p>String ch_weight[6] = {&#8220;0%&#8221;, &#8220;20%&#8221;, &#8220;40%&#8221;, &#8220;60%&#8221;, &#8220;80%&#8221;, &#8220;100%&#8221;};<br />
float Temp = temp.readObjectTempC();<br />
int weight = analogRead(Weight);<br />
int weight_state = 0;</p>
<p>if(weight &gt; 910) weight_state = 5; //100%<br />
else if(weight &gt; 850) weight_state = 4; //80%<br />
else if(weight &gt; 800) weight_state = 3; //60%<br />
else if(weight &gt; 760) weight_state = 2; //40%<br />
else if(weight &gt; 650) weight_state = 1; //20%<br />
else weight_state = 0; // 0%</p>
<p>WiFiClient client = server.available();<br />
/*<br />
if (!client) {<br />
delay(500);<br />
Serial.print(&#8220;.&#8221;);<br />
return;<br />
}<br />
*/<br />
/*<br />
WiFiClient client;<br />
const int httpPort = 80;<br />
if (!client.connect(host, httpPort)) {<br />
delay(500);<br />
Serial.print(&#8220;.&#8221;);<br />
return;<br />
}<br />
*/<br />
client.print(&#8220;temperature = &#8220;);<br />
client.print(Temp);</p>
<p>Serial.print(&#8220;Weight = &#8220;); Serial.print(ch_weight[weight_state]); //Serial.println(&#8221;<br />
*C&#8221;);<br />
//Serial.print(&#8220;Temp = &#8220;); Serial.print(Temp); Serial.println(&#8221; *C&#8221;);<br />
Serial.println();</p>
<p>myDisplay.home();<br />
// print the millis:<br />
myDisplay.print(&#8221; &#8220;);<br />
myDisplay.print(Temp);<br />
myDisplay.print(&#8220;*C&#8221;);</p>
<p>}</p>
</div>
<p><span style="color: #33cccc"><strong>5.1.2. 서버 데이터 전송</strong></span></p>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p>&lt;?php<br />
$servername = &#8220;localhost&#8221;;<br />
$username = &#8220;root&#8221;;<br />
$password = &#8220;raspberry&#8221;;<br />
$dbname = &#8220;rpidb&#8221;;</p>
<p>// Create connection<br />
$conn = new mysqli($servername, $username, $password, $dbname);<br />
// Check connection<br />
if ($conn-&gt;connect_error) {<br />
die(&#8220;Connection failed: &#8221; . $conn-&gt;connect_error);<br />
}</p>
<p>$sql = &#8220;SELECT time, humidity0, humidity1, temperature0, temperature1 FROM envdata ORDER BY time DESC LIMIT 0, 12&#8243;;<br />
$result = $conn-&gt;query($sql);</p>
<p>$time = &#8220;&#8221;;<br />
$humidity = &#8220;&#8221;;<br />
$temperature = &#8220;&#8221;;w</p>
<p>if ($result-&gt;num_rows &gt; 0) {<br />
// output data of each row<br />
while($row = $result-&gt;fetch_assoc()) {<br />
//echo &#8220;time: &#8221; . $row["time"]. &#8221; &#8211; humidity: &#8221; . $row["humidity0"]. &#8220;.&#8221; . $row["humidity1"]. &#8221; &#8211; temperature: &#8221; . $row["temperature0"]. &#8220;.&#8221; . $row["temperature1"]. &#8220;&lt;br&gt;&#8221;;</p>
</div>
<p><span style="color: #537eff"><strong>5.2. 참고문헌</strong></span><br />
· Smart Homes that Monitor Breathing and Heart Rate Fadel Adib Hongzi Mao Zachary Kabelac Dina Katabi Robert C. Miller Massachusetts Institute of Technology<br />
· 3D Tracking via Body Radio Reflections : Fadel Adib, Zach Kabelac, Dina Katabi, and Robert C. Miller, Massachusetts Institute of Technology<br />
· VITAL SIGN MONITORING OF A NON-STATIONARY HUMAN THROUGH IR-UWB RADAR Faheem Khan, Jeong Woo Choi, Sung Ho Cho<br />
· Heartbeat Detection based on Signal Reflected from Antenna in Mobile Device Yong-Jun An., Gi-Ho Yun, Jong-Gwan Yook</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/36014/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[47호]졸음운전 방지 시스템</title>
		<link>http://www.ntrexgo.com/archives/35324</link>
		<comments>http://www.ntrexgo.com/archives/35324#comments</comments>
		<pubDate>Tue, 10 Apr 2018 00:00:52 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[47호]]></category>
		<category><![CDATA[Feature]]></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=35324</guid>
		<description><![CDATA[디바이스마트매거진 7호 &#124; 블랙박스에 졸음운전을 방지하는 기능을 더한다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/07/Cap-2017-10-18-13-15-49-260.png" rel="lightbox[35324]"><img class="alignnone size-large wp-image-34236" alt="Cap 2017-10-18 13-15-49-260" src="http://www.ntrexgo.com/wp-content/uploads/2017/07/Cap-2017-10-18-13-15-49-260-620x137.png" width="620" height="137" /></a></p>
<p><span style="background-color: #000000;color: #ffff00"><strong>2017 ICT 융합 프로젝트 공모전 참가상</strong></span></p>
<p><span style="font-size: large"><strong><span style="font-size: x-large">졸음운전 방지 시스템</span><br />
</strong></span></p>
<p style="text-align: right"><strong>글 | 성결대학교 김성중, 오태식, 여규성, 이정희</strong></p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
칩센 자동차 주행 시의 안전은 무엇보다 운전자와 타인의 생명과 직결되는 문제이고, 이를 기반으로 기획이 이루어진 것이라 생각됩니다. 이를 각 기술의 단계별로 검토가 이루어진 내용이 좋아 보입니다. 하지만, 실제 작품을 제작 및 시연이 이루어 지지 않았습니다. 차선 검출시에 중요한 요소인 소실점 등이 추출되지 않은 경우와 같은 변수가 전혀 고려되지 않아 예상되는 상황만으로 작품 개발이 이루어졌고, 눈 깜빡임 등과 같은 상수에 가까운 사항을 검증하지 않은 점이 아쉬움이 듭니다.<br />
뉴티씨 낮은비용으로 졸음운전을 방지하려는 노력이 좋습니다. 사람들이 이 기능을 활용하여 안전운전을 할 수 있도록 되었으면 좋겠습니다. 많은 오류 등의 처리 등에 많은 개선점이 보이며, 앞으로 연구할 것이 많은 분야로 많은 업그레이드를 예상합니다.<br />
위드로봇 완성이 된 작품인지 보고서만으론 판단하기 어렵습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품 개요</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-1.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35395" alt="47 feature 졸음운전 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-1.png" width="465" height="291" /></a><br />
<span style="color: #008080"><strong>졸음운전 방지 시스템</strong></span><br />
블랙박스에 졸음운전을 방지하는 기능을 더한다 .</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-2.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35396" alt="47 feature 졸음운전 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-2.png" width="463" height="416" /></a></p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-3.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35397" alt="47 feature 졸음운전 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-3.png" width="463" height="254" /></a><br />
졸음운전으로 인한 사고는 잊을만하면 언론의 구설수에 오른다. 특히 큰 사고가 일어나기 쉬운 고속도로에서는 졸음운전으로 인한 사고가 많이 일어나고 있다. 고속도로는 도로 상태가 좋고 차량들의 속도가 빠르고 운전하는 시간이 길기 때문에 운전자가 졸기 쉽다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-4.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35398" alt="47 feature 졸음운전 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-4.png" width="463" height="301" /></a><br />
사고가 나면 대형 사고일 확률이 높은 대형차량에는 졸음운전을 방지하는 여러 가지 시스템이 갖춰져서 출시되고 고급 승용차에는 최신 기술을 사용한 졸음운전 방지 시스템이 있어 옵션으로 선택할 수 있다.<br />
하지만 저가형 승용차에는 최근에서야 졸음운전을 방지하는 LDWS가 달린 몇몇 기종이 출시되는 등 졸음운전에 대해 많이 취약하다.<br />
그래서 고가의 차가 아니더라도 오늘날 차량에 대다수에 설치되는 블랙박스와 보편적 기기인 스마트폰을 가지고 그와 비슷한 시스템을 구현하기로 하였다.</p>
<p><strong><span style="color: #008080">옵션을 추가하지 않아도 졸음운전을 방지</span></strong></p>
<p><strong></strong><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-5.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35399" alt="47 feature 졸음운전 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-5.png" width="606" height="393" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #008080"><strong>아이작 IF520LD (블랙박스)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-6.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35400" alt="47 feature 졸음운전 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-6.png" width="609" height="451" /></a><br />
· 40만원대 블랙박스<br />
· 기본 블랙박스 기능인 상시/주차/충격 녹화 등 여러 가지 기능 제공<br />
·  전방 추돌 경보 시스템(FCWS : Forward Collision Warning System)<br />
▶ 전방에 있는 차량과의 거리를 측정하고 일정거리 이하가 되면 알림을 계속 울리는 시스템</p>
<p>·  차선 이탈 경보 시스템(LDWS : Lane Departure Warning System)<br />
▶ 블랙박스 영상에서 차선을 인식하여 사용자의 차량이 차선을 벗어나면 알림이 울리는 시스템<br />
▶  사용자의 차선 변경 여부를 차량의 방향지시등 점등을 통하여 알수있고 방향지시등이 점등 되었을 때는 알림을 울리지 않음<br />
▶  방향지시등 점등 여부를 알기 위하여 별도로 차량과의 Signal 케이블 필요</p>
<p>· 장점 :  여러 가지 고급 기능이 들어있는 블랙박스. 졸음운전뿐만 아니라 안전 운전에 도움이 되는 기능을 원하는 사용자에게 유용하다.<br />
· 단점 : 제품 가격이 상당히(보급형 제품의 4배) 비싸다.</p>
<p><strong>뷰메이트 DL330A (졸음 방지 알림기)</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-1.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35401" alt="47 feature 졸음운전 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-1.jpg" width="611" height="530" /></a><br />
·  15만원대 제품<br />
·  차량의 핸들/계기판에 설치하는 제품<br />
·  시선 추적기술(Eye-Tracking)<br />
▶  사용자의 안면을 촬영하는 도중 시선을 추적하여 졸음상태를 감지하는 기술</p>
<p>·  졸음운전이 판단 되었을시에 소리로 알림을 준다.<br />
·  장점<br />
: 1)  차량의 상태를 확인하는 타 제품과는 다르게 직접 사용자의 상태를 확인하는 방식으로 졸음을 감지하여 정보의 신뢰도가 높다.<br />
: 2) 차량에 설치하는 형태라서 관리가 쉽다.</p>
<p>·  단점 : 제품 가격이 비싸다.</p>
<p><span style="color: #3366ff"><strong>3.1. 주요 동작 및 특징</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-7.png" rel="lightbox[35324]"><img class="alignnone  wp-image-35402" alt="47 feature 졸음운전 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-7-518x620.png" width="500" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-8.png" rel="lightbox[35324]"><img class="alignnone  wp-image-35403" alt="47 feature 졸음운전 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-8.png" width="500" /></a></p>
<p><span style="color: #008080"><strong>사용한 도구</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-9.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35404" alt="47 feature 졸음운전 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-9.png" width="609" height="230" /></a></p>
<p><span style="color: #008080"><strong>필요한 방법</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-10.png" rel="lightbox[35324]"><img class="alignnone  wp-image-35405" alt="47 feature 졸음운전 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-10.png" width="600" /></a></p>
<p><span style="color: #3366ff"><strong>3.2. 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-11.png" rel="lightbox[35324]"><img class="alignnone size-large wp-image-35406" alt="47 feature 졸음운전 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-11-620x460.png" width="620" height="460" /></a><br />
<span style="color: #008080"><strong>기본 기능</strong></span><br />
<strong>블랙박스(RaspberryPi)</strong><br />
· 차선 이탈 감지 시스템<br />
· 차간 거리 측정 시스템<br />
· 내부 온도 측정 센서<br />
· 측정값을 Bluetooth를 이용하여 스마트폰에 전송</p>
<p><strong>차량 ECU</strong><br />
· 차량의 정보를 블랙박스로 전송</p>
<p><strong>스마트폰(Android Application)</strong><br />
· 눈꺼풀 개폐(눈 깜빡임) 감지 시스템<br />
· 졸음 알림(스마트폰 H/W 사용)<br />
· 블랙박스 환경설정 인터페이스</p>
<p><span style="color: #008080"><strong>추가 기능</strong></span><br />
<strong>스마트폰(Android Application)</strong><br />
· 운전습관 케어(과거 주행 기록정보) 시스템<br />
· 졸음여부를 서버에 전송<br />
<strong>서버</strong><br />
· 인근에 있는 차량에 졸음운전 차량 유무를 전송<br />
<strong>NFC 태그(스마트폰 거치대)</strong><br />
· 블랙박스와 스마트폰 간의 Bluetooth 페어링 보조</p>
<p><span style="color: #008080"><strong>눈깜빡임 감지 시스템 구현 방법</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-12.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35407" alt="47 feature 졸음운전 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-12.png" width="595" height="230" /></a><br />
<strong>0. 감지 과정</strong><br />
① : 얼굴 인식 ② : 눈 지역 추출 ③ : 눈 깜빡임 검출 ④ : 눈 깜빡임 분류</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-2.jpg" rel="lightbox[35324]"><img class="alignnone size-large wp-image-35408" alt="47 feature 졸음운전 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-2-620x246.jpg" width="620" height="246" /></a></p>
<p><strong> 1. 얼굴 인식</strong><br />
사각형 안의 픽셀 강도의 합과 주변을 비교하여 결정. 정확하게 감지하기 위해 부스팅 알고리즘 &#8211; 아다부스트 알고리즘(조사필요)가 효과적이다.</p>
<p><strong>2. 눈 영역 추출</strong><br />
눈 위치는 기하학적으로 발견한다. 얼굴을 h라 보았을 때 보통 눈은 0.2h ~ 0.6h 사이에 있고 평균적으로 0.4h에 존재한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-3.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35409" alt="47 feature 졸음운전 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-3.jpg" width="319" height="244" /></a></p>
<p><strong>3. 눈깜빡임 검출</strong><br />
눈은 정규화된 상호상관 방법(조사 필요)에 의해 검출된다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-4.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35410" alt="47 feature 졸음운전 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-4.jpg" width="617" height="236" /></a></p>
<p><strong>4. 눈깜빡임 분류</strong><br />
자발적으로 눈을 깜빡인 것을 분류하기 위해 분석한다. 눈 깜빡임이 250밀리초 ~ 2초 사이일 때 자발적인 컨트롤로 간주한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-13.png" rel="lightbox[35324]"><img class="alignnone size-large wp-image-35411" alt="47 feature 졸음운전 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-13-620x344.png" width="620" height="344" /></a></p>
<p><span style="color: #008080"><strong>눈깜빡임 검출</strong></span><br />
<strong>1. 준비사항</strong><br />
· 사용 기기 : 스마트폰 (SM-G930S 삼성 갤럭시S7)<br />
· 프로그래밍 언어 : 자바<br />
· 영상처리 api : OpenCV 3.0.0_android</p>
<p><strong>2. 개요</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-5.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35412" alt="47 feature 졸음운전 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-5.jpg" width="282" height="239" /></a><br />
위와 같은 사진에서, 얼굴과 눈을 검출하고 깜빡임을 체크<br />
· 얼굴로서의 특징을 모두 가지고 있다.<br />
· 처음부터 종료시까지 계속 눈을 감고 있지 않는다.</p>
<p><strong>3. 설계과정</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-14.png" rel="lightbox[35324]"><img class="alignnone  wp-image-35413" alt="47 feature 졸음운전 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-14.png" width="600" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-15.png" rel="lightbox[35324]"><img class="alignnone size-large wp-image-35414" alt="47 feature 졸음운전 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-15-572x620.png" width="600 /&gt;&lt;/a&gt;&lt;span style=" /></a></p>
<p><strong>눈깜빡임 검출 구현</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-16.png" rel="lightbox[35324]"><img class="alignnone  wp-image-35415" alt="47 feature 졸음운전 (16)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-16-456x620.png" width="600" /></a></p>
<p><span style="color: #008080"><strong>눈 깜빡임 검출 실험 Source Code</strong></span><br />
<strong>1. 흑백 변환</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
mGray = inputFrame.gray();<br />
</div>
<strong>2. lbp cascade를 이용하여 얼굴 검출</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2,<br />
// TODO: objdetect. CV_HAAR_SCALE_IMAGE<br />
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());</p>
</div>
<p><strong> 3. 눈 영역 추출</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>Rect r = facesArray[i]:<br />
eyearea_right = new Rect(r.x + r.width / 16,<br />
(int) (r.y + (r.height / 4.5)),<br />
(r.width &#8211; 2 + r.width / 16) / 2,<br />
(int) (r.height / 3.0));<br />
eyearea_left = new Rect (r.x + r.width / 16 + (r.width &#8211; 2 + r.width / 16) / 2,<br />
(int) (r.y + (r,height / 4.5)),<br />
(r.width &#8211; 2 + r.width / 16) / 2,<br />
(int) (r.height / 3.0));</p>
</div>
<p><strong> 4. harr cascade를 이용하여 눈 검출</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>clasificator.detectMulti Scale(mROI, eyes, 1,15, 2,<br />
Objdetect.CASCADE_FIND_BIGGEST_OBJECT<br />
Objdetect .CASCADE_SCALE IMAGE, new Size(30, 30),<br />
new Size());</p>
</div>
<p>&nbsp;</p>
<p><span style="color: #008080"><strong>눈의 위치 저장</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>lastEyes_L[lastEyes_num] = new Point(<br />
(((matchLoc_tx_L.X + matchLoc_ty_L.x) / 2.0) &#8211; eyearea_left.x)/ facesArray[0] .width<br />
(((matchLoc_tx_L.y + matchLoc_ty_L.y) / 2.0) &#8211; eyearea_left.y / facesArray[0] . height<br />
}; // 눈 가운데의 좌표에서 두 영역 좌표를 깨고 얼굴 크기로 나누어서 상대좌표가 아닌 절대좌표로 만듬<br />
lastEyes_R[ lastEyes_num] = new Point(<br />
(((matchLoc_tx_R.x + matchLoc_ty_R.x) / 2.0) &#8211; ewearea_right.x )/ facesArray[0] .width ( (matchLoc_tx_R.y + matchLoc_ty_R.y) / 2.0 &#8211; eyearea_right.y / facesArray[0] . height<br />
};<br />
lastEyes_num++;<br />
if(lastEyes_num == MAX_EYE_LEARN){<br />
두 눈 모두 지정한 횟수 이상 높은 검출 했을 경우<br />
insortionSort (lastEyes_L, 0);<br />
insortionSort( lastEyes_R, 1);<br />
}</p>
</div>
<p><span style="color: #008080"><strong>삽입정렬로 정렬 후 오검출 제외</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>private void insortionSort (Point lastEyes[], int lef tRight) {<br />
int i, j;<br />
double ce;<br />
for (i = 1; i &lt;= NAX_EYE_LEARN -1; i++){<br />
ce = lastEyes[i].x:<br />
j =i &#8211; 1;<br />
while( i &gt;= 0){<br />
if (lastEyes[J].x &gt; ce){<br />
lastEyes[j + 1].x = lastEyes[J].x:<br />
j&#8211; ;<br />
} else break;<br />
lastEyes[] + 1].x = ce: }<br />
// 삽입정렬<br />
if (leftRight == 0) {<br />
double tempX = 0, tempY = 0;<br />
for (int k = 4; k&lt; 16 : k++)<br />
{ 오차라 판단하는데 0~3, 16~20을 제외하고 평균을 구함<br />
Temp X = tempX + lastEyes[k].x;<br />
Temp Y = tempy + lastEyes[k].y;<br />
}<br />
Temp X = Temp X / 12.0;<br />
Temp Y = Temp Y/ 12.0;<br />
eyeTemplete_L = new Point(temp X, temp Y);<br />
abc_l= eyelenplete_L;<br />
}</p>
</div>
<p><span style="color: #008080"><strong> 다음 프레임에서 옵티컬 플로우로 추적</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>Video, oalooptionlFlowPyrLK(tmp_last, frame, mat_last, tempMat, Status, err); //포티컬 플로우로 추적<br />
Point[] parray2 = tempMat toArray():<br />
리턴되어 저장될 변수</p>
</div>
<p><strong>4. canny 변환</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>Imgproc.Canny(temp, temp, 50, 100);</p>
</div>
<p><strong>5. 허프변환으로 기울기 계산</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>// 얼굴의 너비에 따라서 최소 선분 길이 지정<br />
if (facesArray[0] .width &gt; 700) line = 1;<br />
else if (facesArray(0) ,width &lt;700 &amp;&amp; facesArray[0] .width &gt; 650) Line = 0.92;<br />
else if (facesArray(0).width &lt;650 &amp;&amp; facesArray(0).width &gt; 600) Line = 0.84;<br />
else if(facesArray[O).width &lt;600 &amp;&amp; facesArray[O).width &gt; 550) Line = 0.76;<br />
else if(facesArray(0) .width &lt;550 &amp;&amp; facesArray[0] .width &gt; 500) Line =0.68;<br />
else if (facesArray(0) .width &lt;500 &amp;&amp; facesArray[0] .width &gt; 450) Line = 0.60;<br />
else if(facesArray[0] .width &lt;450 &amp;&amp; facesArray[0] .width &gt; 400) Line = 0.52;<br />
else if(facesArray[O).width &lt;400 &amp;&amp; facesArray[0] .width &gt; 350) Line = 0.44;<br />
else if (facesArray[0] .width &lt;350 &amp;&amp; facesArray[0] .width &gt; 300) Line = 0.36;<br />
else if (facesArray[0] .width &lt;300 &amp;&amp; facesArray[0] .width &gt; 250) Line = 0.28;<br />
else if (facesArray[0] .width &lt;250) line = 0.20;<br />
Imgproc.HoughLines(temp, mLines, line, Math.PI/ 180.0,facesArray[0] .width/30);</p>
</div>
<p><span style="color: #008080"><strong>기울기에 따라 다른 값 저장</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>private void insortionSort (Point lastEyes[], int lef tRight) {<br />
int i, j;<br />
double ce;<br />
for (i = 1; i &lt;= NAX_EYE_LEARN -1; i++){<br />
ce = lastEyes[i].x:<br />
j =i &#8211; 1;<br />
while( i &gt;= 0){<br />
if (lastEyes[J].x &gt; ce){<br />
lastEyes[j + 1].x = lastEyes[J].x:<br />
j&#8211; ;<br />
} else break;<br />
lastEyes[] + 1].x = ce: }<br />
// 삽입정렬<br />
if (leftRight == 0) {<br />
double tempX = 0, tempY = 0;<br />
for (int k = 4; k&lt; 16 : k++)<br />
{ 오차라 판단하는데 0~3, 16~20을 제외하고 평균을 구함<br />
Temp X = tempX + lastEyes[k].x;<br />
Temp Y = tempy + lastEyes[k].y;<br />
}<br />
Temp X = Temp X / 12.0;<br />
Temp Y = Temp Y/ 12.0;<br />
eyeTemplete_L = new Point(temp X, temp Y);<br />
abc_l= eyelenplete_L;<br />
}</p>
</div>
<p><span style="color: #008080"><strong>눈 깜빡임 체크</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>if (blinkFlag == true){<br />
if (nn &gt; -9.5) blinkNotNum++; // 일정 수치 이상으로 올라가면 눈떴음 체크 변수 ++<br />
if (blinkNotNum &gt;= 3){ // 1.7초 안에 3프레임 이상 눈을 뜬게 발견될 경우<br />
blinkFlag = false; // 눈떴음<br />
blinkNotNum = 0; // 체크변수 = 0<br />
blinkFlagTime = 0; // 시간 초기화<br />
}<br />
Long tmepTime = System. current Timellillis();<br />
if (tmepTime &#8211; blinkFlagTime &gt; 1700) { //1.7초 이상 눈 감고있으면<br />
Vibrator vb=(Vibrator)getSystemService(VIBRATOR_SERVICE); // 진동을 줄 변수<br />
vb. vibrate(100); // 진동<br />
blinkNotNum = 2;<br />
}<br />
}<br />
if(nn &lt; -12.5 &amp;&amp; blinkFlag == false) { // 일정수치 이하(눈감았다 판단)<br />
blinkFlag = true; // 감았다고 판단<br />
blinkFlagTime = System.ourrent Timelillis(); // 그때부터 시간을 잰다.<br />
blinkNotNum = 0; 체크변수 = 0<br />
}</p>
</div>
<p><span style="color: #008080"><strong>눈 깜박임 검출 실험 결과</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-17.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35416" alt="47 feature 졸음운전 (17)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-17.png" width="613" height="323" /></a></p>
<p><strong style="color: #008080">문제점 분석 및 해결방안</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-18.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35417" alt="47 feature 졸음운전 (18)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-18.png" width="613" height="360" /></a></p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #3366ff"><strong> 4.1. 차선 인식</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-6.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35418" alt="47 feature 졸음운전 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-6.jpg" width="612" height="288" /></a><br />
차선을 인식하기 위해서는 먼저 차선의 특징을 알 필요가 있다. 졸음운전이 일어나기 쉬운 고속도로에 존재하는 차선은 흰색/황색/청색이 있다. 이 3가지 종류의 차선을 특정하기 위하여 영상에서 흰색, 황색, 청색 영역을 추출한다. 차선의 종류는 ① : 흰색 차선(일반), ② : 황색 차선(중앙/끝), ③ : 청색 차선(버스전용) (*경부고속도로 상부) 이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-19.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35419" alt="47 feature 졸음운전 (19)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-19.png" width="615" height="288" /></a></p>
<p>흰색영역 추출 : 흰색영역을 추출하였을 때 차선이 아닌 다른 부분도 추출됨을 볼 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-20.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35420" alt="47 feature 졸음운전 (20)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-20.png" width="615" height="289" /></a></p>
<p>차선 특정 : 색영역을 추출하여 얻어낸 데이터를 바탕으로 차선으로 추정되는 객체를 특정한다.</p>
<p><span style="color: #3366ff"><strong>4.2. 차선 이탈 감지</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-21.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35421" alt="47 feature 졸음운전 (21)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-21.png" width="611" height="281" /></a><br />
<strong>차선 내부에서 잘못된 방향</strong><br />
운전자가 졸음으로 인하여 차량의 진행 방향이 차선과 동일하지 않을 경우. 차선 객체들의 연장선(빨강선)이 차량의 중심(파랑선)과 크게 어긋나 있어 이를 이용하여 차선 이탈을 판단할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-22.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35422" alt="47 feature 졸음운전 (22)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-22.png" width="611" height="279" /></a></p>
<p><strong>차선을 밟은 경우</strong><br />
차량의 제어가 불가능하여 차선을 밟은 경우. 차선객체가 차량의 중심(파랑선)에 걸쳐 있음으로 이를 이용하여 차선 이탈을 판단할 수 있다.</p>
<p><span style="color: #3366ff"><strong>4.3. 차선 검출</strong></span><br />
<strong>준비사항 :</strong><br />
사용 기기 : RaspberryPi 3, Logitech Webcam C270<br />
프로그래밍 언어 : C++<br />
영상처리 api : OpenCV 3.1.0</p>
<p><strong>개요</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-23.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35423" alt="47 feature 졸음운전 (23)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-23.png" width="305" height="149" /></a><br />
풍경이 펼쳐지고 있을 때, 차선만을 검출하는 방법에 대하여 일반적인 도로의 모습에서 차선의 특징을 정의 한다.<br />
· 차선의 색은 흰색, 노란색 등이고, 도로의 색과 큰 차이가 난다.<br />
· 차선은 일정한 두께가 있다.<br />
· 차선들은 하나의 소실점에서 만난다.</p>
<p><strong>설계 과정</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-24.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35424" alt="47 feature 졸음운전 (24)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-24.png" width="600" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-25.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35425" alt="47 feature 졸음운전 (25)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-25.png" width="600" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-26.png" rel="lightbox[35324]"><img class="alignnone size-large wp-image-35426" alt="47 feature 졸음운전 (26)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-26-532x620.png" width="600" /></a></p>
<p><strong>차선 검출 구현</strong><br />
<span style="color: #808080"><strong>1. Gray Scale 변환</strong></span><br />
· cv::cvtColor 함수를 사용하여 Gray Scale 변환<br />
· 0. ~ 1. (float) scale로 변환하기 위해<br />
· cv::Mat.convertTo 함수 사용</p>
<p><span style="color: #808080"><strong>2. edge의 크기, 방향을 검출</strong></span><br />
· cv::Sobel 함수를 사용하여 x축, y축으로 미분<br />
· cv::cartToPolar 함수에 x/y축으로 미분한 값을 넣어 edge의 크기(magnitude)와 방향(orientation)을 구한다.</p>
<p><span style="color: #808080"><strong>3.edge가 각 구역에서 최대치가 되는 영역 검출</strong></span><br />
· magnitude의 정보가 담긴 객체의 값 중에 left &lt; middle &gt; right 가 되는 middle 값만 추출</p>
<p><span style="color: #808080"><strong>4. 차선 후보 검출</strong></span><br />
· 영상의 아래쪽으로 갈수록 커지고 위로 갈수록 작아지는 최저 차선폭을 지정<br />
· 같은 y값을 가지는 인접한 두 지점간 거리와 해당되는 y축의 최저 차선폭을 비교한다.<br />
· 두 지점의 magnitude 값이 유사한지 검사한다.<br />
· 위의 조건을 만족하였을 시에 두 지점의 orientation 값이 160 ~ 200도 차이가 나는지 비교한다.<br />
· 모든 조건을 만족하면 두 지점의 중심점을 차선후보점으로 지정한다.</p>
<p><span style="color: #808080"><strong>5. 선 검출</strong></span><br />
· cv::HoughLinesP 함수에 이전 연산의 결과로 나온 객체를 입력하여 직선 좌표값을 뽑아낸다.</p>
<p><span style="color: #808080"><strong>6. 소실점 계산</strong></span><br />
· RANSAC 알고리즘을 이용하여 소실점을 찾아낸다.<br />
· 소실점으로 향하는 직선만 차선으로 인정한다.</p>
<p><span style="color: #008080"><strong>차선 검출 실험 Source Code</strong></span><br />
<strong>1. Gray Scale 변환</strong><br />
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
// 0 ~ 255 그래미 스케일로 변환한다.<br />
Mat gray = Mat(source.rows, source.cols, CV_BUC1);<br />
cvt color( source, gray, CV-BGR2GRAY);</p>
<p>// 0. ~1. 그래미 스케일로 변환한다.<br />
Mat gray32 = Mat::Oness source.ros, source.cols, CV-32FC1).<br />
gray. convert Tof gray32, CV_32F, 1.01 255.0);</p>
<p>// 이미지를 부드럽게 만든다.<br />
Mat smooth = Mat:; ones( source, rows, source.cols, CV-32FC1);<br />
GaussianBlurgray32, smooth, Size(5,5), 2.0.2.0);<br />
</div>
<p><strong> 2. edge의 크기, 방향을 검출</strong><br />
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
// Sobel 연산자로 이미지를 x, y방향으로 미분한다. 즉, edge 검출.<br />
Mat sobei x, sobel y:<br />
Sobel( smooth, sobe X, CV_32F, 1, 0);<br />
Sobel( smooth, sobe Y, CV_32F, 0, 1);<br />
// Edge의 magnitude와 orientation을 계산한다.<br />
Mat mag = Mat::ones( source.rows, source.cols, CV_32FC1);<br />
Mat ori &#8211; Mat::ones( source.rows, source.cols, CV_32FC1);<br />
cartToPolar( sobe IX, sobely, mag, ori);<br />
</div>
<p><strong> 3. 차선 후보 검출</strong><br />
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
for(int j = i + 1 ; j &lt; (int)tmp.size(); j++)<br />
{<br />
int width = tmp[j].x &#8211; tmp[i].x;<br />
if(lane_width)lo &lt;= width &amp;&amp; width &lt;= lane_width_hi)<br />
{<br />
float mag_err = (tmp[j].mag &#8211; tmp[i].mag) / (tmp[j].mag + tmp[i].mag); //크기 차<br />
float ori_err = DeltaRad(DeltaRad(tmp[j].ori, tmp[i].ori, M_Plf);// 방향 차</p>
<p>if((-mag_threshold &lt; mag_err &amp;&amp; mag_err &lt; +mag_threshold) &amp;&amp; (-ori_threshold &lt; ori_err &amp;&amp; ori_err &lt; +ori_threshold))<br />
{<br />
int x_mid = (tmp[j].x + tmp[i].x / 2;<br />
float mag_avg = (tmp[j].mag + tmp[i].mag) / 2.f;<br />
// 평균을 낼 때 edge에 수직인 각을 pi/2를 더해 edge에 평행하게 바꾼다.<br />
float ori_avg = (tmp[j].ori + tmp[i].ori / 2.f + M_Plf;</p>
<p>if(mag_avg &lt;= 1.)<br />
dst.at (h, x_mid) = 255;<br />
//d[x_mid] = (mag_avg &lt;= 1.) ? (int)(mag_avg+255) ; 255;</p>
<p>// For Debugging : 이미지 상에 Lane 후보들을 표시한다.<br />
circle(source, Point(x_mid. h), 2, CV_RGB(0,0,255));<br />
}<br />
}<br />
</div>
<p><strong> 4. 선 검출</strong><br />
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
//Lnae 후보 점들을 기록할 이미지를 만든다.<br />
Mat lane = Mat::zeros(source, rows, source.cols, CV_BUC1);</p>
<p>//Lane의 후보가 될 점들을 찾는다.<br />
LaneCandidate(mag, ori, lane);</p>
<p>//Lane 후보 점들을 저장할 공간 확보<br />
vector(sLine&gt; cand;<br />
cand. reserve(1000);</p>
<p>//http://doce.opencv.org/2.4/modules/imgproc/doc/feature_detection.html<br />
vector lines;<br />
HoughLinesP(lane, lines, 1, CV_PI/180,5,2,10);</p>
<p>//Mat hought = Mat::zeros(source, rows, source.cols, CV_BUC1);<br />
for(int i = 0; i &lt; lines. size(); i++)<br />
{<br />
Point start = Point(lines[i][0], lines[i][1]);<br />
Point end = Point(lines[i][2], lines[i][3]);</p>
<p>cand.push_back(sLine(start.x, start.y, end.x, end.y));</p>
<p>// For Debugging<br />
line(source, start, end, CV_RGB(255,0,0),3,8);<br />
line(hough, start, end, CV_RGB(255,255,255),3,8);<br />
</div>
<p><strong> 4. 소실점 찾기</strong><br />
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
double ransac_Vanishing-point( vector &amp;data, sPoint &amp;model, double distance_threshold)<br />
Const int no_samples = 2;<br />
if (data.size() &lt; no_samples) {<br />
return 0..<br />
Vectors samples:<br />
Vectors sPoint est imated_model: double max_cost = 0..<br />
int max_iteration = (int )1 + log(1. &#8211; 0.99) log(1. &#8211; pow(0.5, no_samples)));<br />
for (int i = 0; i&lt;max_iteration: j++){&lt;br=&#8221;"&gt; if(i==0){<br />
//처음 한 번은 미전 스탭의 모델로 알고리즘을 수행한다.<br />
est imated_model = model:<br />
else {<br />
//1. Hypothesis</p>
<p>// 원본 데 미터 에서 임의로 N개의 샘플 데이터를 고른다.<br />
Samples = get_samples (no_samples, data);</p>
<p>//이 데이터를 정상적인 데이터로 보고 모델 파라미터를 예측한다. estinated_model = Compute_model-parameter (samples):</p>
<p>// 2. Verification<br />
//원본 데이터가 예측된 모델에 잘 맞는지 검사한다.<br />
inliers.clear( ) double Cost = model-Verification(inliers, estimated_model, datadistance_threshold}}<br />
만일 예측된 모델이 잘 맞는다면, 이 모델에 대한 유효한 데이터로 새로운 모델을 구한다.<br />
if (max_cost &lt; cost) {<br />
max_cost = Costs;<br />
model = compute_model-parameter (inliers):<br />
}<br />
}<br />
return maX_Cost:<br />
}<br />
</div>
<span style="color: #008080"><strong>차선 검출 실험 Source Code</strong></span></p>
<p><strong>1. 차선 후보점 검출</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-7.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35427" alt="47 feature 졸음운전 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-7.jpg" width="605" height="217" /></a><br />
<strong> </strong></p>
<p><strong>2. 직선 검출</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-8.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35428" alt="47 feature 졸음운전 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-8.jpg" width="605" height="220" /></a><br />
<strong> </strong></p>
<p><strong>3. 소실점 계산, 최종 결과</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-9.jpg" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35429" alt="47 feature 졸음운전 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-9.jpg" width="606" height="219" /></a></p>
<p><strong>4. 실제 Webcam을 사용한 실험 결과</strong><br />
- 직선 도로 상황</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-27.png" rel="lightbox[35324]"><img class="alignnone  wp-image-35430" alt="47 feature 졸음운전 (27)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-27.png" width="500" /></a></p>
<p>- 곡선 도로 상황</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/Cap-2018-07-11-15-50-23-792.png" rel="lightbox[35324]"><img class="alignnone  wp-image-35435" alt="Cap 2018-07-11 15-50-23-792" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/Cap-2018-07-11-15-50-23-792.png" width="500" /></a></p>
<p><span style="color: #3366ff"><strong>네트워크 통신</strong></span><br />
<span style="color: #008080"><strong>준비사항</strong></span><br />
사용 기기 : 스마트폰<br />
프로그래밍 언어 : 자바<br />
통신 방식 : FCM (FireBase Cloud Message)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-28.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35431" alt="47 feature 졸음운전 (28)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-28.png" width="594" height="270" /></a></p>
<p><span style="color: #008080"><strong>개요</strong></span><br />
위와 같이 라즈베라파이와 안드로이드 스마트폰 사이의 통신을 조사하여 FCM이라는 클라우드 메시지 방식을 테스트해본다. FCM이란 메시지를 무료로 안정적으로 전송해줄 수 있는 메시지 전송 시스템이다.</p>
<p><span style="color: #008080"><strong>설계과정</strong></span><br />
1. 안드로이드 app에 firebase를 추가한다. (패키지 이름, 앱 닉네임, 빈칸)<br />
2. 자동적으로 google-services.json이 다운로드되면 프로젝트의 메니페스트가 있는 경로에 복사한다.<br />
3. 서버에 프로젝트를 등록하고 sener ID와 server KEY를 얻는다. (Project&gt;Settins&gt;Cloud Messaging에서 체크<br />
프로젝트수준 build.gradle 설정<br />
앱 수준 build.gradle 설정<br />
4. 프로젝트 수준과 앱 수준에서의 gradle을 전부 설정해준다.<br />
5. 각 기기가 서버에 접속할 수 있게 토큰을 생성해준다.<br />
6. 메시지 수신 시 이벤트로 노티피케이션과 진동을 준다.<br />
7. 메시지 송신 시 서버로 메시지를 전송한다.</p>
<p><span style="color: #008080"><strong>FCM 구현 및 소스코드</strong></span><br />
<strong>1. 토큰 생성</strong><br />
서버에서 해당 프로젝트의 어플 사용자임을 인증하고 토큰을 받는다. FirebaseInstanceId.getInstance().getToken() 메소드를 이용하여 해당 기기의 토큰을 생성한다. okhttp3의 Request 메소드를 이용하여 토큰을 서버에 전송한다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>// [START refresh_token]
@Override public<br />
void onTokenRefresh () {<br />
// Get updated Instance ID token.<br />
String token = FirebaseInstanceId.getInstance().getToken();<br />
// 생성등록된 토크를 개인 앱서버에 보내 저장해 두었다가 뭔가를 하고 싶으면 할 수 있도록 하다.<br />
sendRegistrationToServer (token);<br />
}</p>
<p>private void sendRegistrationToServer (String token) {<br />
// Add custom implementation, as needed.<br />
OkHttpClient client = new OkHttpClient ();<br />
RequestBody body = new FormBody.Builder ()<br />
.add(&#8220;Token&#8221;, token) .build();<br />
//request Request request = new Request. Builder (0)<br />
. url(&#8220;http://https://lastproject-c8250.firebaseio.com&#8221;) -post (body)<br />
.build();<br />
try {<br />
client.newCall (request) .execute();<br />
} catch (IOException e) {<br />
e.printStackTrace();<br />
}<br />
}<br />
</div>
<p><strong>2. 메시지 수신 시</strong></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>// [START receive_message]
@Override<br />
public void onMessageReceived (RemoteMessage remoteMessage) {<br />
sendNotification (remoteMessage.getData().get (&#8220;message&#8221;)); vibrator vide;<br />
vide = (vibrator) qetSystemService (Context.VIBRATOR SERVICE) ; vide.vibrate (1000);<br />
}<br />
private void sendNotification (String messageBody) {<br />
Intent intent = new Intent (this, MainActivity.class); intent.addFlags (Intent. FLAG_ACTIVITY CLEAR TOP); PendingIntent pendingIntent = PendingIntent.getActivity (this, 0 /* Request code */, intent,<br />
Pending Intent. FLAG_ONE_SHOT);<br />
Uri defaultSoundUri = RingtoneManager.getDefaultUri (RingtoneManager.TYPE_NOTIFICATION) ; NotificationCompat. Builder notificationBuilder = new NotificationCompat. Builder (this)<br />
.setSmallIcon (R. mipmap.ic_launcher) .setContentTitle (&#8220;FCM Push Test&#8221;) .setContentText (messageBody) .setAutoCancel(true) .setSound (defaultSoundUri) .setContentIntent (pending Intent);<br />
NotificationManager notificationManager =<br />
(NotificationManager) getSystemService (Context. NOTIFICATION_SERVICE);<br />
notificationManager.notify (0 /* ID of notification */, notificationBuilder.build(0);</p>
</div>
notificationManager. 메소드를 이용하여 받은 메시지를 띄운다. Vibrator로 진동을 준다.</p>
<p>3. 메시지 송신 시<br />
databaseReference.메소드를 이용하여 서버의 데이터 베이스에 메시지를 쓴다.</p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>final DatabaseReference database Reference = firebaseDatabase.getReference (); sendButton.setOnClickListener(new view.OnClickListener() {<br />
@Override public void onClick(View v) { Chatpata chatData = new ChatData (editID.getText().toString(),<br />
editText.getText().toString());<br />
// 유저 이름과 메세지로 chatdata 만들기<br />
databaseReference.child (&#8220;message&#8221;).push().setValue (chatData);<br />
// 기본 database 하위 message라는 child에 chatdata를 list로 만들기<br />
editText.setText (&#8221; &#8220;);<br />
String a = editText.getText().toString(); if (a.equals(&#8220;&#8221;)) {<br />
editText.setText(&#8220;&#8221;);<br />
else<br />
editText.setText (&#8220;&#8221;); listview.setTranscriptMode (AbsListView. TRANSCRIPT_MODE ALWAYS SCROLL);<br />
// 메시지를 보낼때 제일 상단에 출력이 되게끔 한다.<br />
}<br />
});<br />
databaseReference.child (&#8220;message&#8221;).addChildEventListener(new ChildEventListener() {<br />
// message는 child의 이벤트를 수신합니다.<br />
@Override public void onChildAdded (DataSnapshot data Snapshot, String s) {<br />
Chatpata chatData = datasnapshot.getValue (ChatData.class);<br />
} chatData를 가져오고<br />
adapter.add (chatData.getUserName () + &#8220;:&#8221; + chatData.getMessage ());<br />
// adapter에 추가합니다.<br />
}<br />
});<br />
FirebaseMessaging.getInstance().subscribeToTopic (&#8220;news&#8221;); FirebaseInstance(d.getInstance().getToken();</p>
</div>
<p><span style="color: #008080"><strong>FCM 실험 결과</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-29.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35432" alt="47 feature 졸음운전 (29)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-29.png" width="616" height="514" /></a></p>
<p><span style="color: #008080"><strong>제품 모형 제작</strong></span><br />
<strong>1. 준비 사항</strong><br />
제작 툴 : 스케치업, Creator K, 3DS Max<br />
사용한 제작도구 : 3D 프린터<br />
3D 프린터등을 이용하여 모형이나 외관 제작에 대해 조사한다. 여러 제작 툴을 사용해보고 가장 알맞은 제작 툴을 결정한다. 결정된 제작 툴로 테스트 모형을 출력해본다.</p>
<p><strong>2. 제작 과정</strong><br />
1. 레이아웃 설계 및 제작 &#8211; STP<br />
2. Creator K 호환 가능한 파일로 변환한다. &#8211; OBJ<br />
3. Creator K를 통해 G-Code를 생성하고 프린팅을 시작한다.</p>
<p><strong>3. 모형 제작 실험 결과</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-30.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35433" alt="47 feature 졸음운전 (30)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-30.png" width="613" height="213" /></a></p>
<p>문제점 분석 및 해결방안<br />
뭉침으로 인한 쓰레기 값 출력 : 내부 구조까지 정확한 설계를 해야한다고 판단</p>
<p><strong>4. 진행상황</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-31.png" rel="lightbox[35324]"><img class="alignnone size-full wp-image-35434" alt="47 feature 졸음운전 (31)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-졸음운전-31.png" width="617" height="460" /></a><br />
<strong> 5. 향후 계획</strong><br />
라즈베리파이 &#8211; 고해상도에서 빠르게 검출할 수 있도록 최적화<br />
스마트폰 &#8211; 눈 깜빡임 검출 부분 상세 조사<br />
네트워크 &#8211; 라즈베리파이와 스마트폰 간의 블루투스 통신을 조사<br />
외관 &#8211; 3ds max 프로그램을 더 공부하여 모형 제작</p>
<p><span style="color: #0000ff"><strong>5. 참고문헌</strong></span><br />
옵티컬플로우 예제 : http://me10.sblo.jp/article/88289624.html<br />
옵티컬플로우 함수 설명 : http://mycpp.blog.me/120110317337<br />
opencv에서 옵티컬플로우 : http://blog.naver.com/hms4913/220126252051<br />
옵티컬플로우 사용예제 : http://cafe.naver.com/opencv/38181<br />
canny edge 기초설명 : http://carstart.tistory.com/188<br />
자바에서 canny edge 사용 : http://stackoverflow.com/questions/24174868/edge-detection-using-opencv-canny<br />
허프변환 기초설명 : http://blog.naver.com/dusrb2003/220290145675<br />
허프변환 사용예제 : https://blog.zaven.co/opencv-advanced-android-development-edge-detection/<br />
허프변환 사용예제 : http://stackoverflow.com/questions/7925698/android-opencv-drawing-hough-lines<br />
설계/구현 과정 : http://blog.daum.net/pg365/200<br />
환경 구축 : http://webnautes.tistory.com/916<br />
언어간 함수변환 : http://lispro06.woweb.net/?mid=app&amp;page=21<br />
구글 firebase : https://console.firebase.google.com/<br />
파이썬 채팅 앱 to firebase : https://corikachu.github.io/<br />
안드로이드 UDP이용 메시지 전송예제 :</p>
<p>http://blog.naver.com/PostView.nhn?blogId=chandong83&#038;logNo=220931445463&#038;categoryNo=22&#038;parentCategoryNo=0&#038;viewDate=&#038;currentPage=1&#038;postListTopCurrentPage=1&#038;from=postView</p>
<p>FCM으로 메시지 전송 구현 :</p>
<p>http://blog.naver.com/PostView.nhn?blogId=cosmosjs&#038;logNo=220739141098&#038;categoryNo=0&#038;parentCategoryNo=56&#038;viewDate=&#038;currentPage=1&#038;postListTopCurrentPage=1&#038;from=search</p>
<p>안드로이드 FCM 샘플 : http://blog.naver.com/zic325/220719729251<br />
Fire Base DataBase 기초 :</p>
<p>http://blog.naver.com/yoonhok_524/220918425133</p>
<p>스케치업 위키백과 : https://ko.wikipedia.org/wiki/%EC%8A%A4%EC%BC%80%EC%B9%98%EC%97%85<br />
Creator K 사용자 가이드 http://print3dison.cafe24.com/board/free/read.html?no=816&amp;board_no=1<br />
3ds 맥스 위키백과 :</p>
<p>https://ko.wikipedia.org/wiki/3ds_%EB%A7%A5%EC%8A%A4</p>
<p>눈 깜빡임 관련 알고리즘 :</p>
<p>http://link.springer.com/article/10.1007/s10209-011-0256-6</p>
<p>안드로이드 눈깜빡임 감지 :</p>
<p>http://romanhosek.cz/android-eye-detection-and-tracking-with-opencv/</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/35324/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[47호]독거노인을 위한 안전 경보 시스템</title>
		<link>http://www.ntrexgo.com/archives/35322</link>
		<comments>http://www.ntrexgo.com/archives/35322#comments</comments>
		<pubDate>Tue, 10 Apr 2018 00:00:44 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[47호]]></category>
		<category><![CDATA[Feature]]></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=35322</guid>
		<description><![CDATA[디바이스마트 매거진 47호 &#124; 독거노인의 안전을 위한 시스템으로 인체 감지센서(PIR Sensor)를 이용해 독거노인의 생활 패턴을 파악하고 파악한 데이터를 통해 평소와 다른 이상 부분이 감지 및 발생될 경우 신속한 경보를 알리는 시스템입니다.
]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/07/Cap-2017-10-18-13-15-49-260.png" rel="lightbox[35322]"><img class="alignnone size-large wp-image-34236" alt="Cap 2017-10-18 13-15-49-260" src="http://www.ntrexgo.com/wp-content/uploads/2017/07/Cap-2017-10-18-13-15-49-260-620x137.png" width="620" height="137" /></a></p>
<p><span style="background-color: #000000;color: #ffff00"><strong>2017 ICT 융합 프로젝트 공모전 참가상</strong></span></p>
<p><span style="font-size: large"><strong><span style="font-size: x-large">독거노인을 위한 안전 경보 시스템</span><br />
</strong></span></p>
<p style="text-align: right"><strong>글 | 동아대학교 허수종, 유창희</strong></p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 작품의 개발 의도는 대략 이해할 수 있습니다만, 구체적으로 어떤 시나리오에 따라 동작하는지에 대해 명확히 파악이 되지 않습니다. 제품의 개발 의도와 같은 서비스를 각 지자체 등에서 충분히 고려하고 있어 아이템의 의도나 사용성은 충분한 분위기가 만들어져 있으나, 이를 실제로 적용할 때 완성도를 떠나 구체적인 시나리오가 필요한 작품입니다. PIR 센서의 동작 감지 범위등과 같은 특성과 감지 주파수(감도)등에 대한 기술적 부분을 먼저 이해하여, 이를 효율적으로 사용할수 있는 것에 대한 내용이 없고, 또한 시스템 전체 동작 시나리오가 부족합니다. 이러한 부분이 보고서를 통해 이해하기에는 쉽지 않습니다.<br />
<strong>뉴티씨</strong> 요즘 고독사도 증가하고 있고, 이웃나라에서는 벌써 사회적 문제가 된 지 오래다. 우리나라도 조만간 독거노인이 매우 늘어나게 되는 데, 노인들의 안전은 우리 자신의 문제가 되가고 있다. 따라서 이 아이템은 매우 중요한 아이템으로 보인다. 다만, 센서의 단순화로 감지할 수 있는 내용이 제한되므로, 좀 더 많은 종류의 여러 가지 센서를 사용하여 접근하였으면 좋았을 것이다. 앞으로 관심을 가지고 좀 더 다양하고 실질적인 내용으로 거듭나기를 기대해 본다.<br />
<strong>위드로봇</strong> 고령화 시대에 걸맞는 주제입니다. 실용성이나 작품의 완성도는 높습니다만, PIR 센서 이외에 추가 센서를 활용하여 이상 징후를 좀 더 명확하게 알 수 있는 부분이 아쉽습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품요약</strong></span><br />
독거노인의 수가 증가하는 추세인 요즘 독거사와 같은 문제가 사회 문제로 대두되고 있습니다. 독거노인의 안전을 위한 시스템으로 인체 감지센서(PIR Sensor)를 이용해 독거노인의 생활 패턴을 파악하고 파악한 데이터를 통해 평소와 다른 이상 부분이 감지 및 발생될 경우 부저와 LED를 이용해 장거리 무선 통신을 통해 주위 이웃에게 알리고 미리 지정해 놓은 가족의 휴대폰 애플리케이션을 이용해 진동과 토스트 메시지를 사용함으로써 신속한 경보를 알리는 시스템입니다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 개요</strong></span><br />
<span style="color: #3366ff"><strong>3.1. 선정 배경 및 목적</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-1.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35387" alt="47 feature 독거노인 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-1.png" width="505" height="600" /></a></p>
<p>노인 고독사가 사회적으로 큰 문제가 되고 있다. 보건복지부에 따르면 2015년 기준 독거노인은 138만명을 넘어섰다. 이 가운데 고독사 위험군의 노인이 30만명 정도 된다고 알려졌다. 2015년 기준 통계이므로, 2017년 3월인 지금은 그 수가 더 늘어났으리라 예상된다.<br />
홀로 쓸쓸히 죽음을 맞이하는 노인 수도 한 해 1,000명을 넘어선다고 밝혀졌다. 갈수록 1인 가구가 늘고 고령화 속도가 빨라지면서 고령자 1인 가구도 더욱 많아지고 있다. 그만큼 노인 고독사도 더욱 증가할 것으로 보인다.<br />
정부에서 고독사 통계를 낼 때, 고독사 대신 무연고 사망자 수로 통계를 파악하고 있고, 2013년의 명백한 고독사는 1717건이다. 고독사 가운데 일부는 유족에게 시신이 인계되므로 고독사는 무연고 사망자수보다 훨씬 많을 것으로 예상된다. 명백한 수치로만 통계를 내도 5시간마다 한명씩 아무도 모르게 죽고 있는 것이다. 그런데 고독사에 대한 대책은 자발적 참여자를 받아 독거노인 5~10명을 한 집에 모여 살게 하는 노인 공동생활가정을 운영하는 것, 주기적으로 봉사 활동자가 방문하는 것, 상담을 늘리는 것 정도로 문제의 규모에 비해 작은 편이다.<br />
우리나라는 현재 고령화가 급속히 진행 중이다. 전문가들에 따르면, 10년 후 65세 이상 1인 가구가 현재보다 2배로 늘고 고령자 1인 가구도 전체 3분의 1수준에 육박할 것으로 전망하고 있다. 노인 고독사는 누구든지 처할 수 있는 문제이다. 그전까지는 생각하지 못했던 부분이지만, 작품을 계획하는 과정에서 조사를 하면서 문제의 심각성이 예상보다 크다는 점을 깨달았다. 고독사는 인간의 존엄성을 훼손하는 비극적인 사건이다. 독거노인 비중의 증가에 따른 고독사 문제를 해결하는데 도움이 되고자 해당 아이디어를 구상하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-2.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35388" alt="47 feature 독거노인 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-2.png" width="505" height="252" /></a></p>
<p><span style="color: #3366ff"><strong>3.2. 아이디어 대상</strong></span><br />
<strong>1. 독거노인 </strong></p>
<p><strong>2. 출장이나 여행이 잦은 집</strong><br />
아이디어를 통해 집안에 외부 침입자의 유무를 파악할 수 있다.</p>
<p><span style="color: #0000ff"><strong>4. 작품 설명</strong></span><br />
<span style="color: #3366ff"><strong>4.1. 주요 동작 및 특징</strong></span><br />
<span style="color: #33cccc"><strong> 4.1.1. PIR 센서</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-3.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35389" alt="47 feature 독거노인 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-3.png" width="505" height="234" /></a><br />
PIR 센서는 인간의 몸에서 나오는 적외선을 감지했을 때 작동한다. 주로 3V-12V에서 작동하고 적외선을 전압의 형태로 변환시켜서 출력 전압은 High일 경우 3.3V의 출력을 Low 일 경우 0V의 출력을 발생한다.<br />
감지 거리는 최대 7m, 140˚의 거리를 감지 할 수 있다.</p>
<p><span style="color: #33cccc"><strong>4.1.2.블루투스</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-4.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35390" alt="47 feature 독거노인 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-4.png" width="253" height="117" /></a><br />
블루투스의 무선 시스템은 ISM 주파수 대역인 2400 ~ 2483.5MHz를 사용한다. 블루투스는 저렴한 가격에 저전력(100mW)으로 사용할 수 있다는 점이 장점이다. 블루투스는 주파수 대역을 나누기 때문에 데이터 전송을 여러 주파수에 걸쳐서 분할해 보낼 수 있다. 그렇기 때문에 무선 전송에 따른 보안 위협에서도 상대적으로 안전하다. 블루투스 신호는 벽이나 가방 등을 통과해서 전송될 수 있으므로 배선이나 연결 상황을 육안으로 확인할 필요가 없고 장애물이 있어도 신호를 주고받을 수 있다. 주파수 특성도 전 방향으로 신호가 전송되므로 각 장치를 연결하기 위해 일정한 각도를 유지할 필요가 없어 사용하기에 편리하다. 마지막으로 무엇보다 전 세계 수많은 국가가 블루투스 표준 규격을 준수하기 때문에 세계 어느 곳에서나 같은 기술을 이용할 수 있다.</p>
<p><span style="color: #3366ff"><strong>4.2. 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-5.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35382" alt="47 feature 독거노인 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-5.png" width="505" height="432" /></a><br />
전원을 공급한 후 안드로이드 스튜디오를 통해 제작된 애플리케이션과 블루투스 페어링(블루투스 외 비콘(Beacon)이나 와이파이를 이용한 통신방법도 가능) 과정을 거친 후 PIR 센서가 사람을 인식하고 있을 때는 동작하지 않는다. 그러나 사람이 일정 시간동안 감지되지 않을 경우에 작동 하게 되는데 부저와 LED를 이용해 주위에 알리고 블루투스를 이용하여 독거노인의 가족들에게 관련 메시지와 진동 기능을 통해 보다 신속 정확한 대처를 할 수 있도록 한다. 작동을 멈추기 위해서는 미리 설정되어있는 비밀번호를 입력하여 동작을 해제해야 한다. 추가적으로 애플리케이션에 긴급 전화 버튼을 추가하여 알림을 받는 동시에 바로 전화하여 조치를 취하게 할 수 있다.</p>
<p><span style="color: #3366ff"><strong>4.3. 개발 환경</strong></span><br />
ATmega128를 이용한 하드웨어 설계 및 제작<br />
안드로이드 스튜디오를 이용한 애플리케이션 제작</p>
<p><span style="color: #3366ff"><strong>4.4. 기대효과</strong></span><br />
독거노인의 비중이 증가하고 따라서 연간 독거사 사망자의 수가 늘어나고 있는 현재 사회에서 보다 체계적인 안전 시스템을 통해 위급 상황 시 빠른 응급조치를 통해 생명을 구할 수 있다. 또한 노인들로 하여금 안전 시스템을 통한 심리적 안정감을 줄 수 있다.</p>
<p><span style="color: #0000ff"><strong>5. 단계별 제작 과정</strong></span><br />
애플리케이션과 연동을 위해 ATmega128을 이용해 블루투스 개발 및 주위에 알릴 수 있는 수단으로 부저와 LED 추가<br />
· 애플리케이션에 블루투스 기능 추가 및 페어링 환경 구축<br />
· 블루투스 페어링 동작 유무 확인 및 메시지 송수신 여부 확인<br />
· 외부 하드웨어 설계</p>
<p><span style="color: #0000ff"><strong>6. 기타</strong></span><br />
<span style="color: #3366ff"><strong> 6.1. 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-6.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35383" alt="47 feature 독거노인 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-6.png" width="505" height="564" /></a></p>
<p>ATmega128, PIR Sensor, Bluetooth 모듈과 관련된 회로 라이브러리를 제공하지 않기 때문에 OrCAD를 이용해서 추가로 제작하여 회로를 구성.</p>
<p><span style="color: #3366ff"><strong>6.2. OrCAD를 이용한 기판 배치도(PCB)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-7.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35384" alt="47 feature 독거노인 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-7.png" width="507" height="293" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #3366ff"><strong>6.3. 애플리케이션</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-8.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35385" alt="47 feature 독거노인 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-8.png" width="514" height="279" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-9.png" rel="lightbox[35322]"><img class="alignnone size-full wp-image-35386" alt="47 feature 독거노인 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-독거노인-9.png" width="488" height="576" /></a><br />
PIR 센서가 인식이 되면 LED와 부저가 켜지고 안드로이드 스튜디오를 통해 제작한 애플리케이션과의 블루투스 통신을 통해 AVR에서 문자를 전송하고 애플리케이션에서 문자를 수신하면 토스트 메시지와 진동이 울린다. 센서가 인식을 안 할 때 까지 계속해서 동작 하는 시스템이다.</p>
<p><span style="color: #3366ff"><strong>6.4.소스 코드</strong></span><br />
<span style="color: #008080"><strong>AVR 소스</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>/*<br />
* Reference about PIN Setting<br />
* BlueTooth : PE1(RXD0/PDI), PE0(TXD0/PDO)<br />
* PIR Sensor : PD0(SCL/INT0)<br />
* LED : PB4-7<br />
* Buzzer : PG3<br />
*/<br />
#include &lt;avr/io.h&gt;<br />
#include &lt;avr/interrupt.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &#8220;ATmega128_v20.H&#8221;<br />
#include &#8220;sub32.h&#8221;</p>
<p>ISR(TIMER3_OVF_vect) // 타이머 카운터 오버플로우 인터럽트<br />
{<br />
OCR3A =360; // 0~360까지 비교일치 후 오버플로우 발생, Port : PE3<br />
}</p>
<p>int main()<br />
{<br />
MCU_initialize(); // MCU 초기화<br />
Delay_ms(50);<br />
LCD_initialize(); // LCD 초기화<br />
Beep();<br />
LCD_string(0&#215;80,&#8221;16 Fall Semester&#8221;);<br />
LCD_string(0xC0,&#8221;PROJECT &#8220;);<br />
/* The first setting for state initialize */</p>
<p>UCSR0B |=(1&lt;&lt;TXEN0); // 송신 허용<br />
UCSR0C |=(1&lt;&lt;UCSZ01)|(1&lt;&lt;UCSZ00); // Data rate 8bit<br />
UBRR0H=0; UBRR0L=103; // Communication(signal) speed 9600bps<br />
sei(); // 전역 인터럽트 허용<br />
/* Setting for USART(about BlueTooth) */</p>
<p>Delay_ms(1000);<br />
LCD_string(0&#215;80,&#8221;SENSOR &#8220;);<br />
LCD_string(0xC0,&#8221;COUNTER &#8220;);</p>
<p>while (1) password_input();<br />
}</p>
<p>/*<br />
* 사용된 함수들만 따로 헤더파일 정리<br />
*/<br />
#include &#8220;sub32.h&#8221;</p>
<p>int detect_counter=-1; // 센서 횟수 카운터 변수<br />
unsigned char str[100];<br />
int pw[5]={1,2,3,4};<br />
int pw_check=0;<br />
int num;<br />
int str_num[20];<br />
int enter=0;<br />
//char *str=&#8221;abc123&#8243;;<br />
unsigned int sum, ad_result;<br />
unsigned int i =0;<br />
unsigned int ADC6=0, ADC7=0;<br />
int ADConvertor(char ch)<br />
{<br />
ADMUX = (ch&amp;0x1F) | 0&#215;40; // AVCC 사용<br />
ADCSRA = (1&lt;&lt;ADEN)|(1&lt;&lt;ADSC)|(7&lt;&lt;ADPS0);<br />
// ADC 허용, 프리스케일러 128<br />
while((ADCSRA &amp; 0&#215;10)!= 0&#215;10); //AD변환 과정이 끝났는지 확인</p>
<p>sum = ADCL+ADCH*256; // ADCW*256<br />
return(ADC); // ADC의 값을 반환<br />
}</p>
<p>void main_while()<br />
{<br />
ad_result = ADConvertor(6);<br />
ADConvertor(6);<br />
ADC6 = (sum/102.3*10);<br />
LCD_command(0&#215;80+12);<br />
LCD_3d(ADC6); // LCD에 ADC6의 값을 출력</p>
<p>ADConvertor(7);<br />
ADC7 = (sum/102.3*10); //in board ADC6 Position setting<br />
LCD_command(0&#215;80+8);<br />
LCD_3d(ADC7); // LCD에 ADC7의 값을 출력</p>
<p>if(ADC6==100&amp;ADC7==100) // 가변저항 2개의 값이 100 100 인지 확인<br />
{<br />
Delay_ms(70);<br />
if(ADC7==100)<br />
{<br />
Delay_ms(1000);<br />
state_on();<br />
tx_char(&#8217;1&#8242;); // 문자 전송<br />
}<br />
}<br />
else state_off();<br />
}</p>
<p>void password_check(int input) // 비밀번호 확인 함수<br />
{<br />
num=input;<br />
//LCD_command(0xC0+2);<br />
//LCD_3d(num);<br />
if(num==pw[pw_check]) // 미리 지정해둔 비밀번호와 일치 여부 확인<br />
{<br />
Beep();<br />
pw_check++;<br />
Delay_ms(100);<br />
if(pw_check==4)<br />
{<br />
Beep();<br />
Delay_ms(100);<br />
Beep();<br />
enter=1;<br />
}<br />
}<br />
return enter;<br />
}</p>
<p>void password_input() // 각각의 스위치에 숫자 지정<br />
{<br />
if(enter==0)<br />
{<br />
main_while();<br />
switch(Key_input())<br />
{<br />
case 0x0E : password_check(1); // 1입력<br />
break;<br />
case 0x0D : password_check(2);// 2입력<br />
break;<br />
case 0x0B : password_check(3); // 3입력<br />
break;<br />
case 0&#215;07 : password_check(4); // 4입력<br />
break;<br />
default : break;<br />
}<br />
}<br />
else if(enter==1)<br />
{<br />
LCD_string(0&#215;80,&#8221;LOGIN OK &#8220;);<br />
LCD_string(0xC0,&#8221; &#8220;);<br />
}<br />
}</p>
<p>int counter(void)<br />
{<br />
++detect_counter; // 센서 감지 횟수 카운터<br />
return detect_counter; // 카운터 값을 출력<br />
}</p>
<p>void state_off(void) // PIR detect off<br />
{<br />
PORTB=0&#215;00;<br />
//PORTG=0&#215;00;<br />
//LCD_string(0&#215;80,&#8221;SENSOR &#8220;);<br />
}</p>
<p>void state_on(void) // PIR detect on<br />
{<br />
PORTB=0xf0; // LED 0000<br />
//PORTG=0&#215;08; // Buzzer<br />
Beep();<br />
//LCD_string(0&#215;80,&#8221;SENSOR &#8220;);<br />
LCD_command(0xC0+11);<br />
counter();<br />
LCD_3d(detect_counter);<br />
}</p>
<p>void tx_char(unsigned char tx_data) // 한 문자 전송 함수<br />
{<br />
while((UCSR0A&amp;0&#215;20) == 0); // UDR0 레지스터가 빌 때까지 대기<br />
UDR0 = tx_data; // UDR0 레지스터에 전송할 문자 입력<br />
}</p>
<p>void tx_string(char *str) // 문자열 전송 함수<br />
{<br />
int i,j;<br />
i=strlen(str); // 입력 받은 문자열의 길이를 변수 i로 지정<br />
for(j=0;j&lt;i;j++)<br />
{<br />
tx_char(*(str++));<br />
/* 한 문자 전송 함수에 문자열의 길이를 파악 후 그 수치만큼 전송 */<br />
}<br />
}<br />
</div>
<p><span style="color: #3366ff"><strong>6.5. 참고문헌</strong></span><br />
· 인체감지센서 참고 :http://blog.naver.com/yjhzzing4699?Redirect=Log&amp;logNo=20161140929<br />
· 블루투스 참고 : http://tip.daum.net/question/83517583<br />
· 통계청 : http://kostat.go.kr/portal/korea/index.action<br />
· 특허정보검색서비스 : www.kipris.or.kr<br />
· 독거노인의 증가 추이와 독거노인 현황 : 한겨레 신문</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/35322/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[47호]Auxiliary Device For Shooting(ADFS)</title>
		<link>http://www.ntrexgo.com/archives/35318</link>
		<comments>http://www.ntrexgo.com/archives/35318#comments</comments>
		<pubDate>Tue, 10 Apr 2018 00:00:15 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[47호]]></category>
		<category><![CDATA[Feature]]></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=35318</guid>
		<description><![CDATA[디바이스마트매거진 47호 &#124; ATmega8A-PU와의 I2C(TWI)통신을 기반으로 한다. 일정 값 이상으로 진동할 경우, LED에 불이 꺼지도록 하여 적절한 사격 준비가 되지 않았음을 사용자에게 알린다.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.ntrexgo.com/wp-content/uploads/2017/07/Cap-2017-10-18-13-15-49-260.png" rel="lightbox[35318]"><img class="alignnone size-large wp-image-34236" alt="Cap 2017-10-18 13-15-49-260" src="http://www.ntrexgo.com/wp-content/uploads/2017/07/Cap-2017-10-18-13-15-49-260-620x137.png" width="620" height="137" /></a></p>
<p><span style="font-size: large;background-color: #ffff00;color: #000000"><strong>2017 ICT 융합 프로젝트 공모전 참가상</strong></span></p>
<p><span style="font-size: x-large"><strong>Auxiliary Device For Shooting(ADFS)</strong></span></p>
<p>글 | 광운대학교 이상하, 이상훈</p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
칩센 경험을 통해 불편한 점을 개선하기 위한 노력이 보이는 작품입니다. 다만 경험을 통해 덧붙이자면, 군대에서 사격 훈련의 2인 1조를 운용하는 것은 단순히 바둑돌을 올리기 위함으로 보기는 힘들어 보입니다. 간단한 시스템 구성을 통해 작품의 의도인 군 훈련의 효율성을 높일수도 있지만, 기술적으로 높은 아이디어라 보기는 힘들고 부착된 센서들의 기능이 너무 단순화되어 있는데 이것을 또 다른 부가 기능으로 사용하는 방법은 없었을지에 대한 아쉬움도 남습니다.<br />
뉴티씨 군에 보급하게 된다면 군대 전체의 사격 명중률을 책임지는 장비가 될 가능성이 있습니다. 걸리적 거리는 선 없이 장비를 일체화시키면 간단한 부착을 통한 동작에 충분히 실용성이 있어 보입니다.<br />
위드로봇 MEMS 센서를 활용해 사격 훈련에 활용하는 아이디어가 돋보입니다. 아쉬운 점은 &#8220;진동&#8221;을 판단하는 부분은 is_safe() 부분인데, 단순한 thresholding으로 처리한 부분입니다. 이 부분에 대한 고민이 더 있으면 좋겠습니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품개요</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-1.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35349" alt="47 feature adfs (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-1.jpg" width="620" height="316" /></a><br />
소총 사격 시 가장 중요한 것은 손 떨림 없이 사격하는 것이다<br />
PRI(Preliminary Rifle Instruction) 훈련은 표적을 정확히 명중시키기 위하여 조준, 자세, 호흡, 격발의 사격술을 숙달하고 사격 연습과 가늠자 조정을 숙달하기 위한 훈련이다. 소총사격 시 가장 중요한 것은 손 떨림 없이 사격하는 것이다. 그래서 우리는 PRI(Preliminary Rifle Instruction) 훈련을 했었던 기억이 있다. 특히, 대한민국 육군에선 바둑돌을 K2 맨 앞에 올려 2인 1조로 사격 연습을 한다. 바둑돌 대신 조그만 한 센서(sensor)를 소총에 부착시키면, 2인 1조의 수고를 덜어줄 수 있고 실제 사격에도 훌륭한 사격 보조 장치가 될 것이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-1.png" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35350" alt="47 feature adfs (1)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-1.png" width="620" height="206" /></a></p>
<p>물체의 방위 변화를 인지하는 자이로 센서(Gyro-sensor)를 이용하여 가속도(진동)를 인지하고, ATmega8A-PU와의 I2C(TWI)통신을 기반으로 한다. 일정 값 이상으로 진동할 경우, LED에 불이 꺼지도록 하여 적절한 사격 준비가 되지 않았음을 사용자에게 알린다. 또한, 야간 사격의 경우 LED의 불이 밝다면 적군에게 위치를 알려주는 셈이다.<br />
이를 보완하고자 조도센서를 이용하여, 빛에 따라 LED의 밝기를 제어할 수 있도록 하였다.<br />
이러한 작품을 군에서 활용한다면, 실제 사격에서 유용한 사격 보조 장치가 될 것이다. 또한, 기존의 사격술 예비 훈련(Preliminary Rifle Instruction)의 단점을 보완하여, 혼자서도 객관적이고 확실한 사격 훈련을 할 수 있을 것이다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #3366ff"><strong>3.1. 주요 동작 및 특징</strong></span><br />
군대에서의 사격 훈련을 좀 더 보완할 수 있는 장치로서 고안하게 된 작품이다. 흔히, 군대에서의 사격 훈련을 생각해보면 PRI(Preliminary Rifle Instruction) 훈련을 떠올릴 수 있는데, 정확한 훈련 방법이 아니라고 생각한다. 대표적인 PRI(Preliminary Rifle Instruction)훈련은 총구위의 바둑알을 올려놓고 방아쇠를 당길 때 바둑알이 총구에서 떨어지는지 여부에 따라 사격 자세를 판단하는 훈련이다. 이는 여러 가지 외부적 요인으로 인하여 정확성이 떨어질 수밖에 없고 또한, 대체로 2인 1조를 이루어 훈련을 하게 되기 때문에 비효율적이다. 이러한 점을 보완하기 위해 만든 이번 작품은 기존의 아날로그적 훈련 방식을 탈피할 수 있게 한다. 먼저 작품의 특징이다.</p>
<p><span style="color: #33cccc"><strong>소형화</strong></span><br />
3(cm)*3(cm) 정도의 소형 작품이다. 소형화는 작품의 활용성을 높이는 중요한 요인이다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-2.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35351" alt="47 feature adfs (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-2.jpg" width="599" height="305" /></a></p>
<p><span style="color: #33cccc"><strong>탈부착</strong></span><br />
총기에 작품을 탈부착 할 수 있다. 새로운 제작 과정 없이 기존의 총기에 바로 적용이 가능하도록 설계를 하였다.<br />
크기, 디자인 등과 관계없이 사격 훈련을 위해 다양한 총기에 탈부착을 할 수 있게 하여 자원의 효율성을 높였다.<br />
<strong></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-8.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35359" alt="47 feature adfs (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-8.jpg" width="609" height="316" /></a></p>
<p><span style="color: #33cccc"><strong>저전력</strong></span><br />
ATmega8A-PU, 코인전지를 사용하여, 저전력방식을 택하였는데 이는 군대에서의 활용성을 높이는 중요한 요인이다.<br />
ATmega8A-PU는 AVR RISC(Reduced Instruction Set Computer)구조로 제조된 대표적 고성능, 저전력 소모용 CMOS 8bit MCU이다.<br />
작품의 주요 동작은 다음과 같다.<br />
첫째, 전원을 켜게 되면 LED가 점등하게 되고, 총기 옆에 부착된 MPU6050이 포함된 회로에서 가속도(진동)를 수시로 측정한다. 측정된 값을 Sampling 과정을 거쳐 진동이 있다고 판단될 경우 LED가 소등되면서 정확한 사격 준비 자세를 갖추지 않았음을 알린다. 반대로, 진동이 없다고 판단될 경우 LED는 점등하게 된다.<br />
즉, 사용자는 LED가 깜빡거리거나, 소등될 때 자신의 사격 자세가 부정확하다는 것을 깨닫고 자세를 고칠 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-4.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35353" alt="47 feature adfs (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-4.jpg" width="599" height="324" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-5.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35354" alt="47 feature adfs (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-5.jpg" width="599" height="324" /></a><br />
둘째, LED 밝기를 주위 환경에 따라 자동으로 제어할 수 있다.<br />
군에서의 야간 사격의 경우와 사격 준비가 되었음을 알리는 LED의 밝기가 너무 밝을 경우에, 적군에게 나의 위치를 알릴 수 있어서 큰 문제가 될 수 있다. 또한, 낮에는 빛의 양이 많기 때문에, LED가 점등이 되어도 잘 보이지 않는다.<br />
이를 해결하고자 Cds(조도) 센서를 통한 빛 감지, ADC 기능을 이용하여 듀티비를 조정하여 빛의 양에 따라 LED의 밝기를 자동으로 조절할 수 있게 하였다. 밤에는 LED 밝기를 낮추어 적군에게 눈에 띄지 않도록 하였고, 낮에는 LED 밝기를 높여 LED가 잘 보이도록 설계하였다.<br />
마지막으로, 하드웨어적으로 나사나 드라이버를 이용하여 수동으로 가변 저항을 조정, ADC를 이용하여 움직임(진동)의 민감도를 조정할 수 있다. 즉, 허용할 수 있는 진동의 민감도를 사용자가 조정할 수 있도록 하여편의를 도모하였다.<br />
예를 들어 설명해보면, 어떠한 진동에 깜빡거리거나 소등되었던 LED를 가변저항을 시계 방향으로 나사나 드라이버를 이용하여 돌릴 경우, 진동의 민감도는 낮아져 둔감해진다. 따라서 앞서와 똑같은 진동에는 더 이상 깜빡거리지 않고 켜져 있게 된다.<br />
반대로, 반시계 방향으로 가변 저항을 돌릴 시 진동의 민감도는 높아지게 되어 더 향상된 고도의 사격 훈련을 할 수 있을 것이다.</p>
<p><span style="color: #3366ff"><strong>3.2. 전체 시스템 구성</strong></span><br />
전체 시스템 구성을 보기 쉽게 표현하여 보았다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-2.png" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35355" alt="47 feature adfs (2)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-2.png" width="599" height="370" /></a><br />
시스템을 크게 총 4가지로 구성으로 나누었다.</p>
<p>· MPU6050(자이로 센서)를 통하여 가속도(진동) 인지하여 IC2 통신을 기반으로 값을 전달한다.<br />
· 전달된 값이 사용자가 설정한 진동 값 기준보다 클 경우 LED는 소등되며, 작을 경우 LED는 점등된다. 여기서 LED가 점등된다는 것은 진동이나 움직임이 거의 없으므로, 적절한 사격 준비 상태라는 의미이다. 반대로, LED가 소등된다는 것은 손 떨림이나 움직임이 많으므로, 사격 준비가 되지 않았다는 의미이다.<br />
· 조도 센서를 이용하여 빛을 감지하고, 풀 다운 저항을 통과한 아날로그 전압 신호는 ADC 과정을 거쳐 디지털 신호로 변화하고, 듀티비를 조정하여 LED를 제어한다.<br />
· 가변 저항과 풀 다운 저항, ADC를 이용하여, 진동의 민감도를 조정한다. 가변 저항을 시계방향으로 돌릴 시, 진동의 민감도는 낮아지게 된다. 반대로, 반시계 방향으로 돌릴 경우, 진동의 민감도는 높아져 똑같은 진동을 가하더라도, 가변저항의 조정으로 LED 점등 여부는 달라질 수 있다.</p>
<p>이러한 시스템 구성도와 각각의 기능을 이해하기 위해서는 몇 가지 알아야 될 배경지식이 있다.</p>
<p>첫째, IC2(TWI)통신이다. ATmega8A-PU와 MPU6050모듈을 사용하여 IC2(TWI)통신을 기반으로 가속도(진동)를 측정할 수 있다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-6.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35356" alt="47 feature adfs (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-6.jpg" width="599" height="207" /></a><br />
IC2통신의 특징은 다음과 같다.</p>
<p>· 단지 두 개의 버스 선을 사용하는 간단하고 효율적인 통신 방식<br />
· 마스터(Master)와 슬레이브(Slave) 동작을 모두 지원<br />
· 디바이스에서 송수신 모두 가능<br />
· 7비트 주소를 사용하여 128개의 다른 슬레이브 주소 가능<br />
· 400kHz 데이터 속도까지 지원</p>
<p>둘째, 빛을 감지하기 위한 조도 센서와 ADC이다. 또한, Cds sensor에서의 아날로그 신호를 ATmega8A-PU 시스템에서 처리하기 위해서는 ADC과정을 거쳐서 디지털 신호로 변환을 해야한다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-7.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35357" alt="47 feature adfs (7)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-7.jpg" width="599" height="207" /></a></p>
<p>빛의 양에 따라, LED를 제어하기 위해 Cds sensor를 이용한다.<br />
Cds sensor는 광센서의 가장 기본적인 sensor로서, 빛의 밝기에 대하여 전기적인 성질로 변환시켜주는 sensor이다.<br />
Cds sensor의 특징은 빛이 많을수록 광자 양은 많아져 저항값이 작아지고, 빛이 적을 경우에는 저항값은 커지게 된다. 빛의 양에 대한 저항값의 변화를 이용하여 주위의 밝기를 알아낼 수 있다.<br />
Cds sensor를 이용하여 주위 환경의 밝기에 따라 아날로그 전압의 값은 바뀐다. 이러한 아날로그 전압은 ADC(Analog-to-digital converter)를 통하여 디지털 값으로 변환되고, ATmega8A-PU모듈에서 그 값을 처리할 수 있게 된다.<br />
기준 전압을 AVCC핀으로 연결하고 풀 다운 저항을 사용하여 ADC0 핀으로 아날로그 신호가 입력되고 ADC 변환이 이루어지도록 하였다.<br />
또한, Date sheet에서는 AREF핀을 사용하지 않을 경우 GND와 0.1uF의 커패시터를 연결할 것을 권한다. 하지만 이 역시 A/D변환 회로부에 들어가게 될지도 모르는 전원 잡음을 조금이라도 줄이기 위한 방편이며, 연결하지 않아도 크게 영향을 미치지 않는다.</p>
<p>셋째, 풀 다운 저항의 이해이다.<br />
ADC0 핀에 들어가는 전압을 조정할 수 있도록 풀 다운 저항을 사용하였다. 풀 다운 저항은 전압 분배의 원리를 적용한 것인데, Ground로 연결된 저항의 값을 올리게 되면 핀에 들어가는 전압의 크기는 증가하게 된다. 즉, 각각의 저항의 값을 조정하여 핀에 입력되는 전압 기준을 원하는 대로 조정할 수 있다.</p>
<p><span style="color: #3366ff"><strong>3.3. 개발 환경</strong></span><br />
<span style="color: #33cccc"><strong>교차 개발</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-3.png" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35358" alt="47 feature adfs (3)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-3.png" width="609" height="246" /></a></p>
<p>교차 개발은 어떤 컴퓨터 시스템에서 운영하는 소프트웨어를 해당 시스템이 아닌 다른 시스템 상에서 개발하는 것을 말한다.<br />
Windows10 시스템에서 운영되는 AVR studio 4.19 tool을 사용하여, ATmega8A-PU 시스템 상에서 교차 개발하였다.<br />
개발 언어로는 C언어를 사용하였다.</p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작과정</strong></span><br />
<span style="color: #33cccc"><strong>기획</strong></span><br />
군 생활 시절 불편한 점을 생각하였고, 이 점을 전공 지식을 활용하여 해결할 수 있는 부분을 생각하였다. 그 중에서 사격 훈련에 여러 전자 장치를 가미하여 좀 더 효율적으로 훈련을 받을 수 있도록 하고자 이번 작품을 고안하게 되었다.</p>
<p><span style="color: #33cccc"><strong>설계</strong></span><br />
4가지 경우로 나누고 각각에 대해서 설계하였다.<br />
· 밝은 날 햇빛에 의한 조도센서 값<br />
· 밤에 햇빛이 없을 때 조도센서 값<br />
· 진동 없을 때 gyro센서 값<br />
· 진동 있을 때 gyro센서 값</p>
<p><span style="color: #33cccc"><strong>검증</strong></span><br />
tera term 프로그램을 이용하여 디버깅을 위한 소스 코드를 짜서, 각각의 경우에 대해서 sensor 값을 얻을 수 있었다.</p>
<p><span style="color: #33cccc"><strong>제작</strong></span><br />
브레드보드를 이용하여 시스템 구성도를 바탕으로 제작을 해보았다.</p>
<p><span style="color: #33cccc"><strong>적용</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-8.jpg" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35359" alt="47 feature adfs (8)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-8.jpg" width="609" height="316" /></a></p>
<p><span style="color: #0000ff"><strong>5. 기타</strong></span><br />
<span style="color: #33cccc"><strong>회로도</strong></span><br />
세 가지로 나누어 구현하였다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-4.png" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35360" alt="47 feature adfs (4)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-4.png" width="609" height="392" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-5.png" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35361" alt="47 feature adfs (5)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-5.png" width="609" height="290" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-6.png" rel="lightbox[35318]"><img class="alignnone size-full wp-image-35362" alt="47 feature adfs (6)" src="http://www.ntrexgo.com/wp-content/uploads/2018/04/47-feature-adfs-6.png" width="609" height="429" /></a><br />
<span style="color: #33cccc"><strong>소스코드</strong></span></p>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p>#include&lt;avr/io.h&gt;<br />
#include&lt;compat/ina90.h&gt; // 헤더 선언<br />
#include&lt;util/delay.h&gt;<br />
#include&lt;stdio.h&gt;<br />
#define CDS_VALUE 800</p>
<p>static int putchar0(char c, FILE *stream);<br />
static FILE mystdout = FDEV_SETUP_STREAM(putchar0, NULL, _FDEV_SETUP_WRITE);</p>
<p>void write(unsigned char add,unsigned char dat); // 쓰기<br />
unsigned short read(char addr); // 읽기<br />
int is_safe(unsigned short GxLow); //진동 측정, 민감도 조절가능<br />
void init_adc();<br />
unsigned short read_adc();<br />
void show_adc(unsigned short value);<br />
void my_delay(int value);<br />
int sensitivity;</p>
<p>int main()<br />
{<br />
unsigned short GxLow; // x축 센서값 변수<br />
unsigned short value;<br />
int i;</p>
<p>DDRB=0&#215;01; //LED 포트 출력설정<br />
UBRRH = 0; //UART 초기설정<br />
UBRRL = 51;<br />
UCSRB=(1&lt;&lt;RXEN)|(1&lt;&lt;TXEN);<br />
UCSRC=(3&lt;&lt;UCSZ0)|(1&lt;&lt;URSEL);<br />
stdout = &amp;mystdout;<br />
init_adc();</p>
<p>PORTC=0&#215;30; //풀업저항 활성화<br />
SFIOR &amp;= ~(1&lt;&lt;PUD);//풀업저항 활성화</p>
<p>// I2C INIT<br />
TWCR=0&#215;04; // TWI 활성화<br />
TWSR=TWSR &amp; 0xfc; // Prescaler : 1, 상태 초기화<br />
TWBR=92; // 00001100, Fscl = 400KHz(Fcpu/(16+2*TWBR*Prescaler) = Fscl)</p>
<p>_SEI(); //SREG IBit SET (_CLI() : CLEAR)</p>
<p>write(0x6B, 0&#215;00); //센서 ON<br />
write(0x6C, 0&#215;00);<br />
write(0x1B, 0&#215;08); // gyro set &#8211; 500/s로 설정<br />
write(0x1A, 0&#215;05); // DLPF 10Hz로 설정</p>
<p>sensitivity = read_adc(); //하드웨어적으로 저장된 진동 조절값 가져옴<br />
while(1)<br />
{<br />
_delay_us(100);<br />
GxLow=read(0&#215;44); //자이로 x L값 읽어오기<br />
//printf(&#8220;gyro-value\n&#8221;);<br />
//printf(&#8220;%d\n&#8221;,GxLow);<br />
//printf(&#8220;**********************\n&#8221;);<br />
if(is_safe(GxLow))<br />
{<br />
ADMUX=0&#215;40; //ADC0로 스위칭<br />
value=read_adc(); //조도센서값 가져옴</p>
<p>PORTB=0&#215;01;<br />
my_delay(value/3); //숫자값 조정하면 빛의양 조정 가능 (범위 1 ~ 500)<br />
PORTB=0&#215;00;<br />
}<br />
}<br />
}</p>
<p>void write(unsigned char add,unsigned char dat) //자이로 센서 설정<br />
{<br />
_delay_us(50); // 50us<br />
TWCR=0xA4; // S<br />
while((TWCR&amp;0&#215;80)==0&#215;00); // 전송 대기<br />
while((TWSR&amp;0xF8)!=0&#215;08); //신호 대기</p>
<p>TWDR=0xD0; // AD+W저장<br />
TWCR=0&#215;84; // 전송</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00); //전송대기<br />
while((TWSR&amp;0xF8)!=0&#215;18); //ACK대기<br />
TWDR=add; // RA<br />
TWCR=0&#215;84; // 전송</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00);<br />
while((TWSR&amp;0xF8)!=0&#215;28); // ACK<br />
TWDR=dat; // DATA<br />
TWCR=0&#215;84; // 전송</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00);<br />
while((TWSR&amp;0xF8)!=0&#215;28); // ACK<br />
TWCR|=0&#215;94; // P<br />
_delay_us(50); // 50us<br />
}</p>
<p>unsigned short read(char addr) //자이로 센서 값 읽어오기<br />
{<br />
unsigned short data; // data넣을 변수</p>
<p>TWCR=0xA4; // S<br />
while((TWCR&amp;0&#215;80)==0&#215;00); //통신대기<br />
while((TWSR&amp;0xF8)!=0&#215;08); //신호대기<br />
TWDR=0xD0; // AD+W<br />
TWCR=0&#215;84; // 전송</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00); //통신대기<br />
while((TWSR&amp;0xF8)!=0&#215;18); //ACK<br />
TWDR=addr; // RA<br />
TWCR=0&#215;84; //전송</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00); //통신대기<br />
while((TWSR&amp;0xF8)!=0&#215;28); //ACK<br />
TWCR=0xA4; // RS</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00); //통신대기<br />
while((TWSR&amp;0xF8)!=0&#215;10); //ACK<br />
TWDR=0xD1; // AD+R<br />
TWCR=0&#215;84; //전송</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00); //통신대기<br />
while((TWSR&amp;0xF8)!=0&#215;40); // ACK<br />
TWCR=0&#215;84;//전송</p>
<p>while((TWCR&amp;0&#215;80)==0&#215;00); //통신대기<br />
while((TWSR&amp;0xF8)!=0&#215;58); //ACK<br />
data=TWDR;<br />
TWCR=0&#215;94;<br />
_delay_us(50); // 50us<br />
return data;<br />
}</p>
<p>void init_adc()<br />
{<br />
ADMUX=0&#215;41; //ADC0 입력, 싱글엔드입력,<br />
ADCSRA=0&#215;87;<br />
}</p>
<p>unsigned short read_adc()<br />
{<br />
unsigned char adc_low, adc_high;<br />
unsigned short value;<br />
ADCSRA|=0&#215;40; //ADC start conversion, ADSC=&#8217;1&#8242;<br />
while((ADCSRA&amp;0&#215;10)!=0&#215;10); //ADC 변환 완료 검사<br />
adc_low=ADCL;<br />
adc_high=ADCH;<br />
value=(adc_high&lt;&lt;8)|adc_low; // 16비트 만들기<br />
return value;<br />
}</p>
<p>void my_delay(int value)<br />
{<br />
int i;<br />
for(i=0;i&lt;value;i++)<br />
_delay_us(100);<br />
}</p>
<p>int putchar0(char c, FILE *stream)<br />
{<br />
if(c==&#8217;\n&#8217;)<br />
putchar0(&#8216;\r&#8217;,stream);<br />
while(!(UCSRA &amp; 0&#215;20));<br />
UDR = c;<br />
return 0;<br />
}</p>
<p>int is_safe(unsigned short GxLow)<br />
{<br />
int temp=1;<br />
if(GxLow&gt;sensitivity) //숫자를 크게하면 둔감해지고, 작게하면 민감해진다.<br />
{ // ㄴ50~200 사이 조정가능<br />
temp=0;<br />
}</p>
<p>return temp;<br />
}<br />
</div>
<span style="color: #33cccc"><strong>참고 문헌</strong></span><br />
· http://studymake.tistory.com/383<br />
· USP-ISP와 AVR-Studio로 시작하는 AVR ATmega9 프로그래밍</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/35318/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
