Arduinoのネットワーク通信

Socket通信


Socket通信のクライアント側のスケッチは以下の様になります。
5秒ごとにメッセージをサーバー側に送って、サーバーからの応答を待ちます。
以下はENC28J60を使う場合ですが、W5100を使う場合もライブラリだけを変更すれば動きます。
/*
  * W5100/ENC28J60 Ethernet Module Socket Client example.
  */

#include <UIPEthernet.h> // https://github.com/UIPEthernet/UIPEthernet
//#include <SPI.h>
//#include <Ethernet.h>

#define INTERVAL       5000
#define SOCKET_HOST    "192.168.10.190" // You have to change
#define SOCKET_PORT    9876             // You have to change
#define TIME_OUT       10000

#define MODULE         "ENC28J60"
//#define MODULE         "W5100"

EthernetClient client;

unsigned long nextMillis;

void setup() {
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

  Serial.begin(9600);
  Serial.print("Ethernet begin....");
  if (!Ethernet.begin(mac) ) {
    Serial.println("faild");
    while(1) {}
  }
  Serial.println("ok");
  Serial.print("localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  nextMillis = millis();
}

void loop() {
  static int num = 0;
  char smsg[30];
  char rmsg[30];
  int rflag;
  unsigned long timeout;
  unsigned long now;

  now = millis();
  if ( long(now - nextMillis) > 0) {
    nextMillis = millis() + INTERVAL;
    Serial.print("Client connect....");
    if (!client.connect(SOCKET_HOST, SOCKET_PORT)) {
      Serial.println("failed");
    } else {
      Serial.println("ok");
      sprintf(smsg,"data from arduino %05d",num);
      num++;
      client.write(smsg, strlen(smsg));

      // wait for responce
      rflag = 1;
      timeout = millis();
      while(client.available() == 0) {
        now = millis();
//        Serial.println("now="+String(now));
//        Serial.println("timeout="+String(timeout));
        if (long(now - timeout) > TIME_OUT) {
          rflag = 0;
        }
      } // end while

      Serial.print("Server response....");
      if (rflag == 0) {
        Serial.println("failed");
      } else {
        Serial.println("ok");
        int size;
        while((size = client.available()) > 0) {
          Serial.print("["+String(MODULE)+" Socket Client]Receive Size=");
          Serial.println(size);
          size = client.read(rmsg,size);
          Serial.write(smsg,size);
          Serial.write("->");
          Serial.write(rmsg,size);
          Serial.println("");
        } // end while
      }

      //disconnect client
      Serial.println("Client disconnect");
      client.stop();
    } // end if
  } // end if
}



Socket通信のサーバー側のスケッチは以下の様になります。
クライアントから受け取った文字を小文字→大文字に変換してクライアントに応答します。
応答した後は、クライアントからの切断を待ちます。
以下はW5100を使う場合ですが、ENC28J60を使う場合もライブラリだけを変更すれば動きます。
クライアントのスケッチとはMACアドレスを変えています。
/*
 * W5100/ENC28J60 Ethernet Module TcpServer example.
 */

//#include <UIPEthernet.h> // https://github.com/UIPEthernet/UIPEthernet
#include <SPI.h>
#include <Ethernet.h>

#define SOCKET_PORT    9876             // You have to change
//#define MODULE         "ENC28J60"
#define MODULE         "W5100"

EthernetServer server = EthernetServer(SOCKET_PORT);

void setup()
{
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };
  byte myIP[] = { 192, 168, 10, 190 };

  Serial.begin(9600);
  Serial.print("Ethernet begin....");
  Ethernet.begin(mac,myIP);
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
//    Serial.println(Ethernet.localIP()[thisByte]);
    if (Ethernet.localIP()[thisByte] != myIP[thisByte] ) {
      Serial.println("fail....");
      while (1) {}
    }
  }

  Serial.println("ok....");
  Serial.print("localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());

  server.begin();
  Serial.println("Server Start");
}

void loop()
{
  size_t size;
  EthernetClient client;
 
  if (client = server.available()) {
    while((size = client.available()) > 0) {
//      size = client.available();
      Serial.print("["+String(MODULE)+" Socket Server]Receive size=");
      Serial.println(size);
      char* rmsg = (char*)malloc(size);
      char* smsg = (char*)malloc(size);
      memset(smsg,0,sizeof(smsg));
      size = client.read(rmsg,size);
      for (int i=0; i< size; i++){
        if(isalpha(rmsg[i])) {
          smsg[i] = toupper(rmsg[i]);
        } else {
          smsg[i] = rmsg[i];
        }
      } // end for
      Serial.write(rmsg,size);
      Serial.write("->");
      Serial.write(smsg,size);
      Serial.println("");

      free(rmsg);
      client.write(smsg,size);
      free(smsg);
    } // end while

    //wait for client disconnect
    while(1) {
      int r = client.connected();
//      Serial.println("r=" + String(r));
      if (r == 0) break;
    }
    Serial.println("client
disconnect");
    client.stop();
  }
}



クライアント側のIDEにはこのように表示されます。


サーバー側のIDEにはこのように表示されます。


次回は、MQTT通信を紹介します。

続く...