직접 Maker가 만들고 공유하는 다양하고 유용한 WIZnet TCP/IP Ethernet Controller Driver

Written by MC


Overview

WIZnet는 W3100(단종)을 시작으로 W3150A+, W5100, W5200, W5300, W5500 등 개선되고 안정화된 TCP/IP Chip을 선보이고 있으며, 전세계의 많은 개발자와 Maker에게 지속적인 관심을 받고 있다.

위즈네트는 큰 사랑을 받은 W5100의 성능을 개선하고 가격을 낮춘 W5100S를 최근 출시하였고, 곧 다가올 IPv6 IoT 시장에 대응할 수 있는 Dual TCP/IP Stack(IPv4 & IPv6) 지원하는 W6100을 곧 출시할 예정이다.

위즈네트는 공식적으로 W5xxx Series을 통합 운영할 수 있는 ioLibrary를 제공하고 있으며, 이는 사용자 Application의 수정을 최소화하고, 손쉽게 새로운 칩으로 변경할 수 있도록 한다.

그리고, W6100에 대한 io6Library 또한 Github를 통해 제공될 예정이다.
ioLibrary에 익숙한 사용자라면 io6Library 역시 손쉽게 사용할 수 있을 거라 기대한다.

이 글에서 소개하고자 하는 것은 위즈네트의 공식 ioLibrary가 아닌, 위즈네트 뮤지엄에서 소개하고 있는 전세계 Maker나 개발자가 개발한 유용하고 다양한 Library를 소개하고자 한다.

소개할 Library는 다음과 같다.

Arduino Library

Official Arduino Library

Aurdino Library는 전세계 Maker에게 가장 사랑받고 활용되고 있는 Library이다. 누구나 손쉽고 빠르게 개발할 수 있는 장점은 있지만, 단순한 Library 구조로 위즈네트 Chip이 제공하는 세부적인 기능을 제어하기에는 한계가 있다.

이러한 단점에도 불구하고, 전세계 Maker들에게 지속적으로 사랑받고 활용되는 이유는, 손쉽게 동작할 수 있는 다양한 Example을 제공하고, 전세계 Maker들이 함께 만들어가는 Library로 github에 공유되어 W5100, W5200, W5500, W5100S, W6100 등을 Runtime에 지원하는 Library를 제공한다.

Multicasting Arduino Library

이 Library는 Arduino Library가 지원하지 않는 UDP Mutilcasting 구현을 위한 Library를 제공한다. 저자는 udp.h 와 udp.c에서 UdpClass::begin() 함수와 같은 UdpClass::beginMulti() 추가하여 구현하였다.

필자 생각에는 UdpMultiClass를 원본 Library를 수정하지 않고, UdpClass 상속 받아 beginMulti()를 추가하는 것이 활용도 면에서 좋을 것으로 판단된다.

 
   class UdpMultiClass : UdpClass {
      public:
      void beginMutli(uint16_t portMulti, uint8_t * addrMulti);
   }

   void UdpMutiClass::beginMulti(uint16_t portMulti, uint8_t * addrMulti) 
   {
      _port = portMulti;
      _sock = 0; //TODO: should not be hardcoded
      // set destination IP
      W5100.writeSnDIPR(_sock, addrMulti);
      W5100.writeSnDPORT(_sock, portMulti);

      socket(_sock, SnMR::UDP, _port, 0x80);
   }
 

[Refer to WIznet Museum]
[Download Library]
[How to Use]

Non-blocking Arduino Library

Non-Blocking Arduino Library는 Arduino Board가 DHCP Server로 부터 IP address는 할당받거나, DNS 요청이 Blocking 되어 수초 동안 아무런 동작도 하지 않는 Standard Library를 Blocking 되지 않도록 일부 코드를 수정한 것입니다. 저자와 같은 고민을 해본 분들에게 도움이 될 만한 Library입니다.

[Refer to WIznet Museum]
[Download Library]
[How to Use]

FreeRTOS Library

FreeRTOS 기반에 동작하는 ATmega MCU의 WIZnet Library로 WIZnet가 제공하는 초기 ioLibrary로 구현되었습니다.

이 Library는 RTOS 기반의 Application에서 WIZnet Library가 어떻게 활용될 수 있는지 잘 보여줍니다.
저자는 그외에도 FreeRTOS 기반의 uIP Stack도 지원하고 있으며, 이는 WIZnet의 Hardware TCP/IP stack과 Software Stack를 손쉽게 비교할 수 있습니다.

또한, 이 Site는 WIZnet Chip의 MACRAW SOCKET 기능을 활용하여 uIP Stack을 구현하는 Library도 제공하고 있습니다. 여기를 참조하세요.

[Refer to WIznet Museum]
[Download Library]
[How to Use]

ATmega Library

ATmega Library는 W5100을 기반으로 하는 간단한 Library 입니다.
ermicor의 Library를 수정하여 만들었습니다.
이 Library는 ioLibrary를 필요한 기능만을 구현하여 아주 작게 만들었습니다.
아래 코드는 WIZnet Chip을 Access하기 위한 기본 IO library입니다.


void  W51_register(W5100_CALLBACKS  *pcallbacks)
{
    select = pcallbacks->_select;
    xchg = pcallbacks->_xchg;
    deselect = pcallbacks->_deselect;
    reset = pcallbacks->_reset;
    inited = FALSE;
    if ((select) && (xchg) && (deselect))  inited = TRUE;    // these functions must be valid
}
void  W51_write(unsigned int  addr, unsigned char  data)
{
    if (!inited)  return;                        // not set up, ignore request

    select();                                    // enable the W5100 chip
    xchg(W5100_WRITE_OPCODE);                    // need to write a byte
    xchg((addr & 0xff00) >> 8);                  // send MSB of addr
    xchg(addr & 0xff);                           // send LSB
    xchg(data);                                  // send the data
    deselect();                                  // done with the chip
}
unsigned char  W51_read(unsigned int  addr)
{
    unsigned char                val;

    if (!inited)  return  0;                     // not set up, ignore request

    select();                                    // enable the W5100 chip
    xchg(W5100_READ_OPCODE);                     // need to read a byte
    xchg((addr & 0xff00) >> 8);                  // send MSB of addr
    xchg(addr & 0xff);                           // send LSB
    val = xchg(0x00);                            // need to send a dummy char to get response
    deselect();                                  // done with the chip
    return  val;                                 // tell her what she's won
}

[Refer to WIznet Museum]
[How to Use]

PSoC Library

PSoC Library는 Cypress사의 PSoC4 & PSoC4에 동작하며, W5100, W5200, W5500을 통합한 Library이다. PSoC 사용자에게는 아주 유용한 Library가 될 것이다.

[Refer to WIznet Museum]
[Download Library]

Library for BASIC Language Users

이 Library는 특이하게 일반적인 C library가 아닌 Basic 언어로 작성된 Library이다.

PIC 과 ATmega MCU를 지원한다.

PIC Library

[Refer to WIznet Museum]
[Download Library]
[How to Use]

ATmega Library

[Refer to WIznet Museum]
[Download Library]
[How to Use]

BSD SOCKET

다음 표는 ioLibrary와 BSD Socket Library와의 지원 함수를 비교한 것이다.

ioLibrary BSD Sccket
socket() O O
bind() X O
listen() O O
accept() X O
send() & recv() O O
sendto() & recvfrom() O O
select() & poll() X O

WIZnet의 ioLibrary는 BSD Socket과 달리 bind()accept() 함수를 지원하지 않는다.

BSD Socket Library인 경우, 다음 그림처럼 bind()에 의해 source port가 할당되고 socket resource와 바인딩된다. 또한, client의 접속을 accept()를 통해 대기하며, client 접속 요구가 있을 경우, 새로운 socket을 생성하고 임의의 source port로 바인딩하여 이를 data communication socket으로 사용한다.

ioLibrary인 경우, BSD Socket의 socket()와 bind() 함수를 ioLibrary의 socket() 함수 하나로 통합되어 있다.

또한, 아래 그림처럼 Socket resource는 BSD와 달리 동적으로 할당받는 것이 아니라, 이미 Chip에 존재하는 Hardwired socket을 그대로 사용함ㅇ로 accept() 함수가 필요없다. 즉, ioLibrary의 listen socket은 client의 접속 요구를 항상 대기하고 있으며, client의 요구가 받아질 경우 곧바로 Data communication socket으로 역할을 변경한다. 여러 client의 접속 요구를 받아들이기 위해서는 client 수 만큼 listen socket을 생성하여야 한다.

이러한 차이에도 불구하고, WIZnet chip은 아래와 같이 BSD socket Library를 지원한다.

BSD Socket by using ioLibrary

이 Library를 위즈네트의 ioLibrary에 bind()와 accept() 함수를 추가 구현한 Library이다.
여기서 이 함수는 아래와 같이 empty function으로 구현하여 BSD와의 호환성만을 유지한 것 같다.


int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
   return 0;
}
int bind(int s, const struct sockaddr *name, socklen_t namelen)
{
   return 0;
}

이것보다는 아래와 같이 구현하는 것이 좀 더 정확한 구현이 될 것이다.


int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
   struct sockaddr_in * destaddr = (struct sockaddr_in *)addr;
   while(getSn_SR(s) != SOCK_ESTABLISHED)
   {
      if(getSn_IR(s) & Sn_IR_TIMEOUT) return -1;
   }
   destaddr->sin_family = AF_INET;
   destaddr->sin_port = getSn_DPORTR(s);
   destaddr.sin_addr.s_addr = ntohl(getSn_DIPR(s));
   return 0;
}
int bind(int s, const struct sockaddr *name, socklen_t namelen)
{
   setSn_PORTR(((struct sockaddr_in *)name)->sin_port);
   return 0;
}

[Refer to WIZnet Musuem]
[Download Library]

POSIX BSD Socket

POSIX BSD Library와 가장 유사하게 구현된 Library로 BSD Socket Library로 구현된 다양한 Application을 손쉽게 Porting 할 수 있다.
select()와 poll(), 그리고 getsockoptH()와 setsockopt() 함수도 구현되어 있다.


int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    int ret;
    struct w5100_socket *s;

    s = get_socket_from_fd(sockfd);
    if (s == NULL)
    {
        ret = -1;
    }
    else if ( addr->sa_family != AF_INET )
    {
        errno = EAFNOSUPPORT;
        ret = -1;
    }
    else if (s->state != W5100_SOCK_STATE_CREATED)
    {
        errno = EINVAL;
        ret = 1;
    }
    else if (s->type == SOCK_STREAM)
    {
        struct sockaddr_in *server;
        uint8_t sr;
        uint8_t sr_end;

        (void)addrlen;
        server = (struct sockaddr_in *)addr;

        /* TODO: check if already in use EADDRINUSE */
        w5100_write_sock_regx(W5100_Sn_PORT, s->isocket, &server->sin_port);
        w5100_command(s->isocket, W5100_CMD_OPEN);
        sr_end = W5100_SOCK_INIT;
        do {
            sr = w5100_read_sock_reg(W5100_Sn_SR, s->isocket);
        } while (sr != sr_end);
        s->sockname = *server;
        s->state = W5100_SOCK_STATE_BOUND;
        ret = 0;
    }
    else if (s->type == SOCK_DGRAM)
    {
        struct sockaddr_in *server;
        (void)addrlen;

        server = (struct sockaddr_in *)addr;
        bind_udp(s, server->sin_port);
        ret = 0;
    }
    else
    {
        /* TODO: RAW */
        errno = EBADF;
        ret = -1;
    }
    return ret;
}

[Refer to WIZnet Musuem]
[Download Library]
[How to Use]


블로그 이미지

밤소 MidnightCow

위즈네트 칩(W5300, W5200, W7100, W7500) 개발자

Home Automation with OpenHAB



WIZnet Museum에서는, 아래와 같은 Home Automation을 구현한 다양한 예제가 많이 소개되어 있다.

  • Relay 제어를 통한 전등 On/OFF
  • 온습도, 가스 누출, 누수 감지와 같은 각종 센서를 이용한 Data Logging, Monitoring, Alert 기능
  • Xively와 같은 Cloud Server를 이용한 Home Automation




여기서 소개할 다양한 Home Automation 중에 OpenHAB Server를 활용한 응용사례에 살펴 볼 것이다.

OpenHAB (Open Automation Bus)

먼저, OpenHAB는 Kai Kreuzer 가 2010년부터 개발한 오픈 소스 홈 자동화 서버이다. 이 프로그램은 Equinox (Eclipse PDE) OSGi(Open Service Gateway initiative) 프레임워크 상에서 자바로 구현되었으며, 현재까지 많은 개발자들이 참여하여 활발하게 개발되고 있다. openHAB 는 The Thing System 과 마찬가지로 KNX, Z-Wave, Insteon, Arduino, Ethernet, MQTT 등 수많은 다양한 사물인터넷 기기와 프로토콜을 지원하여 동적으로 바인딩할 수 있도록 설계되었다. 간단히, 가정에 있는 각종 전자 제품을 물리적 연결(Hardware connection such as serial, ethernet, and wifi)이나 소프트웨어(software protocol such as XMPP, MQTT, and REST api)에 제약없이 연결되어 서비스할 수 있도록 설계된 Home Gateway라 생각하면 된다. 자세한 내용은 OpenHAB 사이트를 참조하라.

Arduino Ethernet Board나 WIZwiki-W7500과 같은 IoT platform을 이용한다면 가정에 있는 대부분의 가전 제품은 자동화 할 수 있으며, 언제, 어디서든지 손쉽게 제어하고 감시할 수 있다.

Home Automation with OpenHAB

WIZnet Museum에는 아래와 같이 OpenHAB을 활용한 Home Automation 예제가 있으며, 특히 Uber Home Automation 나, Another Home Automation - Forget Me Not 과 같은 example은 Home Automation이 어떻게 구현되고 어떻게 응용될 수 있는 아주 잘 보여주는 예제라 할 수 있다.

블로그 이미지

밤소 MidnightCow

위즈네트 칩(W5300, W5200, W7100, W7500) 개발자

The successful project with WIZnet products on the crowdfunding site



위즈네트 제품을 이용하여, Startup을 꿈꾸는 maker들이 KickstarterIndieGoGo와 같은 crowdfunding site를 통해 Funding에 성공한 사례들이 WIZnet museum에는 어떤 것들이 있으며, 어떤 특징들이 있는지 알아보자.

현재까지 WIZnet museum에는 6 project가 소개되어 있으며, 다음과 같이 특징 지을 수 있다.

  • Applications
    특정 기능을 서비스하는 제품, 상용 제품
  • Open Source Hardware Platform for IoT Devices
    Maker나 Developer의 제품 Prototype을 위한 개발 보드
  • Software Framework
    Arudino Libarary와 같이 Software를 손쉽게 개발할 수 있는 API Library와 개발환경 IDE를 제공하는 서비스

이와 같이, W5100, W5500과 같은 WIZnet 고유의 Hardwired TCP/IP Ethernet Controller는 손쉽게 Maker들이 Internet Connectivity 기능을 구현하여, 보다 빠르고보다 쉽고, 보다 싸고, 보다 간단한 IoT 아이디어 제품을 만들 수 있도록 도와 준다.



The crowdfunded projects in KickStarter & IndieGoGo

다음은 WIZnet Museum에 소개되어 있는 Crowdfunding에 성공한 Project 사례 들이다.





블로그 이미지

밤소 MidnightCow

위즈네트 칩(W5300, W5200, W7100, W7500) 개발자

Remote Control with WIZnet TCP/IP or WiFi Solution

By MidnightCow

위즈네트뮤지엄(WIZnet Museum)에는 2014년 12월 현재 Remote Control 응용에 대한 50여개의 컨텐츠를 참조할 수 있다. Remote Control이라함은 말그대로 원격지에 원하는 장치나 기구 등을 제어할 수 있는 응용으로. 요즘 핫이슈가 되고 있는 Internet Of Things(IoT) 응용의 가장 대표적인 예가 될 것이다.

Alt Text

그럼 Remote Control을 구현함에 있어 기본적으로 알아야할 몇가지를 알아 보자.

  • 무엇을 제어할 것인가?
    보일러, 전등, 도어록, 에어콘, 선풍기 등 현 세상에 존재하는 모든 장치나 기구를 제어할 수 있다
  • 어떻게 제어할 것인가?
    장치나 기구를 제어하는 방법은 그 기구가 사용하는 제어방식에 따른다.
    일반적으로 GPIO를 통해서 제어되며, Device 간 Local 통신 방식인 UART, SPI, I2C, PWM 등으로 제어된다.
  • 원격지 지원(Internet)을 위해 어떤 솔루션을 사용할 것인가?
    ZigBee, X10, BuleTooth 와 같은 Local 통신방신과 이를 원격으로 변환하는 게이트웨이 장치를 이용하는 방법이 있으며, 게이트웨이를 사용하지 않고 Ehternet이나 WiFi를 사용하여 각종 장치나 기구를 직접 제어하는 방식 크게 두가지 정도가 있을 수 있을 것이다.

여기서는 아래와 같이 설명한다.

  1. 무엇을 제어할 것인가는 Anything…
  2. 어떻게 제아할 것인가는 가장 많이 활용되고 있는 GPIO 포트 제어를 통해
  3. 원격지 지원은 WIZnet SolUtion을 사용 (TCP/IP Ethernet / WizFi2X0)

GPIO를 통한 Remote control

일반적으로 GPIO 제어는 단순히 GPIO 값을 High, Low로 변경하는 것만으로 쉽게 이루어진다.
하지만 GPIO를 통해 제어를 하고자 하는 경우 주의사항을 살펴 보자.
먼저 제어하고하는 장치의 GPIO 입력 전압을 고려해야 한다.
대부분 3.3V 동작 전압에 5V IO tolerent를 사용하지만 그렇지 않을 경우 전압을 분리하는 방법을 사용해야 한다.

  1. 3.3V with 5V IO tolerent 기반의 MCU를 사용하고 제어하는 장치 역시 같은 전압을 사용할 경우
    GPIO를 해당 디바이스와 직접 연결하여 사용할 수 있다. LED 제어를 생각해보자. LED는 LED 보호용 저항을 이용하여 GPIO에 바로 연결하여 On/OFF를 제어할 수 있다. 간단히 구성할 수 있기 때문에 더 이상 설명은 하지 않겠다.

  2. 제어하는 장치가 MCU의 동작 전압과 다를 경우

    예로 220V 형광등을 제어한다고 생각 해보자. 3.3V GPIO를 연결하는 순간 무슨일이 일어날지 상상할 수 없다.
    이 경우는 GPIO를 바로 연결할 경우 MCU가 Electroic Damage를 입을 있으며, MCU의 고장 원인 된다.
    그렇다면 어떻게 이런 장치를 제어할 수 있을까? 방법은 두 전압을 분리 시키는 것이다. 두 전압을 분리시키는 방법에 대해서 2가지 정도를 간략히 설명하겠다.

    A. Relay를 사용하는 경우
    Alt Text
    먼저 릴레이의 원리는 간단한다. 어릴때 배운 전자석의 원리를 안다면 쉽게 이해할 수 있다. V_in에 GPIO를 연결하고 High/Low를 인가할 경우 전자석이 작동하여 +/-를 연결하는 스위치를 On/Off한다.

    B. Photo-Coupler를 사용하는 경우
    Alt Text
    Photo-Coupler 역시 Relay와 동일한 방식으로 동작한다. 차이점은 전자석 대신 빛을 이용한다는 것이다.
    1번 PIN에 GPIO를 연결, 2번 PIN에 Ground를 연결하고, 3번 4번 PIN에 제어를 원하는 장치를 연결한다.
    1번 PIN에 High/Low를 인가할 경우 내부 LED가 On/Off되고, 3번 4번 PIN이 연결/단락된다.

원격지원을 위한 WIZnet Soultion

위즈네트뮤지엄(WIZnet Museum)에는 Arduino Ethernet 뿐만 아니라 다양한 Open source hardware platformd을 기반으로 하는 Ethernet/WiFi 응용 예와 사용법등을 한 눈에 볼 수 있다.

  1. TCP/IP Ethernet solution
    WIZnet사는 3100을 시작으로 W5100, W5200, W5300, W5500 과 같은 Fully Hardwired TCP/IP Ethernet Controller 칩을 공급한다. Ethernet 기반 원격지원을 하고자 할 경우 이 Solution을 사용한다.
    Alt Text

  2. WiFi Solution
    WIZnet사는 WizFi210과 WizFi250을 제공한다. WizFi2x0은 AT command 기반으로 UART나 SPI Interface를 통해 WiFi를 지원한다.
    Alt Text


Content on WIZnet Museum

다음은 위즈네트뮤지엄에 소개되어 있는 Remote Control 응용 사례들이다.

  1. 단순 GPIO를 이용한 LED 제어

    http://wiznetmuseum.com/portfolio-items/arduino-ethernet-shield-tutorial/

  2. Relay와 GPIO를 이용한 원격 제어

    http://wiznetmuseum.com/portfolio-items/arduino-web-server-with-bmini-ethernet-relay-shield-biemme-automations/

  3. WizFi250을 이용한 GPIO 원격제어

    http://wiznetmuseum.com/portfolio-items/control-moter-driver-using-wizfi250/


Reference

위즈네트 홈페이지 : http://www.wiznet.co.kr/
위즈네트 위키페이지 : http://wizwiki.net/
위즈네트 포럼 : http://wizwiki.net/forum/
아두이노 홈페이지 : http://www.arduino.cc/

블로그 이미지

밤소 MidnightCow

위즈네트 칩(W5300, W5200, W7100, W7500) 개발자