2009年11月28日

WOLリピータ(個別送信機能付き)

※なんだかよく分からないけど、arduino WOLリピーターを作りたい方は、こちらの初心者用の説明をどうぞ

昨日の続き

昨日はリピータ機能のみのものを紹介しましたが、今日は
登録した端末から可変抵抗器でターゲットを選択して、押しボタン押下でマジックパケットを送信する機能を持たせたものです。

使用部品は
CIMG3986.JPG
arduino2009×1
ethernet shield
×1
LCD (GDM1602K)×1
可変抵抗10k×1
半固定抵抗10k×1
抵抗10k×1
抵抗150×1
タクトスイッチ×1
ブレッドボード×1


回路図は多分こんな感じ。
WOLrepSender.gif

「arduino WOL リピーター」は、bjoern / arduino_oscというライブラリを利用してUDPを取り扱っています。リンクページからarduino_osc-tip.zipというファイルをダウンロードして、中にあるEthernet及びStringフォルダのファイルを、arduino IDEのフォルダ「\hardware\libraries\Ethernet」及び「\hardware\libraries\String」にコピーしてください。

当然ですが、ルーターでポートを開けて、開けたポートを「arduino WOL リピーター」に転送する設定が必要です。

以下スケッチ。

// WOLリピータ(個別送信機能付き)
// Digital 7, プッシュボタン(マジックパケット送信用)
// Analog 0, 可変抵抗器(送信先選択用)


// http://yutakalife.net/article/134042204.html

// 販売などの商用利用はご遠慮ください

// Copyright love4nature All Rights Reserved.

#include <WString.h>

#include <Ethernet.h>

#include <UdpRaw.h>

#include <LiquidCrystal.h>

// LCDピン接続:
// rs on pin 10
// rw on pin 9
// enable on pin 8
// d0, d1, d2, d3 on pins 5, 4, 3, 2
// 使用するピンの定義
LiquidCrystal lcd(10, 9, 8, 5, 4, 3, 2);

byte TargetMac1[] = { 0x00,0x00,0x00,0x00,0x00,0x00 }; // hostName1のMAC addressをセット
byte TargetMac2[] = { 0x00,0x00,0x00,0x00,0x00,0x00 }; // hostName2のMAC addressをセット
byte TargetMac3[] = { 0x00,0x00,0x00,0x00,0x00,0x00 }; // hostName3のMAC addressをセット

char hostName1[] = " hostName1 ";
char hostName2[] = " hostName2 ";
char hostName3[] = " hostName3 ";


// イーサネットの設定
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC address
byte ip[] = { 192, 168, 1, 200 }; // Arduino のIP address
byte gw[] = { 192, 168, 1, 1 }; // Gateway IP address
int localPort = 7; // 受信ポート(sndmagic version 0.2)を使用の場合は7番

// ターゲットのブロードキャストアドレスを指定
byte targetIp[] = { 192, 168, 1, 255};
int targetPort = 8000;

#define MAX_SIZE 192
// パケットサイズの最大値を設定
byte packetBuffer[MAX_SIZE]; // 受信パケット用バッファ
int packetSize; // 受信パケットのサイズが格納される
byte remoteIp[4]; // 送信元のIPアドレスを格納
unsigned int remotePort; // 送信元のポート番号を格納

int i;
int packetLen = 102;
byte packet[102];

void setup() {
Ethernet.begin(mac,ip,gw);
UdpRaw.begin(localPort);
lcd.begin(2,16);
lcd.clear(); // LCD表示をクリア
lcd.setCursor(4,0); // カーソルを1行目4カラム目にセット
lcd.print("arduino"); // 1行目にメッセージを表示
lcd.setCursor(2,1); // カーソルを2行目3カラム目にセット
lcd.print("WOL Repeater"); // 2行目にメッセージを表示
delay(2000);
lcd.clear();
lcd.print(" and Sender ");
delay(2000);
lcd.clear();

// 7番ピンをデジタル入力に設定
pinMode(7,INPUT);
Serial.begin(9600);
}

void loop() {
// アナログ0番ピンの可変抵抗器の値を読み込み341で割る
int val = analogRead(0)/341;

switch (val) {
case 1:
lcd.print(" Target host: ");
lcd.setCursor(0,1); lcd.print(hostName1);
break;
case 2:
lcd.print(" Target host: ");
lcd.setCursor(0,1); lcd.print(hostName2);
break;
case 3:
lcd.print(" Target host: ");
lcd.setCursor(0,1); lcd.print(hostName3);
break;
default:
lcd.print(" Target host:");
lcd.setCursor(0,1); lcd.print(hostName1);
}

// デジタル入力がHIGH(5V)でマジックパケットを作成
if(digitalRead(7)==HIGH){
delay(100); // チャタリング対策
packetSize = 126;
Serial.println(""); Serial.println("Sent packet to:"); Serial.println("");

for (int i = 0; i <= 5; i++){
packet[i] = 0xFF;
}

for (int i = 6; i <= packetLen; i++){
int j = abs((packetLen - i) % 6 - 6);
if ( j == 6 ) j = 0;
// 可変抵抗器の値に応じてターゲットを切り替える

switch (val) {
case 1:
packet[i] = TargetMac1[j];
break;
case 2:
packet[i] = TargetMac2[j];
break;
case 3:
packet[i] = TargetMac3[j];
break;
default:
packet[i] = TargetMac1[j];
}
}

if ( val == 1 ){
UdpRaw.sendPacket(packet,packetLen,targetIp,targetPort);
lcd.clear(); lcd.print("SentMagicPacket:");
lcd.setCursor(0,1); lcd.print(hostName1);
Serial.println(""); Serial.println(hostName1); Serial.println("");
delay(1000);
}
if ( val == 2 ){
UdpRaw.sendPacket(packet,packetLen,targetIp,targetPort);
lcd.clear(); lcd.print("SentMagicPacket:");
lcd.setCursor(0,1); lcd.print(hostName2);
Serial.println(""); Serial.println(hostName2); Serial.println("");
delay(1000);
}
if ( val == 3 ){
UdpRaw.sendPacket(packet,packetLen,targetIp,targetPort);
lcd.clear(); lcd.print("SentMagicPacket:");
lcd.setCursor(0,1); lcd.print(hostName3);
Serial.println(""); Serial.println(hostName3); Serial.println("");
delay(1000);
}

lcd.clear();

Serial.println("Magic packet ordering Done!");

for (int i = 0; i < packetLen; i++){
Serial.print(packet[i], HEX);
Serial.print(" ");
}
Serial.println(""); Serial.println("");
}

// 受信データがあれば実行(WOLリピータ機能)
if(UdpRaw.available()) {
packetSize = UdpRaw.readPacket(packetBuffer,MAX_SIZE,remoteIp,(uint16_t *)&remotePort);

Serial.print("Received packet of size ");
Serial.println(abs(packetSize));

Serial.print("From IP ");
for(i=0; i<3; i++) {
Serial.print(remoteIp[i],DEC);
Serial.print(".");
}
Serial.print(remoteIp[3],DEC);

Serial.print(" Port ");
Serial.println(remotePort);

if(packetSize < 0) {
Serial.print("ERROR: Packet was truncated from ");
Serial.print(packetSize*-1);
Serial.print(" to ");
Serial.print(MAX_SIZE);
Serial.println(" bytes.");
}

Serial.println("Contents:");
for(i=0; i<min(MAX_SIZE,abs(packetSize)); i++) {
Serial.print(packetBuffer[i],HEX);
Serial.print(" ");
}
Serial.println("");

// マジックパケットを送信
UdpRaw.sendPacket(packetBuffer,packetSize,targetIp,targetPort);
Serial.println("Start port forwarding to broadcast address:");
for(i=0; i<3; i++) {
Serial.print(targetIp[i],DEC);
Serial.print(".");
}
Serial.print(targetIp[3],DEC);
Serial.println("");
Serial.println("Done!");

lcd.clear(); lcd.print("Received packet"); delay(2000);
lcd.clear(); lcd.setCursor(4,0); lcd.print("From IP:");

lcd.setCursor(0,1);
for(i=0; i<3; i++) {
lcd.print(remoteIp[i],DEC);
lcd.print(".");
}
lcd.print(remoteIp[3],DEC); delay(2000);

lcd.clear(); lcd.print("Target MAC:");

lcd.setCursor(0,1);
for(i=6; i<11; i++) {
lcd.print(packetBuffer[i],HEX);
lcd.print(":");
}
lcd.print(packetBuffer[11],HEX); delay(2000);

lcd.clear(); lcd.print(" Target host: ");
}
}


posted by love4nature at 01:00| Comment(0) | TrackBack(0) | 趣味の部屋 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。