📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

ページの作成:「== 概要 == <br><br> == Ethernetシールド == ==== DHCPの利用 ==== ArduinoでEthernetシールド等を使用する場合、プログラムで明示的にIPアド…」
 
 
(同じ利用者による、間の3版が非表示)
3行目: 3行目:
<br><br>
<br><br>


== Ethernetシールド ==
== EthernetシールドとDHCPの利用 ==
==== DHCPの利用 ====
ArduinoでEthernetシールド等を使用する場合、プログラムで明示的にIPアドレスを指定するのではなく、<br>
ArduinoでEthernetシールド等を使用する場合、プログラムで明示的にIPアドレスを指定するのではなく、<br>
DHCPで自動的にIPアドレスの割り当てを行う方法を記載する。<br>
DHCPで自動的にIPアドレスの割り当てを行う方法を記載する。<br>
31行目: 30行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br><br>
==== Webサーバの実装 ====
 
== EthernetシールドとWebサーバの実装 ==
このセクションでは、Arduinoの標準のEthernetライブラリを使用して、単純なWebサーバを実装する。<br>
このセクションでは、Arduinoの標準のEthernetライブラリを使用して、単純なWebサーバを実装する。<br>
簡単なWebサーバの実装例はExampleに含まれている。<br>
簡単なWebサーバの実装例はExampleに含まれている。<br>
148行目: 148行目:
       client.stop();
       client.stop();
       Serial.println("Client disconnected");
       Serial.println("Client disconnected");
    }
}
</syntaxhighlight>
<br><br>
== EthernetシールドとArduinoの遠隔操作 ==
Arduinoのメリットの1つに、各種シールドと開発環境における各種ライブラリの存在が挙げられる。<br>
<br>
例えば、Arduino UnoをLANに接続するには、Ethernetシールドのみ準備することで、Arduino Unoにネットワーク機能を追加することができる。<br>
そして、そのネットワーク機能はハードウェアの違いを意識せずに、Ethernetライブラリを使用することで実現できる。<br>
さらに、プログラミングインターフェイスとして、ソケットよりも抽象化されたサーバオブジェクトとクライアントオブジェクトが用意されている。<br>
<br>
このセクションでは、ArduinoとEthernetシールドを使用したLED遠隔操作ソフトウェアを作成する。<br>
ホストPC上のソフトウェアONボタンまたはOFFボタンを押下することで、Arduinoに接続されたLEDを制御する。<br>
また、ArduinoとホストPCは、有線LANケーブルを使用してルータまたはハブに接続する。<br>
<br>
Arduinoのソースコードでは、TCP 50000番をリスニングしており、データ<code>S:1</code>を受信するとLEDを点灯、データ<code>S:0</code>を受信するとLEDを消す。<br>
ホストPCのソフトウェアでは、ONボタンを押下した時はArduinoにデータ<code>S:1</code>を送信、OFFボタンを押下した時はデータ<code>S:0</code>を送信する。<br>
このようなクライアントとサーバ間のデータ通信の取り決めのことを、プロトコルという。<br>
[[ファイル:Arduino Ethernet 1.jpg|フレームなし|中央]]
<br>
次に、ArduinoにEthernetシールドを接続する。<br>
下図に、Ethernetシールドの表面と裏面、接続図を示す。<br>
[[ファイル:Arduino Ethernet 2.jpg|フレームなし|中央]]
<br>
下図に、ArduinoとLEDの接続を示す。<br>
8番ピンのデジタル出力を使用している。<br>
ここでは、抵抗は470[Ω]を使用しており、流れる電流は<math>I = \frac{5 \mbox{[V]} - 2.1 \mbox{[V]}}{470 [\Omega]} = 6 \mbox{[mA]}</math>である。<br>
[[ファイル:Arduino Ethernet 3.jpg|フレームなし|中央]]
<br>
以下に、Arduino Unoのソースコードを記述する。<br>
データ<code>S:1</code>でLEDを点灯、データ<code>S:0</code>でLEDを消す。その他のデータを受信した場合、クライアントがそのデータを捨てる。<br>
1バイトずつにデータを取得するため、下図のような状態遷移となる。<br>
[[ファイル:Arduino Ethernet 4.jpg|フレームなし|中央]]
<br>
MACアドレスは、一意性のある6バイトを設定する。(ここでは、0xDE 0xAD 0xBE 0xEF 0xF0 0x0Dとしている)<br>
ネットワークアドレスは192.168.1.0/24、ArduinoのIPアドレスは192.168.1.10(固定)、ポート番号は、TCP 50000番とする。<br>
<syntaxhighlight lang="c++">
#include <EthernetServer.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <Dhcp.h>
#include <Dns.h>
#include <EthernetUdp.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D };
byte ip[] = { 192, 168, 1, 10 };
EthernetServer server(50000);
const int STATE_INIT = 0;
const int STATE_1 = 1;
const int STATE_2 = 2;
const int STATE_3 = 3;
const int PIN_LED = 8;
void setup()
{
    Ethernet.begin( mac, ip );
    server.begin();
    pinMode( PIN_LED, OUTPUT );
    digitalWrite( PIN_LED, LOW );
}
void loop()
{
    EthernetClient client = server.available();
    int state = STATE_INIT;
    int i;
    if(client)
    {
      while(client.connected())
      {
          while( ( i = client.read() ) != -1 )
          {
            if( state == STATE_INIT )
            {
                if( i == 'S' )
                {
                  state = STATE_1;
                }
                else
                {
                  client.stop();
                  break;
                }
            }
            else if( state == STATE_1 )
            {
                if( i == ':' )
                {
                  state = STATE_2;
                }
                else
                {
                  state = STATE_INIT;
                  client.stop();
                  break;
                }
            }
            else if( state == STATE_2 )
            {
                if( i == '1' )
                {
                  switch_led(1);
                  client.print("OK");
                }
                else if( i == '0' )
                {
                  switch_led(0);
                  client.print("OK");
                }
                state = STATE_INIT;
                client.stop();
                break;
            }
          } 
      }
    }
}
void switch_led(int on)
{
    digitalWrite( PIN_LED, on ? HIGH : LOW ); 
}
</syntaxhighlight>
<br>
最後に、ホストOSのソフトウェア(.NET Frameworkの<code>TcpClient</code>クラスを使用)のソースコードを記述する。<br>
ここでは、Windowsで利用可能なC#と.NET Frameworkを利用して、上述のプロトコルをサポートするTCPクライアントを作成する。<br>
下図に示すソフトウェアのUIでは、ArduinoのIPアドレスとポート番号を指定できるようにしている。<br>
[[ファイル:Arduino Ethernet 5.jpg|フレームなし|中央]]
<syntaxhighlight lang="c#">
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace LightApp
{
    public partial class Form1 : Form
    {
      public Form1()
      {
          InitializeComponent();
      }
      private void button1_Click( object sender, EventArgs e )
      {
          SendCommand( true );
      }
      private void button2_Click( object sender, EventArgs e )
      {
          SendCommand( false );
      }
      void SendCommand( bool on )
      {
          try
          {
            var port = int.Parse(textBox2.Text);
            using(var client = new TcpClient(textBox1.Text, port))
            {
                using(NetworkStream stream = client.GetStream())
                {
                  // データの送信 "S:0" または "S:1"
                  Byte[] TxData = System.Text.Encoding.ASCII.GetBytes(string.Format("S:{0}", on ? "1" : "0"));
                  stream.Write(TxData, 0, TxData.Length);
                  // データの受信
                  var RxData = new Byte[256];
                  Int32 bytes = stream.Read(RxData, 0, RxData.Length);
                  String responseData = System.Text.Encoding.ASCII.GetString(RxData, 0, bytes);
                }
            }
          }
          catch(Exception ex)
          {
            MessageBox.Show(ex.Message, "Switch", MessageBoxButtons.OK, MessageBoxIcon.Error);
          }
      }
     }
     }
  }
  }