IoT 강의자료

TOP

IoT (사물인터넷)

Internet Of ThingsIOT / 사물인터넷

IOT (사물인터넷)는 각종 센서와 사물에 통신 기능을 내장하여 인터넷에 연결하는 기술을 의미합니다.
예를 들어, 스마트폰을 활용하여 집안이 아닐 때에 집안의 조명을 켜거나 끄고 추운 겨울날 퇴근 후 집에 오는 동안에 스마트폰으로 미리 집안의 보일러를 켜놓는 등이 대표적인 IOT의 활용 사례라고 볼 수 있습니다.
이번 아두이노 RC카 만들기 프로젝트 또한 IOT를 활용한 사례라고 볼 수 있습니다.

아두이노 RC카

아두이노 RC카는 다음과 같은 기능을 가지고 있습니다.

  1. 01언제 어디서든 전원과 인터넷만 된다면 작동 가능

    RC카를 직접 인터넷에 연결시켜서 동작시키기 때문에 배터리가 충분하고 인터넷 접속이 가능하다면 언제 어디서든 원거리에서도 컨트롤 및 데이터를 받아올 수 있습니다.

  2. 02스마트폰 앱을 활용해 컨트롤

    번거롭게 전용 리모트 컨트롤을 사용하지 않고 스마트폰 앱으로 쉽게 컨트롤할 수 있습니다.

  3. 03RC카에 부착된 카메라의 영상을 앱으로 확인

    스마트폰 앱에서 언제 어디서든 RC카에 부착된 카메라의 실시간 영상을 확인할 수 있습니다.

  4. 04RC카에 부착된 센서의 데이터를 앱으로 확인

    스마트폰 앱에서 언제 어디서든 RC카에 부착된 센서들(온도 및 습도, 조도, 초음파)의 데이터를 확인할 수 있습니다.

하드웨어 구성

아두이노 RC카 만들기 키트는 여러 하드웨어 부품으로 구성되어 있습니다.
각각 크기와 용도가 다르니 주의하세요.

아두이노, 쉴드

센서

입출력

전원

구동

차체

기타

소프트웨어 구성

아두이노 RC카 만들기 프로젝트에서 사용하는 플랫폼은 크게 2가지로 볼 수 있습니다.
하나는 RC카 자체를 프로그래밍 하기 위한 아두이노와, 나머지 하나는 RC카를 컨트롤하기 위한 안드로이드입니다.

조립 방법

소프트웨어 적용

조립이 완료되었으니 작동을 시키기 위해 프로그램을 작성해보겠습니다.
소프트웨어 구성 항목에서 이야기한 바와 같이 이번 아두이노 RC카 만들기 프로젝트에서 프로그램은 크게 두가지로 나뉘어지며, 아두이노부터 살펴보도록 하겠습니다.

아두이노 프로그램

아두이노 스케치를 작성하고 업로드하기 위하여 아두이노 IDE를 설치해 보겠습니다.

우선, 아두이노 홈페이지에 접속하고, 상단 메뉴에서 "Download"를 클릭합니다.


그리고, 본인의 현재 운영체제에 맞는 버전을 클릭합니다.


그 다음 화면에서 기부 금액을 선택하는 화면이 나오는데,
"JUST DOWNLOAD"를 클릭하여 설치 프로그램을 다운받은 후 설치를 진행합니다.


설치가 끝나고 아두이노 프로그램을 실행시켰을 때 빈 스케치가 생성되면 정상적으로 설치된 것입니다.

이제 RC카에 적용될 아두이노 스케치를 작성해보겠습니다.
아두이노 IDE를 실행하고, 빈 스케치를 생성합니다.

아두이노 RC카의 기능은 크게 4가지로 나눌 수 있습니다.

1) RC카 움직이기 (앞, 뒤, 좌, 우)
2) 카메라 움직이기 (상,중,하)
3) 센서로 데이터 측정하기(온습도, 초음파, 조도)
4) 카메라 영상 스트리밍

이 중 4)카메라 영상 스트리밍은 YUN쉴드에서 설정하여 구현하고,아두이노 스케치에서는 1 ~ 3번을 진행합니다.
본 자료에서는 전체 코드 중 특정 부분을 발췌합니다.

1) 초기 설정하기

//YUN 쉴드를 통해 들어온 명령어 처리를 위한 변수
						byte serialIn = 0;
						byte commandAvailable = false;
						String strReceived = "";
						YunServer server;

						// RC카 구동을 위한 변수
						AF_DCMotor motor1(1, MOTOR12_64KHZ);// 1번모터 객체 생성,속도 64KHz pwm (L293D 에서 좌측 모터 2개 통제)
						AF_DCMotor motor2(2, MOTOR12_64KHZ);// 2번모터 객체 생성,속도 64KHz pwm (L293D 에서 우측 모터 2개 통제)
						Servo myservo1;  //카메라 상하 운동 서보 모터
						int cpos=90; // 서보모터 각도값

						// 센서들을 위한 변수
						int echoPin = 6; // 초음파센서 발신부
						int trigPin = 7; // 초음파센서 수신부

						int dhtpin = 11; //온습도센서
						DHT11 dht11(dhtpin);

						int lightPin = 0; // 조도센서

						void setup(){
							server.begin(); // YUN 쉴드에서 명령을 대기함

							motor1.setSpeed(200);// 초기 모터 속도 설정,200~255중 임의 조정(두개의 모터속도가 같으면 된다.)
							motor2.setSpeed(200);
							myservo1.attach(10,1000,2000); // 카메라 조정 서보모터 설정
						}
					


1) 명령 구분하기
					void loop(){
						YunClient client = server.accept(); // 인터넷을 통해 보내진 명령을 체크한다
						if (client) { // 명령이 있다면
							process(client); //처리하는 함수로 전달
							client.stop(); // 연결을 해제한다
						 }
						 delay(50); // 50ms마다 명령을 체크한다.
					}

					// loop()에서 명령 발생시 처리하는 함수
					void process(YunClient client) {
						String command = client.readStringUntil('@'); // 전달된 명령에서 "@"기호 전까지의 String을 읽어 저장한다.
						processCommand(command, client); // 명령을 실제로 처리하는 함수로 넘김.
					}
					


2) 명령 처리하기
					 // process(YunClient client)에서 명령을 받아 실제로 처리하는 함수
					 void processCommand(String input,YunClient client)
					 {
						String command = input; //넘어온 명령을 command라는 String 변수에 저장한다.

						if (command == "MF")  //명령이 MF라면(전진)
						{
							motor1.run(FORWARD); // 모터 1을 앞으로
							motor2.run(FORWARD); // 모터 2를 앞으로
						}
						else if (command == "MB") //명령이 MB라면(후진)
						{
							motor1.run(BACKWARD);// 모터 1을 뒤로
							motor2.run(BACKWARD);// 모터 2를 뒤로
						}
						else if (command == "ML")  //명령이 ML이라면(좌측)
						{
							motor1.run(BACKWARD);// 모터 1을 뒤로
							motor2.run(FORWARD);// 모터 2를 앞으로
						}
						else if (command == "MR") //명령이 MR이라면(우측)
						{
							motor1.run(FORWARD);// 모터 1을 앞으로
							motor2.run(BACKWARD);// 모터 2를 뒤로
						}
						else if (command == "MS")  //명령이 MS라면(정지)
						{
							motor1.run(RELEASE); //모터 1 정지
							motor2.run(RELEASE); //모터 2 정지
						}
						else if (command == "C_U") // 명령이 C_U라면(카메라 위로)
						{
							cpos=cpos+5; // 현재 각도값 + 5
							myservo1.write(cpos); //서보모터 조정
						}
						else if (command == "C_D") // 명령이 C_D라면(카메라 아래로)
						{
							cpos=cpos-5; // 현재 각도값 - 5
							myservo1.write(cpos); // 서보모터 조정
						}
						else if (command == "C_C") // 명령이 C_C라면(카메라 중앙)
						{
							cpos=90; // 현재 각도값을 90으로 지정
							myservo1.write(cpos); // 서보모터 지정
						}
						else if(command == "status") // 명령이 status라면(센서값)
						{
							float duration, distance; // 초음파 거리값과 시간값을 저장할 변수
							digitalWrite(trigPin, HIGH); // 초음파 신호 전송
							delay(10); // 10ms 간 전송
							digitalWrite(trigPin, LOW); // 전송 중지

							duration = pulseIn(echoPin, HIGH);  // 초음파 신호 수신까지 걸린 시간 저장
							distance = ((float)(340 * duration) / 1000000) / 2;  // 시간을 활용해서 실제 거리 계산(m)

							int err; // 온습도 계산시 에러 발생한 경우 사용
							float temp, humi; // 온도, 습도값 저장할 변수
							if((err=dht11.read(humi, temp))==0){}  // 온도, 습도값을 측정해서 저장, 만약 값이 0이라면 넘어감

							int lightVal; // 조도값을 저장할 변수
							lightVal = analogRead(lightPin); // 조도값 측정 후 저장

							// 지금까지 얻은 데이터를 json 형식으로 가공해서 웹에 표시한다.
							client.print("[{\'distance\':\'");
							client.print(distance);
							client.print("m\',\'temperature\':\'");
							client.print(temp);
							client.print("\',\'humidity\':\'");
							client.print(humi);
							client.print("\',\'light\':\'");
							client.print(lightVal,DEC);
							client.print("\'}]");
						}
					 }
					


본 코드 외에도 위의 링크를 통해 전체 코드를 복사, 혹은 다운로드 받은 후에
보드로 업로드하시면 이 코드들이 보드에 적용됩니다.

업로드 하는 방법은 여기에 "보드에 스케치 업로드 하기"부분을 확인하세요.

조립된 RC카에 배터리를 연결하면, YUN 쉴드 우측에 주황색 LED가 들어오게 됩니다.
2개의 주황색 LED가 들어온 후 잠시 기다리면, 와이파이 목록에 "iduino-xxxxxx"라는 와이파이 존이 생기는 것을 확인할 수 있습니다.

노트북 혹은 스마트폰 등으로 그 와이파이에 접속한 후, 주소창에 192.168.240.1을 입력하여 와이파이 관리용 웹페이지로 접속합니다.
최초 패스워드는 iduino입니다.



일반적인 가정용 공유기 관리 페이지와 거의 비슷한 역할을 하는 페이지로, 우측 상단의 "SYSTEM"을 눌러 시스템 관리 페이지로 접속합니다.
이 페이지에서는 와이파이 이름과 비밀번호, Rest API Acess 등을 수정할 수 있습니다.
페이지의 중간정도에 WIRELESS PARAMETERS 부분에서
CONFIGURE A WIRELESS NETWORK 옵션을 선택하고, DETECTED WIRELESS NETWORKS 부분에서 RC카를 접속시킬 와이파이를 선택합니다.
선택 후 보안 방식(SECURITY)과 비밀번호(PASSWORD)를 입력하고,
하단 REST API ACCESS 부분을 OPEN으로 설정하고 CONFIGURE & RESTART 버튼을 눌러 적용하면 YUN 쉴드가 자동으로 재부팅되며
방금 선택한 네트워크에 자동으로 접속합니다.

이전 단계에서 RC카의 YUN 쉴드를 자신이 선택한 와이파이에 접속시켰다면, 이제 본인의 와이파이에서 RC카에 할당된 IP를 확인해야 합니다.
각 공유기 회사별로 관리자 페이지에 접속해서 RC카에 부여된 IP를 확인합니다.
RC카에 부여된 IP를 확인하고 나면 해당 IP를 그 공유기에 접속된 다른 기기에서 브라우저를 통해 열어보고,
3번에서 진행한 설정 페이지가 나온다면 정상적으로 확인한 것입니다.

* 공유기 내부ip 확인법

YUN 쉴드는 OpenWRT라는 무선랜 라우터를 위한 리눅스 기반의 오픈소스 운영 체제를 가지고 있습니다.
따라서 리눅스에 ssh 등으로 접속하여 여러 설정, 패키지 설치 등의 작업이 가능합니다.

웹캠 스트리밍을 사용하기 위해서는 스트리밍이 가능하게 하는 여러 패키지들을 리눅스에 설치하고 설정을 해주어야 합니다.
우선 YUN 쉴드가 공유기에 잘 접속되있는 것을 확인하고, 해당 공유기에 접속된 다른 PC에서 리눅스에 접속을 해보도록 하겠습니다.

1) Windows 운영체제인 경우
원격으로 리눅스에 접속하기 위하여 PUTTY라는 프로그램을 사용합니다.



PUTTY 홈페이지에 들어가면 다음과 같이 여러 종류가 있는데,
그 중 목록에서 가장 상단에 있는 putty.exe를 눌러 프로그램을 다운로드 받고 실행합니다. (따로 설치가 진행되지 않습니다.)



실행된 프로그램에서 상단 Host Name(or IP address) 부분에 4단계에서 확인한 RC카 IP 주소를 적고, Port는 22로,
Connection type을 SSH로 설정한 후에 하단 우측에 Open 버튼을 클릭합니다.

그림과 같이 dos창이 하나 뜨고 잠시 기다리면 "login as : " 라는 메시지가 표시됩니다.
root를 적고 엔터를 누르면, 패스워드를 입력하라는 메시지가 나오고 iduino를 입력하고 엔터를 누릅니다.
(패스워드는 화면에 표시되지 않는것이 정상입니다.)



다음과 같은 화면이 나오면 정상적으로 접속된 것입니다.

이제 웹캠 스트리밍을 위한 패키지를 설치해보도록 하겠습니다.
우선, 패키지 설치에 앞서 이미 설치된 패키지들의 업데이트를 진행하고, 스트리밍을 위한 패키지들을 설치하겠습니다.

						root@iduino:~# opkg update
						root@iduino:~# opkg install kmod-video-uvc
						root@iduino:~# opkg install fswebcam
						


여기까지 kmod-video-uvc라는 패키지와 fswebcam이라는 패키지가 설치되었고,
이번에는 폴더를 제작하고 해당 폴더에 mjpg-streamer이라는 패키지를 설치해 보도록 하겠습니다.

						root@iduino:~# cd /www
						root@iduino:~# mkdir webcam
						root@iduino:~# cd /www/webcam
						root@iduino:~# opkg install mjpg-streamer
						


이제 웹캠 스트리밍을 위한 패키지는 모두 설치하였고,
공유기 부팅시 자동으로 웹캠 스트리밍이 시작되도록 설정해 보겠습니다.

						root@iduino:~# vi /etc/rc.local
						// 부팅시 자동으로 실행되게 하는 설정파일인 rc.local file을 엽니다.
						


						# Put your custom commands here that should be executed once
						# the system init finished. By default this file does nothing.

						mjpg_streamer -i "input_uvc.so -d /dev/video0 -y -f 20 -r 320x480" -o "output_http.so"
						// 이 줄을 추가합니다.
						exit 0

						//esc를 누르고, :wq 를 눌러서 저장하고 나옵니다.
						


공유기 부팅시 자동으로 웹캠 스트리밍이 시작되도록 설정하였습니다.

방금 입력했던 mjpg_streamer -i "input_uvc.so -d /dev/video0 -y -f 20 -r 320x480" -o "output_http.so" 에서,
-f는 프레임을 의미하고 -r은 해상도를 의미합니다.
각자가 원하는 사이즈와 해상도로 설정해도 무관하나 너무 고해상도, 혹은 높은 프레임의 경우에는 끊김 등의 문제가 발생할 수 있으니 주의하세요.

이제 RC카의 전원을 잠시 끄고, 다시 배터리를 연결한 후 잠시 부팅을 기다리고 난 후부터는
http://RC카의 공유기 내부 아이피:8080/?action=stream 을 브라우저로 들어가면 카메라에서 나오는 영상의 스트리밍을 확인할 수 있습니다.

지금까지 진행한 작업은 내부 네트워크(공유기)를 통해서만 명령 전달, 처리, 웹캠 스트리밍 등이 가능하지만
언제 어디서든 인터넷이 연결된다면 RC카를 제어하고 웹캠 스트리밍을 확인할 수 있도록 하기 위하여
외부에서 네트워크를 통해 RC카에 접속할 수 있도록 설정해야 합니다.

공유기는 하나의 외부 IP를 가지고 있고, 공유기에 접속된 기기들에게 내부 IP를 할당시켜주는 방식으로 작동되고 있습니다.
외부에서 특정한 기기에 네트워크로 접속하려고 한다면, 공유기가 가지고 있는 외부 IP에 접근 후 공유기를 통해 기기의 내부 IP를 찾아 접속해야 합니다.
고정 IP에 접근을 할 때 접속하고자 하는 특정 기기에 대한 정보를 담아서 접속을 해야 공유기에서 최종적으로 원하는 기기로 접속을 시켜 주는데,
이때 특정 기기를 판별하는 조건이 "포트"입니다.

각 공유기 관리 페이지에는 "포트 포워딩"이라는 기능이 있으며,
포트 포워딩이란 외부 IP와 함께 들어온 특정한 포트 번호를 각 특정 내부 IP로 매핑하는 기능을 의미합니다.
따라서 언제 어디서든 RC카를 제어하고 웹캠 스트리밍을 보려면 RC카의 IP에 포트 포워딩을 적용하고,
접속시 외부 IP와 설정한 포트번호를 함께 사용해서 언제 어디서든 외부 IP를 통해 접속시킬 수 있도록 합니다.

포트 포워딩은 "외부 포트"와 "내부 포트", 그리고 "내부 IP"를 설정하게 되어 있습니다.
여기서 "외부 포트"란 외부 IP와 함께 사용될 포트 번호를,
"내부 포트"란 특정 기기 내부에서 사용하는 포트를 의미합니다.
그리고 "내부 IP"란 공유기에서 특정 기기에 할당한 IP를 의미합니다.

예를 들어, 5번 항목에서 웹캠 스트리밍을 확인하기 위한 링크는
http://RC카의 공유기 내부 아이피:8080/?action=stream 였고,
외부 IP가 1.1.1.1이며, 원하는 외부 포트 번호가 1111이라고 가정하고
웹캠 스트리밍에 포트 포워딩을 적용한다면

여기서 외부 포트는 1111, 내부 포트는 8080, 내부 IP는 1.1.1.1로,
적용하게 되면 http://1.1.1.1:1111/?action=stream 을 통해 언제 어디서든 웹캠 스트리밍을 확인할 수 있습니다.

RC카를 위해 적용해야 할 포트 포워딩은 2가지로,
첫번째는 RC카 명령을 전달할 포트, 이 경우 내부 포트는 80, 내부 IP는 3번 항목에서 확인한 IP입니다.
두번째는 웹캠 스트리밍을 확인할 포트, 이 경우 내부 포트는 위와 같이 8080, 내부 IP는 3번 항목에서 확인한 IP입니다.

공유기에서 포트포워딩 설정하는 방법

외부 IP 확인하는 방법

안드로이드 앱

두번째로, 지금까지 RC카를 제작하고 아두이노에 들어갈 스케치와 기타 처리를 해 주었으니 RC카를 제어할 안드로이드 앱에 대해서 살펴보겠습니다.

안드로이드

아두이노에서 스케치를 위해 아두이노 IDE를 설치했던 것처럼 안드로이드에서도 안드로이드 앱을 개발하기 위해 안드로이드 스튜디오를 설치해야 합니다.
하단의 링크를 참조해서 안드로이드 스튜디오 설치를 진행해주세요.

안드로이드 스튜디오 설치 링크 안드로이드 스튜디오 설치 방법

안드로이드 스튜디오 설치가 완료되었다면, 안드로이드 스튜디오를 실행하고, 프로젝트를 불러옵니다.
(불러오는 방법)

RC카 앱의 기능은 크게 4가지로 나눌 수 있습니다.

1) RC카 움직이기 (앞, 뒤, 좌, 우)
2) 카메라 움직이기 (상,중,하)
3) 측정된 센서 데이터 확인(온습도, 초음파, 조도)
4) 카메라 영상 스트리밍 보기

본 자료에서는 전체 코드 중 특정 부분을 발췌하며, 전체 아두이노 스케치는 이곳 에서 다운로드 받으세요.
코드상에 http://1.1.1.1:포트번호 부분은 위에서 본인이 확인하고 지정한 IP와 포트번호로 변경해주세요.

1) UI 구성하기
					...
					
					...

					

						

							
						

						

							
						

						

							
						

						

							
						

					
					

					...

					  
						
						

							

							
							

								
							

							

						

						

							
							

								
							

							
							

								
							

							
							

								
							

						
					

					...

						
						

							
						

							
						

							
						

							
						

							
						

							
						

					


				


2) 초기 설정하기
	 private ImageButton btnForward;//앞
		private ImageButton btnBack;//뒤
		private ImageButton btnLeft;//좌
		private ImageButton btnRight;//우

		//카메라 서보 모터
		private ImageButton cbtnU;//위로
		private ImageButton cbtnD;//아래로
		private ImageButton cbtnM;//중앙

		private WebView videoview;
		private WebView commandView;

		private TextView temp_tv, humi_tv, distance_tv, light_tv;

					...

				   videoview = (WebView) findViewById(R.id.yun_webview);
			videoview.getSettings().setLoadWithOverviewMode(true);
			videoview.getSettings().setUseWideViewPort(true);
			videoview.getSettings().setJavaScriptEnabled(true);

			commandView = (WebView) findViewById(R.id.commandView);

			btnForward = (ImageButton) findViewById(R.id.f_b);
			btnBack = (ImageButton) findViewById(R.id.b_b);
			btnLeft = (ImageButton) findViewById(R.id.l_b);
			btnRight = (ImageButton) findViewById(R.id.r_b);

			cbtnU = (ImageButton) findViewById(R.id.u_b);
			cbtnD = (ImageButton) findViewById(R.id.d_b);
			cbtnM = (ImageButton) findViewById(R.id.m_b);

			temp_tv = (TextView) findViewById(R.id.temperature);
			humi_tv = (TextView) findViewById(R.id.humidity);
			light_tv = (TextView) findViewById(R.id.light);
			distance_tv = (TextView) findViewById(R.id.distance);
				


3) 버튼 이벤트 작성하기
	   btnForward.setOnTouchListener(new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					touchHandle(event, "MF@", "전");
					return true;
				}
			});
			btnBack.setOnTouchListener(new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					touchHandle(event, "MB@", "후");
					return true;
				}
			});

			btnLeft.setOnTouchListener(new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					touchHandle(event, "ML@", "좌");
					return true;
				}
			});
			btnRight.setOnTouchListener(new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					touchHandle(event, "MR@", "우");
					return true;
				}
			});

			//---------------카메라-----------------------------------//
			cbtnU.setOnTouchListener(new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					touchHandle(event, "C_D@", "하");

					return true;

				}
			});
			cbtnD.setOnTouchListener(new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					touchHandle(event, "C_U@", "상");

					return true;
				}
			});

			cbtnM.setOnTouchListener(new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					touchHandle(event, "C_C@", "중앙");
					return true;
				}
			});

				


4) 실제 명령 전송하기
	  private void touchHandle(MotionEvent event, String orderStr, String tips) {
			int action = event.getAction();
			switch (action) {
				case MotionEvent.ACTION_DOWN:
					MainActivityOrder(orderStr, tips);
					break;

				case MotionEvent.ACTION_UP:
					MainActivityOrder("MS@", "정지");
					break;

				default:
					break;
			}
		}

		private void MainActivityOrder(String orderStr, String tips) {
			commandView.loadUrl("http://1.1.1.1:1235/arduino/" + orderStr);
			Log.w("command", tips + "/" + orderStr);
		}
				


5) 상태 가져오기
			new GetStatusTask().execute("http://1.1.1.1:1235/arduino/status@");
	...

					private class GetStatusTask extends AsyncTask {
			private String Content;
			ProgressDialog asyncDialog;

			protected void onPreExecute() {
				if (asyncDialog == null) {
					asyncDialog = new ProgressDialog(MainActivity.this);
				}
				asyncDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				asyncDialog.setCancelable(false);
				asyncDialog.setMessage("센서정보를 가져오고 있습니다..");
				asyncDialog.show();
			}

			protected Void doInBackground(String... urls) {

				BufferedReader reader = null;
				try {
					URL url = new URL(urls[0]);

					URLConnection conn = url.openConnection();
					conn.setDoOutput(true);

					reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
					StringBuilder sb = new StringBuilder();
					String line = null;

					while ((line = reader.readLine()) != null) {
						sb.append(line);
					}
					Content = sb.toString();
					Log.w("content", Content);
				} catch (Exception ex) {
				} finally {
					try {
						reader.close();
					} catch (Exception ex) {
					}
				}
				return null;
			}

			protected void onPostExecute(Void unused) {
				try {
					if (Content == null) {
						Toast.makeText(MainActivity.this, "센서정보를 가져올 수 없습니다.\nRC카 재부팅을 해주세요.", Toast.LENGTH_SHORT).show();
						finish();
					} else {
						JSONArray jarray = new JSONArray(Content);
						for (int i = 0; i < jarray.length(); i++) {
							JSONObject jObject = jarray.getJSONObject(i);
							String distance = jObject.getString("distance");
							String temperature = jObject.getString("temperature");
							String humidity = jObject.getString("humidity");
							String light = jObject.getString("light");

							distance_tv.setText(distance + "");
							temp_tv.setText(temperature + "");
							humi_tv.setText(humidity + "");
							light_tv.setText(light + "");
						}
						asyncDialog.dismiss();
					}
				} catch (JSONException e) {
					Toast.makeText(MainActivity.this, "RC카가 꺼져 있습니다.\n전원을 켜주세요.", Toast.LENGTH_SHORT).show();
				}

			}
				


6) 카메라 영상 확인하기
			videoview.loadUrl("http://1.1.1.1:1234/?action=stream");