2020年12月12日 星期六

三、Dweet.io雲端網站IOT資料下載實習— 遠端遙控開關輸出

 三、 Dweet.io雲端網站IOT資料下載實習—

遠端遙控開關輸出


1 使用ESP8266構成一遠端輸出遙控系統

介紹過Dweet.io這個雲端網站的上傳及暫存(因為免費使用只能保存24小時)方法後,接下來就開始介紹如何以WiFi晶片ESP8266從Dweet.io這個雲端網站下載資料的方法。為了能讓讀者更有感,在本範例中是以遠端的主控端上傳ESP8266輸出控制指令後,再由本地端的ESP8266下載這些指令控制其輸出腳的開與關。


1-1 單一輸出遙控

為了方便測試,我們先以ESP8266郵票版上內建的指示LED(接在GPIO2腳上)當作輸出控制的標的,這支GPIO腳輸出為Low時會點亮LED,而輸出High時會令LED熄滅,只要能順利控制一隻腳的輸出狀態,再擴充到多隻接腳就不會是什麼大問題了!

以下是本實習的完整範例程式列表


  1. // Libraries

  2. #include <ESP8266WiFi.h>

  3. const char* ssid = "yourSSID"; // 換成你的WiFi SSID名稱

  4. const char* password = "yourPassword"; // 換成你的WiFi 密碼

  5.  

  6. /// Host

  7. const char* host = "dweet.io";

  8. String  dweeting="GET /get/latest/dweet/for/%dweets% HTTP/1.1\r\nHost:

  9. dweet.io\r\nConnection: close\r\n\r\n";

  10. String myThing= "myDweetGetTest";

  11.  

  12. const byte  LED_Pin=2;

  13.  

  14. void setup() {

  15.  

  16.   // Start Serial

  17.   Serial.begin(115200);

  18.   pinMode(LED_Pin,OUTPUT);

  19.   delay(10);

  20.   digitalWrite(LED_Pin,1);

  21.   Serial.println();

  22.   Serial.print("Connecting to ");

  23.   Serial.println(ssid);

  24.   WiFi.begin(ssid, password);

  25.   while (WiFi.status() != WL_CONNECTED) {

  26.     delay(500);

  27.     Serial.print(".");

  28.   }

  29.  

  30.   Serial.println("");

  31.   Serial.print("WiFi connected : ");

  32.   Serial.println(ssid);

  33.   Serial.println("IP address: ");

  34.   Serial.println(WiFi.localIP());

  35.   Serial.println("");

  36.  

  37. }

  38.  

  39. void loop() {

  40.  

  41.   Serial.print("Connecting to ");

  42.   Serial.print(host);

  43.   Serial.println(".......");

  44.   Serial.println();

  45.   

  46.   // Use WiFiClient class to create TCP connections

  47.   WiFiClient client;

  48.   const int httpPort = 80;

  49.   if (!client.connect(host, httpPort)) {

  50.     Serial.println("connection failed");

  51.     return;

  52.   }

  53.   

  54.   dweeting.replace("%dweets%",myThing);

  55. //  Serial.println(dweeting);

  56.   client.print(dweeting);

  57.   delay(10);

  58.  

  59.   String payLoad="";

  60.   Serial.println();

  61.   Serial.println("[dweet.io Response:]");

  62.   while (client.connected())

  63.   {

  64.     if (client.available())

  65.     {

  66.       String line = client.readStringUntil('\n');

  67.       payLoad+=line;

  68. //        Serial.println(line);

  69.     }

  70.   }

  71.   Serial.println();

  72.     Serial.println("[dweet.io Response End!]");

  73.   client.stop();

  74.   Serial.println("\n[Disconnected]");

  75.   Serial.println();


  76.   payLoad=payLoad.substring(payLoad.indexOf(":{")+1,payLoad.indexOf("}")+1);

  77.   Serial.print("你的Iot ==> ");    

  78.   Serial.println(payLoad);

  79.   Serial.println();

  80.   payLoad.toUpperCase();

  81.   if(payLoad.indexOf("LED\":\"ON") >= 0) 

  82.   {

  83.      Serial.println("LED is on!");

  84.      digitalWrite(LED_Pin,0);

  85.   }

  86.   if(payLoad.indexOf("LED\":\"OFF") >= 0) 

  87.   {

  88.      Serial.println("LED is off!");

  89.      digitalWrite(LED_Pin,1);

  90.   }

  91.       

  92.   // 每 5 秒上Dweet.io雲端網站抓取指令資料一次

  93.   delay(5000);

  94. }


程式一開始當然就是引入ESP8266要用到的WiFi函式庫<ESP8266WiFi.h>,還有不要忘記把要連線的WiFi分享器名稱和密碼改成你自己的。


#include <ESP8266WiFi.h>

const char* ssid = "yourSSID"; // 換成你的WiFi SSID名稱

const char* password = "yourPassword"; // 換成你的WiFi 密碼


接下來就是建構從Dweet.io雲端網站下載指令的基本指令架構,在此我們只抓取最後一次上傳的資料,所以完整的URL應該如下:


http://dweet.io/get/latest/dweet/for/myThing


其中的myThing就是主控端給這個輸出控制IoT物件所取的名字在下面的變數定義中我們暫定為myThing= "myDweetGetTest"」;由於我們是用%dweets%這種字串變數取代的方式來傳遞名稱所以讀者可依自己的喜好去更改免得大家都用這個名字到時候會混成一團以致天下大亂

當我們使用一般的瀏覽器只要在網址欄位鍵入上面的URL就可以可是當我們要透過ESP8266送出這樣的下載指令時由於實際使用的通訊協定層級較低所以要補足其他由較高階的瀏覽器所提供的部分因此實際的動作是事先連上Dweet.io雲端網站後再以”GET”方式送出指令所以後面的指令內容應該是


"GET /get/latest/dweet/for/%dweets% HTTP/1.1\r\nHost: dweet.io\r\nConnection: close\r\n\r\n"


這樣一個字串這也就是下面dweeting」這個字串變數的由來。


const char* host = "dweet.io";

String  dweeting="GET /get/latest/dweet/for/%dweets% HTTP/1.1\r\nHost: dweet.io\r\nConnection: close\r\n\r\n";

String myThing= "myDweetGetTest";


初始化程式(setup())的部分會連線上指定的WiFi分享器,而且把分配到的本地IP位址在Arduino IDE監控視窗上顯示出來,由於是非常標準的制式作法,在此就不多做說明。


至於主迴圈(loop())部分主要是由面幾個步驟所構成:


1.先連線Dweet.io雲端網站

2.連線成功後送出下載指令並等待Dweet.io雲端網站的回傳訊息。

3.將主控端所發出的輸出控制指令從回傳訊息中取出。

4.測試輸出指令的內容如果正確的話就執行之。


下列程式的前半段(46~56行)先令ESP8266以客戶端(Client)的腳色連線到Dweet.io雲端網站,如果連線成功,接著再把「dweeting」這個代表下載「"myDweetGetTest"」IoT物件的指令字串變數傳至Dweet.io雲端網站,然後等待回應也就是執行上面所述的步驟12。


  // Use WiFiClient class to create TCP connections

  WiFiClient client;

  const int httpPort = 80;

  if (!client.connect(host, httpPort)) {

    Serial.println("connection failed");

    return;

  }

 

  dweeting.replace("%dweets%",myThing);

//  Serial.println(dweeting);

  client.print(dweeting);


接著的程式會依序接收從Dweet.io雲端網站回傳的訊息,直到全部資料傳送完為止,而這些訊息會整合打包在「payLoad」這個字串變數上,並且列印在Arduino IDE的監控視窗中當資料接收完成後終止和Dweet.io雲端網站的連線整段程式在執行上面所述步驟3的動作。


  String payLoad="";

  Serial.println();

  Serial.println("[dweet.io Response:]");

  while (client.connected())

  {

    if (client.available())

    {

      String line = client.readStringUntil('\n');

      payLoad+=line;

//        Serial.println(line);

    }

  }

  Serial.println();

    Serial.println("[dweet.io Response End!]");

  client.stop();


下面的程式會從接收到的Dweet.io雲端網站回傳訊息中,把由主控端所送來跟輸出控制有關的IOT物件及其內容分離出來,並且列印在Arduino的監控視窗內


payLoad=payLoad.substring(payLoad.indexOf(":{")+1,payLoad.indexOf("}")+1);

  Serial.print("你的Iot ==> ");    

  Serial.println(payLoad);

  Serial.println();


以下的程式就是用來執行前述步驟4的動作,為了方便測試,程式會先把指令內容都轉換成大寫後再來比對;如果指令是「"LED: ON"」,會令接在GPIO2上的LED點亮,對於接在ESP8266郵票版上的LED而言,要輸出低態(Low)電壓,反之如果是「"LED: OFF"」,則會令LED熄滅;至於其他內容的指令則不予理會,也就是說不會有任何回應的動作。


  payLoad.toUpperCase();

  if(payLoad.indexOf("LED\":\"ON") >= 0) 

  {

     Serial.println("LED is on!");

     digitalWrite(LED_Pin,0);

  }

  if(payLoad.indexOf("LED\":\"OFF") >= 0) 

  {

     Serial.println("LED is off!");

     digitalWrite(LED_Pin,1);

  }


在這個範例中我們會每隔5秒到Dweet.io雲端網站抓取指令資料一次使用者可依自己的需要加快或減慢不過一般來說即使設定為一秒由於實際網路通訊傳輸結構的限制與傳送反應延遲反而會出現反效果甚至出現錯誤


  // 每 5 秒上Dweet.io雲端網站抓取指令資料一次

  delay(5000);


接下來讓我們看看如何去測試這個程式,簡單的說就是要有一個工具可以把輸出控制指令上傳到”dweet.io”這個雲端網站,然後再由本範例的ESP8266將指令下載後解譯並執行,在此使用任何可以上網裝置(不管是桌機筆電或手機)內的瀏覽器都可以下圖是使用Google Chrome當作控制APP的方式其中的標記1是送出點亮LED的URL指令內容其中的IoT物件名稱為「myDweetGetTest」標記2則是由”dweet.io”這個雲端網站回傳的訊息至於標記3是控制LED熄滅的URL指令上傳成功的話就會看到標記4的內容



當然也可以用上一小節介紹的用AI2設計的APP,如下圖所示,先在標記1的IoT名稱文字盒輸入這個物件名稱「myDweetGetTest」,如果要控制LED點亮的話,可在標記2的內容文字盒中輸入「led=on」這樣的指令,或是如標記3所示輸入「led=off」讓LED熄滅,其中的英文字元大小寫都可以。最後只要按下【送出】按鈕就可將控制指令上傳到”dweet.io”這個雲端網站不管成功與否,都可以在標記4的地方看到”dweet.io”雲端網站的回應內容,這樣一來我們便可以由回傳的內容知道上傳是否成功。



下圖是程式執行後在Arduino IDE的監控視窗中所看到的畫面,其中標記1是連線到”dweet.io”這個雲端網站的提示訊息,而標記2是ESP8266送出下載指令到”dweet.io”這個雲端網站後它的回應內容。至於標記3是把”dweet.io”雲端網站回傳的訊息中萃取出由主控端所傳來的輸出控制指令後的提示訊息,而標記4則是測試輸出指令的內容後,所執行對應的動作,在此為點亮ESP8266郵票貼片板上接在GPIO2的LED。




在本範例整個使用與操作的過程中應該可以發現不管是發出控制指令的主控端或是接收下載指令的被控端完全不需要跟”dweet.io”這個雲端網站申請註冊或是申請特定的Key值直接就可以連線使用”dweet.io”這個雲端網站的功能了這也就是”dweet.io”這個雲端網站所宣稱的使用方式簡單到不行原因而唯一要注意的就是你取的IoT物件名稱一定要具有獨特性否則在不付費的情形下任何人都可以存取跟這個名稱相同的所有資訊

如果有興趣拿這個範例來單獨控制一些電器裝置,在程式測試完成後,可以把它燒錄在之前介紹過如下圖所示的ESP-01繼電器模組上,由於繼電器的控制接點是和系統隔離的所謂的乾接點,因此直接拿來控制一些AC交流電裝置是不會有甚麼問題的!不過要記得要將輸出腳改為GPIO0



沒有留言:

張貼留言