WiFi控制LED灯
# Smart之WIFI控制LED灯
# 1. 说明
范例采用WIFI通讯协议,控制驳接在NodeMCU上的LED灯。NodeMCU是以ESP8266(ESP12)晶片为基础,包含了WiFi,GPIO,PWM,ADC,I2C等功能的主控板,执行效率高,非常适合物联网应用开发,因为它内建了WiFi功能,与Arduino相容,Arduino中可用的传感器基本都可用于NodeMCU。范例中使用的LED灯正极(长脚)连接电阻再连接至NodeMCU D5针脚,LED灯负极连接到NodeMCU GND针脚。
范例中使用的NodeMCU的ESP8266无线网络,先从路由器得知取得IP,连接网络成功后,检测是否从WiFi网络接收到用户端传输的字符串。如果该字符串=1,NodeMCU D5针脚输出为高电平,LED灯点亮,字符串=0,NodeMCU D5针脚输出为低电平,LED灯熄灭。
通过范例学习,可以掌握 TIdTCPClient组件的基本通讯原理,并结合NodeMCU ESP8266开发板进行LED的控制功能。
# 2. 零件连接图

NodeMCU中的引脚定义如下:

# 3. 使用零件
序 | 零件名称 | 数量 |
---|---|---|
1 | NodeMCU ESP8266 开发板 | 1 |
3 | USB数据线 | 1 |
4 | 面包板 | 1 |
5 | 杜邦线 | 2 |
6 | LED灯 | 1 |
7 | 220欧姆电阻 | 1 |
# 4. Arduino流程图

# 5. Arduino程序
使用Arduino IDE 编译并上传以下Arduino程序。该程序使用的是NodeMCU开发板,关于该开发板在Arduino中的设置选项可参考Arduino IDE 搭建 ESP8266 开发环境及项目演示 (opens new window)。
// 使用 NodeMCU 开发板
// https://github.com/evothings/evothings-examples/tree/master/examples/arduino-led-onoff-tcp
// 输入字符串并以换行符作为结束字符,字符串=1 开发板开启LED灯,字符串=0 开发板关闭LED灯。
// 字符串=Rn 开发板传回数字信号 Pin n脚位的值
// 字串=An 开发板传回模拟信号 Pin n脚位的值
#include <SPI.h>
#include <ESP8266WiFi.h>
#define LED_PIN 14 //定义LED 针脚D5 NodMCU可以设定为D1
const char* ssid = "WIFI_SSID"; //输入WIFI的SSID 请修改为您实际需要连接的WIFI SSID
const char* password = "WIFI_PASSWORD"; //输入WIFI的密码 请修改为您实际需要连接的WIFI 密码
int status = WL_IDLE_STATUS; //服务器的状态表示的定义
WiFiServer server(3300); // 设置WIFI服务器的端口
void setup() {
Serial.begin(9600); // 设定串口的通讯速率,需与
WiFi.mode(WIFI_STA);
//指定IP位址,請自行在此加入WiFi.config()敘述。
WiFi.config(IPAddress(192,168,0,169), // IP地址
IPAddress(192,168,0,1), // 网关地址
IPAddress(255,255,255,0)); // 子网掩码
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { // 检查是否连接到WIFI
delay(500);
Serial.print(".");
}
server.begin(); // WIFI服务器开始运行
printWifiStatus(); // 输出WIFI的状态
pinMode(LED_PIN, OUTPUT); //设定针脚D5位为输出模式
}
// 读取使用 JavaScript客户端发送的字符串, 该字符串使用换行符作为结尾
String readRequest(WiFiClient* client)
{
String request = "";
while (client->connected()) // 检查是否连接
{
while (client->available()) // 是否有客户端传输的字符串
{
char c = client->read(); // 读取字符串
Serial.write(c); // 从串口输出字符串,用于纠错
if ('\n' == c) // 如果读取到换行字符,则返回
{
return request;
}
request += c; // 累加读取到的字符串
}
}
return request;
}
// 依据读取到的字符串进行相关的控制操作
void executeRequest(WiFiClient* client, String* request)
{
char command = readCommand(request); // 读取命令字符,即第一个字符
int n = readParam(request); // 读取动作指令
if (command == '0')
{
digitalWrite(LED_PIN, LOW); //输出为低电平,LED熄灭
}
else if (command == '1')
{
digitalWrite(LED_PIN, HIGH); //输出为高电平,LED点亮
}
else if (command == 'R')
{
sendResponse(client, String(digitalRead(n))); //读取开发板上的数字针脚的n脚位 输出到客户端
}
else if (command == 'A')
{
sendResponse(client, String(analogRead(n))); //读取开发板上的模拟针脚的n脚位 输出到客户端
}
}
// 读取命令字符,即第一个字符
char readCommand(String* request)
{
String commandString = request->substring(0, 1);
return commandString.charAt(0);
}
// 读取动作指令
int readParam(String* request)
{
char buffer[2]; //可以处理0到F(0到15)的十六进制数字
buffer[0] = request->charAt(1);
buffer[1] = 0;
return (int) strtol(buffer, NULL, 16);
}
void sendResponse(WiFiClient* client, String response)
{
client->println(response); // 将读取到的字符输出到串口
Serial.println("sendResponse:"); // 纠错用
Serial.println(response);
}
void loop() {
if (WiFi.status()!= WL_CONNECTED) //检查WiFi网络是否已连接
{
return;
}
WiFiClient client = server.available(); //监听传入的客户端请求
if (!client)
{
return;
}
//Serial.println("客户端已连接");
String request = readRequest(&client); // 读取客户端发送的字符串
executeRequest(&client, &request); // 依据读取到的字符串进行相应的控制动作
//Serial.println("客户端已断线");
}
// 从串口输出WIFI的状态信息
void printWifiStatus()
{
Serial.println("WiFi网络状态");
Serial.print(" SSID: "); // 输出连接的WIFI SSID
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP(); // 输出网络的IP地址
Serial.print(" IP地址: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print(" 信号强度(RSSI):"); // 输出信号强度
Serial.print(rssi);
Serial.println(" dBm");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# 6. 设计明细
开启Smart智慧控制平台,分别加入下插图之控件。或者通过点击菜单栏[文件]-[打开项目]
选择范例项目文件来打开该范例。

①:TLabel组件,控件名称为Label1
。
②:TImage组件,控件名称为Image1
。
③:TImage组件,控件名称为Image4
。
④:TIdTCPClient组件,控件名称为IdTCPClientLED
。
⑤:TImage组件,控件名称为Image3
。
⑥:TImage组件,控件名称为Image2
。
Main窗体属性设置
ClientHeight
:窗体客户区高度=624
。ClientWidth
:窗体客户区宽度=918
。
①Label1属性设置
AutoSize
:是否根据字体调整控件大小,设置为True
。Caption
:标签内容,设置为ModbusRTU之LED智能照明
。
②Image1属性设置
Align
:设置控件占满=alClient
。Stretch
:设置图片是否按照控件大小拉伸=Yes
。Picture
:设置图片(背景)。点击Picture
属性右侧的[...]
按钮,打开文件上传界面,点击[Load...]
从文件浏览器中选择对应的图片文件上传,返回该界面下,待显示出图片后点击[OK]
加载图片。
③Image4属性设置
Height
:设置控件高度=109
。Width
:设置控件宽度=109
。Picture
:设置图片(背景)。点击Picture
属性右侧的[...]
按钮,打开文件上传界面,点击[Load...]
从文件浏览器中选择对应的图片文件上传,返回该界面下,待显示出图片后点击[OK]
加载图片。
④IdTCPClientLED属性设置
Host
:NodeMCU设备的IP地址,设置为Arduino程序中设置的IP地址,例如192.168.1.162
。Port
:NodeMCU 设备使用的端口,设置为Arduino程序中设置的端口号,例如3300
。Name
:控件名称,设置为IdTCPClientLED
。
⑤Image3属性设置
Height
:设置控件高度=367
。Width
:设置控件宽度=909
。Picture
:设置图片(灯亮)。点击Picture
属性右侧的[...]
按钮,打开文件上传界面,点击[Load...]
从文件浏览器中选择对应的图片文件上传,返回该界面下,待显示出图片后点击[OK]
加载图片。
⑥Image2属性设置
Height
:设置控件高度=366
。Width
:设置控件宽度=909
。Picture
:设置图片(灯灭)。点击Picture
属性右侧的[...]
按钮,打开文件上传界面,点击[Load...]
从文件浏览器中选择对应的图片文件上传,返回该界面下,待显示出图片后点击[OK]
加载图片。
# 7. 程序设计
# 7.1. 程序初始设置
该程序无初始设置。
# 7.2. 事件设置
- ③Image4-OnClick事件
点击Image4
时,根据程序中的LED灯显示状态,开启或者关闭LED灯。
procedure TMyHandler.Image4Click;
begin
if FThis.Image3.Visible then
begin
//关灯
iot.IdTCPClientSendCmd(FThis.IdTCPClientLED,'0');
FThis.Image3.Visible := False;
end
else
begin
//开灯
iot.IdTCPClientSendCmd(FThis.IdTCPClientLED,'1');
FThis.Image3.Visible := True;
end;
end;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 8. 运行结果
通过工具栏保存,将程序保存为 sdb 项目文件。
使用鼠标点击工具栏运行(Run),测试运行结果。当点击右侧开关按钮图像时,如果底下照明灯显示为熄灭的状态,则会更新状态为点亮,同时连接到NodeMCU的LED灯也会点亮;如果照明灯显示为点亮的状态,则会更新状态为熄灭,同时连接到NodeMCU的LED灯会熄灭。
