1. ENC28J60 이더넷 모듈

HTTP stack 을 활용하고 싶지만 이더넷 쉴드는 가격이 부담스러울 때, 간단하게 활용하기 좋은 심플한 모듈이 필요할 때 ENC28J60 이 딱일듯 합니다. 해외 가격이 $10 정도로 저렴하고 카페 공구를 잘 뒤져보시면 호환 모듈을 저렴한 가격에 구하실 수 있습니다. 요즘 화분 관리하는 아두이노 프로젝트도 많이 있던데, 이 모듈을 이용하면 화분 상태를 주기적으로 Twitter로 날리는 등의 활용이 가능합니다.

상세 제원

ENC28j60 Ethernet Interface Module1

– ENC28J60 이더넷 칩, SOP28 패키지, 최대 10MB / s의 속도
– SPI 인터페이스
– 2×6 커넥터 와 쉽게 MCU와 연결해서 사용
– RJ45 커넥터 HR911102A 내장
– 전원 상태 LED
– 전원 공급 : 3.3V 레귤레이터가 내장 되어있어 3.3V 와 5V(VCC) 핀으로 선택해서 공급 가능
– 25Mhz 크리스탈

– 보드크기 : 4.76 x 1.88 (Cm)

2. 연결방법

12개 핀 중 6개의 핀을 다음과 같이 연결합니다.

이더넷 모듈 아두이노
3.3V 3.3V
GND GND
MISO D12
MOSI D11
SCK D13
CS D10

3. 코드 (스케치)

아래 링크에서 라이브러리 파일을 받아서 설치합니다. 압축을 받아서 푸시고 아두이노 설치폴더 > libraries 폴더안에 복사합니다. 아두이노 IDE를 실행시키고 [파일 > 예제 > EtherShield > etherShield_webserver] 선택해서 예제 파일을 불러옵니다. 아래 소스에서 붉은색 부분은 직접 수정해 주셔야 합니다.

[wpdm_file id=16]

일반적으로 이더넷 모듈이 공유기를 통해 연결될 것이므로 내부 IP address를 사용할 것입니다. 공유기와 연결된 PC에서 http://192.168.0.1 or http://192.168.1.1 들어가셔서 사용되고 있는 IP 리스트 등을 확인해 두세요.

// EtherShield webserver demo
#include “EtherShield.h”

// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = { 0x54,0x55,0x58,0x10,0x00,0x25};

static uint8_t myip[4] = {192,168,0,205};  // 본인이 사용할 IP

#define MYWWWPORT 80    // 그대로 사용해도 무방
#define BUFFER_SIZE 550
static uint8_t buf[BUFFER_SIZE+1];

// The ethernet shield
EtherShield es=EtherShield();

uint16_t http200ok(void)
{
return(es.ES_fill_tcp_data_p(buf,0,PSTR(“HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n”)));
}

// prepare the webpage by writing the data to the tcp send buffer, 여기에서 웹 페이지로 사용될 HTML 코드를 수정해서 입력합니다.

uint16_t print_webpage(uint8_t *buf)
{
uint16_t plen;
plen=http200ok();
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“<html><head><title>Arduino ENC28J60 Ethernet Shield V1.0</title></head><body>”));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“<center><h1>Welcome to Arduino ENC28J60 Ethernet Shield V1.0</h1>”));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“<hr><br><h2><font color=\”blue\”>– Put your ARDUINO online — “));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“<br> Control digital outputs”));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“<br> Read digital analog inputs HERE”));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“<br></font></h2>”) );
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“</center><hr>”));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“V1.0 <a href=\”http://blog.thiseldo.co.uk\”>blog.thiseldo.co.uk</a>”));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(“</body></html>”));

return(plen);
}
void setup(){

// Initialise SPI interface
es.ES_enc28j60SpiInit();

// initialize enc28j60
es.ES_enc28j60Init(mymac);

// init the ethernet/ip layer:
es.ES_init_ip_arp_udp_tcp(mymac,myip, MYWWWPORT);
}

void loop(){
uint16_t plen, dat_p;

while(1) {
// read packet, handle ping and wait for a tcp packet:
dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));

/* dat_p will be unequal to zero if there is a valid
* http get */
if(dat_p==0){
// no http request
continue;
}
// tcp port 80 begin
if (strncmp(“GET “,(char *)&(buf[dat_p]),4)!=0){
// head, post and other methods:
dat_p=http200ok();
dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR(“<h1>200 OK</h1>”));
goto SENDTCP;
}
// just one web page in the “root directory” of the web server
if (strncmp(“/ “,(char *)&(buf[dat_p+4]),2)==0){
dat_p=print_webpage(buf);
goto SENDTCP;
}
else{
dat_p=es.ES_fill_tcp_data_p(buf,0,PSTR(“HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>”));
goto SENDTCP;
}
SENDTCP:
es.ES_www_server_reply(buf,dat_p); // send web page data
// tcp port 80 end

}

}

소스를 컴파일-업로드 하고 이더넷 모듈과 랜 포트에 불이 들어오는지 Serial Monitor에 에러 메시지는 없는지 확인합니다. 여기까지 되면 이제 PC나 폰에서 브라우저로 접속이 되는지 확인해야 합니다.

4. 동작 방법

이더넷 모듈이 랜선으로 공유기와 물려있고 내부 IP : 192.168.0.250 을 사용해서 테스트 했습니다. 먼저 같은 공유기에 연결된 PC의 브라우저에서 http://192.168.0.250 으로 접속해서 아래 화면이 나오는지 확인합니다.

connect_from_external_ip2

이 화면이 보이면 내부망에서 이더넷 모듈 접속은 성공입니다. 이제 외부망에서 이더넷 모듈 접속이 되는지 확인할 차례입니다.

외부에서는 이더넷 모듈이 직접 보이지 않기 때문에 먼저 공유기에 접속하면 공유기가 이더넷 모듈과 연결시켜 주도록 설정해야 합니다. HTTP 포트는 80번을 사용하는 것이 기본이고 이더넷 모듈 소스에도 80번을 썼습니다. 하지만 공유기 내부에 다른 HTTP 서버가 있어서 이미 이 포트를 사용하고 있다면 이더넷 모듈은 다른 포트를 사용해야 합니다. 그래서 전 8087번 포트를 사용하도록 설정 했습니다. 즉 아래 흐름도처럼 공유기가 8087번 포트로 들어오는 요청을 내부망의 이더넷 모듈의 IP, 80번 포트로 전달하도록 설정할겁니다.

[외부망]— http://10.87.xx.xx:8087 —> [공유기] — 192.168.0.205:80 —> [이더넷 모듈]

공유기가 이런 작업을 할 수 있도록 포트포워딩 이라는 기능을 제공합니다. 보통 브라우저에서 http://192.168.0.1 으로 접속하면 공유기에 대한 설정을 할 수 있는 페이지가 나옵니다.(자신의 PC IP에서 끝자리만 1로 바꿈) 여기서 포트포워딩 항목을 찾아서 위에서 설명한 대로 포트포워딩 규칙을 추가합니다. 아래는 제가 포트포워딩을 설정한 화면입니다.

setting_port_forwarding

맨 아래에 포트포워딩 규칙이 하나 추가된게 보이실겁니다. 공유기가 받은 Request 중 8087번 포트로 온 request를 내부 IP, 80번 포트… 즉 이더넷 모듈로 포워딩 시켜줍니다.

이제 공유기의 IP, 8087번 포트로 접속하면 외부에서도 이더넷 모듈로 접속할 수 있습니다. 공유기 설정 화면에서 공유기의 IP를 확인하시고… http://xxx.xxx.xxx.xxx:8087 로 접속합니다. 아래와 같이 이더넷 모듈이 전송하는 화면이 보이면 성공입니다.

connect_from_external_ip

전 핸드폰으로 접속해서 되는지 확인했습니다. (wifi 끄고 3G/LTE 망으로 테스트하면 확실) 여기까지 완료 하셨다면 etherShield 의 다른 예제들도 확인해보세요.

UPDATE!! 본 문서에 사용된 EtherShield 라이브러리는 더 이상 업데이트 되지 않습니다. 현재는 EtherCard 라이브러리만 업데이트 됩니다. EtherCard 라이브러리는 연결 방법이 약간 틀립니다. 아래 HTTP Client – Request 예제는 EtherCard 라이브러리를 이용해 작성 되었습니다. 참고하세요.

HTTP Client – Request 예제