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燈。