#include <WiFi.h>
#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会阻塞服务器响应
}