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燈會熄滅。