SKETCH

最終更新日 2017年12月8日

/*
 * 20171207 Rev03
 * 
 * Rev00:
 * 20171201
 * この日新たに購入したKEYESTUDIOのEtherNetShield(KS0156)でこのWOLコードから実行できることが
 * 確認出来た。
 *
 * Rev01:
 * SDカードから必要な情報を読み込むようにする。
 * 環境ファイルは“WOLENV.ini”
 * SDカード用のライブラリは"SdFat.h"を採用
 * 
 * Rev02:
 * SDカード内の環境ファイル“WOLENV.ini”を解釈して扱うように修正できた
 * 
 * Rev03:
 * AI1~AI4をデジタル入力設定とし、w1,w2,w3,w4の入力に割り当てる
 */
//#define USE_SERIAL_DEBUG
#include <SPI.h>
#include <Ethernet.h>
#include <Utility\Socket.h>
#include "SdFat.h"
//PinAsign/Researved
#define SD_CS 4
#define ETH_CS 10
#define EnvFile "WOLENV.ini"
#define DI00   2               //UNO_A0
#define DI01   3               //UNO_A1
#define DI02   4               //UNO_A2
#define DI03   5               //UNO_A3
// Make up a mac Address &amp; an IP address. Both should be globally unique or
// at least unique on the local network. 
// {0x90,0xA2,0xDA,0xxx,0xxx,0xxx}はArduinoが取得したコード
static byte g_MyMacAddress[] = {0x90,0xA2,0xDA,0x0D,0x7D,0x54};
static IPAddress g_MyIPAddress(192,168,0,198);
static IPAddress g_MySubnetmask(255,255,255,0);
static IPAddress g_MyGateway(192,168,0,1);
static IPAddress g_MyDNSserver(8,8,8,8);
// The machine to wake up. WOL should already be configured for the target machine. 
// The free windows program "Wake On LAN Ex 2" by Joseph Cox can be useful for testing the remote
// machine is properly configured. Download it here: https://software.bootblock.co.uk/?id=wakeonlanex2
static byte g_TargetMac1[] = {0x28,0xD2,0x44,0x99,0x70,0xE5};     //T440p
static byte g_TargetMac2[] = {0x90,0xA2,0xDA,0x0D,0x7D,0x55};     //
static byte g_TargetMac3[] = {0x90,0xA2,0xDA,0x0D,0x7D,0x56};     //
static byte g_TargetMac4[] = {0x90,0xA2,0xDA,0x0D,0x7D,0x57};     //
// file system object
SdFat sd;
void SendWOLMagicPacket(byte *pMacAddress){
#ifdef USE_SERIAL_DEBUG       
        for(int i = 0;i < 6;i++){                               //sizeof()ではもとまらないので固定値にした
               Serial.print(pMacAddress[i],HEX);Serial.print(F("."));
        }
        Serial.println(F(""));
#endif
        // The magic packet data sent to wake the remote machine. Target machine's
        // MAC address will be composited in here.
        const int nMagicPacketLength = 102;
        byte MagicPacket[nMagicPacketLength] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
        byte TargetIPAddress[] = { 255, 255, 255, 255 };        // 実際のIPアドレスは必要ないはず
        const int nWOLPort = 7;
        const int nLocalPort = 8888; // to "listen" on (only needed to initialize udp)
 
        // Compose magic packet to wake remote machine. 
        for (int ix=6; ix<102; ix++){
                MagicPacket[ix]=pMacAddress[ix%6];
        }
        if (UDP_RawSendto(MagicPacket, nMagicPacketLength, nLocalPort,TargetIPAddress, nWOLPort) != nMagicPacketLength){
#ifdef USE_SERIAL_DEBUG 
                Serial.println(F("Error sending WOL packet"));
#endif
        }
#ifdef USE_SERIAL_DEBUG 
        for(int i = 0;i < sizeof(MagicPacket);i++){
               Serial.print(MagicPacket[i],HEX);Serial.print(F("."));
        }
        Serial.println(F(""));
#endif
}
 
int UDP_RawSendto(byte* pDataPacket, int nPacketLength, int nLocalPort, byte* pRemoteIP, int nRemotePort){
        int nResult;
        int nSocketId;                  // Socket ID for Wiz5100
 
        // Find a free socket id.
        nSocketId = MAX_SOCK_NUM;
        for (int i = 0; i < MAX_SOCK_NUM; i++) {
                uint8_t s = W5100.readSnSR(i);
                if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
                        nSocketId = i;
                        break;
                }
        }
        if (nSocketId == MAX_SOCK_NUM)  return 0;       // couldn't find one. 
        if (socket(nSocketId, SnMR::UDP, nLocalPort, 0)){
                nResult = sendto(nSocketId,(unsigned char*)pDataPacket,nPacketLength,(unsigned char*)pRemoteIP,nRemotePort);
                close(nSocketId);
        } else{
                nResult = 0;
        }
        return nResult;
}
int LoadEnvFile(){
        //環境ファイルを読み取って値を再定義します。
        const int line_buffer_size = 64;
        char buffer[line_buffer_size];
        ifstream sdin(EnvFile);
        int line_number = 0;
        int p1,p2,p3,p4,p5,p6;
        char c1[24];
        char c2[24];
        char c3[24];
        char c4[24];
        
        while (sdin.getline(buffer, line_buffer_size, '\n') || sdin.gcount()) {
                int count = sdin.gcount();
                if (sdin.fail()) {
#ifdef USE_SERIAL_DEBUG 
                        Serial.println(F("Partial long line"));
#endif
                        sdin.clear(sdin.rdstate() & ~ios_base::failbit);
                        return 1;
                } else if (sdin.eof()) {
#ifdef USE_SERIAL_DEBUG 
                        Serial.println(F("Partial final line"));        // sdin.fail() is false
#endif
                } else {
                        count--;                                        // Don’t include newline in count
#ifdef USE_SERIAL_DEBUG 
                        Serial.print(F("Line = " ));Serial.print(++line_number);Serial.print("\t");
                        Serial.println(buffer);
#endif
                        if(sscanf(buffer,"MyIPAddress = %s",c1) > 0){
                                //IPアドレスの再定義
#ifdef USE_SERIAL_DEBUG 
                                Serial.print(F("SetIPAddress:"));
#endif
                                sscanf(c1,"%d.%s",&p1,c2);
                                sscanf(c2,"%d.%s",&p2,c3);
                                sscanf(c3,"%d.%d",&p3,&p4);
                                g_MyIPAddress=IPAddress(byte(p1),byte(p2),byte(p3),byte(p4));
#ifdef USE_SERIAL_DEBUG 
                                Serial.print(F("MyIPAddress = "));
                                Serial.print(p1);Serial.print(" ");Serial.print(p2);Serial.print(" ");
                                Serial.print(p3);Serial.print(" ");Serial.println(p4);
#endif                                                       
                        }else if(sscanf(buffer,"MySubnetmask = %s",c1) > 0){
                                //サブネットマスクの再定義
#ifdef USE_SERIAL_DEBUG 
                                Serial.print(F("SetSubnetMask:"));
#endif
                                sscanf(c1,"%d.%s",&p1,c2);
                                sscanf(c2,"%d.%s",&p2,c3);
                                sscanf(c3,"%d.%d",&p3,&p4);
                                g_MySubnetmask=IPAddress(byte(p1),byte(p2),byte(p3),byte(p4));
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("MyIPAddress = "));                     
                                Serial.print(p1);Serial.print(" ");Serial.print(p2);Serial.print(" ");
                                Serial.print(p3);Serial.print(" ");Serial.println(p4);
#endif
                        }else if(sscanf(buffer,"MyGateway = %s",c1) > 0){
                                //ゲートウエイの再定義
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("SetMyGateway:"));
#endif
                                sscanf(c1,"%d.%s",&p1,c2);
                                sscanf(c2,"%d.%s",&p2,c3);
                                sscanf(c3,"%d.%d",&p3,&p4);
                                g_MyGateway=IPAddress(byte(p1),byte(p2),byte(p3),byte(p4));
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("MyGateway = "));
                                Serial.print(p1);Serial.print(" ");Serial.print(p2);Serial.print(" ");
                                Serial.print(p3);Serial.print(" ");Serial.println(p4);
#endif
                        }else if(sscanf(buffer,"MyDNSserver = %s",c1) > 0){
                                //DNSの再定義
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("SetDNSserver:"));
#endif
                                sscanf(c1,"%d.%s",&p1,c2);
                                sscanf(c2,"%d.%s",&p2,c3);
                                sscanf(c3,"%d.%d",&p3,&p4);
                                g_MyDNSserver=IPAddress(byte(p1),byte(p2),byte(p3),byte(p4));
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("MyDNSserver = "));
                                Serial.print(p1);Serial.print(" ");Serial.print(p2);Serial.print(" ");
                                Serial.print(p3);Serial.print(" ");Serial.println(p4);
#endif
                        }else if(sscanf(buffer,"TargetMac1 = %s",c1) > 0){
                                 //ターゲットMACアドレス1の定義
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("SetTargetMac1:"));
#endif
                                sscanf(c1,"%2x.%2x.%2x.%2x.%2x.%2x",&p1,&p2,&p3,&p4,&p5,&p6);
                                g_TargetMac1[0]=byte(p1);g_TargetMac1[1]=byte(p2);
                                g_TargetMac1[2]=byte(p3);g_TargetMac1[3]=byte(p4); 
                                g_TargetMac1[4]=byte(p5);g_TargetMac1[5]=byte(p6);
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("TargetMac1 = "));
                                Serial.print(p1,HEX);Serial.print(".");Serial.print(p2,HEX);Serial.print(".");
                                Serial.print(p3,HEX);Serial.print(".");Serial.print(p4,HEX);Serial.print(".");
                                Serial.print(p5,HEX);Serial.print(".");Serial.println(p6,HEX);
#endif
                        }else if(sscanf(buffer,"TargetMac2 = %s",c1) > 0){
                                 //ターゲットMACアドレス2の定義
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("SetTargetMac2:"));
#endif
                                sscanf(c1,"%2x.%2x.%2x.%2x.%2x.%2x",&p1,&p2,&p3,&p4,&p5,&p6);
                                g_TargetMac2[0]=p1;g_TargetMac2[1]=p2;g_TargetMac2[2]=p3;
                                g_TargetMac2[3]=p4;g_TargetMac2[4]=p5;g_TargetMac2[5]=p6;
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("TargetMac2 = "));
                                Serial.print(p1);Serial.print(" ");Serial.print(p2);Serial.print(" ");
                                Serial.print(p3);Serial.print(" ");Serial.print(p4);Serial.print(" ");
                                Serial.print(p5);Serial.print(" ");Serial.println(p6);
#endif
                        }else if(sscanf(buffer,"TargetMac3 = %s",c1) > 0){
                                //ターゲットMACアドレス3の定義
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("SetTargetMac3:"));
#endif
                                sscanf(c1,"%2x.%2x.%2x.%2x.%2x.%2x",&p1,&p2,&p3,&p4,&p5,&p6);
                                g_TargetMac3[0]=p1;g_TargetMac3[1]=p2;g_TargetMac3[2]=p3;
                                g_TargetMac3[3]=p4;g_TargetMac3[4]=p5;g_TargetMac3[5]=p6;
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("SetTargetMac3 = "));
                                Serial.print(p1);Serial.print(" ");Serial.print(p2);Serial.print(" ");
                                Serial.print(p3);Serial.print(" ");Serial.print(p4);Serial.print(" ");
                                Serial.print(p5);Serial.print(" ");Serial.println(p6);
#endif
                        }else if(sscanf(buffer,"TargetMac4 = %s",c1) > 0){
                                //ターゲットMACアドレス4の定義
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("SetTargetMac4:"));
#endif
                                sscanf(c1,"%2x.%2x.%2x.%2x.%2x.%2x",&p1,&p2,&p3,&p4,&p5,&p6);
                                g_TargetMac4[0]=p1;g_TargetMac4[1]=p2;g_TargetMac4[2]=p3;
                                g_TargetMac4[3]=p4;g_TargetMac4[4]=p5;g_TargetMac4[5]=p6;
#ifdef USE_SERIAL_DEBUG
                                Serial.print(F("TargetMac4 = "));
                                Serial.print(p1);Serial.print(" ");Serial.print(p2);Serial.print(" ");
                                Serial.print(p3);Serial.print(" ");Serial.print(p4);Serial.print(" ");
                                Serial.print(p5);Serial.print(" ");Serial.println(p6);
#endif
                        }
                }
                
        }
        return 0;   
}

void setup () {
        Serial.begin(115200);
        //IOsetting
        pinMode(DI00, INPUT_PULLUP);
        pinMode(DI01, INPUT_PULLUP);
        pinMode(DI02, INPUT_PULLUP);
        pinMode(DI03, INPUT_PULLUP);
        // 50MHzを超えないボードがサポートする最高速度で初期化します。
        //SPIエラーが発生した場合は、速度を下げます。
        //UNOですので16MHzを指定します。
        if (!sd.begin(SD_CS, SD_SCK_MHZ(16))) {
                sd.initErrorHalt();
        } 
        //環境ファイルを読み込みます。
        if(LoadEnvFile()){
#ifdef USE_SERIAL_DEBUG 
                //エラー発生
                Serial.println(F("Error NotLoadEnvFile"));
#endif
                return;
        }
        //Serial.print(g_MyIPAddress[0]);Serial.print(" ");Serial.print(g_MyIPAddress[1]);Serial.print(" ");
        //Serial.print(g_MyIPAddress[2]);Serial.print(" ");Serial.println(g_MyIPAddress[3]);
        //環境ファイルを読み終えてからNICのセットアップをする
        Ethernet.begin(g_MyMacAddress, g_MyIPAddress);
#ifdef USE_SERIAL_DEBUG 
        Serial.println(Ethernet.localIP());
        Serial.println(F("Send WOL Prgram"));
        Serial.println(F("Send '1..4' to initiate WOL")); 
#endif
}
 
void loop() {
        // When 'w1' is received, send a magic packet to wake the remote machine. 
        if(Serial.available() > 0){
                //入力認知したらWaitが必要
                char input = Serial.read();
#ifdef USE_SERIAL_DEBUG 
                Serial.print(F("InputString = "));Serial.println(input);
#endif
                if(input == '1') {
                        SendWOLMagicPacket(g_TargetMac1);
#ifdef USE_SERIAL_DEBUG 
                        Serial.println(F("Magic packet1 sent"));
#endif
                }
                if(input == '2') {
                        SendWOLMagicPacket(g_TargetMac2);
#ifdef USE_SERIAL_DEBUG                        
                        Serial.println(F("Magic packet2 sent"));
#endif
                }
                if(input == '3') {
                        SendWOLMagicPacket(g_TargetMac3);
#ifdef USE_SERIAL_DEBUG 
                        Serial.println(F("Magic packet3 sent"));
#endif
                }
                if(input == '4') {
                        SendWOLMagicPacket(g_TargetMac4);
#ifdef USE_SERIAL_DEBUG 
                        Serial.println(F("Magic packet4 sent"));
#endif                        
                }
                delay(1000);
        }else if(!digitalRead(DI00)){   //LOW_Active
                SendWOLMagicPacket(g_TargetMac1);
#ifdef USE_SERIAL_DEBUG 
                Serial.println(F("Di0ON_Magic packet1 sent"));
#endif 
                delay(1000);             
        }else if(!digitalRead(DI01)){   //LOW_Active
                SendWOLMagicPacket(g_TargetMac2);
#ifdef USE_SERIAL_DEBUG 
                Serial.println(F("Di1ON_Magic packet2 sent"));
#endif               
                delay(1000);
        }else if(!digitalRead(DI02)){   //LOW_Active
                SendWOLMagicPacket(g_TargetMac3);
#ifdef USE_SERIAL_DEBUG 
                Serial.println(F("Di2ON_Magic packet3 sent"));
#endif               
                delay(1000);
        }else if(!digitalRead(DI03)){   //LOW_Active
                SendWOLMagicPacket(g_TargetMac4);
#ifdef USE_SERIAL_DEBUG 
                Serial.println(F("Di3ON_Magic packet4 sent"));
#endif
                delay(1000);
        }
}


免責事項

本ソフトウエアは、あなたに対して何も保証しません。本ソフトウエアの関係者(他の利用者も含む)は、あなたに対して一切責任を負いません。
あなたが、本ソフトウエアを利用(コンパイル後の再利用など全てを含む)する場合は、自己責任で行う必要があります。

本ソフトウエアの著作権はToolsBoxに帰属します。
本ソフトウエアをご利用の結果生じた損害について、ToolsBoxは一切責任を負いません。
ToolsBoxはコンテンツとして提供する全ての文章、画像等について、内容の合法性・正確性・安全性等、において最善の注意をし、作成していますが、保証するものではありません。
ToolsBoxはリンクをしている外部サイトについては、何ら保証しません。
ToolsBoxは事前の予告無く、本ソフトウエアの開発・提供を中止する可能性があります。

商標・登録商標

Microsoft、Windows、WindowsNTは米国Microsoft Corporationの米国およびその他の国における登録商標です。
Windows Vista、Windows XPは、米国Microsoft Corporation.の商品名称です。
LabVIEW、National Instruments、NI、ni.comはNational Instrumentsの登録商標です。
I2Cは、NXP Semiconductors社の登録商標です。
その他の企業名ならびに製品名は、それぞれの会社の商標もしくは登録商標です。
すべての商標および登録商標は、それぞれの所有者に帰属します。