WiFi控制LED灯
# PinToo之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灯熄灭。
通过范例学习,可以掌握 TfxIdTCPClient组件的基本通讯原理,并结合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 开发板
// 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
const char* password = "PASSWORD"; //输入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. 设计明细
开启PinToo设计器,分别加入下插图之控件。或者点击左上角的[打开模板Lib文件]
选择模板文件来打开对应模板。

①:TfxSwitchButton组件,控件名称为fxSwitchButton2
。
②:TfxSwitchButton组件,控件名称为fxSwitchButton1
。
③:TfxIdTCPClient组件,控件名称为fxIdTCPClientLED
。
fxRunFrame属性设置
Height
:设置页面高度=800
。Width
:设置页面宽度=401
。
①fxSwitchButton2属性设置
Height
:设置控件高度=200
。Width
:设置控件宽度=200
。HitTest
:是否响应点击操作,设置为False
。SwitchOffBmp
:设置开关状态为关时显示的图像,双击该属性或者点击属性右侧的[...]
打开图像编辑器。点击[Load...]
打开资源管理器,选择所需的图片后点击[打开]
,选择的图像会显示在预览框中。可在该页面下进行裁切或者缩放像素以使图像与控件的宽度高度相适应,修改完成后点击[OK]
按钮完成图像修改。
SwitchOnBmp
:设置开关状态为开时显示的图像,双击该属性或者点击属性右侧的[...]
打开图像编辑器。点击[Load...]
打开资源管理器,选择所需的图片后点击[打开]
,选择的图像会显示在预览框中。可在该页面下进行裁切或者缩放像素以使图像与控件的宽度高度相适应,修改完成后点击[OK]
按钮完成图像修改。
③fxSwitchButton1属性设置
Height
:设置控件高度=200
。Width
:设置控件宽度=200
。SwitchOffBmp
:设置开关状态为关时显示的图像,双击该属性或者点击属性右侧的[...]
打开图像编辑器。点击[Load...]
打开资源管理器,选择所需的图片后点击[打开]
,选择的图像会显示在预览框中。可在该页面下进行裁切或者缩放像素以使图像与控件的宽度高度相适应,修改完成后点击[OK]
按钮完成图像修改。
SwitchOnBmp
:设置开关状态为开时显示的图像,双击该属性或者点击属性右侧的[...]
打开图像编辑器。点击[Load...]
打开资源管理器,选择所需的图片后点击[打开]
,选择的图像会显示在预览框中。可在该页面下进行裁切或者缩放像素以使图像与控件的宽度高度相适应,修改完成后点击[OK]
按钮完成图像修改。
③fxIdTCPClientLED属性设置
Host
:NodeMCU设备的IP地址,在Arduino程序中进行定义,例如192.168.0.169
。Port
:NodeMCU设备使用的端口,在Arduino程序中进行定义,例如3300
。Name
:设置控件名称=fxIdTCPClientLED
。
# 7. 程序设计
点击程序设计界面右下角的按钮,切换至单元选择界面,勾选需要使用的单元。该程序需要引用IdTCPClient
,IdTCPConnection
单元。
# 7.1. 程序初始设置
程序同步按钮与灯的状态。
Begin
fxSwitchButton1.IsChecked := fxSwitchButton2.IsChecked;
End.
2
3
# 7.2. 事件设置
- ③fxSwitchButton1-OnClick事件
点击以进行连接发送开关指令。
Procedure fxSwitchButton1OnClick(Sender: TObject);
Begin
if fxSwitchButton1.IsChecked Then
//开启LED
begin
fxIdTCPClientLED.FastConnect; //快速连接NodeMCU设备
fxIdTCPClientLED.SendData('1'); //发送 1 指令给NodeMCU,点亮LED
fxSwitchButton2.IsChecked := True;
fxRDToastMessage1.ShowToastMessage('LED灯已开启',2.0,100);
End
else
//关闭LED
Begin
fxIdTCPClientLED.FastConnect; //快速连接NodeMCU设备
fxIdTCPClientLED.SendData('0'); //发送 0 指令给NodeMCU,熄灭LED
fxSwitchButton2.IsChecked := False;
fxRDToastMessage1.ShowToastMessage('LED灯已关闭',2.0,100);
End;
End;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 8. 运行结果
使用鼠标在 PinToo 菜单,点击[保存至数据库]
按钮,将其保存至数据库,点击[调试运行]
确认能够正常打开。
通过同步中心,将程序上传至手机PinToo运行;同步时,请确保手机已经运行PinToo,并且已经登陆。


当给NodeMCU设备通电后,点击手机端程序的开关按钮,程序显示开关状态,同时开启或关闭LED灯。