Arduino Ethernet 教程:从零开始让你的 Arduino 连入网络
目录
- 准备工作
- 硬件清单
- 软件环境
- 基础篇:连接网络并获取IP地址
- 硬件连接
- 代码示例:DHCP 获取IP
- 代码示例:使用静态IP
- 核心功能篇:创建一个 Web 服务器
- 原理讲解
- 代码示例:最简单的 Web 服务器
- 代码示例:通过网页控制 Arduino 的 LED
- 进阶篇:向服务器发送数据
- 原理讲解:HTTP GET 请求
- 代码示例:将传感器数据发送到 ThingSpeak
- 常见问题与故障排除
- 进阶应用与资源
准备工作
硬件清单
- Arduino 主板:任何带有 SPI 接口的 Arduino 都可以,最常用的是 Arduino Uno、Arduino Mega 或 Arduino Ethernet (自带以太网接口的版本)。
- Ethernet Shield (以太网扩展板):如果你的 Arduino 主板不带网口,就需要这个,它基于 Wiznet W5500 芯片,是当前最主流的选择。
- 网线 (RJ-45):一根标准的网线,用于将 Shield 连接到路由器或交换机。
- LED (可选):用于 Web 服务器控制 LED 的示例。
- 220Ω 电阻 (可选):用于保护 LED。
- 面包板和杜邦线:用于搭建电路。
软件环境
- Arduino IDE:确保你已经安装了最新版本的 Arduino IDE。
- 安装库:Arduino IDE 通常已经包含了
Ethernet库,但为了确保万无一失,你可以通过库管理器进行安装。- 打开 Arduino IDE,点击
项目->加载库->管理库... - 在搜索框中输入
Ethernet,找到Ethernet by Arduino,点击安装。
- 打开 Arduino IDE,点击
基础篇:连接网络并获取IP地址
这是使用 Ethernet Shield 的第一步,确保你的硬件能正确连接到局域网。

硬件连接
- 将 Ethernet Shield 按照方向(注意对齐 Pin 1)插在你的 Arduino Uno 上。
- 用网线将 Shield 的网口连接到你的 路由器 的一个 LAN 口上。
代码示例:DHCP 获取IP (推荐)
DHCP (动态主机配置协议) 是路由器自动为设备分配IP地址的方式,最常用也最方便。
#include <SPI.h>
#include <Ethernet.h>
// 创建一个 Ethernet 实例
// Mac 地址是每个网络设备的唯一标识符,你可以自己设定,但通常每个 Shield 上都有印刷的 MAC 地址
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
void setup() {
// 初始化串口通信,用于调试
Serial.begin(9600);
while (!Serial) {
; // 等待串口连接
}
Serial.println("正在初始化 Ethernet...");
// 开始使用 DHCP 获取IP地址
if (Ethernet.begin(mac) == 0) {
Serial.println("使用 DHCP 失败。");
// 如果DHCP失败,可以尝试使用静态IP
// Ethernet.begin(mac, ip);
while (true) {
delay(1); // 永久停在这里
}
} else {
Serial.println("DHCP 成功!");
}
// 打印获取到的IP地址
Serial.print("我的 IP 地址是: ");
Serial.println(Ethernet.localIP());
}
void loop() {
// 空循环
}
如何运行:
- 将代码上传到 Arduino。
- 打开
工具->串口监视器(波特率选9600)。 - 重置 Arduino,你应该会看到串口监视器打印出类似
DHCP 成功!和我的 IP 地址是: 192.168.1.105的信息。
代码示例:使用静态IP
如果你的路由器配置了复杂的DHCP规则,或者你需要设备IP地址固定不变,可以使用静态IP。
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// 设置一个你局域网内未被占用的静态IP
IPAddress ip(192, 168, 1, 177);
// 设置你的路由器网关
IPAddress gateway(192, 168, 1, 1);
// 设置你的子网掩码
IPAddress subnet(255, 255, 255, 0);
void setup() {
Serial.begin(9600);
while (!Serial) {
;
}
Ethernet.begin(mac, ip, gateway, subnet);
Serial.print("我的静态IP地址是: ");
Serial.println(Ethernet.localIP());
}
void loop() {
// 空循环
}
核心功能篇:创建一个 Web 服务器
这是 Ethernet Shield 最强大的功能之一,你可以让 Arduino 变成一个微型网站,用户可以通过浏览器访问并控制它。

原理讲解
EthernetServer server(port):创建一个服务器对象,监听一个特定的端口(Web服务默认是80)。server.begin():启动服务器,开始监听客户端连接。EthernetClient client = server.available():检查是否有新的客户端(比如浏览器)尝试连接,如果有,就创建一个客户端对象。client.connected()和client.available():检查客户端是否还连接着,以及客户端是否发来了数据。client.println():向客户端(浏览器)发送数据,HTML 代码。client.stop():关闭与客户端的连接。
代码示例:最简单的 Web 服务器
这个服务器会在浏览器上显示 "Hello from Arduino!"。
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80); // 创建一个监听80端口的服务器
void setup() {
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
Serial.print("服务器启动在: ");
Serial.println(Ethernet.localIP());
}
void loop() {
// 检查是否有客户端连接
EthernetClient client = server.available();
if (client) {
Serial.println("新的客户端连接");
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// 当收到换行符并且当前行是空行时,说明HTTP请求头已结束
if (c == '\n' && currentLineIsBlank) {
// 发送HTTP响应头
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // 一次连接后关闭
client.println();
// 发送HTML内容
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
client.println("<title>Hello Arduino</title>");
client.println("</head>");
client.println("<body>");
client.println("<h1>Hello from Arduino!</h1>");
client.println("</body>");
client.println("</html>");
break;
}
if (c == '\n') {
currentLineIsBlank = true;
} else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
// 等待浏览器接收数据
delay(1);
// 关闭连接
client.stop();
Serial.println("客户端断开连接");
}
}
如何运行:
- 上传代码。
- 打开浏览器,在地址栏输入你从串口监视器看到的IP地址(
http://192.168.1.177)。 - 你应该能看到 "Hello from Arduino!" 的网页。
代码示例:通过网页控制 Arduino 的 LED
这是一个更实用的例子,网页上有一个按钮,点击可以切换 Arduino 上连接的 LED 的状态。
硬件连接:

- 将 LED 的负极(短脚)通过一个 220Ω 电阻连接到 Arduino 的 数字引脚 7。
- LED 的正极(长脚)连接到 5V。
代码:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
// 定义LED引脚
#define ledPin 7
// 存储LED状态的变量
String readString;
void setup() {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(9600);
Ethernet.begin(mac, ip);
server.begin();
Serial.print("服务器启动在: ");
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println("新的客户端连接");
String currentLine = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
readString += c;
if (c == '\n') {
currentLine = "";
} else if (c != '\r') {
currentLine += c;
}
// 当收到换行符并且当前行是空行时
if (currentLine.endsWith("HTTP/1.1") && readString.endsWith("HTTP/1.1\r\n\r\n")) {
// 检查URL中是否包含 /?LED=ON
if (readString.indexOf("/?LED=ON") > 0) {
digitalWrite(ledPin, HIGH);
Serial.println("LED 打开");
}
// 检查URL中是否包含 /?LED=OFF
if (readString.indexOf("/?LED=OFF") > 0) {
digitalWrite(ledPin, LOW);
Serial.println("LED 关闭");
}
// 发送HTML响应
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head>");
client.println("<title>Arduino LED Control</title>");
client.println("<meta name='viewport' content='width=device-width, initial-scale=1'>");
client.println("<style>body { font-family: Arial; text-align: center; margin-top: 50px; } button { font-size: 24px; padding: 10px 20px; margin: 10px; }</style>");
client.println("</head>");
client.println("<body>");
client.println("<h1>Arduino Web Server</h1>");
client.println("<p>LED 状态: " + String(digitalRead(ledPin) ? "开启" : "关闭") + "</p>");
client.println("<a href='/?LED=ON'><button>打开 LED</button></a>");
client.println("<a href='/?LED=OFF'><button>关闭 LED</button></a>");
client.println("</body>");
client.println("</html>");
break;
}
}
}
delay(1);
client.stop();
readString = ""; // 清空字符串,准备下一次请求
Serial.println("客户端断开连接");
}
}
工作原理:
浏览器点击按钮,实际上是向服务器发送了一个特定的URL(http://192.168.1.177/?LED=ON),代码通过检查 readString 中是否包含 /?LED=ON 来判断用户的操作,然后控制引脚,并返回一个更新了状态的HTML页面。
进阶篇:向服务器发送数据
有时候我们不需要显示网页,只需要把 Arduino 上的传感器数据(如温度、湿度)发送到云服务器或数据库。
原理讲解:HTTP GET 请求
我们将模拟浏览器向一个服务器发送一个HTTP GET请求,请求的URL中会包含我们要发送的数据。
http://api.example.com/update?temp=25.5&humidity=60
http://api.example.com/update是服务器地址。- 后面是查询参数,用
&分隔多个参数。 temp=25.5表示一个名为temp,值为5的参数。
代码示例:将传感器数据发送到 ThingSpeak
ThingSpeak 是一个流行的物联网平台,可以轻松地接收数据并生成图表。
硬件准备:
- 一个模拟传感器,LM35 温度传感器。
- LM35 的 VCC 接 5V,GND 接 GND,Vout 接 Arduino 的 模拟引脚 A0。
代码: 你需要先在 ThingSpeak 网站上注册并创建一个 Channel,获取到你的 API Key。
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetClient client;
// 替换成你的 ThingSpeak API Key
String apiKey = "YOUR_API_KEY";
// 替换成你的 ThingSpeak 服务器地址 (通常是 api.thingspeak.com)
const char* server = "api.thingspeak.com";
unsigned long lastConnectionTime = 0;
const long interval = 15000; // 每隔15秒发送一次数据 (ThingSpeak免费版限制)
void setup() {
Serial.begin(9600);
pinMode(A0, INPUT);
Ethernet.begin(mac, ip);
Serial.println("连接到 ThingSpeak...");
}
void loop() {
// 检查是否到了发送数据的时间
if (millis() - lastConnectionTime > interval) {
// 读取传感器数据 (LM35: 10mV/°C)
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
float temperature = voltage * 100; // 转换为摄氏温度
// 发送数据到 ThingSpeak
if (client.connect(server, 80)) {
Serial.println("连接成功");
// 构建GET请求
client.print("GET /update?api_key=");
client.print(apiKey);
client.print("&field1="); // field1 是你在ThingSpeak Channel中设置的字段
client.print(temperature);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();
lastConnectionTime = millis();
} else {
Serial.println("连接失败");
}
}
// 断开连接
if (!client.connected()) {
client.stop();
}
}
如何运行:
- 替换
YOUR_API_KEY为你自己的 API Key。 - 上传代码。
- 打开串口监视器,你会看到连接和数据发送的日志。
- 登录你的 ThingSpeak 账户,查看你的 Channel,数据图表应该会自动更新。
常见问题与故障排除
-
问题1:获取不到IP地址 (DHCP failed)
- 原因:路由器DHCP服务问题、网线没插好、MAC地址冲突。
- 解决:
- 检查网线两端是否插紧。
- 尝试重启路由器和Arduino。
- 使用静态IP地址作为临时解决方案。
- 确保你的MAC地址是唯一的。
-
问题2:浏览器无法访问Arduino的IP
- 原因:防火墙阻止、IP地址冲突、Arduino程序卡住。
- 解决:
- 检查电脑和Arduino是否在同一个局域网(同一个路由器下)。
- 尝试
ping <Arduino的IP>,看是否能通。 - 检查串口监视器,看Arduino是否正常打印信息。
- 关闭电脑的防火墙或添加例外规则。
-
问题3:Web服务器响应很慢或不稳定
- 原因:
loop()函数中有耗时操作(如delay())、代码效率低。 - 解决:避免在
loop()中使用长延时,使用millis()函数来实现非阻塞的延时,就像发送数据到ThingSpeak的例子一样。
- 原因:
进阶应用与资源
当你掌握了基础后,可以探索更广阔的世界:
- MQTT 协议:比HTTP更轻量、更适合物联网的发布/订阅模型,可以使用
PubSubClient库。 - WebSocket:实现服务器和客户端之间的全双工通信,可以实现实时数据更新和双向控制,无需刷新页面。
- OTA (Over-The-Air) 更新:通过网络为Arduino远程更新固件,非常方便。
- 使用其他平台:Blynk、Adafruit IO 等平台提供了更友好的图形界面,可以大大简化开发。
官方资源:
- Arduino Ethernet 官方参考
- Wiznet W5500 芯片数据手册 (了解底层协议)
希望这份详细的教程能帮助你顺利入门 Arduino Ethernet!祝你玩得开心!
