2012年5月1日火曜日

Ethernet Shield

Arduino の特徴として”Shields"(シールド)と呼ばれる、スタック基板での拡張があります。PC104等で使うような足長のピンソケットで基板を積み重ねて、ブロック感覚で機能拡張ができます。この手法は、自分もH8やSHマイコンで実験回路を組むときによく使います。 今回は「Ethernet Shield」(イーサネットシールド)を入手して、お試ししてみました。




Arduino は UNO R3 で Ethernet Shield は microSDスロット付きのR3です。ArduinoとEthernet ShieldはSPIを使って通信しているようです。SPI通信に使用しているのはICSPの6ピン端子のようです。加えてmicroSDの制御用にD4ピンが使われているようです。ってことは、ICSPで接続できないArduinoではこのEthernet Shieldは使えないってことかな?ちなみにEthernetのコントローラはWiznetの W5100 です。

Arduino-IDEのサンプルを元に、telnetでArduinoに接続して文字を送信すると、Arduinoが受信した文字をエコーバックしつつ、シリアル(USB)に出力しつつ、microSDにも書き込むような動きをさせてみました。


#include <spi.h>
#include <ethernet.h>
#include <sd.h>

// DHCPか固定IPかの選択。(trueでDCHCP)
boolean isEnableDHCP = false;

// ネットワーク設定。
/// MACアドレスは必須。シールド裏側のシールを参照。
byte mac[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/// 以下、固定IPの場合に適宜設定。
IPAddress ip(123, 123, 123, 123);
IPAddress gateway(123, 123, 123, 123);
IPAddress subnet(255, 255, 255, 0);

// port23(telnet)でサーバーオブジェクト作成。
EthernetServer server(23);
boolean gotAMessage = false;

// SDカード書込み用ファイル。
File sdFile;

// 初期化。
void setup()
{
// シリアルポートの初期化。
Serial.begin(9600);

// Ethernetデバイスの初期化。
Serial.print("Initializing Ethernet...");
if (isEnableDHCP == true)
{
/// DHCPで初期化。
if (Ethernet.begin(mac) == 0)
{
//// DHCP取得に失敗。
Serial.println("Failed to configure Ethernet using DHCP");
while(true);
}
else
{
//// DHCP取得できたら、IPをシリアルに出力。
Serial.print("IP Address: ");
for (byte b = 0; b < 4; b++)
{
Serial.print(Ethernet.localIP()[b], DEC);
Serial.print(".");
}
Serial.println();
}
}
else
{
// 固定IP。
Ethernet.begin(mac, ip, gateway, subnet);
}

// SDカードの初期化。
Serial.print("Initializing SD card...");
//pinMode(10, OUTPUT);
if(!SD.begin(4))
{
Serial.println("SD card initialization failed!");
return;
}

// リスナ開始。
server.begin();

// ファイルオープン。
sdFile = SD.open("test.txt", FILE_WRITE);
// ファイルへ書き込み。
Serial.println("Writing to test.txt...");
sdFile.println("Start...");
// ファイルクローズ。
sdFile.close();

}

// メインループ。
void loop()
{
// クライアント接続を取得。
EthernetClient client = server.available();

// クライアント接続があれば、
if (client) {
// メッセージ有り状態で無い(接続開始)なら
if (!gotAMessage) {
// シリアルポートにメッセージ出力。
Serial.println("We have a new client");
// メッセージ有り状態へ。
gotAMessage = true;
}

// クライアントからのデータを取得。
char thisChar = client.read();
// クライアントへエコーバック。
server.write(thisChar);
// シリアルポートへも出力。
Serial.print(thisChar);

// ファイルへも書込み。
sdFile = SD.open("test.txt", FILE_WRITE);
sdFile.print(thisChar);
sdFile.close();

}
}