我们在家居生活中,亮度是保护我们眼睛最重要的灵药,家中许多老人、儿童等在房间里面,如果亮度不足,不但没有安全感,对视力的保健,更是一大杀手。如果我们如果在家里看到这样的情形,当然可以马上调整光线,但是如果我们在外面上班,就不太容易查觉到这样隐藏的问题。
因此,如果我们用Arduino来照顾我们的眼睛,可以通过手机上网,直接使用浏览器可以监控我们家的亮度或许是个可行的应用,所以我们想到使用 Arduiono,通过简单的上网扩充卡,瞬间就让我们的家庭进化成先进的智慧家庭。所以本文就要告诉读者,如何简单、快速、有效的建立一个居家亮度监控的物联网。
Arduino Ethernet Shield 简介
Ethernet Shield(W5100) 主要特色是把 TCP/IP Protocols (TCP, UDP, ICMP, IPv4 ARP, IGMP, PPPoE, Ethernet) 做在硬件电路上,减轻了单芯片(MCU )的负担 (也就是 Arduino 开发板的负担)。
Arduino 程序只要使用 Ethernet Library 便可以轻易完成连至因特网的动作,不过 W5100 也不是没有缺点,因为它有一个限制,就是最多只允许同时 4 个 socket 联机。
Arduino Ethernet Shield 使用加长型的 Pin header (如下图.(a)、下图.(b)),可以直接插到 Arduino 控制板上 (如下图.(c)、 下图.(d) 、下图.(e)),而且原封不动地保留了 Arduino 控制板的 Pin Layout,让使用者可以在它上面迭其它的扩充板(如下图.(c) 、 下图.(d) 、 下图.(e))。
▼ Ethernet Shield(W5100)
比较新的 Ethernet Shield 增加了 micro-SD card 插槽,可以用来储存档案,你可以用 Arduino 内建的 SD library 来存取板子上的 SD card。此外,Ethernet Shield 兼容于 UNO 和 Mega 2560 控制板。
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。
如下图所示,Ethernet Shield状态指示灯 (LEDs)功能列举如下:
• PWR: 表示 Arduino 控制板和 Ethernet Shield 已经上电
• LINK: 网络指示灯,当灯号闪烁时代表正在传送或接收数据
• FULLD: 代表网络联机是全双工
• 100M: 表示网络是 100 MB/s (相对于 10 Mb/s)
• RX: 接收数据时闪烁
• TX: 传送数据时闪烁
• COLL: 闪烁时代表网络上发生封包碰撞的情形 (network collisions are detected)
▲ W5100指示灯
实做亮度监控网站
首先,组立W5100 以太网络模块是非常容易的一件事,如下图所示,只要将W5100 以太网络模块堆栈到任何Arduino开发板之上就可以了。
▲ 将Arduino开发板与W5100 以太网络模块堆栈组立
之后,再将组立好的W5100 以太网络模块,如下图所示,只要将USB线差到Arduino开发板,再将RJ 45的网络线一端插到W5100以太网络模块,另一端插到可以上网的集线器(Switch HUB)的任何一个局域网络接口(Lan Port)就可以了。
▲ 接上电源与网络线的W5100 以太网络模块堆栈卡
将Arduino 开发板的驱动程序安装好之后,我们打开Arduino 开发板的开发工具:Sketch IDE整合开发软件,攥写一段程序,如下表所示之实做亮度监控网站测试程序,我们就可以让W5100 以太网络模块堆栈卡变成一台简易的实做亮度监控服务器运作了。
实做亮度监控网站测试程序(LightMonitorServer)
/*
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>
#include <Wire.h>
#include <BH1750.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);
BH1750 lightMeter;
void setup() {
lightMeter.begin();
// 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() {
uint16_t lux = lightMeter.readLightLevel();
// 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.print("Light: ");
client.print(lux);
client.println(" lx");
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
如下图所示,你就可以看到本次实验- 实做亮度监控网站测试程序结果画面。
▲实做亮度监控网站测试程序结果画面
最后,你还可以将家中的虚拟IP透过分享器(NAT),将192.168.30.200转成真时IP, 那么所有在因特网上的使用者,都可以轻易使用任何装置,手机、平板、笔电....等等上网,使用浏览器查看到我们家里的亮度了。