本篇為『物聯網系統開發系列』之運用 ARDUINO 乙太網路擴充板建立簡單網頁伺服器,筆者建立這個新專欄,主要是未來物聯網時代推瀾下,希望能夠透過文章,來推廣筆者在物聯網開發的實務經驗與技術分享
文\曹永忠、吳佳駿、許智誠、蔡英德
(曹永忠, 吳佳駿, 許智誠, & 蔡英德, 2017a, 2017b, 2017c; 曹永忠, 許智誠, & 蔡英德, 2015a, 2015b, 2015c, 2015d, 2015e),所以第二篇文章就要介紹 Arduino 開發板累加上乙太網路擴充板(Ethernet Shield),讓創客神器Arduino開發板可以連上網際網路(曹永忠, 許智誠, & 蔡英德, 2015f),可以成為物聯網開發中最簡單使用的開發版。
本系列希望貢獻筆者一些經驗,讓非資訊、電機、電子等 Makers 可以學到在物聯網開發中,一些程式開發的技巧、原理、法則與穩固的技術,因本系列文章主要讀者為初學者,內容程度為基礎入門程度,深入之處不足,但請高手們給筆者賜教,也請讀者關注本系列。
Arduino Ethernet Shield 簡介
W5100 主要特色是把 TCP/IP Protocols (TCP, UDP, ICMP, IPv4 ARP, IGMP, PPPoE, Ethernet) 做在硬體電路上,減輕了單晶片(MCU)的負擔 (也就是 Arduino 開發板的負擔)(曹永忠 et al., 2015b, 2015c)。Arduino 程式只要使用 Ethernet Library1 便可以輕易完成連至網際網路的動作,不過 W5100 也不是沒有缺點,因為它有一個限制,就是最多只允許同時4 個 socket 連線。
1.可到 Arduino.cc 的官網:http://www.arduino.cc/en/reference/ethernet,下載函式庫與相關範例。
Arduino Ethernet Shield 使用加長型的 Pin header (如圖 1.(a) & 圖 1.(b)),可以直接插到 Arduino 控制板上 (如圖 1.(c) & 圖 1.(d) & 圖 1.(e)),而且原封不動地保留了 Arduino 控制板的 Pin Layout,讓使用者可以在它上面疊其它的擴充板(如圖 1.(c) & 圖 1.(d) & 圖 1.(e))。比較新的 Ethernet Shield 增加了 micro-SD card 插槽(如圖 1.(a)),可以用來儲存檔案,你可以用 Arduino 內建的 SD library 來存取板子上的 SD cardEthernet Shield 相容於 UNO 和 Mega 2560 控制板。
▲圖1 Ethernet Shield (W5100)
Arduino 開發板跟 W5100 以及 SD card 之間的通訊都是透過 SPI bus (通過 ICSP header)。以 UNO開發板 而言,SPI bus 腳位位於 pins 11, 12 和 13,而 Mega 2560開發板 則是 pins 50, 51 和 52。UNO 和 Mega 2560 都一樣,pin 10 是用來選擇 W5100,而 pin 4 則是用來選擇 SD card。這邊提到的這幾支腳位都不能拿來當 GPIO 使用,請讀者勿必避開這兩個 GPIO 腳位。
另外,在 Arduino Mega 2560 開發板上,pin 53 是 hardware SS pin,這支腳位也必須保持為 OUTPUT,不然 SPI bus 就不能動作。在使用的時候要注意一件事,因為 W5100 和 SD card 共享 SPI bus,所以在同一個時間只能使用其中一個設備。如果你程式裏會用到 W5100 和 SD card 兩種設備,那在使用對應的 library 時就要特別留意,要避免搶 SPI bus 資源的情形。假如你確定不會用到其中一個設備的話,你可以在程式裏明白地指示 Arduino開發板,方法是: 如果不會用到 SD card,那就把 pin 4 設置成 OUTPUT 並把狀態改為 high,如果不會用到 W5100,那麼便把 pin 10 設置成 OUTPUT 並把狀態改為 high。
如圖 2所示,Ethernet Shield 狀態指示燈 (LEDs)功能列舉如下:
- PWR: 表示 Arduino 控制板和 Ethernet Shield 已經上電
LINK: 網路指示燈,當燈號閃爍時代表正在傳送或接收資料
FULLD: 代表網路連線是全雙工
100M: 表示網路是 100 MB/s (相對於 10 Mb/s)
RX: 接收資料時閃爍
TX: 傳送資料時閃爍
COLL: 閃爍時代表網路上發生封包碰撞的情形 (network collisions are detected)
資料來源:http://www.arduino.cc/en/Main/ArduinoEthernetShield
▲圖2 W5100指示燈
簡單 Web Server
首先,組立 W5100 以太網路模組是非常容易的一件事,如下圖所示,只要將 W5100 以太網路模組堆疊到任何 Arduino 開發板之上就可以了。
▲圖3 將 Arduino 開發板與 W5100 以太網路模組堆疊組立
之後,在將組立好的 W5100 以太網路模組,如下圖所示,只要將USB線差到 Arduino 開發板,再將 RJ 45的網路線一端插到 W5100 以太網路模組,另一端插到可以上網的集線器(Switch HUB)的任何一個區域網路接口(Lan Port)就可以了。
▲圖4 接上電源與網路線的 W5100 以太網路模組堆疊卡
我們遵照前幾章所述,將 Arduino 開發板的驅動程式安裝好之後,我們打開 Arduino 開發板的開發工具:Sketch IDE 整合開發軟體,攥寫一段程式,如下表所示之 WebServer 測試程式,我們就可以讓 W5100 以太網路模組堆疊卡變成一台簡易的網頁伺服器運作了。
W5100 以太網路模組(WebServer) |
/* Web Server
A simple web server that shows the value of the analog input pins. using an Arduino Wiznet Ethernet shield.
Circuit: * Ethernet shield attached to pins 10, 11, 12, 13 * Analog inputs attached to pins A0 through A5 (optional)
created 18 Dec 2009 by David A. Mellis modified 9 Apr 2012 by Tom Igoe
*/
#include <SPI.h> #include <Ethernet.h>
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; IPAddress ip(192, 168, 30, 200); IPAddress dnServer(168, 95, 1, 1); // the router's gateway address: IPAddress gateway(192, 168, 30, 254); // the subnet: IPAddress subnet(255, 255, 255, 0);
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80);
void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only }
// start the Ethernet connection and the server: Ethernet.begin(mac, ip, dnServer, gateway, subnet); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); }
void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println("Refresh: 5"); // refresh the page automatically every 5 sec client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); // output the value of each analog input pin for (int analogChannel = 0; analogChannel < 6; analogChannel++) { int sensorReading = analogRead(analogChannel); client.print("analog input "); client.print(analogChannel); client.print(" is "); client.print(sensorReading); client.println("<br />"); } client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); Serial.println("client disconnected"); } } |
程式範例原始碼網址:https://github.com/brucetsao/arduino_RFProgramming
如下圖所示,讀者可以看到本次實驗- WebServer 測試程式結果畫面。
▲圖5 WebServer 測試程式結果畫面
下一頁還有更精采的教學喔 !
請注意!留言要自負法律責任,相關案例層出不窮,請慎重發文!