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

<channel>
	<title>NTREXGO - 디바이스마트, 엔티렉스 컨텐츠 통합 사이트 &#187; 물체탐지</title>
	<atom:link href="http://www.ntrexgo.com/archives/tag/%eb%ac%bc%ec%b2%b4%ed%83%90%ec%a7%80/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>[66호]물체탐지 4족 보행로봇</title>
		<link>http://www.ntrexgo.com/archives/40660</link>
		<comments>http://www.ntrexgo.com/archives/40660#comments</comments>
		<pubDate>Wed, 23 Jun 2021 00:00:16 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></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>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=40660</guid>
		<description><![CDATA[디바이스마트 매거진 66호 &#124; 재해로 접근하기 어려운 지역이나 좁은 지역에서 사용할 수 있는 자동화 로봇을 만들어 효율적으로 일을 처리하고자 한다. ]]></description>
				<content:encoded><![CDATA[<p><span style="font-size: large;color: #3366ff"><strong><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-1.png" rel="lightbox[40660]"><img class="alignnone size-large wp-image-40757" alt="66 ICT_보행로봇 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-1-620x175.png" width="620" height="175" /></a></strong></span></p>
<p><span style="font-size: medium;color: #888888"><strong>2020 ICT 융합 프로젝트 공모전 장려상</strong></span></p>
<p><span style="color: #0000ff;font-size: xx-large"><strong>물체탐지 4족 보행로봇</strong></span></p>
<p style="text-align: right">글 | 선문대학교 곽호권</p>
<p>&nbsp;</p>
<p><span style="color: #0000ff"><strong>1. 심사평</strong></span><br />
<strong>칩센</strong> 개인적으로 더 좋은 하드웨어 적용과 더 많은 시간을 들이면 훨씬 개선된 움직임이 보여질 거라는 생각이 드는데, 작품이 개발자의 초기 기대치가 어느 정도인지가 궁금합니다. 로봇을 통해 사람이 하기에 어렵거나 위험한 일을 대신하게 하는 것은 앞으로도 계속 추구 되어야할 중요한 기술 개발 분야라고 생각됩니다. 공모전을 통해 이번에 시작을 한거라고 보면, 추가로 충분히 개선이 가능할만한 작품으로 보여 기대가 됩니다.<br />
<strong>펌테크</strong> 아이디어와 실용성을 갖춘 작품이라고 생각이 듭니다. 단 제출된 보고서 내용을 고려하자면 작품에 대한 기획 의도는 우수하다고 생각되지만 계획에 대비해서 출품작의 일부 진행 과정은 확인이 되나 최종적인 완성도를 구체적으로 확인할 수가 없었습니다.<br />
<strong>위드로봇</strong> 게이트 제어 및 영상 스트리밍 등 높은 난이도 기술을 구현한 작품입니다.</p>
<p><span style="color: #0000ff"><strong>2. 작품개요</strong></span><br />
<span style="color: #00ccff"><strong>2.1. 선정동기</strong></span><br />
뉴스에서 자연재해로 인한 인명구조를 하기 위해 위험을 무릅쓰고 탐사하는 모습을 보고 물체 탐지 4족 보행로봇을 통해 인명구조를 하면 좋을 것 같다는 생각에 선정하게 되었습니다.<br />
사람이 들어갈 수 없는 덕트 안에 어떠한 물체가 걸리는 현상이 발생하여 한 개의 라인 자체를 중단시키고 위험하게 물체를 꺼내는 모습을 보고 로봇을 통해 그 문제를 해결하면 좋을 것 같다는 영감을 얻어 선정하게 되었습니다.</p>
<p><span style="color: #00ccff"><strong>2.2. 목적</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-1.jpg" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40756" alt="66 ICT_보행로봇 (1)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-1.jpg" width="598" height="330" /></a></p>
<p>· 재해로 접근하기 어려운 지역이나 좁은 지역에서 사용할 수 있는 로봇입니다.<br />
· 좁고 어두운 하수관 같은 곳에 사용할 수 있는 자동화 로봇입니다.<br />
· 물체 탐지 4족 보행로봇을 통해 효율적으로 일을 처리할 수 있게 하기 위함입니다.</p>
<p><span style="color: #00ccff"><strong>2.3. 필요성</strong></span><br />
· 여러 인력을 동원해서 해야 하는 번거로운 일을 혼자서 핸드폰으로 할 수 있으므로 불필요한 인력이 감소됩니다.<br />
· 공장에서 사용시 라인이 중단되는 현상을 막아 시간과 비용이 절감됩니다.<br />
· 사람이 접근하기 위험한 곳에 로봇이 직접 탐사를 진행하기 때문에 안전하고 위험 부담이 감소합니다.</p>
<p><span style="color: #0000ff"><strong>3. 작품 설명</strong></span><br />
<span style="color: #00ccff"><strong>3.1. 주요 동작 및 특징</strong></span><br />
· 4족 보행로봇 보행<br />
· 적외선 센서 감지 및 DATA 출력<br />
· Application 스트리밍<br />
· Application 조작</p>
<p><span style="color: #00ccff"><strong>3.2. 전체 시스템 구성</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-2.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40759" alt="66 ICT_보행로봇 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-2.png" width="598" height="305" /></a><br />
Application을 통한 4족 보행로봇 제어 및 실시간 영상 스트리밍, 센서 DATA값 확인합니다.</p>
<p><span style="color: #00ccff"><strong>3.3. 개발 환경(개발 언어, Tool, 사용 시스템 등)</strong></span><br />
· CodeVision AVR<br />
· Visual Studio 2017 (C++)<br />
· PADS Logic<br />
· PADS Layout<br />
· Autodesk Inventor<br />
· Simplify 3D Printing with Ultimaker Cura 4.0<br />
· RasberryPi Python<br />
· Android studio</p>
<p><span style="color: #0000ff"><strong>4. 단계별 제작 과정</strong></span><br />
<span style="color: #00ccff"><strong>4.1. 모터 제어 시스템 개발 (CodeVision AVR Tool 사용)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-3.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40761" alt="66 ICT_보행로봇 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-3.png" width="620" height="569" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-2.jpg" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40758" alt="66 ICT_보행로봇 (2)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-2.jpg" width="605" height="362" /></a></p>
<p><span style="color: #339966"><strong>4.1.1. 모터 제어 실험 준비</strong></span><br />
1. PCB Bread Board에 Pinheader를 사용하여 ATmega128를 부착할 수 있도록 설계합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-3.jpg" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40760" alt="66 ICT_보행로봇 (3)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-3.jpg" width="602" height="333" /></a></p>
<p>2. 서보모터를 제어하기 위해 PortA(0~7) 와 PortC(0~3)까지 12개의 포트를 와이어링합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-4.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40763" alt="66 ICT_보행로봇 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-4.png" width="598" height="453" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-5.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40765" alt="66 ICT_보행로봇 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-5.png" width="595" height="412" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-6.png" rel="lightbox[40660]"><img class="alignnone size-large wp-image-40767" alt="66 ICT_보행로봇 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-6-563x620.png" width="563" height="620" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-7.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40768" alt="66 ICT_보행로봇 (7)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-7.png" width="599" height="570" /></a></p>
<p><span style="color: #339966"><strong>4.1.2. 모터 제어 실험</strong></span><br />
1. 서보모터인 SG90과 MG90s에 PWM신호를 입력하여 원하는 각도로 제어할 수 있도록 변하는 값을 각도는 각도기로 PWM신호는 오실로스코프로 확인합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-8.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40769" alt="66 ICT_보행로봇 (8)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-8.png" width="597" height="434" /></a></p>
<p>2. 1400usec만큼 PWM신호를 입력하였을 때 서보모터가 90도만큼 회전합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-9.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40770" alt="66 ICT_보행로봇 (9)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-9.png" width="603" height="226" /></a></p>
<p><span style="color: #00ccff"><strong>4.2. 4족 보행로봇 3D Modeling 및 3D Print (Inventor Tool 사용)</strong></span><br />
※ Inventor를 이용한 4족 보행 로봇 부품 설계</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-4.jpg" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40762" alt="66 ICT_보행로봇 (4)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-4.jpg" width="593" height="423" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #00ccff"><strong>4.3. 4족 보행로봇 걸음걸이 연구 (AVR과 MFC 시리얼 통신)</strong></span></p>
<p><span style="color: #339966"><strong>4.3.1. 걸음걸이 알고리즘 연구</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-10.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40771" alt="66 ICT_보행로봇 (10)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-10.png" width="599" height="330" /></a></p>
<p><span style="color: #339966"><strong>4.3.2. Creep Gait (크립 걸음걸이)</strong></span><br />
1. 크립 걸음 걸이는 사용하기 가장 쉬운 걸음 걸이입니다. 로봇은 지상에서 3피트를 유지하고 그 3피트가 형성하는 삼각형 안에 무게중심(CoG)을 유지합니다. CoG가 너무 오랫동안 삼각형을 벗어나면 넘어질 것입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-11.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40772" alt="66 ICT_보행로봇 (11)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-11.png" width="592" height="165" /></a></p>
<p>문제점 : 걷는 동안 안정성을 유지하는 방법<br />
1. 이것은 시작 위치이며 한쪽은 두 개의 다리가 밖으로 나오고 다른 두 개의 다리는 안쪽으로 당겨집니다.<br />
2. 오른쪽 상단 다리가 로봇의 앞쪽으로 들어 올려 밖으로 나옵니다.<br />
3. 모든 다리가 뒤로 움직여 몸을 앞으로 움직입니다.<br />
4. 뒷좌석 다리가 몸체와 함께 앞으로 들어 올려집니다. 이 위치는 시작 위치의 대칭 이미지입니다.<br />
5. 왼쪽 상단 다리가 로봇 앞쪽으로 들어 올려 밖으로 나옵니다.<br />
6. 다시 모든 다리가 뒤로 움직여 몸이 앞으로 움직입니다.<br />
7. 뒤 우측 다리가 들어 올려 신체로 다시 들어가서 우리를 시작 위치로 되돌립니다. 모든 시간에 다리의 바닥에 형성된 삼각형에는 무게중심(CoG)이 포함됩니다. 이것은 크립 걸음 걸이의 본질입니다. 이 패턴을 보면, 그것이 본질적으로 두 세트의 미러 된 움직임 임을 알 수 있습니다. 단계, 단계 및 교대, 다른 단계, 단계 및 교대가 뒤 따릅니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-12.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40773" alt="66 ICT_보행로봇 (12)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-12.png" width="599" height="345" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-13.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40774" alt="66 ICT_보행로봇 (13)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-13.png" width="596" height="346" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-14.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40775" alt="66 ICT_보행로봇 (14)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-14.png" width="597" height="408" /></a></p>
<p><span style="color: #00ccff"><strong>4.4. 전자회로기판 설계</strong></span><br />
PADS Logic Tool, PADS Layout Tool 사용</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-5.jpg" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40764" alt="66 ICT_보행로봇 (5)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-5.jpg" width="597" height="326" /></a></p>
<p><span style="color: #00ccff"><strong>4.5. 라즈베리파이와 적외선 센서 연동 (Python 사용)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-15.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40776" alt="66 ICT_보행로봇 (15)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-15.png" width="598" height="471" /></a></p>
<p>· 이름 : mini PIR motion sensor<br />
· 크기 : 20mm*20mm*12mm<br />
· 감지거리 : 2m(25°C)<br />
· 감지방법 : 적외선 온열 신체 감지<br />
· 공급전압 : 2.7~3.3V</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-16.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40777" alt="66 ICT_보행로봇 (16)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-16.png" width="595" height="244" /></a></p>
<p>· 이름 : analog sensor<br />
· 크기 : 25*10mm<br />
· 감지거리 : 5~15mm<br />
· 감지방법 : 적외선 반사 감지<br />
· 전압 : 5V<br />
· 출력 : 아날로그 전압</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-17.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40778" alt="66 ICT_보행로봇 (17)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-17.png" width="596" height="492" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-18.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40779" alt="66 ICT_보행로봇 (18)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-18.png" width="591" height="498" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-19.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40780" alt="66 ICT_보행로봇 (19)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-19.png" width="597" height="285" /></a></p>
<p><span style="color: #00ccff"><strong>4.6. 라즈베리파이와 적외선 카메라 연동 (Python 사용)</strong></span><br />
<span style="color: #339966"><strong>4.6.1. 라즈베리 파이 설정 </strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-20.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40781" alt="66 ICT_보행로봇 (20)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-20.png" width="600" height="81" /></a></p>
<p><span style="color: #339966"><strong>4.6.2. 인터페이스 옵션 설정(카메라활성화)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-21.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40782" alt="66 ICT_보행로봇 (21)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-21.png" width="596" height="218" /></a></p>
<p><span style="color: #339966"><strong>4.6.3. mjpg streamer 패키지 설치</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-22.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40783" alt="66 ICT_보행로봇 (22)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-22.png" width="593" height="299" /></a></p>
<p><span style="color: #339966"><strong>4.6.4. 편집기를 이용한 옵션사용</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-23.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40784" alt="66 ICT_보행로봇 (23)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-23.png" width="598" height="135" /></a></p>
<p>- i뒤에 내용은 파이카메라 옵션<br />
- o뒤에 내용은 스트리밍 출력옵션</p>
<p><span style="color: #339966"><strong>4.6.5. 옵션변경</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-24.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40785" alt="66 ICT_보행로봇 (24)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-24.png" width="600" height="85" /></a></p>
<p><span style="color: #00ccff"><strong>4.7. 동영상 스트리밍 서버 구현</strong></span></p>
<p><span style="color: #339966"><strong>4.7.1. 라즈베리파이 ip주소 찾기</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-25.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40786" alt="66 ICT_보행로봇 (25)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-25.png" width="595" height="66" /></a></p>
<p><span style="color: #339966"><strong>4.7.2. 서버접속 후 스트리밍 확인</strong></span><br />
<strong></strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-26.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40787" alt="66 ICT_보행로봇 (26)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-26.png" width="600" height="251" /></a></p>
<p><span style="color: #00ccff"><strong>4.8. Application 개발 (Android Studio 사용)</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-6.jpg" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40766" alt="66 ICT_보행로봇 (6)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-6.jpg" width="601" height="368" /></a> <a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-27.png" rel="lightbox[40660]"><img class="alignnone size-full wp-image-40788" alt="66 ICT_보행로봇 (27)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-27.png" width="603" height="320" /></a></p>
<p><span style="color: #339966"><strong>4.8.1. 버튼 세 개(실시간 영상,센서값, 같이보기)를 만듭니다.</strong></span><br />
<span style="color: #339966"><strong>4.8.2. loadData를 이용한 앱 안 동영상 스트리밍과 Toast를 이용한 알림 창 생성합니다. </strong></span><br />
<span style="color: #339966"><strong>4.8.3. 안드로이드 앱 안 동영상 스트리밍합니다.</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-28.png" rel="lightbox[40660]"><img class="alignnone  wp-image-40789" alt="66 ICT_보행로봇 (28)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-28-479x620.png" width="500" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-29.png" rel="lightbox[40660]"><img class="alignnone  wp-image-40790" alt="66 ICT_보행로봇 (29)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-29-464x620.png" width="500" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-30.png" rel="lightbox[40660]"><img class="alignnone  wp-image-40791" alt="66 ICT_보행로봇 (30)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-30.png" width="500" /></a></p>
<p><strong style="color: #339966">4.8.4. 라즈베리파이 센서 데이터 값 App에 전송</strong></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-31.png" rel="lightbox[40660]"><img class="alignnone  wp-image-40792" alt="66 ICT_보행로봇 (31)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-31-429x620.png" width="620" /></a></p>
<p><span style="color: #0000ff"><strong>5. 회로도</strong></span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-32.png" rel="lightbox[40660]"><img alt="66 ICT_보행로봇 (32)" src="http://www.ntrexgo.com/wp-content/uploads/2021/06/66-ICT_보행로봇-32.png" width="600" height="455" /></a></p>
<p><span style="color: #0000ff"><strong>6. 참고문헌</strong></span><br />
· App 개발 때 사용한 문헌 : http://blog.naver.com/PostView.nhn?blogId=juke45ef&amp;logNo=220827583111<br />
· https://webnautes.tistory.com/995<br />
· https://tony2012.tistory.com/category/Develop/IT</p>
<p><span style="color: #0000ff"><strong>7. 소스코드</strong></span></p>
<div class="symple-box blue none" style="text-align:left; width:100%;"> 
<p><strong>Android Studio &#8211; Application 개발</strong></p>
<p>* 버튼 세개만들기<br />
&lt;Button<br />
android:id=&#8221;@=id/btn_video&#8221;<br />
android:layout_width=&#8221;295dp&#8221;<br />
android:layout_height=&#8221;217dp&#8221;<br />
android:text=&#8221;실시간 영상&#8221;<br />
android:layout_gravity=&#8221;center&#8221;/&gt;</p>
<p>&lt;Button<br />
android:id=&#8221;@=id/btn_sensor&#8221;<br />
android:layout_width=&#8221;296dp&#8221;<br />
android:layout_height=&#8221;217dp&#8221;<br />
android:text=&#8221;실시간 영상&#8221;<br />
android:layout_gravity=&#8221;center&#8221;/&gt;</p>
<p>&lt;Button<br />
android:id=&#8221;@=id/btn_video&#8221;<br />
android:layout_width=&#8221;295dp&#8221;<br />
android:layout_height=&#8221;217dp&#8221;<br />
android:text=&#8221;실시간 영상&#8221;<br />
android:layout_gravity=&#8221;center&#8221;/&gt;</p>
<p>1. AndroidManifest.xml에 추가<br />
&lt;uses-permission android:name=&#8221;android.permission.BLUETOOTH&#8221; /&gt;<br />
&lt;uses-permission android:name=&#8221;android.permission.BLUETOOTH_ADMIN&#8221; /&gt;</p>
<p>2. 디바이스에서 블루투스를 지원하는지 체크<br />
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();<br />
if (mBluetoothAdapter == null) {<br />
showErrorDialog(&#8220;This device is not implement Bluetooth.&#8221;);<br />
return;<br />
}</p>
<p>3. 사용자에게 블루투스를 켜도록 요청<br />
if (!mBluetoothAdapter.isEnabled()) {<br />
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);<br />
startActivityForResult(intent, REQUEST_BLUETOOTH_ENABLE);<br />
}</p>
<p>4. 블루투스 활성화시 showPairedDevicesListDialog() 메소드를 호출<br />
if (!mBluetoothAdapter.isEnabled()) {<br />
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);<br />
startActivityForResult(intent, REQUEST_BLUETOOTH_ENABLE);<br />
}<br />
else {<br />
Log.d(TAG, &#8220;Initialisation successful.&#8221;);</p>
<p>showPairedDevicesListDialog();<br />
}</p>
<p>5. 페어링 되어 있는 블루투스 장치들의 목록을 보여준다.<br />
public void showPairedDevicesListDialog()<br />
{<br />
Set&lt;BluetoothDevice&gt; devices = mBluetoothAdapter.getBondedDevices();<br />
final BluetoothDevice[] pairedDevices = devices.toArray(new BluetoothDevice[0]);</p>
<p>if ( pairedDevices.length == 0 ){<br />
showQuitDialog( &#8220;No devices have been paired.\n&#8221;<br />
+&#8221;You must pair it with another device.&#8221;);<br />
return;<br />
}</p>
<p>String[] items;<br />
items = new String[pairedDevices.length];<br />
for (int i=0;i&lt;pairedDevices.length;i++) {<br />
items[i] = pairedDevices[i].getName();<br />
}</p>
<p>AlertDialog.Builder builder = new AlertDialog.Builder(this);<br />
builder.setTitle(&#8220;Select device&#8221;);<br />
builder.setCancelable(false);<br />
builder.setItems(items, new DialogInterface.OnClickListener() {<br />
@Override<br />
public void onClick(DialogInterface dialog, int which) {<br />
dialog.dismiss();</p>
<p>// Attempt to connect to the device<br />
ConnectTask task = new ConnectTask(pairedDevices[which]);<br />
task.execute();<br />
}<br />
});<br />
builder.create().show();<br />
}<br />
6. 블루투스 페어링 확인<br />
pi@raspberrypi:~ $ bluetoothctl</p>
<p>7. 라즈베리파이 센서 데이터 값 APP에 전송</p>
<p>7-1) 기본 ExampleFragment 에 버튼을 추가<br />
&lt;span style=&#8221;font-size: 12pt;&#8221;&gt;&lt;Button<br />
android:layout_width=&#8221;wrap_content&#8221;<br />
android:layout_height=&#8221;wrap_content&#8221;<br />
android:text=&#8221;put&#8221;<br />
android:id=&#8221;@+id/button1&#8243;<br />
android:layout_marginTop=&#8221;120dp&#8221;<br />
android:layout_centerHorizontal=&#8221;true&#8221; /&gt;&lt;#textarea&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&#8221;autosourcing-stub-extra&#8221;&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style=&#8221;color: rgb(161, 161, 161); line-height: 1.5; margin: 25px 0px 10px; font-style: normal; font-variant: normal; font-weight: normal; font-stretch: normal; font-size: 11px; font-family: Dotum, sans-serif; background-color: rgb(255, 255, 255);&#8221;&gt;<br />
&lt;/div&gt;<br />
&lt;/div&gt;<br />
&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;<br />
7-2) ExampleFragemnt 파일에 Activity 로 콜백해주는 함수를 선언하고 button 클릭시 만든 함수를 호출하는 이벤트를 작성</p>
<p>&lt;span style=&#8221;font-size: 12pt;&#8221;&gt;package com.hardcopy.btctemplate.fragments;</p>
<p>import android.annotation.SuppressLint;<br />
import android.content.Context;<br />
import android.os.Bundle;<br />
import android.os.Handler;<br />
import android.support.v4.app.Fragment;<br />
import android.view.LayoutInflater;<br />
import android.view.View;<br />
import android.view.ViewGroup;<br />
import android.widget.Button;</p>
<p>import com.hardcopy.btctemplate.R;</p>
<p>public class ExampleFragment extends Fragment {</p>
<p>private Context mContext = null;<br />
private IFragmentListener mFragmentListener = null;<br />
private Handler mActivityHandler = null;<br />
Button button1;<br />
String message = &#8220;%Swif^&#8221;;<br />
public ExampleFragment(){}</p>
<p>@SuppressLint(&#8220;ValidFragment&#8221;)<br />
public ExampleFragment(Context c, IFragmentListener l, Handler h) {<br />
mContext = c;<br />
mFragmentListener = l;<br />
mActivityHandler = h;<br />
}</p>
<p>@Override<br />
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {<br />
View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);</p>
<p>//버튼 클릭이벤트<br />
button1 = (Button) rootView.findViewById(R.id.button1);<br />
button1.setOnClickListener(new View.OnClickListener() {<br />
@Override<br />
public void onClick(View v) {<br />
if(message != null &amp;&amp; message.length() &gt; 0)<br />
sendMessage(message); //아래 함수에 message를 전달하여 호출<br />
}<br />
});</p>
<p>return rootView;<br />
}</p>
<p>//*****************************************</p>
<p>// Activity 에 데이터를 전달하는 콜백하는 함수</p>
<p>//*****************************************<br />
private void sendMessage(String message) {<br />
if(message == null || message.length() &lt; 1)<br />
return;<br />
// send to remote<br />
if(mFragmentListener != null)<br />
mFragmentListener.OnFragmentCallback(IFragmentListener.CALLBACK_SEND_MESSAGE, 0, 0, message, null,null);<br />
else<br />
return;<br />
}<br />
}<br />
&lt;#textarea&gt;&lt;/span&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class=&#8221;autosourcing-stub-extra&#8221;&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;</p>
<p>7-3) MainActivity.java 파일에 해당 콜백에 얻어오는 데이터를 가지고 블루투스에 전송<br />
public void OnFragmentCallback(int msgType, int arg0, int arg1, String arg2, String arg3, Object arg4) {<br />
switch(msgType) {<br />
case IFragmentListener.CALLBACK_RUN_IN_BACKGROUND:<br />
if(mService != null)<br />
mService.startServiceMonitoring();<br />
break;<br />
case IFragmentListener.CALLBACK_SEND_MESSAGE:<br />
if(mService != null &amp;&amp; arg2 != null)<br />
mService.sendMessageToRemote(arg2);</p>
<p>//sendMessageToRemote()함수는 BTCTempleteService.java에서 구성된 블루투스 송신메서드.<br />
default:<br />
break;<br />
}<br />
}<br />
&lt;#textarea&gt;&lt;/span&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;<br />
&lt;p style=&#8221;list-style: none; margin: 0px; padding: 0px; font-family: inherit; font-size: inherit;&#8221;&gt;&lt;strong&gt;&lt;font color=&#8221;rgb(0,0,0)&#8221; style=&#8221;background-color: rgb(228, 255, 117);&#8221;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</p>
<p><em>출처: https://tony2012.tistory.com/?page=28 [Useless]</em><br />
</div>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p><strong>CodeVision AVR_4족보행로봇 제어</strong></p>
<p>#include &lt;mega128.h&gt; //codevision에서 Atmega128사용시<br />
#include &lt;string.h&gt; //string 관련 함수 , sprintf<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;stdio.h&gt;<br />
#include &lt;delay.h&gt;<br />
#include &lt;math.h&gt;</p>
<p>// 시리얼통신에서 입력한 명령을 담아두는 곳<br />
//예: m00123(enter) -&gt; string[0]=&#8217;m&#8217; string[1]=&#8217;0&#8242; &#8230; string[6]=0x0d=‘\r’(enter에 해당하는 ASCII Code값;<br />
char string[64];</p>
<p>int iTimer0,iTimer2; //타이머 초기화 카운트 값<br />
int cmd_count;<br />
//cmd_count: command counting, 키보드입력시 입력 횟수<br />
int count_10usec;<br />
//count_10usec; 10usec마다 카운팅되는 변수 timer2 overflow 시<br />
//DegMotor:각 모터의 회전 각도,<br />
//CntMotor:각모터의 PWM Pulse 폭<br />
int DegMotor[12],CntMotor[12];<br />
int OffsetDegMotor[12]={0,-5,10,5,-5,-10,13,-5,-20,-3,-2,15};<br />
//Leg Length<br />
float La=55,Lb=77.5,Lc=27.5;<br />
float pi=3.141592;<br />
/*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
data를 시리얼 포트로 1 바이트 송신하기<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;*/<br />
void sendChar(char data)<br />
{<br />
int i = 0;<br />
// To send data with the USART put the data in the USART data register<br />
UDR0 = data;</p>
<p>// Check to see if the global interrupts are enabled<br />
if(SREG &amp; 0&#215;80)<br />
{<br />
// Wait until the byte is sent or we count out<br />
while ( !(UCSR0A&amp;0&#215;40) &amp;&amp; (i&lt;10000) )<br />
{<br />
i++;<br />
}<br />
}<br />
else // Wait until the byte is sent<br />
while( !(UCSR0A&amp;0&#215;40) ); //송신완료시까지 대기</p>
<p>// Clear the TXCflag<br />
UCSR0A=UCSR0A|0&#215;40;<br />
}</p>
<p>/*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
문자열 str을 문자열 맨뒤 NULL이 나올떄 까지 한바이트씩 보내기<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-*/</p>
<p>void sendString(char* str)<br />
{<br />
while(*str) sendChar(*str++);<br />
}<br />
/*<br />
만일 str[ ] = &#8220;rs232c&#8221;라면<br />
str[0]=&#8217;r'=0&#215;72<br />
str[1]=&#8217;s&#8217;<br />
str[2]=&#8217;2&#8242;=0&#215;32<br />
str[3]=&#8217;3&#8242;<br />
str[4]=&#8217;2&#8242;=0&#215;32<br />
str[5]=&#8217;c&#8217;<br />
str[6]=&#8221;<br />
&#8216; &#8216;:char<br />
&#8221; &#8220;:string<br />
str: str이라는 문자열이 저장된 주소<br />
*str:str에 저장된 내용<br />
step1:while(*str) =&gt; while(&#8216;r&#8217;); -&gt;while(true)<br />
step2:sendChar(*str); =&gt;sendChar(&#8216;r&#8217;);<br />
step3: str++; //주소증가<br />
step4:while(*str) =&gt; while(&#8216;s&#8217;); -&gt;while(true)<br />
step5:sendChar(*str); =&gt;sendChar(&#8216;s&#8217;);<br />
step6: str++;<br />
&#8230;.<br />
stepn:while(*str) =&gt; while(&#8221;); -&gt;while(false)<br />
*/</p>
<p>/*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
시리얼 포트 초기화<br />
8비트 데이터, 1 stop 비트,non parity, 9600 보레이트<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;*/<br />
void rs232c_initialize(void)<br />
{<br />
DDRE=DDRE|0&#215;02; //포트 E의 입출력 설정 ,PE0:0 Rx0,PE1:1 Tx0<br />
//USART Register Init<br />
UCSR0A=0&#215;00;<br />
UCSR0B=0&#215;98; //1001 1000 //7 bit : RX Complete Interrupt Enable<br />
//4 bit : Receiver Enable. Writing this bit to one enables the USARTn Receiver.<br />
//3 bit : Transmitter Enable. Writing this bit to one enables the USARTn Transmitter.<br />
//2 bit : UCSR0C 2,1 bit와 연결사용</p>
<p>UCSR0C=0&#215;06; //0000 0110 //6 bit : USART Mode Select. Asynchronous Operation<br />
//5,4 bit : Parity Mode. Disabled<br />
//3 bit : Stop Bit Select. 1-bit<br />
//2,1 bit : Character Size. 8-bit<br />
//0 bit : Clock Polarity. Transmitted Data : Rising XCKn Edge<br />
// Received Data : Falling XCKn Edge</p>
<p>UBRR0H=0&#215;00; //USARTn Baud Rate Register<br />
UBRR0L=0&#215;67; //USARTn Baud Rate Register 9600<br />
//UBRR0L=0&#215;8; //USARTn Baud Rate Register 115200<br />
}</p>
<p>void init_Timer()<br />
{<br />
//prescale=1024, input frequency=16MHz/1024=64KHz T=1/64usec<br />
//Overflow시 timing 간격은 256/64msec=16.348msec<br />
iTimer0=0;<br />
//Timer2, input f=16MHz, 160count=10sec is TCNT2=256-160=96<br />
//but from tunning process, the timer2 initialzed variable is 113<br />
iTimer2=113;<br />
DDRC=DDRA=0xff; //Set PORTA all output<br />
PORTC=PORTA=0&#215;00; //Set All PortA Low</p>
<p>TCCR0=0&#215;07; //oc0 not enable, normal, 분주비 1024, pb4 일반포트로 사용<br />
TCCR2=0&#215;01; //0b00000101 //oc2 not enable, normal, 분주비 1, pb7 일반포트로 사용<br />
// 0 0 00 0 010<br />
TIMSK=0&#215;41; //timer 0and 2 overflow interrupt enable<br />
TCNT0=iTimer0; //time 0 초기값<br />
TCNT2=iTimer2;<br />
}</p>
<p>//Deg로 입력된 것을 Pulse Width로 변환하기<br />
void ConvertDeg2Cnt()<br />
{<br />
int i;<br />
for(i=0;i&lt;12;i++)<br />
CntMotor[i]=(10.58*(DegMotor[i]+OffsetDegMotor[i])+459.4)/10+3;<br />
}</p>
<p>interrupt [TIM0_OVF] void timer_int0()<br />
{<br />
PORTC=PORTA=0xff;<br />
count_10usec=0;<br />
TIMSK = TIMSK | 0&#215;40; //Timer 2 Interrupt Enable<br />
}<br />
interrupt [TIM2_OVF] void timer_int2()<br />
{</p>
<p>TCNT2=iTimer2; //the initialzed variable for 10usec timer2 overflow interrupt<br />
count_10usec++;<br />
if(count_10usec == CntMotor[0] ) PORTA.0=0;<br />
if(count_10usec == CntMotor[1] ) PORTA.1=0;<br />
if(count_10usec == CntMotor[2]) PORTA.2=0;<br />
if(count_10usec == CntMotor[3]) PORTA.3=0;<br />
if(count_10usec == CntMotor[4]) PORTA.4=0;<br />
if(count_10usec == CntMotor[5]) PORTA.5=0;<br />
if(count_10usec == CntMotor[6]) PORTA.6=0;<br />
if(count_10usec == CntMotor[7]) PORTA.7=0;<br />
if(count_10usec == CntMotor[8]) PORTC.0=0;<br />
if(count_10usec == CntMotor[9]) PORTC.1=0;<br />
if(count_10usec == CntMotor[10]) PORTC.2=0;<br />
if(count_10usec == CntMotor[11]) PORTC.3=0;<br />
if(count_10usec &gt; 300)<br />
{<br />
TIMSK = TIMSK &amp; 0xbf; //Timer 2 Interrupt disable<br />
}</p>
<p>}</p>
<p>/*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
수신 받은 문자열 s[]데이터 분석<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;*/<br />
void parseInput(char * s)<br />
{<br />
int imotor;<br />
// parse first character<br />
switch (s[0])<br />
{<br />
//xx축 motor 개별 제어<br />
//m+XX(motor no.)+xxx+&#8217;\r&#8217;<br />
case &#8216;m&#8217;:<br />
case &#8216;M&#8217;:<br />
//if m11135 이면 s[1]=&#8217;1&#8242;=0&#215;31, s[2]=&#8217;1&#8242;=0&#215;31<br />
//아스키코드값으로 표현된 연속된 두 숫자를 10진수로 변환 하기 imotor-&gt;1*10+1=11<br />
imotor=(s[1]-&#8217;0&#8242;)*10+(s[2]-&#8217;0&#8242;);<br />
//s+3부터 문자열을 ascii to integer변환<br />
/*<br />
s[0]=&#8217;m&#8217;<br />
s[1]=&#8217;1&#8242;<br />
s[2]=&#8217;1&#8242;<br />
s[3]=&#8217;1&#8242;<br />
s[4]=&#8217;3&#8242;<br />
s[5]=&#8217;5&#8242;<br />
s[6]=&#8221;<br />
이므로 s[3[부터 끝까지 ascii로되어있는 문자를 정수로 변환하시오<br />
DegMotor[imotor]=135;<br />
*/<br />
DegMotor[imotor]=atoi(s+3);<br />
ConvertDeg2Cnt();<br />
break;</p>
<p>//12개의 모터 제어 데이터 열<br />
//d+xxxxxxxxxxxx+&#8217;\r&#8217;, x는 unsigned char data<br />
case &#8216;d&#8217;:<br />
case &#8216;D&#8217;:<br />
for(imotor=0;imotor&lt;12;imotor++)<br />
DegMotor[imotor]=(unsigned char)s[imotor+1];<br />
ConvertDeg2Cnt();<br />
break;</p>
<p>case &#8216;c&#8217;:<br />
sendString(&#8220;Your command input is ..!\r\n&#8221;);<br />
sendString(s);<br />
sendString(&#8220;\r\n&#8221;);<br />
break;<br />
case &#8216;e&#8217;:<br />
sendString(&#8220;Your message input is ..!\r\n&#8221;);<br />
sendString(s);<br />
sendString(&#8220;\r\n&#8221;);<br />
break;<br />
default:<br />
break;<br />
}<br />
//앞에서 받은 명령을 초기화하기<br />
s[0] = &#8221;;<br />
}</p>
<p>/*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
하이퍼터밀널에서 입력을 하고 엔터키를 입력하면<br />
입력 데이터 뒤에 /n 이 연이어 붙는다.<br />
/r:Carriage Return 0x0D<br />
/n:new line , line feed 0x0A<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;*/<br />
//카보드로 입력이 들어오면 인터럽트 발생<br />
interrupt [USART0_RXC] void usart0_rx_isr(void) //USART0 수신 완료 인터럽트<br />
{<br />
string[cmd_count++] = UDR0; //rx로 받은 값을 data에 저장<br />
// “m11135+/r”=&gt;motor 2 angle 135<br />
/*<br />
string[0]=‘m&#8217;<br />
string[1]=‘1&#8242;<br />
string[2]=‘1&#8242;<br />
string[3]=‘1&#8242;<br />
string[4]=‘3&#8242;<br />
string[5]=‘5&#8242;<br />
string[6]=‘\r&#8217;=0x0d<br />
cmd_count-&gt;7<br />
*/<br />
if(string[cmd_count-1] == &#8216;\r&#8217;)<br />
{<br />
string[cmd_count-1] = &#8221;;<br />
//convert to a string. 문자로 하나하나 모았다가 문자열로 변환하기위해서 뒤에 NULL()로 변경<br />
/*<br />
string[0]=‘m&#8217;<br />
string[1]=‘1&#8242;<br />
string[2]=‘1&#8242;<br />
string[3]=‘1&#8242;<br />
string[4]=‘3&#8242;<br />
string[5]=‘5&#8242;<br />
string[6]=‘&#8217;=0&#215;00<br />
문자열로 변경된 상태<br />
*/</p>
<p>parseInput(string); //명령 분석<br />
cmd_count = 0;<br />
}<br />
else if(string[cmd_count-1] == &#8216;c&#8217;)// &#8216;c&#8217;+/r<br />
{<br />
string[1]=&#8221;; //convert to a string<br />
parseInput(string);<br />
cmd_count = 0;<br />
}<br />
else if(string[cmd_count-1] == &#8216;e&#8217;)// &#8216;e&#8217;+/r<br />
{<br />
string[1]=&#8221;; //convert to a string<br />
parseInput(string);<br />
cmd_count = 0;<br />
//EnableTimer0Interrupt();<br />
}<br />
}</p>
<p>void Leg1(int x,int y,int z, int * theta0,int * theta1,int * theta2)<br />
{<br />
int w,v;<br />
float t0,t1,t2;</p>
<p>w=sqrt(x*x+y*y);<br />
v=w-Lc;<br />
t1=atan2(v,z)+acos((La*La+z*z+v*v-Lb*Lb)/(2*La*sqrt(z*z+v*v)));<br />
t2=acos((La*La+Lb*Lb-z*z-v*v)/(2*La*Lb));<br />
t0=atan2(x,y);</p>
<p>*theta0=t0*180/pi+90;<br />
*theta1=90-t1*180/pi;<br />
*theta2=t2*180/pi;<br />
}</p>
<p>void main(void)<br />
{<br />
int i;<br />
char buff[20];</p>
<p>rs232c_initialize();</p>
<p>cmd_count=0;</p>
<p>for(i=0;i&lt;12;i++) DegMotor[i]=90;<br />
ConvertDeg2Cnt();</p>
<p>init_Timer();</p>
<p>sendString(&#8220;rs232c connected&#8230;.\r\n&#8221;);</p>
<p>SREG=0&#215;80; //1000 0000 //7 bit : Global Interrupt Enable</p>
<p>Leg1(80,40,-15,&amp;DegMotor[0],&amp;DegMotor[1],&amp;DegMotor[2]);<br />
ConvertDeg2Cnt();<br />
itoa(DegMotor[0],buff);<br />
sendString(buff);<br />
sendString(&#8220;\r\n&#8221;);<br />
itoa(DegMotor[1],buff);<br />
sendString(buff);<br />
sendString(&#8220;\r\n&#8221;);<br />
itoa(DegMotor[2],buff);<br />
sendString(buff);<br />
sendString(&#8220;\r\n&#8221;);<br />
while(1)<br />
{<br />
}<br />
}</p>
</div>
<div class="symple-box gray none" style="text-align:left; width:100%;"> 
<p><strong> CodeVision AVR (모터제어)</strong></p>
<p>#include &lt;mega128.h&gt; //For Atmega128 in Code Vision<br />
#include &lt;delay.h&gt; //For dalay_ms, delay_us</p>
<p>int iTimer0,iTimer2; //Timer initialized variable<br />
int count; //count timer2 overflow interrupt<br />
int Degree,Motor;</p>
<p>interrupt [TIM0_OVF] void timer_int0()<br />
{<br />
PORTC=PORTA=0xff;<br />
count=0;<br />
TIMSK = TIMSK | 0&#215;40; //Timer 2 Interrupt Enable<br />
}</p>
<p>interrupt [TIM2_OVF] void timer_int2()<br />
{<br />
TCNT2=iTimer2; //the initialzed variable for 10usec timer2 overflow interrupt<br />
count++;<br />
if(count == Motor ) PORTA.0=0;<br />
if(count == Motor ) PORTA.1=0;<br />
if(count == Motor) PORTA.2=0;<br />
if(count == Motor) PORTA.3=0;<br />
if(count == Motor) PORTA.4=0;<br />
if(count == Motor) PORTA.5=0;<br />
if(count == Motor) PORTA.6=0;<br />
if(count == Motor) PORTA.7=0;<br />
if(count == Motor) PORTC.0=0;<br />
if(count == Motor) PORTC.1=0;<br />
if(count == Motor) PORTC.2=0;<br />
if(count == Motor) PORTC.3=0;<br />
if(count &gt; 300)<br />
{<br />
TIMSK = TIMSK &amp; 0xbf; //Timer 2 Interrupt disable<br />
}<br />
}<br />
void main(void)<br />
{<br />
iTimer0=0;<br />
//Timer2, input f=16MHz, 160count=10sec is TCNT2=256-160=96<br />
//but from tunning process, the timer2 initialzed variable is 113<br />
iTimer2=113;<br />
DDRC=DDRA=0xff; //Set PORTA all output<br />
PORTC=PORTA=0&#215;00; //Set All PortA Low</p>
<p>TCCR0=0&#215;07; //oc0 not enable, normal, 분주비 1024, pb4 일반포트로 사용</p>
<p>TCCR2=0&#215;01; //0b00000101 //oc2 not enable, normal, 분주비 1, pb7 일반포트로 사용<br />
// 0 0 00 0 010<br />
//TIMSK=0xC3; //timer 0 oVerflow interrupt enable<br />
TIMSK=0&#215;41; //timer 0and 2 overflow interrupt enable</p>
<p>TCNT0=iTimer0; //time 0 초기값<br />
TCNT2=iTimer2;</p>
<p>SREG=0&#215;80; //인터럽트 인에이블</p>
<p>Degree=90;<br />
while(1)<br />
{<br />
Motor=(10.58*Degree+459.4)/10+3;<br />
}<br />
}</p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p><strong> Python &#8211; 라즈베리파이와 적외선 카메라 연동</strong><br />
1. SUDO RASPI-CONFIG 접속<br />
sudo raspi-config</p>
<p>2. 인터페이스 옵션 설정(카메라활성화)</p>
<p>3. mjpg-streamer 소스 코드를 다운로드 받을 디렉토리를 생성<br />
pi@raspberrypi:~ $ mkdir project<br />
pi@raspberrypi:~ $ cd project<br />
pi@raspberrypi:~/project $</p>
<p>4. 소스 코드를 다운로드 받기위해서 git가 필요<br />
pi@raspberrypi:~/project $ sudo apt-get install git</p>
<p>5. mjpg-streamer 소스 코드를 다운로드<br />
pi@raspberrypi:~/project $ git clone https://github.com/jacksonliam/mjpg-streamer.git</p>
<p>6. mjpg-streamer 소스 코드를 컴파일하기 위해 필요한 패키지를 설치<br />
pi@raspberrypi:~/project $ sudo apt-get install cmake python-imaging libjpeg-dev build-essential</p>
<p>7. mjpg-streamer 소스 디렉토리로 이동하여 컴파일 및 설치를 진행<br />
pi@raspberrypi:~/project $ cd mjpg-streamer/mjpg-streamer-experimental/<br />
pi@raspberrypi:~/project/mjpg-streamer/mjpg-streamer-experimental $ make CMAKE_BUILD_TYPE=Debug<br />
pi@raspberrypi:~/project/mjpg-streamer/mjpg-streamer-experimental $ sudo make install<br />
pi@raspberrypi:~/project/mjpg-streamer/mjpg-streamer-experimental $ cd<br />
pi@raspberrypi:~ $</p>
<p>8. 캠으로부터 캡처한 영상을 HTTP 포트 8090으로 스트리밍<br />
pi@raspberrypi:~ $ mjpg_streamer -i &#8220;input_uvc.so&#8221; -o &#8220;output_http.so -p 8090 -w /usr/local/share/mjpg-streamer/www/&#8221;</p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p><strong> Python &#8211; 라즈베리파이와 적외선센서연동</strong></p>
<p>터미널창에서 state_Value 라는 파이썬 파일 만들기<br />
nano state_Value.py</p>
<p>소스 코드 입력하기(sensor 값 최소 최대설정)<br />
import Rpi.GPIO as GPIO<br />
import time</p>
<p>IR = 7<br />
GPIOIN = 17<br />
GPIOOUT = 27</p>
<p>GPOI.setmode(GPIO.BCM)<br />
print (&#8221; motion detection start&#8221;)</p>
<p>GPIO.setup(IR, GPIO.IN)<br />
try:</p>
<p>저장후 명령어 python state_Value.py 로 코드 실행<br />
nano state Value.py<br />
python state_Value.py</p>
</div>
<div class="symple-box yellow none" style="text-align:left; width:100%;"> 
<p><strong>Visaul Studio 2017(4족 보행로봇 제어)</strong><br />
// QuadrupedRobotControlDlg.cpp: 구현 파일<br />
//</p>
<p>#include &#8220;stdafx.h&#8221;<br />
#include &#8220;QuadrupedRobotControl.h&#8221;<br />
#include &#8220;QuadrupedRobotControlDlg.h&#8221;<br />
#include &#8220;afxdialogex.h&#8221;</p>
<p>#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#endif<br />
// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.</p>
<p>class CAboutDlg : public CDialogEx<br />
{<br />
public:<br />
CAboutDlg();</p>
<p>// 대화 상자 데이터입니다.<br />
#ifdef AFX_DESIGN_TIME<br />
enum { IDD = IDD_ABOUTBOX };<br />
#endif</p>
<p>protected:<br />
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.</p>
<p>// 구현입니다.<br />
protected:<br />
DECLARE_MESSAGE_MAP()<br />
};</p>
<p>CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)<br />
{<br />
}</p>
<p>void CAboutDlg::DoDataExchange(CDataExchange* pDX)<br />
{<br />
CDialogEx::DoDataExchange(pDX);<br />
}</p>
<p>BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)<br />
END_MESSAGE_MAP()</p>
<p>// CQuadrupedRobotControlDlg 대화 상자</p>
<p>CQuadrupedRobotControlDlg::CQuadrupedRobotControlDlg(CWnd* pParent /*=nullptr*/)<br />
: CDialogEx(IDD_QUADRUPEDROBOTCONTROL_DIALOG, pParent)<br />
, m_str_comport(_T(&#8220;&#8221;))<br />
, m_str_baudrate(_T(&#8220;&#8221;))<br />
, m_Motor0(90)<br />
, m_Motor1(90)<br />
, m_Motor2(90)<br />
, m_Motor3(90)<br />
, m_Motor4(90)<br />
, m_Motor5(90)<br />
, m_Motor6(90)<br />
, m_Motor7(90)<br />
, m_Motor8(90)<br />
, m_Motor9(90)<br />
, m_Motor10(90)<br />
, m_Motor11(90)<br />
, m_Motion_Sleep(0)<br />
, m_iExecIndex(0)<br />
, m_StepDelay(0)<br />
, m_MotionCommand(_T(&#8220;&#8221;))<br />
{<br />
m_hIcon = AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME);<br />
}</p>
<p>void CQuadrupedRobotControlDlg::DoDataExchange(CDataExchange* pDX)<br />
{<br />
CDialogEx::DoDataExchange(pDX);<br />
DDX_Control(pDX, IDC_COMBO_COMPORT, m_combo_comport_list);<br />
DDX_Control(pDX, IDC_COMBO_BAUDRATE, m_combo_baudrate_list);<br />
DDX_CBString(pDX, IDC_COMBO_COMPORT, m_str_comport);<br />
DDX_CBString(pDX, IDC_COMBO_BAUDRATE, m_str_baudrate);<br />
DDX_Control(pDX, IDC_EDIT_RCV_VIEW, m_edit_rcv_view);<br />
DDX_Control(pDX, IDC_EDIT_RCV_DATA, m_edit_rcv_data);<br />
DDX_Text(pDX, IDC_MOTOR0, m_Motor0);<br />
DDX_Text(pDX, IDC_MOTOR1, m_Motor1);<br />
DDX_Text(pDX, IDC_MOTOR2, m_Motor2);<br />
DDX_Text(pDX, IDC_MOTOR3, m_Motor3);<br />
DDX_Text(pDX, IDC_MOTOR4, m_Motor4);<br />
DDX_Text(pDX, IDC_MOTOR5, m_Motor5);<br />
DDX_Text(pDX, IDC_MOTOR6, m_Motor6);<br />
DDX_Text(pDX, IDC_MOTOR7, m_Motor7);<br />
DDX_Text(pDX, IDC_MOTOR8, m_Motor8);<br />
DDX_Text(pDX, IDC_MOTOR9, m_Motor9);<br />
DDX_Text(pDX, IDC_MOTOR10, m_Motor10);<br />
DDX_Text(pDX, IDC_MOTOR11, m_Motor11);<br />
DDX_Control(pDX, IDC_EDIT_MOTION_COMMAND, m_Edit_Motion_Command);<br />
DDX_Text(pDX, IDC_MOTION_SLEEP, m_Motion_Sleep);<br />
DDX_Text(pDX, IDC_INDEX, m_iExecIndex);<br />
DDX_Text(pDX, IDC_EDIT_STEPDELAY, m_StepDelay);<br />
DDX_Text(pDX, IDC_EDIT_MOTION_COMMAND, m_MotionCommand);<br />
}</p>
<p>BEGIN_MESSAGE_MAP(CQuadrupedRobotControlDlg, CDialogEx)<br />
ON_WM_SYSCOMMAND()<br />
ON_WM_PAINT()<br />
ON_WM_QUERYDRAGICON()<br />
ON_MESSAGE(WM_MYCLOSE, &amp;CQuadrupedRobotControlDlg::OnThreadClosed)<br />
ON_MESSAGE(WM_MYRECEIVE, &amp;CQuadrupedRobotControlDlg::OnReceive)<br />
ON_BN_CLICKED(IDC_BT_CONNECT, &amp;CQuadrupedRobotControlDlg::OnBnClickedBtConnect)<br />
ON_BN_CLICKED(IDC_BT_CLEAR, &amp;CQuadrupedRobotControlDlg::OnBnClickedBtClear)<br />
ON_CBN_SELCHANGE(IDC_COMBO_COMPORT, &amp;CQuadrupedRobotControlDlg::OnCbnSelchangeComboComport)<br />
ON_CBN_SELCHANGE(IDC_COMBO_BAUDRATE, &amp;CQuadrupedRobotControlDlg::OnCbnSelchangeComboBaudrate)<br />
ON_BN_CLICKED(IDC_BT_SEND, &amp;CQuadrupedRobotControlDlg::OnBnClickedBtSend)<br />
ON_BN_CLICKED(IDC_BT_MOTION, &amp;CQuadrupedRobotControlDlg::OnBnClickedBtMotion)<br />
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_MOTION, &amp;CQuadrupedRobotControlDlg::OnDeltaposSpinMotion)<br />
ON_BN_CLICKED(IDC_BT_EXECUTION, &amp;CQuadrupedRobotControlDlg::OnBnClickedBtExecution)<br />
ON_BN_CLICKED(IDC_BT_CONT_EXECUTION, &amp;CQuadrupedRobotControlDlg::OnBnClickedBtContExecution)<br />
ON_BN_CLICKED(IDC_BT_SEND2, &amp;CQuadrupedRobotControlDlg::OnBnClickedBtSend2)<br />
ON_BN_CLICKED(IDC_OPEN, &amp;CQuadrupedRobotControlDlg::OnBnClickedOpen)<br />
ON_BN_CLICKED(IDC_LOAD, &amp;CQuadrupedRobotControlDlg::OnBnClickedLoad)<br />
END_MESSAGE_MAP()</p>
<p>// CQuadrupedRobotControlDlg 메시지 처리기</p>
<p>BOOL CQuadrupedRobotControlDlg::OnInitDialog()<br />
{<br />
CDialogEx::OnInitDialog();</p>
<p>// 시스템 메뉴에 &#8220;정보&#8230;&#8221; 메뉴 항목을 추가합니다.</p>
<p>// IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.<br />
ASSERT((IDM_ABOUTBOX &amp; 0xFFF0) == IDM_ABOUTBOX);<br />
ASSERT(IDM_ABOUTBOX &lt; 0xF000);</p>
<p>CMenu* pSysMenu = GetSystemMenu(FALSE);<br />
if (pSysMenu != nullptr)<br />
{<br />
BOOL bNameValid;<br />
CString strAboutMenu;<br />
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);<br />
ASSERT(bNameValid);<br />
if (!strAboutMenu.IsEmpty())<br />
{<br />
pSysMenu-&gt;AppendMenu(MF_SEPARATOR);<br />
pSysMenu-&gt;AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);<br />
}<br />
}</p>
<p>// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는<br />
// 프레임워크가 이 작업을 자동으로 수행합니다.<br />
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.<br />
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.</p>
<p>// TODO: 여기에 추가 초기화 작업을 추가합니다.<br />
m_combo_comport_list.AddString(_T(&#8220;COM1&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM2&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM3&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM4&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM7&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM9&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM10&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM13&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM14&#8243;));<br />
m_combo_comport_list.AddString(_T(&#8220;COM16&#8243;));</p>
<p>m_combo_baudrate_list.AddString(_T(&#8220;1200&#8243;));<br />
m_combo_baudrate_list.AddString(_T(&#8220;9600&#8243;));<br />
m_combo_baudrate_list.AddString(_T(&#8220;19200&#8243;));<br />
m_combo_baudrate_list.AddString(_T(&#8220;38400&#8243;));<br />
m_combo_baudrate_list.AddString(_T(&#8220;115200&#8243;));</p>
<p>comport_state = false;<br />
GetDlgItem(IDC_BT_CONNECT)-&gt;SetWindowText(_T(&#8220;OPEN&#8221;));<br />
m_str_comport = _T(&#8220;COM7&#8243;);<br />
m_str_baudrate = _T(&#8220;9600&#8243;);<br />
m_iExecIndex=iExecindex = 0;<br />
m_StepDelay = 500;</p>
<p>UpdateData(FALSE);</p>
<p>return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.<br />
}</p>
<p>void CQuadrupedRobotControlDlg::OnSysCommand(UINT nID, LPARAM lParam)<br />
{<br />
if ((nID &amp; 0xFFF0) == IDM_ABOUTBOX)<br />
{<br />
CAboutDlg dlgAbout;<br />
dlgAbout.DoModal();<br />
}<br />
else<br />
{<br />
CDialogEx::OnSysCommand(nID, lParam);<br />
}<br />
}</p>
<p>// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면<br />
// 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는<br />
// 프레임워크에서 이 작업을 자동으로 수행합니다.</p>
<p>void CQuadrupedRobotControlDlg::OnPaint()<br />
{<br />
if (IsIconic())<br />
{<br />
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.</p>
<p>SendMessage(WM_ICONERASEBKGND, reinterpret_cast&lt;WPARAM&gt;(dc.GetSafeHdc()), 0);</p>
<p>// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.<br />
int cxIcon = GetSystemMetrics(SM_CXICON);<br />
int cyIcon = GetSystemMetrics(SM_CYICON);<br />
CRect rect;<br />
GetClientRect(&amp;rect);<br />
int x = (rect.Width() &#8211; cxIcon + 1) / 2;<br />
int y = (rect.Height() &#8211; cyIcon + 1) / 2;</p>
<p>// 아이콘을 그립니다.<br />
dc.DrawIcon(x, y, m_hIcon);<br />
}<br />
else<br />
{<br />
CDialogEx::OnPaint();<br />
}<br />
}</p>
<p>// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서<br />
// 이 함수를 호출합니다.<br />
HCURSOR CQuadrupedRobotControlDlg::OnQueryDragIcon()<br />
{<br />
return static_cast&lt;HCURSOR&gt;(m_hIcon);<br />
}</p>
<p>LRESULT CQuadrupedRobotControlDlg::OnThreadClosed(WPARAM length, LPARAM lpara)<br />
{<br />
// overlapped i/o 핸들을 닫는다<br />
((Ccomm*)lpara)-&gt;HandleClose();<br />
delete ((Ccomm*)lpara);</p>
<p>return 0;<br />
}</p>
<p>LRESULT CQuadrupedRobotControlDlg::OnReceive(WPARAM length, LPARAM lpara)<br />
{<br />
CString str;<br />
char data[20000];<br />
if (m_comm)<br />
{<br />
m_comm-&gt;Receive(data, length); // length 길이 만큼 데이터를 받는다.<br />
data[length] = _T(&#8221;);</p>
<p>for (int i = 0; i &lt; length; i++)<br />
{<br />
str += data[i];<br />
}<br />
m_edit_rcv_view.ReplaceSel(str); // 에디터 박스에 표시하기 위함<br />
str = _T(&#8220;&#8221;);<br />
m_edit_rcv_view.LineScroll(m_edit_rcv_view.GetLineCount()); // 화면이 넘어가면 우측 스크롤을 맨 아래로 내려 주는 역할<br />
}<br />
return 0;<br />
}<br />
void CQuadrupedRobotControlDlg::OnBnClickedBtConnect()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
if (!comport_state) // Comport가 없다면..<br />
{<br />
m_comm = new Ccomm(_T(&#8220;\\\\.\\&#8221;) + m_str_comport, m_str_baudrate,<br />
_T(&#8220;None&#8221;), _T(&#8220;8 Bit&#8221;), _T(&#8220;1 Bit&#8221;)); // initial Comm port</p>
<p>if (m_comm-&gt;Create(GetSafeHwnd()) != 0) // 통신 포트를 열고 윈도우의 핸들을 넘긴다.<br />
{<br />
AfxMessageBox(_T(&#8220;COM 포트열림&#8221;));<br />
comport_state = true;<br />
GetDlgItem(IDC_BT_CONNECT)-&gt;SetWindowText(_T(&#8220;CLOSE&#8221;));<br />
GetDlgItem(IDC_BT_SEND)-&gt;EnableWindow(true);<br />
}<br />
else<br />
{<br />
AfxMessageBox(_T(&#8220;ERROR!&#8221;));<br />
}<br />
}<br />
else<br />
{<br />
if (m_comm) // Comport가 존재하면..<br />
{<br />
m_comm-&gt;Close();<br />
m_comm = NULL;<br />
AfxMessageBox(_T(&#8220;COM 포트닫힘&#8221;));<br />
comport_state = false;<br />
GetDlgItem(IDC_BT_CONNECT)-&gt;SetWindowText(_T(&#8220;OPEN&#8221;));<br />
GetDlgItem(IDC_BT_SEND)-&gt;EnableWindow(false);<br />
}<br />
}</p>
<p>}<br />
void CQuadrupedRobotControlDlg::OnBnClickedBtClear()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
GetDlgItem(IDC_EDIT_RCV_VIEW)-&gt;SetWindowText(_T(&#8221; &#8220;));<br />
}<br />
void CQuadrupedRobotControlDlg::OnCbnSelchangeComboComport()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
UpdateData();<br />
}<br />
void CQuadrupedRobotControlDlg::OnCbnSelchangeComboBaudrate()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
UpdateData();<br />
}<br />
void CQuadrupedRobotControlDlg::OnBnClickedBtSend()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
CString str;<br />
int i;</p>
<p>GetDlgItem(IDC_EDIT_RCV_DATA)-&gt;GetWindowText(str);<br />
str += _T(&#8220;\r&#8221;);; //문장 뒤에 ’\r’ carriage return 을 붙여 명령 끝을 알린다.<br />
//m_comm-&gt;Send(str, str.GetLength());</p>
<p>char* ss = LPSTR(LPCTSTR(str)); //CString을 char 형으로 변환<br />
/*마이콤에서 해독하는 데 일정 시간이 소요되어 마치 키보드 입력처럼 명령사이에<br />
지연시간을 준다.<br />
또한 CString을 char로 변환시 하나의 문자가 2바이트로 변환되며 두번쨰는 비어있다.<br />
예로<br />
CString &#8220;2345: -&gt; &#8220;2&#8243;,&#8221;",&#8221;3&#8243;,&#8221;",&#8221;4&#8243;,&#8221;",&#8221;5&#8243;,&#8221;"<br />
*/</p>
<p>for (i = 0; i &lt; str.GetLength(); i++)<br />
{<br />
m_comm-&gt;Send(ss, 1);<br />
ss = ss + 2; //2 byte offset<br />
Sleep(5);<br />
}</p>
<p>}<br />
void CQuadrupedRobotControlDlg::OnBnClickedBtSend2()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
CString str;<br />
int i;</p>
<p>GetDlgItem(IDC_EDIT_RCV_DATA)-&gt;GetWindowText(str);</p>
<p>char* ss = LPSTR(LPCTSTR(str)); //CString을 char 형으로 변환<br />
for (i = 0; i &lt; str.GetLength(); i++)<br />
{<br />
m_comm-&gt;Send(ss, 1);<br />
ss = ss + 2; //2 byte offset<br />
Sleep(5);<br />
}<br />
}<br />
void CQuadrupedRobotControlDlg::OnBnClickedBtMotion()<br />
{<br />
int i;<br />
char buf[30];<br />
char * ss;<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
UpdateData(true); //read parameter</p>
<p>if (m_Motion_Sleep == 0) //Motion Command<br />
{<br />
buf[0] = &#8216;d&#8217;;<br />
buf[1] = m_Motor0;<br />
buf[2] = m_Motor1;<br />
buf[3] = m_Motor2;<br />
buf[4] = m_Motor3;<br />
buf[5] = m_Motor4;<br />
buf[6] = m_Motor5;<br />
buf[7] = m_Motor6;<br />
buf[8] = m_Motor7;<br />
buf[9] = m_Motor8;<br />
buf[10] = m_Motor9;<br />
buf[11] = m_Motor10;<br />
buf[12] = m_Motor11;<br />
buf[13] = &#8216;\r&#8217;;</p>
<p>ss = buf;<br />
for (i = 0; i &lt; 14; i++)<br />
{<br />
m_comm-&gt;Send(ss, 1);<br />
ss++;<br />
Sleep(5); //실험으로 정함 매우중요<br />
}<br />
}<br />
else //Sleep Command<br />
{<br />
buf[0] = &#8216;s&#8217;;<br />
buf[1] = m_Motion_Sleep;<br />
buf[2] = &#8216;\r&#8217;;<br />
ss = buf;<br />
for (i = 0; i &lt; 3; i++)<br />
{<br />
m_comm-&gt;Send(ss, 1);<br />
ss++;<br />
Sleep(5);<br />
}<br />
}<br />
//m_comm-&gt;Send((char *)buf, strlen((char *)buf));<br />
}</p>
<p>void CQuadrupedRobotControlDlg::OnDeltaposSpinMotion(NMHDR *pNMHDR, LRESULT *pResult)<br />
{<br />
LPNMUPDOWN pNMUpDown = reinterpret_cast&lt;LPNMUPDOWN&gt;(pNMHDR);<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
if (pNMUpDown-&gt;iDelta &gt; 0)<br />
{<br />
iExecindex&#8211;;<br />
if (iExecindex &lt; 0) iExecindex = 0;<br />
}<br />
else<br />
{<br />
iExecindex++;<br />
}<br />
m_iExecIndex = iExecindex;<br />
UpdateData(false);<br />
*pResult = 0;<br />
}<br />
/*<br />
CString -&gt; int 변환, int-&gt;CString 변환<br />
CString → int<br />
int형 = _ttoi(CString형);<br />
int → CString<br />
CString형.Format(_T(&#8220;%d&#8221;), int형);<br />
*/</p>
<p>void CQuadrupedRobotControlDlg::OnBnClickedBtExecution()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
CString str, strBuff;<br />
CString mCode;<br />
CString mMotor0, mMotor1, mMotor2, mMotor3, mMotor4, mMotor5, mMotor6, mMotor7, mMotor8, mMotor9, mMotor10, mMotor11, mSleep;</p>
<p>UpdateData(true); //read parameter</p>
<p>GetDlgItem(IDC_EDIT_MOTION_COMMAND)-&gt;GetWindowText(str);<br />
if (AfxExtractSubString(strBuff, str, m_iExecIndex, &#8216;\n&#8217;))<br />
{<br />
mCode = strBuff.Left(1);<br />
if (mCode.Compare(_T(&#8220;d&#8221;)) == 0)<br />
{<br />
AfxExtractSubString(mMotor0, strBuff, 1, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor1, strBuff, 2, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor2, strBuff, 3, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor3, strBuff, 4, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor4, strBuff, 5, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor5, strBuff, 6, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor6, strBuff, 7, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor7, strBuff, 8, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor8, strBuff, 9, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor9, strBuff, 10, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor10, strBuff, 11, &#8216;,&#8217;);<br />
AfxExtractSubString(mMotor11, strBuff, 12, &#8216;,&#8217;);<br />
m_Motor0 = _ttoi(mMotor0);<br />
m_Motor1 = _ttoi(mMotor1);<br />
m_Motor2 = _ttoi(mMotor2);<br />
m_Motor3 = _ttoi(mMotor3);<br />
m_Motor4 = _ttoi(mMotor4);<br />
m_Motor5 = _ttoi(mMotor5);<br />
m_Motor6 = _ttoi(mMotor6);<br />
m_Motor7 = _ttoi(mMotor7);<br />
m_Motor8 = _ttoi(mMotor8);<br />
m_Motor9 = _ttoi(mMotor9);<br />
m_Motor10 = _ttoi(mMotor10);<br />
m_Motor11 = _ttoi(mMotor11);<br />
m_Motion_Sleep = 0;<br />
}<br />
else if (mCode.Compare(_T(&#8220;s&#8221;)) == 0)<br />
{<br />
AfxExtractSubString(mSleep, strBuff, 1, &#8216;,&#8217;);<br />
m_Motion_Sleep = _ttoi(mSleep);<br />
}<br />
else<br />
{<br />
}<br />
m_iExecIndex++;<br />
}<br />
UpdateData(false);</p>
<p>OnBnClickedBtMotion();</p>
<p>//출처: https://bigmark.tistory.com/11 [마크의 맥시멈 라이프]
<p>}<br />
void CQuadrupedRobotControlDlg::OnBnClickedBtContExecution()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
CString str, strBuff;<br />
m_iExecIndex = 0;<br />
UpdateData(true); //read parameter</p>
<p>GetDlgItem(IDC_EDIT_MOTION_COMMAND)-&gt;GetWindowText(str);<br />
while(AfxExtractSubString(strBuff, str, m_iExecIndex, &#8216;\n&#8217;))<br />
{<br />
OnBnClickedBtExecution();<br />
Sleep(m_StepDelay);<br />
}<br />
m_iExecIndex = 0;<br />
UpdateData(false);</p>
<p>}<br />
void CQuadrupedRobotControlDlg::OnBnClickedOpen()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
CString m_strStatus,tmp;<br />
CString m_strPath;<br />
CStdioFile file;<br />
// CFile file;<br />
CFileException ex;<br />
CFileDialog dlg(TRUE, _T(&#8220;*.txt&#8221;), NULL, OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT, _T(&#8220;Motion Files(*.txt)|*.txt|&#8221;), NULL);<br />
if (dlg.DoModal() == IDOK)<br />
{<br />
m_strPath = dlg.GetPathName();<br />
if (m_strPath.Right(4) != &#8220;.txt&#8221;)<br />
{<br />
m_strPath += &#8220;.txt&#8221;;<br />
}<br />
file.Open(m_strPath, CFile::modeRead, &amp;ex);</p>
<p>while (file.ReadString(tmp))<br />
m_MotionCommand += tmp + _T(&#8220;\n&#8221;);<br />
file.Close();<br />
//http://blog.naver.com/PostView.nhn?blogId=kan0909&amp;logNo=90138161650<br />
UpdateData(false);<br />
}<br />
}<br />
void CQuadrupedRobotControlDlg::OnBnClickedLoad()<br />
{<br />
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.<br />
CString m_strStatus;<br />
CString m_strPath;<br />
CStdioFile file;</p>
<p>// CFile file;<br />
CFileException ex;<br />
CFileDialog dlg(FALSE, _T(&#8220;*.txt&#8221;), NULL, OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT, _T(&#8220;Motion Files(*.txt)|*.txt|&#8221;), NULL);<br />
if (dlg.DoModal() == IDOK)<br />
{<br />
m_strPath = dlg.GetPathName();<br />
if (m_strPath.Right(4) != &#8220;.txt&#8221;)<br />
{<br />
m_strPath += &#8220;.txt&#8221;;<br />
}<br />
file.Open(m_strPath, CFile::modeCreate | CFile::modeReadWrite | CFile::modeRead, &amp;ex);</p>
<p>GetDlgItem(IDC_EDIT_MOTION_COMMAND)-&gt;GetWindowText(m_strStatus);</p>
<p>file.WriteString(m_strStatus);<br />
file.Close();<br />
}<br />
}</p>
</div>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/40660/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
