[INTERFACE]/Ethernet2008. 11. 5. 08:59

Mini WebServer real time page update(실시간 웹페이지 업데이트)

Mini WebServer real time page update(실시간 웹페이지 업데이트)



소형 웹서버에서 모니터링을 위한 여러 방법이 있다. 가장 간단한 HTML테그를 이용하여 웹브라우저에서 1초에 한번씩 웹서버로 접근하여 데이를 가져와 페이지를 업데이트 하는 방법이 있다. 하지만 이 방법을 이용하면 최소 시간이 1초이고 페이지 내용이 많으면 많을수록 느려지고 실시간 업데이트 확인이 어렵다.

ActiveX, ASP등을 이용할 수도 있지만 등치도 있고 여러 제약 사항이 많다. 설치 없이 간단히 사용할 수 있는 방법으로 javascript를 이용하는 방법이 있는데, 요즘 동적 웹페이지를 위해 AJAX을 많이 사용한다고 한다.

원리를 먼저 MCU측에서보면 전송할 데이터를 XML파일로 업데이트 해두었다가 웹브라우저에서 파일을 요청하면 XML파일을 요청한 페이지에 전송한다. 웹페이지 측에서 보면 AJAX를 이용하여 웹페이지에서 타이머 이벤트로 마이컴 보드에 XML데이터를 요청하고 받은 XML파일을 파싱하여 원하는 데이터를 원하는 페이지 테그에 대체 해 넣는다.



테스트 동영상
간단한 예제로 MCU의 ADC포트에서 VR값을 읽어 XML데이터로 저장하고 실시간으로 페이지를 업데이트 해서 사용자는 외부 ADC값을 웹페이지 상에서 실시간으로 모니터링 하는 예제를 작성해 보았다.





Ajax 이용한 동적 웹페이지





Ajax - 출처 위키백과(http://ko.wikipedia.org/wiki/Ajax)

기존의 웹 애플리케이션은 브라우저에서 폼을 채우고 이를 웹 서버로 제출(submit)을 하면 하나의 요청으로 웹 서버에 전달 된다. 웹 서버는 요청된 내용에 따라서 데이터를 가공하여 새로운 웹 페이지를 작성하고 응답으로 되돌려준다. 이때 최초에 폼을 가지고 있던 페이지와 사용자가 이 폼을 채워 결과물로서 되돌려 받은 페이지는 일반적으로 유사한 내용을 가지고 있는 경우가 많다. 결과적으로 중복되는 HTML 코드를 다시 한번 전송 받게 되므로써 많은 대역폭을 낭비하게 된다. 대역폭의 낭비는 금전적 손실을 야기할 수 있으며 사용자와 대화(상호 반응)하는 서비스를 만들기 어렵게도 한다.

반면에 Ajax 애플리케이션은 필요한 데이터만을 웹서버에 요청해서 받은 후 클라이언트에서 데이터에 대한 처리를 할 수 있다. 보통 SOAP이나 XML 기반의 웹 서비스 프로토콜이 사용되며, 웹 서버의 응답을 처리하기 위해 클라이언트 쪽에서는 자바스크립트를 쓴다. 웹 서버에서 전적으로 처리되던 데이터 처리의 일부분이 클라이언트 쪽에서 처리 되므로 웹 브라우저와 웹 서버 사이에 교환되는 데이터량과 웹서버의 데이터 처리량도 줄어들기 때문에 애플리케이션의 응답성이 좋아진다. 또한 웹서버의 데이터 처리에 대한 부하를 줄여주는 일이 요청을 주는 수많은 컴퓨터에 대해서 일어나기 때문에 전체적인 웹 서버 처리량도 줄어들게 된다.


Posted by nexp

댓글을 달아 주세요

[INTERFACE]/Ethernet2008. 9. 15. 09:50

초소형 W5300 Web Server Module 보드 제작

사용자 삽입 이미지
 

 AVR128, 64k SRAM Memory, 512k Flash Memory, W5300을 이용하여 초소형 웹서버 모듈을 만들었다.




Posted by nexp

댓글을 달아 주세요

[INTERFACE]/AVR_W5100_EVM2008. 6. 3. 22:50

[Mega128 EVM] TCP Server Loopback Test - Network 전송속도 측정

[Mega128 EVM] TCP Server Loopback Test - Network 전송속도 측정

사용자 삽입 이미지


소스코드



Atmega128 16AU와 W5100을 이용하여 네트웍 속도 측정을 위해 TCP Loopback 프로그램을 작성해 테스트 해보았다.
PC쪽 프로그램은 Wiznet에서 제공하는 AX Loopback Test Program을 이용하였다.





먼저 Mega128 EVM에 loopbak프로그램을 다운로드 하여 서버모드로 Lesten한다.
AX프로그램을 설치 하고 실행하여 서버( [Mega128 EVM]보드 )에 접속(Connection)을 한다.


IP주소와 포트 번호 입력



접속이 되면 TCP전송을 클릭하면 전송할 파일을 선택할수 있고, 여기서는 간단히 이미지 파일을 이용해서 테스트 했다.
물론 다른 파일도 가능하다.



연속으로 테스트 결과 송신 5.288Mbps, 수신 5.2783Mbps가 나온다. 물론 단반향이므로 실제 속도는 두배로 생각하면 된다. 따라서  다이렉트 모드로(BUS Access) W5100을 이용하여 AVR atMega128에서 10Mbps이상의 전송속도가 나온다.



인다이렉트 모드의 경우 3.6146Mbps로 측정된다.




SPI모드로 측정하면 600KBps정도 측정이 된다.

Posted by nexp

댓글을 달아 주세요

[INTERFACE]/AVR_W5100_EVM2008. 5. 25. 23:44

[Mega128 EVM] 이더넷 테스트 - TCP Server

[Mega128 EVM] 이더넷 테스트 - TCP Server

사용자 삽입 이미지


W5100, Atmega128  TCP Server 예제



[Mega128 EVM]에서 W5100제어는 direct, indirect, spi방식으로 제어 가능하고 J7 점퍼 설정으로 설정 가능하다.
소프트웨어에서 설정은 \01_drv\wiznet\mcu\types.h 에서 설정할 수 있다.


#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_DIRECT_MODE__
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_INDIRECT_MODE__
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_SPI_MODE__
    /*Enable SPI_mode*/



TCP서버의 일은 통신의 종단점을 설정해 놓고 클라이언트로 부터 연결 요구를 수동적으로 기다리는 것이다.
TCP로 서버로서 데이터를 송수신 하기 위한 절차는 아래와 같다.
1) NetInit()함수로 W5100초기화
2) socket()함수로 서버 설정
3) listen()함수로 클라이언트의 접속을 대기
4) 접속이 이루어 지면 recv(), send()함수로 데이터 송수신
 
 
 
 
1)최기화
먼저 W5100을 초기화 하기 위해 NetInit()함수에서 iinchip_init() 설정 초기화 및 MAC, IP, Sub NET, Gateway등을 설정하면 된다. 아주 간단히 W5100의 레지스터에 값을 설정하는 것 만으로 네트웍 초기화가 되고 ping테스트가 된다.
//-----------------------------------------------------------------------------
void NetInit(void)
{
	unsigned char mac[6]	= MY_NET_MAC;
	unsigned char sm[4]	= MY_SUBNET;
	unsigned char gwip[4]	= MY_NET_GWIP;

	//W5100 Chip Init
	iinchip_init();

	//Set MAC Address
	setSHAR(mac);

	//Set Gateway
	setGAR(gwip);

	//Set Subnet Mask
	setSUBR(sm);

	//Set My IP
	setSIPR(m_sip);
	
#ifdef __DEF_IINCHIP_INT__
	setIMR(0xEF);
#endif
	
	sysinit(MY_NET_MEMALLOC, MY_NET_MEMALLOC);
}
//-----------------------------------------------------------------------------


2)서버 설정
서버모드는 클라이언트 모드와 거의 유사하지만 socket()함수로 소켓을 생성한 후 listen()함수로
서버로부터 접속을 기다리게 된다.
//----------------------------------------------------------------------------- //Initialize socket - 서버 모드로 소켓 초기화 unsigned char InitSocketServer(unsigned int Socket, unsigned Port) { //initialize the socket if(socket(Socket,Sn_MR_TCP, Port,0x20) == 0) { DebugPrint("Fail to create socket."); return 0; } else { listen(Socket); } return 1; }

 
3)접속후 데이터 송수신 
데이터 수신은 접속후 getSn_SR(SOCK_TCPS)함수로 소켓의 상태를 체크하다 SOCK_ESTABLISHED상태,
즉 서버에 연결된 상태가 되었을때 getSn_RX_RSR()함수로 수신된 데이터가 있으면
recv()함수로 데이터를 수신할 수 있다.
클라이언트에 의해 접속 종료 요청이 오면 SOCK_CLOSE_WAIT 상태가 되고 disconnect()함수로 연결을 종료 할 수 있다.
이후 TCP상태는 SOCK_CLOSED가 되고 InitSocketServer()함수를 이용하여
다시 소켓을 초기화 해서 서버로 접속을 대기할 수 있다.












//-----------------------------------------------------------------------------
//수신데이터 처리 void EthernetTest(unsigned char *pRcvBuffer, unsigned int len) { unsigned int i; DebugPrint("Read Data[%d]\r\n", len); for(i=0;i<len;i++) { //if(i%16==0)DebugPrint("\r\n"); DebugPrint("%02X ", pRcvBuffer[i]); } DebugPrint("\r\nReceive OK!\r\n"); } //TCP-Server 처리 void ProcessTcpSever(void) { int len; unsigned char data_buf[TX_RX_MAX_BUF_SIZE]; uint16 port = MY_LISTEN_PORT; switch (getSn_SR(SOCK_TCPS)) { case SOCK_ESTABLISHED: //check Rx data if((len = getSn_RX_RSR(SOCK_TCPS)) > 0) { //if Rx data size is lager than TX_RX_MAX_BUF_SIZE if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE; //read the received data len = recv(SOCK_TCPS, data_buf, len); //send the received data - loop back test send(SOCK_TCPS, data_buf, len); EthernetTest(data_buf, len); } break; case SOCK_CLOSE_WAIT: //If the client request to close disconnect(SOCK_TCPS); break; case SOCK_CLOSED: //if a socket is closed //reinitialize the socket InitSocketServer(SOCK_TCPS, port); break; } } //-----------------------------------------------------------------------------

 
테스트
Client는 PC프로그램 으로 하고 예전에 작성했던 TCP Server/Client Host Program(VC++) 예제 프로그램으로 테스트 한다. EthernetHost.exe

프로그램을 실행하고 Client모드로 설정하고 Port, IP설정후 Connect를 하면 접속된다.



서버에 접속후 원하는 데이터를 전송하면 시리얼 창에 전송된 데이터가 출력되는것을 확인 할 수 있다.







 
[Atmega128 EVM] W5100 TCP/IP Server 예제 소스코드

//=============================================================================
// Mega128 EVM Module Test Program
// by nexp76(nexp76@naver.com) http://cafe.naver.com/elab
// [tcps1.c]
//=============================================================================

/*
 - [W5100] EVM Tcp Server Test Program
 - MY_LISTEN_PORT(5000)로 접속 대기하여 수신한 데이터 시리얼로 표시 예제
*/

#include "..\00_hal\system.h"
#include "..\01_drv\serial.h"

#include "../01_drv/wiznet/mcu/types.h"
#include "../01_drv/wiznet/iinchip/w5100.h"
#include "../01_drv/wiznet/iinchip/socket.h"
#include "../01_drv/wiznet/iinchip/wiznet.h"


//-----------------------------------------------------------------------------
#define MY_NET_MAC			{0x00, 0x08, 0xdc, 0x00, 0x00, 0x00}	// MY Mac Address : 00.08.DC.00.00.00

#define MY_NET_GWIP		{192,  168, 0,    1}	// MY Gateway IP    : 192.168.0.1
#define MY_DESTINATIONIP		{192,  168, 0,  154}	// MY Destination   : 192.168.0.154
#define MY_SOURCEIP		{193,  168, 0,  100}	// MY Source IP     : 192.168.0.100
#define MY_SUBNET			{255, 255, 255,   0}

#define MY_NET_MEMALLOC		0x55					// MY iinchip memory allocation

#define MY_LISTEN_PORT		5000					// MY Listen Port  : 5000 
#define MY_CONNECT_PORT		3000					// MY Connect Port : 3000

#define TX_RX_MAX_BUF_SIZE	1024
#define SOCK_TCPC			0
#define SOCK_TCPS			1
//-----------------------------------------------------------------------------

unsigned char m_dip[4]	= MY_DESTINATIONIP;			//Destination IP	: 192.168.0.154
unsigned char m_sip[4]	= MY_SOURCEIP;				//Source IP     	: 192.168.0.100

//-----------------------------------------------------------------------------
void NetInit(void)
{
	unsigned char mac[6]	= MY_NET_MAC;
	unsigned char sm[4]	= MY_SUBNET;
	unsigned char gwip[4]	= MY_NET_GWIP;

	//W5100 Chip Init
	iinchip_init();

	//Set MAC Address
	setSHAR(mac);

	//Set Gateway
	setGAR(gwip);

	//Set Subnet Mask
	setSUBR(sm);

	//Set My IP
	setSIPR(m_sip);
	
#ifdef __DEF_IINCHIP_INT__
	setIMR(0xEF);
#endif
	
	sysinit(MY_NET_MEMALLOC, MY_NET_MEMALLOC);
}
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
//Initialize socket - 서버 모드로 소켓 초기화
unsigned char InitSocketServer(unsigned int Socket, unsigned Port)
{
	//initialize the socket 
	if(socket(Socket,Sn_MR_TCP, Port,0x20) == 0)
	{
		DebugPrint("Fail to create socket.");

		return 0;
	}
	else
	{
		listen(Socket);
	}

	return 1;
}

//-----------------------------------------------------------------------------
//수신데이터 처리
void EthernetTest(unsigned char *pRcvBuffer, unsigned int len)
{
	unsigned int i;

	DebugPrint("Read Data[%d]\r\n", len);
	
	for(i=0;i<len;i++)
	{
		//if(i%16==0)DebugPrint("\r\n");
		DebugPrint("%02X ", pRcvBuffer[i]);
	}

	DebugPrint("\r\nReceive OK!\r\n");
}


//TCP-Server 처리
void ProcessTcpSever(void)
{
	int len;							
	unsigned char data_buf[TX_RX_MAX_BUF_SIZE];

	uint16 port = MY_LISTEN_PORT;
	
	switch (getSn_SR(SOCK_TCPS))
	{
	case SOCK_ESTABLISHED:
		//check Rx data
		if((len = getSn_RX_RSR(SOCK_TCPS)) > 0) 			
		{
			//if Rx data size is lager than TX_RX_MAX_BUF_SIZE 
			if (len > TX_RX_MAX_BUF_SIZE) len = TX_RX_MAX_BUF_SIZE;	
			
			//read the received data
			len = recv(SOCK_TCPS, data_buf, len);

			//send the received data - loop back test
			send(SOCK_TCPS, data_buf, len);	
			
			EthernetTest(data_buf, len);
		}		
		break;
		
	case SOCK_CLOSE_WAIT:                           		
		//If the client request to close
		disconnect(SOCK_TCPS);
		break;
		
	case SOCK_CLOSED:
		//if a socket is closed
		
		//reinitialize the socket 
		InitSocketServer(SOCK_TCPS, port);
		break;
	}
}
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
int main(void)
{
	SystemInit();
	
	//Serial Init
	DebugInit(BAUD_115200);
	DebugPrint("[Mega128 EVM] Test Program. - TCP Server\r\n");

	//W5100 Chip Initialize
	//----------------------------
	InitWiznet();

	NetInit();
	//----------------------------
	
	//Display Net Configuration..
	DisplayConfig();
	
	//Initialize TCP Server
	InitSocketServer(SOCK_TCPS, MY_LISTEN_PORT);
	
	while (1)
	{
		//TCP Server Process
		ProcessTcpSever();
	}		
}
//-----------------------------------------------------------------------------

Posted by nexp

댓글을 달아 주세요

  1. 곽상훈

    안녕하세요
    혹시 AVR로 Wiznet 제어 하셨자나요
    Direct 모드로 LM3s2965로 제어를 하려고 하는데요
    레지스트리 R/W가 잘안되네요..
    2965에는 외부메모리를 쓰는것이 없어서 16Bit BUS 통신으로 제어를하고 있습니다.
    도와주세요~

    2010.07.03 14:20 [ ADDR : EDIT/ DEL : REPLY ]

[Proramming]/C#2008. 4. 28. 21:17

C#을 이용한 시리얼 포트 제어 - AVR AtMega128 제어

C#을 이용한 시리얼 포트 제어 - AVR AtMega128 제어
 
사용자 삽입 이미지
 

Visual Studio .Net에 시리얼 포트 제어 컴포넌트가 기본으로 제공된다. 이를 이용하면 시리얼 포트를 이용한 제어가 상당히 편리해 지는데 C#을 이용하여 하드웨어(시리얼 포트)제어 프로그램 작성을 해 보았다.
하드웨어는 Usb2Serial을 가지고 있는 [Meag128 EVM]을 이용하였고 예전에 작성해 둔 시리얼 포트 제어 펌웨어를 그대로 사용 하였다.
 
 
VC#을 실행하고 새로운 프로젝트를 생성한다.
적당히 폼을 생성하고 시리얼 포트 제어를 위해 'SerialPort' 컴포넌트도 배치한다.
시리얼 포트의 속성은 속성창에서 설정해도 되고 소스코드상에서 입력가능하다.
사용자 삽입 이미지
 
 
코드작성
코드는 상당히 간단히 작성할 수 있고 Byte Buffer나 String데이터를 시리얼 포트로 전송할 수 있다.
초기에 설정해야 하는 프로퍼티로 COM Port를 설정하는 PortNmae와 Baudrate를 설정하는 BaudRate가 있다.
PC에서 시리얼 포트로 데이터를 전송하기 위해 Write() 매소드를 사용하면 된다. 문자열 단위 혹은 Byte단위로 전송 가능하다.
아래 코드를 보면 쉽게 이해 가능하다.
 
 
프로그램 실행
프로그램 실행해서 포트 초기화 하고 [Mega128 EVM]의 Led를 PC프로그램으로 제어 가능하다.


 
테스트 동영상
C# 으로 작성한 시리얼 포트 제어 프로그램으로 Atmeag128 EVM의 LED를 제어 하는 프로그램
 
결론적으로 말하면 "정말 간단한다" 이다. 하드웨어 엔지니어 입장으로 보면 PC는 그냥 도구일 뿐이므로 내부 사정은 자세하게 알 필요가 없다. 그저 좀더 쉬운 환경에서 명령 내리고 데이터 수집해서 분석하는 용도로 사용하기에 Visual툴을 이용하면 너무 좋은것 같다. 한가지 아쉬운 점이 있다면 C#코드 자체가 C와 완벽히 호환되지 않기 때문에 임베디드로 포팅을 할때는 조금 무리가 있을듯... 그렇다면 C++.net으로 가는것이 맞을것 같다.

다른 예제
Cortex-M3 STM32 USB를 이용하여 각도값 표시 - 윈도창에 센서 데이터를 그래프로 표시해서 디버깅을 쉽게 할 수 있다.
")//]]>
Posted by nexp

댓글을 달아 주세요

  1. gimchiii

    씨샵이 편리하군요...
    기능도 좋은듯 하고...
    써보고 싶군요...

    2008.10.21 14:16 [ ADDR : EDIT/ DEL : REPLY ]
  2. gimchiii

    실례지만 C# 2005는 닷넷 2005의 일부인가요?

    2008.10.21 14:21 [ ADDR : EDIT/ DEL : REPLY ]
  3. nowdream

    저기 전 8051 을 c#으로 제어하려고 합니다..
    8051에 미리 프로그램을 구워놓고 c#으로 제어하면 되는 겁니까 ?ㅠ

    2009.05.02 11:43 [ ADDR : EDIT/ DEL : REPLY ]
  4. 비밀댓글입니다

    2009.05.14 09:46 [ ADDR : EDIT/ DEL : REPLY ]
  5. dsu

    저기 질문이 있는데 atmega 의 플래쉬 메모리에 별다른 프로그래밍이 되어 있지않은 상태에서 저렇게 제어가 가능하다는 것입니까? 결국에는 플래쉬메모리에 저장된 프로그래밍이 데이터를 받고 작동시킨다는 것입니까? 너무 초보적인 질문같아서 죄송합니다.

    2010.01.26 08:57 [ ADDR : EDIT/ DEL : REPLY ]
  6. 이동현

    관리자의 승인을 기다리고 있는 댓글입니다

    2011.03.04 17:32 [ ADDR : EDIT/ DEL : REPLY ]