2017年2月5日 星期日

Arduino: 自動WIFI重置器 Automatic WIFI reseter (Auto AP reseter)

因特別需求家中裝了很多無線設備,也不知道為什麼家中的中華電信數據機三不五時就會斷線,斷電再重新通電後又會恢復正常。又因為家裡不是隨時都有人可以幫忙處理,於是冒出了這個想法,要是有個設備可以自動偵測我的無線網路連線,當網路斷線時自動把AP的電源切斷,過個幾秒在通電,這樣就不用怕AP當機了呀! 查了一下,國外還真的有這種產品:ResetPlug  不過並不便宜,那就用Arduino自己做一個吧!


[免責聲明]

本網誌所提及之內容僅供參考,請讀者務必多方蒐集相關資料以確保自己知道每個步驟的用意。本網誌採用交流電的部分會有觸電的危險,請勿火線作業。本網誌所製成之成品僅供測試,本站不負任何因製作與測試時產生之意外責任。

[要準備的有...]

Wemos D1 mini 核心部分,包含了Arduino以及ESP866 WIFI module,但又小小一片不占空間,該有的I/O port都給足了,各大拍賣網站都買的到,便宜又好用的Arduino無線網路板!!

- 5V Relay module 繼電器模組

- USB Adapter,我用手機USB充電器充當5V電源

- 插頭、交流電電纜、插座端子(連接USB Adapter用)、USB-A公頭、黃銅線(數十公分即可)、插座、杜邦線、容易鑽孔的盒子

- 三用電錶、鑽孔機、線鋸、手工具、絕緣膠布、烙鐵、熱融槍等

[Arduino Coding...]

- 假設你已經用過Arduino並且知道怎麼燒錄程式到你的板端,我這邊只針對Wemos D1 mini跟標準版Arduino UNO不同的部分做說明:
  1. 參考Youtube的教學: educ8s.tv。輸入ESP8266這個WIFI module會用到的程式庫: http://arduino.esp8266.com/stable/package_esp8266com_index.json,並載入Wemos D1 R2 & mini開發板



  2. 下載ESP8266Ping程式庫並載入: https://github.com/dancol90/ESP8266Ping
     
  3. 貼上我的程式碼,把SSID及密碼改成你家WIFI的設定


 #include <ESP8266WiFi.h>  
 #include <ESP8266Ping.h>  
   
 const char* ssid   = "yourwifissid";  
 const char* password  = "yourpassword";  
 const char* remote_host = "www.google.com";  
   
 #define MinutesToCheck   10     // set x minutes to check internet access  
 #define TimesForRecheck   3      // retry x times to determine if wifi disconnected  
 #define RelayPin      D4     // Relay control pin  
   
 //-------------------------------------------------  
 // Connect to WIFI  
 //-------------------------------------------------  
 void ConnectWifi() {  
  int retry_times = 0;  
    
  Serial.println("Connecting to WiFi");  
  WiFi.disconnect();  
  delay(1000);  
  WiFi.begin(ssid, password);  
  delay(500);  
    
  while (WiFi.status() != WL_CONNECTED) {  
   Serial.print(".");  
   retry_times =retry_times + 1;  
   if (retry_times >= 60) {  
    WiFi.begin(ssid, password);  
    retry_times = 0;  
   }  
   delay(500);  
  }  
   
  Serial.println();  
  Serial.print("WiFi connected with ip ");  
  Serial.println(WiFi.localIP());  
    
 }  
   
 //-------------------------------------------------  
 // Ping WIFI  
 //-------------------------------------------------  
 boolean PingWifi() {  
  Serial.print("Pinging host ");  
  Serial.print(remote_host);  
   
  if(Ping.ping(remote_host)) {  
   Serial.println(" ... Success!!");  
   return true;  
  } else {  
   Serial.println(" ... Error :(");  
   return false;  
  }  
 }  
   
 //-------------------------------------------------  
 // Reset Relay  
 //-------------------------------------------------  
 void ResetRelay() {  
  Serial.println("Reseting AP power");  
  digitalWrite(RelayPin, HIGH);   // cut off relay  
  delay(10000);           // wait for 10 seconds  
  digitalWrite(RelayPin, LOW);   // restore relay  
 }  
   
 //-------------------------------------------------  
 // DelayOneMinute  
 //-------------------------------------------------  
 void DelayOneMinute() {  
  for (int i=0; i < 60; i++)  
  {  
   delay(1000);         // waits for a second  
  }  
 }  
   
 //-------------------------------------------------  
 // setup  
 //-------------------------------------------------  
 void setup() {  
  Serial.begin(115200);  
  delay(10);  
    
  pinMode(RelayPin, OUTPUT);   // sets the digital pin as output  
  digitalWrite(RelayPin, LOW);  // default LOW  

  // Set ESP8266 in station mode to hide broadcasted SSID: AI-THINKER_XXXXXX
  WiFi.mode(WIFI_STA);
   
  Serial.println("Wait for 2 mins AP initial time");  
  DelayOneMinute();        // wait for AP restart  
  DelayOneMinute();        // wait for AP restart  
  ConnectWifi();  
  PingWifi();  
 }  
   
 //-------------------------------------------------  
 // Main  
 //-------------------------------------------------  
 void loop() {  
  for (int i=0; i < MinutesToCheck; i++) {  // waits for x minutes  
   Serial.print(MinutesToCheck-i);  
   Serial.println(" minutes to ping");  
   DelayOneMinute();  
  }  
   
  for (int i=0; i < TimesForRecheck; i++) {  
   Serial.println("Checking WIFI status...");  
   if (WiFi.status() == WL_CONNECTED) {  
    Serial.println("WIFI connected");  
    if (PingWifi()) {  
     break;  
    }  
   }  
   if (i == TimesForRecheck-1) {   // ping failed x times, reset AP power  
    ResetRelay();  
    Serial.println("Wait for 2 mins AP initial time");  
    DelayOneMinute();        // wait for AP restart  
    DelayOneMinute();        // wait for AP restart  
    ConnectWifi();  
    break;  
   }  
   Serial.println("WIFI disconnected, wait 5 sec to retry");  
   delay(5000);           // wait for re-ping again  
  }  
 }  

[硬體部分]

- Wemos D1 mini跟繼電器的連接很簡單,用三條杜邦線連接Wemos D1 mini上的5V、GND以及D4到繼電器上的5V、GND及Signal,在開始施工裝入盒子之前可以先試一下Wemos D1 mini是否可以正確控制繼電器

            ------------------------------------
            |  Wemos D1 mini  |     Relay      |
            ------------------------------------
            |      5V         |      5V        |
            |                 |                |
            |      GND        |      GND       |
            |                 |                |
            |       D4        |     Signal     |
            ------------------------------------


- 繼電器的另一邊會有三個可以鎖螺絲夾線的孔,分別是常開(NO)、共接點(COM)及常閉(NC)。在Signal線沒有訊號進來的情況下(LOW),用三用電錶可以測試到常閉(NC)與共接點(COM)導通;當Signal外部拉HIGH時,常開(NO)與共接點(COM)導通,與常閉點(NC)斷開

- 5V電源供應器,這其實很簡單,直接把家裡多到不行的手機充電器拿來接就好。由於會需要把110V接進設備盒中,我找了一個金屬端子方便固定電線,鎖好後要用絕緣膠帶完整包覆。

- 充電器的另一端就用USB公頭焊上杜邦線到5V與GND給WeMos D1 mini與5V Relay。5V跟GND會在4根腳的兩頭,用三用電表量一下就知道囉。

                    |--------------------|
           110V <--O|AC 110V          5V |O ----> Wemos D1 mini 5V
                    |                    | \----> Relay 5V
                    |    USB Charger     |
           110V <--O|AC 110V          GND|O ----> Wemos D1 mini GND
                    |--------------------| \----> Relay GND


- 插座跟繼電器的連接也很簡單,插座的一邊直接並聯到110V的一端,插座的另一端先接去繼電器常閉(NC)孔,共用點(COM)在接去110V的另一條。


    |----------------|
    |O              O|<-----------------
    |     ______     |                 |
    |      插座       |                 | 
    |     ______     |                 |
    |O              O|<-----------     |
    |----------------|           |     |
                                 |     |
                                 |     |
    |------------------------|   |     |    |---------\
   O| Signal              NC |O<-|     |--->|          |-----  
    |                        |              |   插頭    |
   O| 5V      RELAY      COM |O------------>|          |-----
    |                        |              |---------/
   O| GND                 NO |O
    |------------------------|

[成品]



沒有留言:

張貼留言

Thanks for your message.

Python notes: Calculate delay time by WinDBG log

用WinDBG開Event Timestamps可以產生下面格式的log: Fri Sep 21 18:43:50.946 2018 (UTC + 8:00): @#$#^$@#$^ 以下python code用來找出兩個指定log中的時間差