Arduino と Ethernet シールドを用いた LED 遠隔操作アプリの作成

Arduino を非常に便利なものにしているのは何といっても、各種シールドと開発環境における各種ライブラリの存在があげられます。

例えば、ここでは Arduino Uno を LAN に接続することを考えていますが、イーサネット・シールド (Ethernet Shield) さえ用意すれば、まるでレゴブロックの如く Arduino Uno にネットワーク機能を追加することが可能になります。

そして、そのネットワークの機能はソフトウェア開発環境からは特にハードウェアの違いを意識せずとも、Ethernet ライブラリを取り込めば利用可能です。

さらにプログラミングインターフェイスとしては、ソケットよりもより抽象化されたサーバーオブジェクト及びクライアントオブジェクトが用意されているので便利です。

それでは、早速ここで作るプログラムをみてみましょう。

Arduino と Ethernet シールドを用いた LED 遠隔操作アプリの作成

ここで作るプログラムは次のようなものです。

Windows 上のアプリケーションの ON/OFF ボタンを押すことによって、Arduino に接続された赤色 LED が ON/OFF できていることがわかりますね。

また、Arduino は Windows に直接接続されているのではなく、LAN ケーブルでネットワークに接続されています。

Arduino 上のソフトウェア (スケッチ) では、TCP ポート 8888 番をリスニングしており、 データ "S:1" を受けとると LED を ON に、"S:0" を受けとると LED を OFF にします

従って当然ながら、クライアントプログラムは ON ボタンを押下したときにサーバーに対して "S:1" というデータを送信し、OFF ボタンを押したときに "S:0" というデータを送信しています。

この辺は単に、「そのように実装した」と言うだけの話で、どんなデータを受け取ったときにサーバープログラム側で何をするかは適当に決めてください。

ちなみに、このようなクライアントとサーバー間のデータ通信の取り決めのことを「プロトコル」といいます。

イーサネット・シールドの接続

ここでは Arduino Uno を用いますが、Arduino Uno は基本的にネットワークインターフェイスを持っていませんので、ネットワークに接続するためのインターフェイスが必要になります。

ここでは Ethernet シールドを利用します。

裏面はこうなってます。

Arduino Uno にそのまま接続できます。

これで LAN ネットワークへの接続が可能になりました。

Arduino と LED の接続

LED の接続については次の通りです。8 番ピンのデジタル出力を使っています。

ここでは HIGH で 5V。抵抗は 470Ω としています。念のため確認しておくと、 (電流) = ( (電源電圧) - (順方向降下電圧) ) / (抵抗値) = ( 5V - 2.1V )/470Ω = 6[mA] です。

【参考】LED を点灯させる

Arduino Uno での LED サーバープログラムの作成

LED サーバーというと何だか大袈裟な感じはありますが、実際に TCP のサーバープログラムではあります。

プロトコルは単純で文字列データ "S:1" で LED を ON とし、 "S:0" で LED を OFF とします。

単に "1" を受け取って ON、"0" で OFF でも良かったのですが、今後の拡張性とかゴミ耐性とか少し気になったので、こんな感じにしてます。 想定したデータ以外が飛んできたら、クライアントをブチ切りします。

実装は1バイト毎に読むので次のような状態遷移をイメージして、コマンドを受け付けます。

スケッチ全体は次の通りです。

#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, 10, 10 };
EthernetServer server(8888);

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 );  
}

点滅も必要ないので、接続しているピンを HIGH/LOW 切り替えているだけです。

IP アドレスは 192.168.10.0/24 のネットワークを想定していて、192.168.10.10 にハードコードしてあります。 ポート番号も 8888 で固定としてます。

また、MAC アドレスもハードコードです。一意の 6 バイトを設定してください。ここでは適当に 0xDE 0xAD 0xBE 0xEF 0xF0 0x0D にしてます。

クライアントプログラムの作成

ここでは Windows で利用可能な .NET Framework を利用して、上述のプロトコルをサポートする TCP クライアントを作成しました。

画面は次のように、Arduino の IP アドレスとポート番号を指定できるようにしてあります。

.NET Framework の TcpClient クラスを用いたデータ通信部分は次のようになります。

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 {
                Int32 port = int.Parse( textBox2.Text );
                TcpClient client = new TcpClient( textBox1.Text, port );
                Byte[] data = System.Text.Encoding.ASCII.GetBytes( string.Format( "S:{0}", on ? "1" : "0" ) );
                NetworkStream stream = client.GetStream();
                stream.Write( data, 0, data.Length );
                data = new Byte[256];
                String responseData = String.Empty;
                Int32 bytes = stream.Read( data, 0, data.Length );
                responseData = System.Text.Encoding.ASCII.GetString( data, 0, bytes );
                stream.Close();
                client.Close();
            } catch(Exception ex) {
                MessageBox.Show( ex.Message, "Switch", MessageBoxButtons.OK, MessageBoxIcon.Error );
            }

        }

    }
}

このアプリケーションを実行する Windows のネットワーク設定を次のようにします。

Ethernet のネットワークインターフェイスのプロパティを開きます。

IPv4 の設定を次のようにします。通常は DCHP が有効になっていると思いますが、IP アドレスを手動で入力しておきます。

このように構成した Windows を Arduino と同一のネットワークに接続します。接続した図は次のようになります。

以上で準備ができました。

Arduino に上記のスケッチをアップロードすれば、上記のビデオのように LED が ON/OFF できるはずです。

このプログラムは単に LED を点灯、消灯するだけのものですが、同様の仕組みでインターネットを介して Arduino が操作可能になります。 いよいよ IoT らしい応用になってきましたね。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 基礎からの IoT 入門