Wizarduino WIFI로 CoAP 통신하기

1. CoAP란?

CoAP_main


이번 예제에서는 Wizarduino WIFI를 이용하여 CoAP통신을 하려고 합니다.

arduino의 간단한 예제를 이용하여 구현방법을 소개하겠습니다.

먼저, CoAP란 Constrained Application Protocol의 약자로 저사양 모듈을 위한 application 프로토콜 입니다.

다시 말해 HTTP를 사용하고 싶으나, 리소스가 제한된 WPAN 기기를 위한 lightweight 버전이라고 볼 수 있습니다.

저전력을 지향하고, 센서 데이터 전달이 주된 목적이며, 비동기적인 요청/응답 디자인 구조를 지녔습니다.

method는 GET, POST, PUT, DELETE 총 네가지가 있습니다.

HTTP와 비교하면 아래와 같은 layer를 가집니다.

application CoAP HTTP
Session DTLS SSL/TLS
Transport UDP TCP
Network 6LoWPAN(IPv6) IP
Data Link 802.15.4 MAC 802.3 MAC
Physical 802.15.4Phy 802.3 Phy

2. Setup

Server와 Client 구성을 위해 두개의 Wizarduino WIFI를 사용하였습니다.


아두이노 예제를 수정하여서 Client에서 조도센서 데이터값을 읽어 light ON/OFF를 판단하여 서버로 전송하면, 서버측에서 LED를 ON/OFF 해주도록 할것입니다.


우선, Wizarduino WIFI는 Mega 2560기반이기 때문에 Mega보드를 선택해줍니다.


Add_Megaboard

다음으로는 library를 추가해야합니다.


Wizarduino WIFI에는 WizFi310칩이 들어있기때문에 WizFi310라이브러리와 우리가 사용할 CoAP라이브러리를 별도로 설치해 주어야합니다.

WizFi310의 경우, 아래 경로의 github에서 라이브러리를 다운받아 줍니다.


https://github.com/Wiznet/WizFi310_arduino_library

다운받은 라이브러리를 압축을 풀어 아래경로에 복사해줍니다.


C:\Users\”username”\Documents\Arduino\libraries

Route

CoAP는 라이브러리 관리에서 CoAP로 검색하여 가장 상단에 있는 library를 설치해주면 됩니다.


Add_library


3. CODE – Server

위에서 CoAP Simple library를 설치해주었다면 파일-예제에서도 CoAP Simple library를 볼 수 있을겁니다.


coapserver를 선택해주세요

(1) 먼저 include파일을 바꿔주어야 합니다.

우선 이 예제는 Ethernet 기반으로 만들어져 있습니다.


우리는 WIFI를 이용할 것이기 때문에 그에 맞는 파일을 include해줍니다.

(Dhcp, Dns, SPI의 경우 WizFi310.h안에서 포함하고 있으므로 지워줘도 됩니다.)


CoAP_wifi_header

(2) network 설정을 변경해주세요.

WIFI를 사용하고 있으므로 network설정을 변경해주어야합니다.
우선 접속가능한 wifi ID와 PASS를 설정해줍니다.


CoAP_network1

setup부분에서도 WIFI용으로 변경해 주어야합니다.
CoAP_network2


(printWifiStatus()함수의 경우 필수적이지는 않지만, 정확한 정보확인을 위해서 사용하시는것이 좋습니다. 함수의 내용은 아래와 같습니다.)

void printWifiStatus() {
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

(3) LED PIN 설정.

저는 Digital 9번 PIN에 LED가 연결되어있습니다. 다른 pin에 연결하실 분들은 40,43번째 줄을 수정해주세요 (Setup에서 digital mode 설정한 부분도 수정해 주세요)


CoAP_server_led

(4) 이 예제에서는 client에서 보내는 데이터를 server가 수신하기만하면 됩니다.

따라서 server에서는 request를 보낼 필요가없으므로 아래부분을 주석처리해주세요.


CoAP_server_loop

(5) code

#include <WizFi310.h>
#include <WizFi310Udp.h>
#include <coap.h>


char ssid[] = "WIZ_EK";       // your network SSID (name)
char pass[] = "wiznet218";        // your network password
int status = WL_IDLE_STATUS;       // the Wifi radio's status


// CoAP client response callback
void callback_response(CoapPacket &packet, IPAddress ip, int port);

// CoAP server endpoint url callback
void callback_light(CoapPacket &packet, IPAddress ip, int port);

// UDP and CoAP class
WiFiUDP Udp;
Coap coap(Udp);

// LED STATE
bool LEDSTATE;

void printWifiStatus();

// CoAP server endpoint URL
void callback_light(CoapPacket &packet, IPAddress ip, int port) {
  Serial.println("[Light] ON/OFF");

  // send response
  char p[packet.payloadlen + 1];
  memcpy(p, packet.payload, packet.payloadlen);
  p[packet.payloadlen] = NULL;

  String message(p);

  if (message.equals("0")){
    Serial.println("false");
    LEDSTATE = false;
  }
  else if(message.equals("1")) {
    Serial.println("true");
    LEDSTATE = true;
  }

  if (LEDSTATE) {
    digitalWrite(9, HIGH) ; 
    coap.sendResponse(ip, port, packet.messageid, "1");
  } else { 
    digitalWrite(9, LOW) ; 
    coap.sendResponse(ip, port, packet.messageid, "0");
  }
}

// CoAP client response callback
void callback_response(CoapPacket &packet, IPAddress ip, int port) {
  Serial.println("[Coap Response got]");

  char p[packet.payloadlen + 1];
  memcpy(p, packet.payload, packet.payloadlen);
  p[packet.payloadlen] = NULL;

  Serial.println(p);
}

void setup() {

    // initialize serial for debugging
  Serial.begin(115200);
  Serial3.begin(115200);
  Serial.println(F("\r\nSerial Init"));

  WiFi.init(&Serial3);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");

  printWifiStatus();

  Serial.println();

  // LED State
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  LEDSTATE = true;

  // add server url endpoints.
  // can add multiple endpoint urls.
  // exp) coap.server(callback_switch, "switch");
  //      coap.server(callback_env, "env/temp");
  //      coap.server(callback_env, "env/humidity");
  Serial.println("Setup Callback Light");
  coap.server(callback_light, "light");

  // client response callback.
  // this endpoint is single callback.
  Serial.println("Setup Response Callback");
  coap.response(callback_response);

  // start coap server/client
  coap.start();
}

void loop() {
  // send GET or PUT coap request to CoAP server.
  // To test, use libcoap, microcoap server...etc
  // int msgid = coap.put(IPAddress(10, 0, 0, 1), 5683, "light", "1");
 // Serial.println("Send Request");
 // int msgid = coap.get(IPAddress(192, 168, 0, 67), 5683, "time");
  delay(1000);
  coap.loop();
}

void printWifiStatus() {
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

/*
if you change LED, req/res test with coap-client(libcoap), run following.
coap-client -m get coap://(arduino ip addr)/light
coap-client -e "1" -m put coap://(arduino ip addr)/light
coap-client -e "0" -m put coap://(arduino ip addr)/light
*/

CODE – Client

client에서는 coaptest 예제를 선택해서 열어주세요

(1) Server에서와 마찬가지로 include파일 수정, network설정변경을 해줍니다.

(2) 조도센서 데이터를 읽어서 request를 보내주어야 합니다. 아래와 같이 수정해주세요.

server ip에 맞게 설정해주고, 조도센서가 연결되어있는 핀값을 읽어옵니다.

(저는 A1에 조도센서가 연결되어있습니다.)


조도센서값이 250이상일 경우에 LED를 ON하도록 데이터를 보내주었습니다.


CoAP_wifi_client_loop

(3) code

#include <WizFi310.h>
#include <WizFi310Udp.h>
#include <coap.h>


char ssid[] = "WIZ_EK";       // your network SSID (name)
char pass[] = "wiznet218";        // your network password
int status = WL_IDLE_STATUS;       // the Wifi radio's status


// CoAP client response callback
void callback_response(CoapPacket &packet, IPAddress ip, int port);

// UDP and CoAP class
WiFiUDP Udp;
Coap coap(Udp);

void printWifiStatus();

// CoAP client response callback
void callback_response(CoapPacket &packet, IPAddress ip, int port) {
  Serial.println("[Coap Response got]");

  char p[packet.payloadlen + 1];
  memcpy(p, packet.payload, packet.payloadlen);
  p[packet.payloadlen] = NULL;

  Serial.println(p);
}

void setup() {
   // initialize serial for debugging
  Serial.begin(115200);
  Serial3.begin(115200);
  Serial.println(F("\r\nSerial Init"));

  WiFi.init(&Serial3);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  Serial.println("You're connected to the network");

  printWifiStatus();
  Serial.println();


  // client response callback.
  // this endpoint is single callback.
  Serial.println("Setup Response Callback");
  coap.response(callback_response);

  // start coap server/client
  coap.start();
}

void loop() {
  // send GET or PUT coap request to CoAP server.
  // To test, use libcoap, microcoap server...etc
  int msgid;
  int cdsVal=analogRead(A1);
  Serial.print("Cds value : ");
  Serial.println(cdsVal);
  if(cdsVal>=250) {
    msgid = coap.put(IPAddress(192, 168, 0, 70), 5683, "light", "1");
  }
  else {
    msgid = coap.put(IPAddress(192, 168, 0, 70), 5683, "light", "0");
  }

  Serial.println("Send Request");
  //int msgid = coap.get(IPAddress(XXX, XXX, XXX, XXX), 5683, "time");

  delay(1000);
  coap.loop();
}

void printWifiStatus() {
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Result

조도센서를 가렸다가 뗐을때의 결과입니다.


CoAP_wifi_Serial


응용해보세요~~~!