이더넷 쉴드 사용
아두이노와 인터넷을 연결해서 사용할 수 있다면 아두이노를 다양하게 활용할 수 있을 것.
이더넷 모듈이나 쉴드와 접근가능한 IP가 있다면 쉽게 인터넷으로 통신할 수 있음.
아두이노 | 1 |
---|---|
브레드보드 | 1 |
이더넷 쉴드 | 1 |
점퍼 케이블 | 4 |
RGB LED | 1 |
330ohm 저항 | 3 |
우리는 RGB LED가 없어 LED 3개로 활용해 보도록 한다.
회로도
브레드보드 레이아웃
/*
이더넷 쉴드를 이용한 웹서버 만들기 스케치입니다.
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
modified 15 Nov 2014
by Soohwan Kim
본 스케치는 위즈네트 아카데미를 참고하였습니다.
http://wiznetacademy.com/
*/
#include <SPI.h>
#include <Ethernet.h>
#if defined(WIZ550io_WITH_MACADDRESS) //WIZ550io에 표시된 MAC 주소를 사용한다면
;
#else
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //mac 주소 입력
#endif
IPAddress ip(192,168,1,7); //로컬 네트워크에서 유일한 IP를 사용해야 합니다.
IPAddress gateway( 192, 168, 1, 1 );
IPAddress subnet( 255, 255, 255, 0 );
// fill in your Domain Name Server address here:
IPAddress myDns(8, 8, 8, 8); // google puble dns
EthernetServer server(80); //80은 포트번호
void check_led_status();
#define RED_PORT 46 //RED rgb 핀
#define GREEN_PORT 44 //GREEN rgb 핀
#define BLUE_PORT 42 //BLUE rgb 핀
void setup() {
Serial.begin(9600);
while (!Serial) {
; //시리얼 포트가 연결 될 때까지 기다림, 레오나르도 경우만 필요
}
pinMode(RED_PORT, OUTPUT); //RED 핀 출력 설정
digitalWrite(RED_PORT, HIGH); //RED 핀 초기 설정으로 켜놓기
pinMode(GREEN_PORT, OUTPUT); //GREEN 핀 출력 설정
pinMode(BLUE_PORT, OUTPUT); //BLUE 핀 출력 설정
//이더넷 디바이스 초기화
#if defined __USE_DHCP__
#if defined(WIZ550io_WITH_MACADDRESS) //WIZ550io에 할당된 맥 주소를 사용할 경우
Ethernet.begin();
#else
Ethernet.begin(mac);
#endif
#else
#if defined(WIZ550io_WITH_MACADDRESS)
Ethernet.begin(ip, myDns, gateway, subnet);
#else
Ethernet.begin(mac, ip, myDns, gateway, subnet);
#endif
#endif
//서버 연결 시작
server.begin();
Serial.println("WebServerControlLED");
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
//수신 클라이언트가 있는 지 확인
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
//http 요청이 빈 라인으로 끝났을 때
boolean currentLineIsBlank = true;
String buffer = ""; //버퍼 선언
while (client.connected()) {
if (client.available()) {
char c = client.read();
buffer += c; //버퍼 할당
Serial.write(c);
if (c == '\n' && currentLineIsBlank) {
//표준 http 응답 헤더 전송 시작
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
//본문(상황에 맞는 웹 페이지) 전달
//client.println("<!DOCTYPE HTML>");, HTML5 사용시
client.println("<html>"); //웹 페이지 작성은 HTML사용
client.println("<body>");
//LED에 상황을 판단한후 상태를 알림
if (digitalRead(RED_PORT)>0) { //빨간 불이면
client.println("LED is <font color='red'>RED</font>"); //웹페이지에 LED is RED라고 표시, RED는 빨간색
} else if (digitalRead(GREEN_PORT)>0) {
client.println("LED is <font color='green'>GREEN</font>");
} else if (digitalRead(BLUE_PORT)>0) {
client.println("LED is <font color='blue'>BLUE</font>");
} else {
client.println("LED is <font color='black'>OFF</font>");
}
//색 선택 부분 만들기
client.println("<br />");
client.println("<FORM method=\"get\" action=\"/led.cgi\">");
client.println("<P> <INPUT type=\"radio\" name=\"status\" value=\"1\">RED");
client.println("<P> <INPUT type=\"radio\" name=\"status\" value=\"2\">GREEN");
client.println("<P> <INPUT type=\"radio\" name=\"status\" value=\"3\">BLUE");
client.println("<P> <INPUT type=\"radio\" name=\"status\" value=\"0\">OFF");
client.println("<P> <INPUT type=\"submit\" value=\"Submit\"> </FORM>");
client.println("</body>");
client.println("</html>");
break;
}
if (c == '\n') {
currentLineIsBlank = true;
buffer="";
}
else if ( c == '\r') {
//빨간 불을 선택하면
if(buffer.indexOf("GET /led.cgi?status=1")>=0){
//빨간 불 킴
digitalWrite(RED_PORT, HIGH);
digitalWrite(GREEN_PORT, LOW);
digitalWrite(BLUE_PORT, LOW);
//두번째 페이지 전송
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html>");
client.println("<body>");
if (digitalRead(RED_PORT)>0) {
client.println("LED is <font color='red'>RED</font>");
} else if (digitalRead(GREEN_PORT)>0) {
client.println("LED is <font color='green'>GREEN</font>");
} else if (digitalRead(BLUE_PORT)>0) {
client.println("LED is <font color='blue'>BLUE</font>");
} else {
client.println("LED is <font color='black'>OFF</font>");
}
client.println("<br />");
client.println("<a href=\"/led.htm\">Go to control-page</a>"); //다시 처음 페이지로
client.println("</body>");
client.println("</html>");
currentLineIsBlank = false;
break;
}
//초록을 선택하면
if(buffer.indexOf("GET /led.cgi?status=2")>=0){
//초록 핀 킴
digitalWrite(RED_PORT, LOW);
digitalWrite(GREEN_PORT, HIGH);
digitalWrite(BLUE_PORT, LOW);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html>");
client.println("<body>");
if (digitalRead(RED_PORT)>0) {
client.println("LED is <font color='red'>RED</font>");
} else if (digitalRead(GREEN_PORT)>0) {
client.println("LED is <font color='green'>GREEN</font>");
} else if (digitalRead(BLUE_PORT)>0) {
client.println("LED is <font color='blue'>BLUE</font>");
} else {
client.println("LED is <font color='black'>OFF</font>");
}
client.println("<br />");
client.println("<a href=\"/led.htm\">Go to control-page</a>");
client.println("</body>");
client.println("</html>");
currentLineIsBlank = false;
break;
}
//파란 색을 선택하면
if(buffer.indexOf("GET /led.cgi?status=3")>=0){
digitalWrite(RED_PORT, LOW);
digitalWrite(GREEN_PORT, LOW);
digitalWrite(BLUE_PORT, HIGH);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html>");
client.println("<body>");
if (digitalRead(RED_PORT)>0) {
client.println("LED is <font color='red'>RED</font>");
} else if (digitalRead(GREEN_PORT)>0) {
client.println("LED is <font color='green'>GREEN</font>");
} else if (digitalRead(BLUE_PORT)>0) {
client.println("LED is <font color='blue'>BLUE</font>");
} else {
client.println("LED is <font color='black'>OFF</font>");
}
client.println("<br />");
client.println("<a href=\"/led.htm\">Go to control-page</a>");
client.println("</body>");
client.println("</html>");
currentLineIsBlank = false;
break;
}
//off를 선택했을 때
if(buffer.indexOf("GET /led.cgi?status=0")>=0){
digitalWrite(RED_PORT ,LOW);
digitalWrite(GREEN_PORT, LOW);
digitalWrite(BLUE_PORT, LOW);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html>");
client.println("<body>");
if (digitalRead(RED_PORT)>0) {
client.println("LED is <font color='red'>RED</font>");
} else if (digitalRead(GREEN_PORT)>0) {
client.println("LED is <font color='green'>GREEN</font>");
} else if (digitalRead(BLUE_PORT)>0) {
client.println("LED is <font color='blue'>BLUE</font>");
} else {
client.println("LED is <font color='black'>OFF</font>");
}
client.println("<br />");
client.println("<a href=\"/led.htm\">Go to control-page</a>");
client.println("</body>");
client.println("</html>");
currentLineIsBlank = false;
break;
}
} else{ //if( c != '\r') {
currentLineIsBlank = false;
}
}
}
delay(1);
// close the connection:
client.stop();
Serial.println("client disonnected");
}
}
인터넷은 TCP/IP 프로토콜 기반의 네트워크. 아두이노와 이더넷 쉴드를 사용하기 위해 TCP/IP프로토콜 기반으로 하기 때문에 몇가지 초기 설정이 필요하다.
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
- MAC address : 물리적 네트워크에서 TCP/IP사용시 각 기기를 구별할 수 있는 고유한 주소가 필요. 해당 주소를 mac address라고 함.
IPAddress ip(192,168,1,7); //로컬 네트워크에서 유일한 IP를 사용해야 합니다.
IPAddress gateway( 192, 168, 1, 1 );
IPAddress subnet( 255, 255, 255, 0 );
// fill in your Domain Name Server address here:
IPAddress myDns(8, 8, 8, 8); // google puble dns
- IP address : 네트워크 상에서 host를 구별하기 위한 수. 스케치 내부에서 ip주소를 할당해 주어야 함.
- gateway : 다른 네트워크 host와 통신시 중간에 gateway를 거쳐야 함.
- subnet : 현재 네트워크가 자신이 속한 네트워크인지 아닌지 구분하기 위해 사용.
- dns : 사람들이 IP주소를 기억하기 쉽게 바꾼 주소를 의미
- dns server address : dns가 dns server를 통하여 ip 주소로 변환되는데 이때 dns server의 주소를 의미.
이더넷쉴드를 사용하기 위해 아래 두개의 라이브러리가 필요.
#include <SPI.h>
#include <Ethernet.h>
하지만 WIZ550io를 사용한다면 제조사에서 제공되는 라이브러리로 대체 하여야 함. 스케치 버전에 맞는 라이브러리 사용.
클라이언트가 요청이 있으면 버퍼에 메세지를 저장합니다. 만약 다음 행 (\n)문자를 받고 다음 행이 비어있음이 확인되면 메세지가 다 전달된 것입니다. 이런 약속이 바로 http 프로토콜입니다.