#include //如果是ESP8266 用#include
#include "Ticker.h"
//李智勇編碼,采用AP方式做服務端,可以方便控制各種設備,網上此方面的代碼放出不多不完整,在此放出, 沒有采用網上流行的多個客戶端,那樣當新的客戶端不夠用時,處理邏輯太麻煩,一個客戶端發過來消息,服務端接收,發送確認消息,等控制指令結束發送斷開指令給客戶端,當服務端接到新的連接,主動斷開上個連接,這樣就不會阻塞網絡連接。
Ticker ticker_1; //控制一號繼電器,用計時器模擬多線程
Ticker ticker_2; //控制二號繼電器
#define PIN_R1 23 //輸出控制,
#define PIN_R2 22 //輸出控制,
// 初始化一個WiFi服務器,端口為****
#define SERVER_PORT ****
#define CLOSE_CONNECT "Off" //發送關閉指令給客戶端,讓客戶端主動斷開
int count_OPEN = 0;
int count_R1 = -1; //第一次進入打開
WiFiServer server(SERVER_PORT); //端口號,范圍 0-65535
// WiFiAPPSW是AP模式下的WiFi密碼
const String WiFiAPPSW = "12345678"; //設置AP模式下模塊所發出的WIFI的密碼
const String AP_NameString = "lizhiyong_CONTROL";
void setupWiFi() {
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_NameString, WiFiAPPSW);
//自定義IP地址信息
WiFi.softAPConfig(IPAddress(192, ***, ***, ***), IPAddress(192, ***, ***, 1), IPAddress(255, 255, 255, 0));
Serial.println(WiFi.softAPSSID());
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
Serial.print("SSID: ");
Serial.println(WiFi.softAPSSID());
server.begin();
}
void setup() {
pinMode(PIN_R1, OUTPUT); *
pinMode(PIN_R2, OUTPUT); *
*
*
Serial.begin(115200);
Serial.println("Begin now!!!");
setupWiFi();
}
WiFiClient serverClient;
void loop() {
//檢測服務器端是否有活動的客戶端連接
if (server.hasClient()) {
if (serverClient) serverClient.stop();
serverClient = server.available();
// Serial.println("hasClient " + serverClient.remoteIP());
}
//檢查客戶端的數據
if (serverClient && serverClient.connected()) {
if (serverClient.available()) {
Serial.print("Connected to client remoteIP:");
Serial.println(serverClient.remoteIP());
char data[1024] = { 0 };
// ind用于追蹤data數組中已存儲的數據量
int ind = 0;
// 接收客戶端發送的所有數據
Serial.println("Connected to client !!! ");
while (serverClient.available()) {
data[ind] = serverClient.read(); //讀取client端發送的字符,含有換行符
ind++;
}
String str = String(data);
Serial.println(str + String(str.length()));
if (str.indexOf("open") >= 0) { // compareTo equals 接收有回車符等不可見字符容易出錯
Serial.println("relay2 open is recive");
ticker_2.attach(0.1, relay2, 0); //二號繼電器打開。參數1
serverClient.print("relay2 open OK! "); //在client端回復
} else if (str.indexOf("close") >= 0) {
Serial.println("relay2 close is recive");
ticker_2.attach(0.1, relay2, 1); //參數0關斷
serverClient.print("relay2 close OK! "); //在client端回復
} else if (str.indexOf("time") >= 0) { //relay1打開后延時關閉
int time = str.substring(4).toInt(); //substring(4)從第4個數開始一直都末尾
ticker_1.attach(0.1, relay1, time); //繼電器 打開,延時time 后關閉,第一次執行沒有延時,
Serial.println("relay1 close is recive " + str.substring(4));
serverClient.print("relay1 time OK! "); //在client端回復
} else if (str.indexOf("hand") >= 0) { //relay1手動開關
Serial.println("relay1 hand " + String(count_R1));
if (count_R1 == -1) {
ticker_1.attach(0.1, relay1, -1); //手動打開關閉
Serial.println("relay1 hand open " + String(count_R1));
serverClient.print("relay1 hand open OK! "); //在client端回復
count_R1 = 0;
} else {
ticker_1.attach(0.1, relay1, 0); //-1 關閉指令
Serial.println("relay1 hand close ");
serverClient.print("relay1 hand close OK! "); //在client端回復
count_R1 = -1;
}
} else {
serverClient.print("OK! Got your request. "); //在client端回復
Serial.println("OK! Got your request. ");
}
serverClient.print(CLOSE_CONNECT); //在客戶端關閉端回復
}
}
}
void relay1(int action) { //控制繼電器1,參數整數型,0表示關,-1表示開,其他數值表示開的延時
Serial.println("relay1 active !!! " + String(action));
if (action == 0) {
digitalWrite(PIN_R1, !digitalRead(PIN_R1)); // turn the LED on (HIGH is the voltage level)
Serial.println("relay1 open PIN_R1 !!! ");
ticker_1.detach();
} else if (action == -1) {
digitalWrite(PIN_R1, !digitalRead(PIN_R1)); // turn the LED off by making the voltage LOW
Serial.println("relay1 close PIN_R1 !!! ");
ticker_1.detach();
} else {
if (count_OPEN == 0) { //第一次 延時開,打開繼電器
ticker_1.attach(action, relay1, action); //保證下次進來,并且把時間延長,因為第一次進沒有延時
digitalWrite(PIN_R1, !digitalRead(PIN_R1));
Serial.println(String(action) + " relay1 open !!! ");
count_OPEN = 1;
} else { //第二次延時關,關閉繼電器
digitalWrite(PIN_R1, !digitalRead(PIN_R1));
count_OPEN = 0;
ticker_1.detach();
Serial.println(String(action) + " relay1 close !!! ");
}
}
}
void relay2(int level) { //控制繼電器2,參數是高低電平,決定吸合
digitalWrite(PIN_R2, level); // turn the LED on (HIGH is the voltage level)
Serial.println("relay2 active !!! " + String(level));
ticker_2.detach(); //都是執行一次,模擬多線程,用delay會阻塞服務器響應
}
審核編輯 黃宇
-
繼電器
+關注
關注
132文章
5357瀏覽量
149303 -
TCP
+關注
關注
8文章
1374瀏覽量
79159 -
源碼
+關注
關注
8文章
649瀏覽量
29312 -
ESP32
+關注
關注
18文章
971瀏覽量
17415
發布評論請先 登錄
相關推薦
ESP32作為STA時連接不上另一作為AP的ESP32,為什么?
用ESP32做熱點時,用蘋果手機連接模塊,為什么在斷開時檢測不到?
![](https://file1.elecfans.com/web2/M00/84/04/wKgaomRl-CWAO5abAAGMwygkzhg448.png)
哪位朋友可以提供一個用LABWINDOWS多線程控制儀器的例子?
ESP32作為STA時連接不上另一作為AP的ESP32是哪里的問題?
如何使用std::future/std::promise 和 std::packaged_task來促進esp32上的多線程?
ESP32驅動1.54寸彩屏的應用
四、ESP32單片機wifi的AP與STA模式使用
![四、<b class='flag-5'>ESP32</b>單片機wifi的<b class='flag-5'>AP</b>與STA模式使用](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
使用MicroPython在Raspberry Pi上通過雙核編程的多線程控制LED
![使用MicroPython在Raspberry Pi上通過雙核編程的<b class='flag-5'>多線程控制</b>LED](https://file.elecfans.com/web2/M00/55/AF/poYBAGLeZN2ABGE6AANNlnAL4Go059.png)
使用ESP32、Python和javascript的遠程控制繼電器
![使用<b class='flag-5'>ESP32</b>、Python和javascript的遠<b class='flag-5'>程控制</b>繼電器](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論