Note 5. W5500-EVB Web Server를 이용한 I/O 제어

W5500-EVB의 RGB LED On / Off


W5500-EVB의 웹 서버를 활용하는 첫 번째 예제로, 웹 페이지를 통해 W5500-EVB에 on-board 되어 있는 RGB LED를 제어하는 예제이다. 이전 Note 2에서 설명한 것과 같이 W5500-EVB 웹 서버는 CGI를 통해 device 를 제어한다.

Note 2. W5500-EVB를 위한 HTTP Server Library 이해

W5500-EVB 웹 서버 예제에는 웹을 통해 W5500-EVB를 제어하기 위한 CGI가 userHandler.c 와 webpage.h 코드 내에 미리 정의되어 있으니 참고 바란다. 제어 핀 정보는 Arduino compatible pinout 기준으로 구현되어 있다.

본 예제에서 제어할 I/O는 RGB LED이므로, D8 ~ D10에 High / Low 값을 설정하도록 코드를 구현하면 된다.

rgb_led_pins

W5500-EVB의 웹 서버 라이브러리를 이용하여 I/O를 제어하기 위해 구현할 부분은 다음과 같다.

  1. 요청할 CGI 이름 정의
    1. e.g., set_diostate.cgi, 웹 페이지와 펌웨어 간 서로 확인 할 수 있는 이름이면 OK
  2. [ 웹 서버 ] 해당 요청에 대한 HTTP Request가 들어왔을 때 처리할 함수 정의 및 Handler에 등록
  3. [웹페이지] (1) 에서 정의한 CGI 요청을 GET / POST로 AJAX 방식으로 보내고 / 받을 JavaScript 함수 작성
  4. [웹페이지] 웹 브라우저에서 보일 HTML 웹 페이지 및 JavaScript 함수를 호출 할 HTML tag 작성

이 중, [1], [2], [3]은 W5500-EVB의 웹 서버 라이브러리 내에 구현 / 정의되어 있으므로 사용자는 JavaScript를 요청하고 받을 HTML 페이지만 준비하면 된다. 구현에 대한 더 자세한 내용은 아래 자세히 기술되어 있다.

W5500-EVB 웹 서버 라이브러리의 I/O 제어 흐름


웹 브라우저의 HTTP Request는 HTML 페이지와 JavaScript를 이용한 AJAX 요청으로 구성되며, W5500-EVB의 웹 서버는 각각의 요청에 따라 [GET 요청의 경우] JavaScript Callback Function으로 응답하거나 [POST 요청의 경우] 해당 I/O를 조작한 후 적절한 값을 리턴한다.

다음은 Note 2의 simple CGI 동작을 좀 더 자세히 설명한 흐름도이다.

w5500-evb_cgi_processes

다음은 코드 내에 미리 정의된 CGI 목록이다. 웹 페이지에서는 웹 서버 측으로 다음 CGI를 요청하도록 구성되어야 한다.

CGI 정의와 JavaScript 코드


>> Digital I/O : D0 ~ D15 (16)

  • GET CGI : get_dio[n].cgi (D0 ~ D15)
    1. 지정한 Digital I/O의 현 상태 값 (0 : Low, 1 : High) 과 I/O 방향 (0 : NotUsed, 1 : Input, 2 : Output) 을 요청한다.
      1. dio_p : pin
      2. dio_s : pin state
      3. dio_d : pin direction
    2. n은 0~15까지의 Dgital I/O Pin을 의미한다. (Arduino compatible pinout을 기준으로 작성)
    3. 요청 시 Parameter는 없으며 웹 서버는 해당 요청에 대해 JavaScript Callback으로 응답한다. 해당 CGI를 요청하는 웹 페이지 내에 JavaScript Callback과 대응하는 동일한 이름의 JavaScript 함수가 있어야 한다.
      • Ex) D0 요청에 대해 미리 정의된 웹서버의 응답은 다음과 같다.
        • DioCallback({"dio_p" : "0"}, {"dio_s" : "0"}, {"dio_d" : "2"})

실제 JavaScript 함수는 다음과 같이 구현되어 AJAX로 GET CGI를 요청한다. 해당 함수 구현에 활용된 AJAX 관련 JavaScript 함수는 코드 내에 포함되어 있다.

function getDio(o) {
  var p=o.attributes['pin'].value;
  var oUpdate;
  oUpdate=new AJAX('get_dio'+p+'.cgi',function(t){try{eval(t);}catch(e){alert(e);}}
  oUpdate.doGet();
}

D0에 대해 get_dio0.cgi GET 요청을 수행했다면 동일 웹 페이지 내에 구현된 DioCallback 함수에서 자동으로 DOM을 조작한다. 이 때  txtdio_s0 는 해당 HTML value attribute를 찾기 위한 HTML tag id이다. 따라서 HTTP request를 수신하면 해당 HTML tag id를 가진 HTML tag의 value에 수신된 값이 설정된다.

function DioCallback(o){
  var pin = o.dio_p;
  $('txtdio_s'+pin).value=o.dio_s;
  $('txtdio_d'+pin).value=o.dio_d;
}
  • POST CGI : set_diostate.cgi
    1. 웹 서버가 해당 CGI 요청을 수신하면, 웹 페이지에서 요청 시 포함한 Parameter에 해당하는 Val 값으로 Pin의 상태 (state) 를 설정한다. (0 : Low, 1 : High) Parameter는 WebForm element로 첨부되며 ‘pin=0&val=1’ 과 같은 형태로 구성하여 전송한다.
      1. Pin : Pin 번호 (0 ~ 15)
      2. Val : Pin state (0 : Low, 1 : High)
    2. 웹 서버에서 웹 브라우저 측으로 보내는 HTTP Response의 return value는 현 라이브러리 코드에서는 사용하지 않는다.

set_diostate.cgi를 전송하기 위한 JavaScript 함수는 다음과 같이 구현되어 있다.

function setDiostate(o){
  var p=o.attributes['pin'].value;
  var v=o.attributes['s'].value;
  dout=new AJAX('set_diostate.cgi', function(t){try{eval(t);}catch(e){alert(e);}});
  dout.doPost('pin='+p+'&val='+v);
}
  • POST CGI : set_diodir.cgi
    1. 웹 서버가 해당 CGI 요청을 수신하면, 웹 페이지에서 요청 시 포함한 Parameter에 해당하는 Val 값으로 Pin의 방향 (direction) 을 설정한다. (0 : NotUsed, 1 : Input, 2 : Output)  Parameter는 WebForm element로 첨부되며 ‘pin=0&val=1’ 과 같은 형태로 구성하여 전송한다.
      1. Pin : Pin 번호 (0 ~ 15)
      2. Val : Pin direction (0 : NotUsed, 1 : Input, 2 : Output)
    2. 웹 서버에서 웹 브라우저 측으로 보내는 HTTP Response의 return value는 현 라이브러리 코드에서는 사용하지 않는다.

set_diostate.cgi를 전송하기 위한 JavaScript 함수는 다음과 같이 구현되어 있다.

function setDiodir(o){
  var p=o.attributes['pin'].value;
  var v=o.attributes['s'].value;
  dout=new AJAX('set_diodir.cgi', function(t){try{eval(t);}catch(e){alert(e);}});
  dout.doPost('pin='+p+'&val='+v);
}

HTML 코드


JavaScript를 호출하기 위한 HTML 웹 페이지는 다음과 같이 구성하면 된다. I/O를 구분하여 제어하기 위해 input tag에 ‘pin’ 과 ‘s’ attribute를 추가하였다. HTML tag와 attribute에 접근 하기 위한 방법은 이 외에도 여러 가지가 있을 수 있다.

<!DOCTYPE html>
<html>
	<head>
	<title>W5500-EVB Web Server Digital I/O</title>
	<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
	<meta http-equiv='pragma' content='no-cache'>
	<meta http-equiv='content-type' content='no-cache, no-store, must-revalidate'>
	<script type='text/javascript' src='ajax.js'></script>
	<script type='text/javascript' src='dio.js'></script>
	</head>
	<body>
		<div>
		<input type='button' value='LED R On' pin='8' s='0' onclick='setDiostate(this);'> 
		<input type='button' value='LED R Off' pin='8' s= '1' onclick='setDiostate(this);'>
		<br>
		<input type='button' value='LED B On' pin='9' s='0' onclick='setDiostate(this);'> 
		<input type='button' value='LED B Off' pin='9' s= '1' onclick='setDiostate(this);'>
		<br>
		<input type='button' value='LED G On' pin='10' s='0' onclick='setDiostate(this);'> 
		<input type='button' value='LED G Off' pin='10' s= '1' onclick='setDiostate(this);'>
		</div>
	</body>
</html>

Firmware 코드


펌웨어 코드는 W5500-EVB 라이브러리 코드 내 userHandler.c 파일에 정리되어 있다.

핵심은 미리 정의된 CGI 파일 명에 대한 요청이 들어왔을 때 이를 확인하여 해당하는 I/O 제어 함수에 mapping하는 작업이다. 자세한 코드를 확인 하고자 하면 userHandler.c 파일 내 다음 두 함수를 살펴보기 바란다.

>> userHandler.c (GitHub Repository)

  • predefined_get_cgi_processor()
  • predefined_set_cgi_processor()

결과


웹 브라우저에서 웹 서버의 IP로 접속하면 위 HTML 코드에 따라 RGB LED를 제어하기 위한 6개의 On / Off 버튼을 확인 할 수 있다. 각각의 버튼을 눌러 W5500-EVB의 LED 동작을 확인하자.

webpage_rgb_led_control

Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중