esp01s(esp8266)继电器局域网定时插座
定时插座
http://192.168.31.160/LED-Control?ledPwm=0&time=22:59:50
ledPwm:0.关机时间,1.开机时间,2.设置时间,3.手动开,4.手动关, 5.删除时间
现在时间: 00:01:19
开列表: []
关列表: []
继电器状态: 开启
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <Ticker.h>
#define MAX_SCHEDULES 20 // 假设最多支持20个时间计划
Ticker ticker;
int count; // 计时器计数变量
String onTimes[MAX_SCHEDULES];
int onTimesindex = 0;
String offTimes[MAX_SCHEDULES];
int offTimesindex = 0;
int relay = 0; // 继电器引脚,NodeMCU D5
ESP8266WebServer esp8266_server(80);
String currentTime;
int hours = 0; // 当前小时数
int minutes = 0; // 当前分钟数
int seconds = 0; // 当前秒数
void setup(void) {
pinMode(relay, OUTPUT);
Serial.begin(9600);
Serial.println("");
ticker.attach(1, tickerCount);
digitalWrite(relay, HIGH);
pinMode(LED_BUILTIN, OUTPUT);
WiFi.begin("yang1234", "y123456789"); // 输入你的WiFi SSID和密码
Serial.println("Connecting ...");
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(i++);
Serial.print(' ');
}
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID());
Serial.print("IP address:\t");
Serial.println(WiFi.localIP());
if (SPIFFS.begin()) {
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
esp8266_server.on("/LED-Control", handleLEDControl);
// esp8266_server.on("/", HTTP_GET, handleRoot); // 新增根路径的处理函数
esp8266_server.onNotFound(handleUserRequest);
esp8266_server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
esp8266_server.handleClient();
}
void tickerCount() {
// if (count <= 0) {
// digitalWrite(relay, LOW);
// count = 0;
// } else {
// delay(1000);
// count--;
// }
// 每秒增加1秒
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
if (hours >= 24) { // 如果小时数大于等于24,重置为0点
hours = 0;
}
}
}
// 构建时间字符串
currentTime = String(hours < 10 ? "0" : "") + hours + ":" +
String(minutes < 10 ? "0" : "") + minutes + ":" +
String(seconds < 10 ? "0" : "") + seconds;
Serial.print("currentTime=");
Serial.println(currentTime);
// 检查onTimes数组,如果有匹配则打开继电器
for (int i = 0; i < MAX_SCHEDULES; i++) {
String onTime = String(onTimes[i]);
if (onTime == currentTime) {
Serial.println("off");
digitalWrite(relay, HIGH);
break;
}
}
// 检查offTimes数组,如果有匹配则关闭继电器
for (int i = 0; i < MAX_SCHEDULES; i++) {
String offTime = String(offTimes[i]);
if (offTime == currentTime) {
digitalWrite(relay, LOW);
Serial.println("on");
break;
}
}
}
void handleLEDControl() {
String ledPwm = esp8266_server.arg("ledPwm");
int ledPwmVal = ledPwm.toInt();
if (ledPwmVal == 0) {
String timeParam = esp8266_server.arg("time");
offTimes[offTimesindex] = timeParam;
offTimesindex ++;
}
else if (ledPwmVal == 2) {
String timeParam = esp8266_server.arg("time");
// 解析时间参数的格式为hh:mm:ss
int parsedHours, parsedMinutes, parsedSeconds;
if (sscanf(timeParam.c_str(), "%d:%d:%d", &parsedHours, &parsedMinutes, &parsedSeconds) == 3) {
hours = parsedHours;
minutes = parsedMinutes;
seconds = parsedSeconds;
currentTime = String(hours < 10 ? "0" : "") + hours + ":" + String(minutes < 10 ? "0" : "") + minutes + ":" +String(seconds < 10 ? "0" : "") + seconds;
}
} else if (ledPwmVal == 1) {
String timeParam = esp8266_server.arg("time");
onTimes[onTimesindex] = timeParam;
onTimesindex++;
}else if (ledPwmVal == 3) {
digitalWrite(relay, HIGH);
}
else if (ledPwmVal == 4) {
digitalWrite(relay, LOW);
} else if(ledPwmVal == 5){
//删除时间日期
String timeParam = esp8266_server.arg("time");
int len = sizeof(offTimes) / sizeof(offTimes[0]);
// 使用一个循环查找要删除的元素并删除
int indexToDelete = -1;
for (int i = 0; i < sizeof(offTimes) / sizeof(offTimes[0]); i++) {
if (offTimes[i] == timeParam) {
indexToDelete = i;
offTimesindex --;
break;
}
}
// 如果找到要删除的元素,就删除它
if (indexToDelete != -1) {
for (int i = indexToDelete; i < sizeof(offTimes) / sizeof(offTimes[0]) - 1; i++) {
offTimes[i] = offTimes[i + 1];
}
// 将最后一个元素设置为空字符串或者你需要的默认值
offTimes[sizeof(offTimes) / sizeof(offTimes[0]) - 1] = "";
}
len = sizeof(onTimes) / sizeof(onTimes[0]);
// 使用一个循环查找要删除的元素并删除
indexToDelete = -1;
for (int i = 0; i < sizeof(onTimes) / sizeof(onTimes[0]); i++) {
if (onTimes[i] == timeParam) {
indexToDelete = i;
onTimesindex --;
break;
}
}
// 如果找到要删除的元素,就删除它
if (indexToDelete != -1) {
for (int i = indexToDelete; i < sizeof(onTimes) / sizeof(onTimes[0]) - 1; i++) {
onTimes[i] = onTimes[i + 1];
}
// 将最后一个元素设置为空字符串或者你需要的默认值
onTimes[sizeof(onTimes) / sizeof(onTimes[0]) - 1] = "";
}
}
int digitalValue = digitalRead(relay); // 读取 0 号数字引脚的电平状态
String relayStatus;
if (digitalValue == 1){
relayStatus = "开启";
}
else{
relayStatus = "关闭";
}
// 生成HTML内容,包括onTimes和offTimes
String htmlContent = R"(
<!DOCTYPE html>
<html>
<head>
<title>插座开关</title>
<meta charset="UTF-8">
<script>
// 在这里插入Arduino生成的时间变量
var currentTime = ")" + currentTime + R"(";
var timeParts = currentTime.split(":");
var hours = timeParts[0];
var minutes = timeParts[1];
var seconds = timeParts[2];
function updateTime() {
var timeDisplay = document.getElementById("timeDisplay");
// 分割时间字符串为小时、分钟和秒
// 每次加1秒
seconds++;
// 如果秒数达到60,将秒数重置为0并增加分钟
if (seconds === 60) {
seconds = 0;
minutes++;
// 如果分钟达到60,将分钟重置为0并增加小时
if (minutes === 60) {
minutes = 0;
hours++;
// 如果小时达到24,将小时重置为0
if (hours === 24) {
hours = 0;
}
}
}
// 格式化小时、分钟和秒,确保它们始终显示两位数
var formattedHours = ('0' + hours).slice(-2);
var formattedMinutes = ('0' + minutes).slice(-2);
var formattedSeconds = ('0' + seconds).slice(-2);
// 构建格式化后的时间字符串
var formattedTime = formattedHours + ":" + formattedMinutes + ":" + formattedSeconds;
// console.log(formattedTime);
// 更新时间显示
timeDisplay.textContent = formattedTime;
}
// 每秒钟调用一次updateTime函数
setInterval(updateTime, 1000);
// 当页面加载完成时立即更新时间
window.onload = updateTime;
</script>
</head>
<body>
<h1>ledPwm:0.关机时间,1.开机时间,2.设置时间,3.手动开,4.手动关, 5.删除时间</h1>
<p>现在时间: <span id="timeDisplay">00:00:00</span></p>
<p>开列表: )" + getScheduleString(onTimes, onTimesindex) + R"(<p>
<p>关列表: )" + getScheduleString(offTimes, offTimesindex) + R"(<p>
<p><span id="relayStatus">继电器状态: )" + relayStatus + R"(</span></p>
</body>
</html>
)";
esp8266_server.send(200, "text/html", htmlContent);
}
String getScheduleString(String* scheduleArray, int scheduleCount) {
String result = "[";
for (int i = 0; i < scheduleCount; i++) {
result += "\"" + scheduleArray[i] + "\"";
if (i < scheduleCount - 1) {
result += ", ";
}
}
result += "]";
return result;
}
void handleUserRequest() {
String reqResource = esp8266_server.uri();
Serial.print("reqResource: ");
Serial.println(reqResource);
bool fileReadOK = handleFileRead(reqResource);
if (!fileReadOK) {
esp8266_server.send(404, "text/plain", "404 Not Found");
}
}
bool handleFileRead(String resource) {
if (resource.endsWith("/")) {
resource = "/index.html";
}
String contentType = getContentType(resource);
if (SPIFFS.exists(resource)) {
File file = SPIFFS.open(resource, "r");
esp8266_server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
String getContentType(String filename) {
if (filename.endsWith(".htm")) return "text/html";
else if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".png")) return "image/png";
else if (filename.endsWith(".gif")) return "image/gif";
else if (filename.endsWith(".jpg")) return "image/jpeg";
else if (filename.endsWith(".ico")) return "image/x-icon";
else if (filename.endsWith(".xml")) return "text/xml";
else if (filename.endsWith(".pdf")) return "application/x-pdf";
else if (filename.endsWith(".zip")) return "application/x-zip";
else if (filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
python 代码
import requests
import re
import ast
ip = "192.168.31.160"
# ESP-EBFB77 138
from datetime import datetime
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
print(current_time)
off_list = ['07:22:00', "09:48:00","12:30:00", "17:51:00", "23:37:00", "23:50:00"]
on_list = ["07:25:00", "09:51:00", "17:56:00", "23:52:00"]
url = "http://%s/LED-Control?ledPwm=2&time=%s" % (ip, str(current_time))
print(url)
response = requests.post(url)
response.encoding = 'utf-8' # 明确指定编码方式为UTF-8
html = response.text
print(html)
r_list = re.compile("开列表: (\\[.*?\\]).*?<p>关列表: (\\[.*?\\]).*?继电器状态: (.*?)<", re.S).findall(html)
print(r_list)
re_on_list = []
re_off_list = []
jdq = ''
if r_list:
re_on_list = ast.literal_eval(r_list[0][0])
re_off_list = ast.literal_eval(r_list[0][1])
jdq = r_list[0][2]
# print(re_on_list, off, jdq)
for one_time in off_list:
if one_time in re_off_list:
continue
url = "http://%s/LED-Control?ledPwm=0&time=%s" % (ip, str(one_time))
response = requests.post(url)
for one_time in on_list:
if one_time in re_on_list:
continue
url = "http://%s/LED-Control?ledPwm=1&time=%s" % (ip, str(one_time))
response = requests.post(url)
print(jdq)
有继电器,ws2812,光敏电阻,人体传感器HC-SR501,esp8266
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <Ticker.h>
#define MAX_SCHEDULES 20 // 假设最多支持20个时间计划
Ticker ticker;
int count; // 计时器计数变量
String onTimes[MAX_SCHEDULES];
int onTimesindex = 0;
String offTimes[MAX_SCHEDULES];
int offTimesindex = 0;
int relay = D1; // 继电器引脚,NodeMCU D5
const int lresistorPin = A0; // 光敏电阻
const int irSensorPin = D2; // 将人体传感器连接到D2引脚
// 定义阈值
const int ldrThreshold = 800; // 光敏电阻阈值,可以根据环境调整
const int pirThreshold = 1; // 人体传感器阈值,根据需要调整
const int THREE_MINUTES_IN_SECONDS = 180; // 全局变量定义3分钟的秒数,人体感应时候+3分钟
ESP8266WebServer esp8266_server(80);
String currentTime;
int hours = 0; // 当前小时数
int minutes = 0; // 当前分钟数
int seconds = 0; // 当前秒数
void setup(void) {
pinMode(relay, OUTPUT);
pinMode(irSensorPin, INPUT);
Serial.begin(9600);
Serial.println("");
ticker.attach(1, tickerCount);
digitalWrite(relay, LOW);
pinMode(LED_BUILTIN, OUTPUT);
WiFi.begin("yang1234", "y123456789"); // 输入你的WiFi SSID和密码
Serial.println("Connecting ...");
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(i++);
Serial.print(' ');
}
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID());
Serial.print("IP address:\t");
Serial.println(WiFi.localIP());
if (SPIFFS.begin()) {
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
esp8266_server.on("/LED-Control", handleLEDControl);
// esp8266_server.on("/", HTTP_GET, handleRoot); // 新增根路径的处理函数
esp8266_server.onNotFound(handleUserRequest);
esp8266_server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
esp8266_server.handleClient();
// 读取光敏电阻值
int ldrValue = analogRead(lresistorPin);
// 读取人体传感器值
int pirValue = digitalRead(irSensorPin);
// Serial.print("人体传感器: ");
// Serial.println(pirValue);
// Serial.print("光敏电阻: ");
// Serial.println(ldrValue);
// 如果光敏电阻和人体传感器条件满足,则执行操作
if (ldrValue > ldrThreshold && pirValue == pirThreshold) {
digitalWrite(relay, HIGH);
// 清空关数组offTimes
for (int i = 0; i < MAX_SCHEDULES; i++) {
offTimes[i] = "";
}
offTimesindex = 0;
// 获取当前时间
String currentTime = getCurrentTime();
Serial.println("Current Time: " + currentTime);
// 当前时间加3分钟
int currentHours = hours;
int currentMinutes = minutes + (THREE_MINUTES_IN_SECONDS / 60); // 转换为分钟;
if (currentMinutes >= 60) {
currentHours++;
currentMinutes -= 60;
}
// 构建关时间字符串
String offTime = String(currentHours < 10 ? "0" : "") + currentHours + ":" +
String(currentMinutes < 10 ? "0" : "") + currentMinutes + ":" +
String(seconds < 10 ? "0" : "") + seconds;
// 加入关数组offTimes
offTimes[offTimesindex] = offTime;
offTimesindex++;
}
}
String getCurrentTime() {
return String(hours < 10 ? "0" : "") + hours + ":" +
String(minutes < 10 ? "0" : "") + minutes + ":" +
String(seconds < 10 ? "0" : "") + seconds;
}
void tickerCount() {
// if (count <= 0) {
// digitalWrite(relay, LOW);
// count = 0;
// } else {
// delay(1000);
// count--;
// }
// 每秒增加1秒
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
if (hours >= 24) { // 如果小时数大于等于24,重置为0点
hours = 0;
}
}
}
// 构建时间字符串
currentTime = String(hours < 10 ? "0" : "") + hours + ":" +
String(minutes < 10 ? "0" : "") + minutes + ":" +
String(seconds < 10 ? "0" : "") + seconds;
Serial.print("currentTime=");
Serial.println(currentTime);
// 检查onTimes数组,如果有匹配则打开继电器
for (int i = 0; i < MAX_SCHEDULES; i++) {
String onTime = String(onTimes[i]);
if (onTime == currentTime) {
Serial.println("off");
digitalWrite(relay, HIGH);
break;
}
}
// 检查offTimes数组,如果有匹配则关闭继电器
for (int i = 0; i < MAX_SCHEDULES; i++) {
String offTime = String(offTimes[i]);
if (offTime == currentTime) {
digitalWrite(relay, LOW);
Serial.println("on");
break;
}
}
}
void handleLEDControl() {
String ledPwm = esp8266_server.arg("ledPwm");
int ledPwmVal = ledPwm.toInt();
if (ledPwmVal == 0) {
String timeParam = esp8266_server.arg("time");
offTimes[offTimesindex] = timeParam;
offTimesindex ++;
}
else if (ledPwmVal == 2) {
String timeParam = esp8266_server.arg("time");
// 解析时间参数的格式为hh:mm:ss
int parsedHours, parsedMinutes, parsedSeconds;
if (sscanf(timeParam.c_str(), "%d:%d:%d", &parsedHours, &parsedMinutes, &parsedSeconds) == 3) {
hours = parsedHours;
minutes = parsedMinutes;
seconds = parsedSeconds;
currentTime = String(hours < 10 ? "0" : "") + hours + ":" + String(minutes < 10 ? "0" : "") + minutes + ":" +String(seconds < 10 ? "0" : "") + seconds;
}
} else if (ledPwmVal == 1) {
String timeParam = esp8266_server.arg("time");
onTimes[onTimesindex] = timeParam;
onTimesindex++;
}else if (ledPwmVal == 3) {
digitalWrite(relay, HIGH);
}
else if (ledPwmVal == 4) {
digitalWrite(relay, LOW);
} else if(ledPwmVal == 5){
//删除时间日期
String timeParam = esp8266_server.arg("time");
int len = sizeof(offTimes) / sizeof(offTimes[0]);
// 使用一个循环查找要删除的元素并删除
int indexToDelete = -1;
for (int i = 0; i < sizeof(offTimes) / sizeof(offTimes[0]); i++) {
if (offTimes[i] == timeParam) {
indexToDelete = i;
offTimesindex --;
break;
}
}
// 如果找到要删除的元素,就删除它
if (indexToDelete != -1) {
for (int i = indexToDelete; i < sizeof(offTimes) / sizeof(offTimes[0]) - 1; i++) {
offTimes[i] = offTimes[i + 1];
}
// 将最后一个元素设置为空字符串或者你需要的默认值
offTimes[sizeof(offTimes) / sizeof(offTimes[0]) - 1] = "";
}
len = sizeof(onTimes) / sizeof(onTimes[0]);
// 使用一个循环查找要删除的元素并删除
indexToDelete = -1;
for (int i = 0; i < sizeof(onTimes) / sizeof(onTimes[0]); i++) {
if (onTimes[i] == timeParam) {
indexToDelete = i;
onTimesindex --;
break;
}
}
// 如果找到要删除的元素,就删除它
if (indexToDelete != -1) {
for (int i = indexToDelete; i < sizeof(onTimes) / sizeof(onTimes[0]) - 1; i++) {
onTimes[i] = onTimes[i + 1];
}
// 将最后一个元素设置为空字符串或者你需要的默认值
onTimes[sizeof(onTimes) / sizeof(onTimes[0]) - 1] = "";
}
}
int digitalValue = digitalRead(relay); // 读取 0 号数字引脚的电平状态
String relayStatus;
if (digitalValue == 1){
relayStatus = "开启";
}
else{
relayStatus = "关闭";
}
// 生成HTML内容,包括onTimes和offTimes
String htmlContent = R"(
<!DOCTYPE html>
<html>
<head>
<title>插座开关</title>
<meta charset="UTF-8">
<script>
// 在这里插入Arduino生成的时间变量
var currentTime = ")" + currentTime + R"(";
var timeParts = currentTime.split(":");
var hours = timeParts[0];
var minutes = timeParts[1];
var seconds = timeParts[2];
function updateTime() {
var timeDisplay = document.getElementById("timeDisplay");
// 分割时间字符串为小时、分钟和秒
// 每次加1秒
seconds++;
// 如果秒数达到60,将秒数重置为0并增加分钟
if (seconds === 60) {
seconds = 0;
minutes++;
// 如果分钟达到60,将分钟重置为0并增加小时
if (minutes === 60) {
minutes = 0;
hours++;
// 如果小时达到24,将小时重置为0
if (hours === 24) {
hours = 0;
}
}
}
// 格式化小时、分钟和秒,确保它们始终显示两位数
var formattedHours = ('0' + hours).slice(-2);
var formattedMinutes = ('0' + minutes).slice(-2);
var formattedSeconds = ('0' + seconds).slice(-2);
// 构建格式化后的时间字符串
var formattedTime = formattedHours + ":" + formattedMinutes + ":" + formattedSeconds;
// console.log(formattedTime);
// 更新时间显示
timeDisplay.textContent = formattedTime;
}
// 每秒钟调用一次updateTime函数
setInterval(updateTime, 1000);
// 当页面加载完成时立即更新时间
window.onload = updateTime;
</script>
</head>
<body>
<h1>ledPwm:0.设置关机时间列表,1.设置开机时间列表,2.设置现在时间,3.手动开,4.手动关, 5.删除时间</h1>
<p>现在时间: <span id="timeDisplay">00:00:00</span></p>
<p>光敏电阻阈值: )" + String(ldrThreshold) + R"(</p>
<p>人体传感器阈值: )" + String(pirThreshold) + R"(</p>
<p>开列表: )" + getScheduleString(onTimes, onTimesindex) + R"(<p>
<p>关列表: )" + getScheduleString(offTimes, offTimesindex) + R"(<p>
<p><span id="relayStatus">继电器状态: )" + relayStatus + R"(</span></p>
</body>
</html>
)";
esp8266_server.send(200, "text/html", htmlContent);
}
String getScheduleString(String* scheduleArray, int scheduleCount) {
String result = "[";
for (int i = 0; i < scheduleCount; i++) {
result += "\"" + scheduleArray[i] + "\"";
if (i < scheduleCount - 1) {
result += ", ";
}
}
result += "]";
return result;
}
void handleUserRequest() {
String reqResource = esp8266_server.uri();
Serial.print("reqResource: ");
Serial.println(reqResource);
bool fileReadOK = handleFileRead(reqResource);
if (!fileReadOK) {
esp8266_server.send(404, "text/plain", "404 Not Found");
}
}
bool handleFileRead(String resource) {
if (resource.endsWith("/")) {
resource = "/index.html";
}
String contentType = getContentType(resource);
if (SPIFFS.exists(resource)) {
File file = SPIFFS.open(resource, "r");
esp8266_server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
String getContentType(String filename) {
if (filename.endsWith(".htm")) return "text/html";
else if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".png")) return "image/png";
else if (filename.endsWith(".gif")) return "image/gif";
else if (filename.endsWith(".jpg")) return "image/jpeg";
else if (filename.endsWith(".ico")) return "image/x-icon";
else if (filename.endsWith(".xml")) return "text/xml";
else if (filename.endsWith(".pdf")) return "application/x-pdf";
else if (filename.endsWith(".zip")) return "application/x-zip";
else if (filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
使用ws2812 人体传感器HC-SR501,esp8266.(使用光明电阻过一会wifi重启不知原因)
#include <DNSServer.h>
#include "FastLED.h" // 此示例程序需要使用FastLED库
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <Ticker.h>
#define MAX_SCHEDULES 20 // 假设最多支持20个时间计划
Ticker ticker;
int count; // 计时器计数变量
String onTimes[MAX_SCHEDULES];
int onTimesindex = 0;
String offTimes[MAX_SCHEDULES];
int offTimesindex = 0;
const int irSensorPin = D2; // 将人体传感器连接到D2引脚
String litLedsCountStr; // led数量,字符串
// 定义阈值
const int pirThreshold = 1; // 人体传感器阈值,根据需要调整
int pirValue;
const int THREE_MINUTES_IN_SECONDS =60; // 全局变量定义3分钟的秒数,人体感应时候+60秒
ESP8266WebServer esp8266_server(80);
String currentTime;
int hours = 0; // 当前小时数
int minutes = 0; // 当前分钟数
int seconds = 0; // 当前秒数
#define NUM_LEDS 60 // LED灯珠数量
#define LED_DT D6 // Arduino输出控制信号引脚
#define LED_TYPE WS2812 // LED灯带型号
#define COLOR_ORDER GRB // RGB灯珠中红色、绿色、蓝色LED的排列顺序
uint8_t max_bright = 128; // LED亮度控制变量,可使用数值为 0 ~ 255, 数值越大则光带亮度越高
CRGB leds[NUM_LEDS]; // 建立光带leds
uint8_t beginHue;
void setup(void) {
pinMode(irSensorPin, INPUT);
Serial.begin(115200);
Serial.println("");
ticker.attach(1, tickerCount);
LEDS.addLeds<LED_TYPE, LED_DT, COLOR_ORDER>(leds, NUM_LEDS); // 初始化光带
FastLED.setBrightness(max_bright); // 设置光带亮度
pinMode(LED_BUILTIN, OUTPUT);
WiFi.begin("yang1234", "y123456789"); // 输入你的WiFi SSID和密码
Serial.println("Connecting ...");
int i = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(i++);
Serial.print(' ');
}
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID());
Serial.print("IP address:\t");
Serial.println(WiFi.localIP());
if (SPIFFS.begin()) {
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
esp8266_server.on("/LED-Control", handleLEDControl);
// esp8266_server.on("/", HTTP_GET, handleRoot); // 新增根路径的处理函数
esp8266_server.onNotFound(handleUserRequest);
esp8266_server.begin();
Serial.println("HTTP server started");
cdoff(); // 关闭所有LED
}
void loop(void) {
esp8266_server.handleClient();
// 读取人体传感器值
int pirValue = digitalRead(irSensorPin);
// 如果光敏电阻和人体传感器条件满足,则执行操作
if ( pirValue == pirThreshold) {
cdon();
Serial.println("满足开");
Serial.print("人体传感器: ");
Serial.println(pirValue);
// 清空关数组offTimes
for (int i = 0; i < MAX_SCHEDULES; i++) {
offTimes[i] = "";
}
offTimesindex = 0;
// 获取当前时间
String currentTime = getCurrentTime();
Serial.println("Current Time: " + currentTime);
// 当前时间加3分钟
int currentHours = hours;
int currentMinutes = minutes + (THREE_MINUTES_IN_SECONDS / 60); // 转换为分钟;
if (currentMinutes >= 60) {
currentHours++;
currentMinutes -= 60;
}
// 构建关时间字符串
String offTime = String(currentHours < 10 ? "0" : "") + currentHours + ":" +
String(currentMinutes < 10 ? "0" : "") + currentMinutes + ":" +
String(seconds < 10 ? "0" : "") + seconds;
// 加入关数组offTimes
offTimes[offTimesindex] = offTime;
offTimesindex++;
}
}
String getCurrentTime() {
return String(hours < 10 ? "0" : "") + hours + ":" +
String(minutes < 10 ? "0" : "") + minutes + ":" +
String(seconds < 10 ? "0" : "") + seconds;
}
void tickerCount() {
// 每秒增加1秒
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
if (minutes >= 60) {
minutes = 0;
hours++;
if (hours >= 24) { // 如果小时数大于等于24,重置为0点
hours = 0;
}
}
}
// 构建时间字符串
currentTime = String(hours < 10 ? "0" : "") + hours + ":" +
String(minutes < 10 ? "0" : "") + minutes + ":" +
String(seconds < 10 ? "0" : "") + seconds;
Serial.print("currentTime=");
Serial.println(currentTime);
// 检查onTimes数组,如果有匹配则打开继电器
for (int i = 0; i < MAX_SCHEDULES; i++) {
String onTime = String(onTimes[i]);
if (onTime == currentTime) {
Serial.println("时间到on");
cdon();
break;
}
}
// 检查offTimes数组,如果有匹配则关闭继电器
for (int i = 0; i < MAX_SCHEDULES; i++) {
String offTime = String(offTimes[i]);
if (offTime == currentTime) {
Serial.println("时间到off");
cdoff();
break;
}
}
}
void handleLEDControl() {
String ledPwm = esp8266_server.arg("ledPwm");
int ledPwmVal = ledPwm.toInt();
if (ledPwmVal == 0) {
String timeParam = esp8266_server.arg("time");
offTimes[offTimesindex] = timeParam;
offTimesindex ++;
}
else if (ledPwmVal == 2) {
String timeParam = esp8266_server.arg("time");
// 解析时间参数的格式为hh:mm:ss
int parsedHours, parsedMinutes, parsedSeconds;
if (sscanf(timeParam.c_str(), "%d:%d:%d", &parsedHours, &parsedMinutes, &parsedSeconds) == 3) {
hours = parsedHours;
minutes = parsedMinutes;
seconds = parsedSeconds;
currentTime = String(hours < 10 ? "0" : "") + hours + ":" + String(minutes < 10 ? "0" : "") + minutes + ":" +String(seconds < 10 ? "0" : "") + seconds;
}
} else if (ledPwmVal == 1) {
String timeParam = esp8266_server.arg("time");
onTimes[onTimesindex] = timeParam;
onTimesindex++;
}else if (ledPwmVal == 3) {
cdon();
}
else if (ledPwmVal == 4) {
cdoff();
} else if(ledPwmVal == 5){
//删除时间日期
String timeParam = esp8266_server.arg("time");
int len = sizeof(offTimes) / sizeof(offTimes[0]);
// 使用一个循环查找要删除的元素并删除
int indexToDelete = -1;
for (int i = 0; i < sizeof(offTimes) / sizeof(offTimes[0]); i++) {
if (offTimes[i] == timeParam) {
indexToDelete = i;
offTimesindex --;
break;
}
}
// 如果找到要删除的元素,就删除它
if (indexToDelete != -1) {
for (int i = indexToDelete; i < sizeof(offTimes) / sizeof(offTimes[0]) - 1; i++) {
offTimes[i] = offTimes[i + 1];
}
// 将最后一个元素设置为空字符串或者你需要的默认值
offTimes[sizeof(offTimes) / sizeof(offTimes[0]) - 1] = "";
}
len = sizeof(onTimes) / sizeof(onTimes[0]);
// 使用一个循环查找要删除的元素并删除
indexToDelete = -1;
for (int i = 0; i < sizeof(onTimes) / sizeof(onTimes[0]); i++) {
if (onTimes[i] == timeParam) {
indexToDelete = i;
onTimesindex --;
break;
}
}
// 如果找到要删除的元素,就删除它
if (indexToDelete != -1) {
for (int i = indexToDelete; i < sizeof(onTimes) / sizeof(onTimes[0]) - 1; i++) {
onTimes[i] = onTimes[i + 1];
}
// 将最后一个元素设置为空字符串或者你需要的默认值
onTimes[sizeof(onTimes) / sizeof(onTimes[0]) - 1] = "";
}
}
// String relayStatus = "开启";
litLedsCountStr = getLitLedsCountAsString(leds, NUM_LEDS);
// 生成HTML内容,包括onTimes和offTimes
String htmlContent = R"(
<!DOCTYPE html>
<html>
<head>
<title>插座开关</title>
<meta charset="UTF-8">
<script>
// 在这里插入Arduino生成的时间变量
var currentTime = ")" + currentTime + R"(";
var timeParts = currentTime.split(":");
var hours = timeParts[0];
var minutes = timeParts[1];
var seconds = timeParts[2];
function updateTime() {
var timeDisplay = document.getElementById("timeDisplay");
// 分割时间字符串为小时、分钟和秒
// 每次加1秒
seconds++;
// 如果秒数达到60,将秒数重置为0并增加分钟
if (seconds === 60) {
seconds = 0;
minutes++;
// 如果分钟达到60,将分钟重置为0并增加小时
if (minutes === 60) {
minutes = 0;
hours++;
// 如果小时达到24,将小时重置为0
if (hours === 24) {
hours = 0;
}
}
}
// 格式化小时、分钟和秒,确保它们始终显示两位数
var formattedHours = ('0' + hours).slice(-2);
var formattedMinutes = ('0' + minutes).slice(-2);
var formattedSeconds = ('0' + seconds).slice(-2);
// 构建格式化后的时间字符串
var formattedTime = formattedHours + ":" + formattedMinutes + ":" + formattedSeconds;
// console.log(formattedTime);
// 更新时间显示
timeDisplay.textContent = formattedTime;
}
// 每秒钟调用一次updateTime函数
setInterval(updateTime, 1000);
// 当页面加载完成时立即更新时间
window.onload = updateTime;
</script>
</head>
<body>
<h1>ledPwm:0.设置关机时间列表,1.设置开机时间列表,2.设置现在时间,3.手动开,4.手动关, 5.删除时间</h1>
<p>现在时间: <span id="timeDisplay">00:00:00</span></p>
<p>人体传感器阈值: )" + String(pirValue) + R"(</p>
<p>开列表: )" + getScheduleString(onTimes, onTimesindex) + R"(<p>
<p>关列表: )" + getScheduleString(offTimes, offTimesindex) + R"(<p>
<p><span id="relayStatus">灯珠数量: )" + litLedsCountStr + R"(</span></p>
</body>
</html>
)";
esp8266_server.send(200, "text/html", htmlContent);
}
String getScheduleString(String* scheduleArray, int scheduleCount) {
String result = "[";
for (int i = 0; i < scheduleCount; i++) {
result += "\"" + scheduleArray[i] + "\"";
if (i < scheduleCount - 1) {
result += ", ";
}
}
result += "]";
return result;
}
void handleUserRequest() {
String reqResource = esp8266_server.uri();
Serial.print("reqResource: ");
Serial.println(reqResource);
bool fileReadOK = handleFileRead(reqResource);
if (!fileReadOK) {
esp8266_server.send(404, "text/plain", "404 Not Found");
}
}
bool handleFileRead(String resource) {
if (resource.endsWith("/")) {
resource = "/index.html";
}
String contentType = getContentType(resource);
if (SPIFFS.exists(resource)) {
File file = SPIFFS.open(resource, "r");
esp8266_server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
String getContentType(String filename) {
if (filename.endsWith(".htm")) return "text/html";
else if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".png")) return "image/png";
else if (filename.endsWith(".gif")) return "image/gif";
else if (filename.endsWith(".jpg")) return "image/jpeg";
else if (filename.endsWith(".ico")) return "image/x-icon";
else if (filename.endsWith(".xml")) return "text/xml";
else if (filename.endsWith(".pdf")) return "application/x-pdf";
else if (filename.endsWith(".zip")) return "application/x-zip";
else if (filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
//色
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { rainbow, rainbowWithGlitter, confetti, sinelon, juggle, bpm };
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 0; // rotating "base color" used by many of the patterns
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
void cdon() {
gPatterns[gCurrentPatternNumber]();
// send the 'leds' array out to the actual LED strip
Serial.println("执行开");
FastLED.show();
// insert a delay to keep the framerate modest
FastLED.delay(1000/max_bright);
// do some periodic updates
EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow
EVERY_N_SECONDS( 10 ) { nextPattern(); } // change
}
void cdoff() {
Serial.println("执行关");
fill_gradient_RGB(leds, 0, CRGB(0,0,0), 59, CRGB(0, 0, 0));;
FastLED.show();
delay(500);
turnOffAllLeds();
}
void turnOffAllLeds() {
// 设置所有LED颜色为黑色(关闭)
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB::Black;
}
// 更新LED灯的状态
FastLED.show();
}
String getLitLedsCountAsString(CRGB leds[], int numLeds) {
int litCount = 0; // 用于计数亮灯的数量
for (int i = 0; i < numLeds; i++) {
// 如果LED不是黑色(关闭)表示它是亮的
if (leds[i]) { // 这里隐式检查leds[i]是否不等于CRGB::Black
litCount++;
}
}
// 将整数转换为String对象并返回
return String(litCount);
}
void nextPattern()
{
// add one to the current pattern number, and wrap around at the end
gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns);
}
void rainbow()
{
// FastLED's built-in rainbow generator
fill_rainbow( leds, NUM_LEDS, gHue, 7);
}
void rainbowWithGlitter()
{
// built-in FastLED rainbow, plus some random sparkly glitter
rainbow();
addGlitter(80);
}
void addGlitter( fract8 chanceOfGlitter)
{
if( random8() < chanceOfGlitter) {
leds[ random16(NUM_LEDS) ] += CRGB::White;
}
}
void confetti()
{
// random colored speckles that blink in and fade smoothly
fadeToBlackBy( leds, NUM_LEDS, 10);
int pos = random16(NUM_LEDS);
leds[pos] += CHSV( gHue + random8(64), 200, 255);
}
void sinelon()
{
// a colored dot sweeping back and forth, with fading trails
fadeToBlackBy( leds, NUM_LEDS, 20);
int pos = beatsin16( 13, 0, NUM_LEDS-1 );
leds[pos] += CHSV( gHue, 255, 192);
}
void bpm()
{
// colored stripes pulsing at a defined Beats-Per-Minute (BPM)
uint8_t BeatsPerMinute = 62;
CRGBPalette16 palette = PartyColors_p;
uint8_t beat = beatsin8( BeatsPerMinute, 64, 255);
for( int i = 0; i < NUM_LEDS; i++) { //9948
leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10));
}
}
void juggle() {
// eight colored dots, weaving in and out of sync with each other
fadeToBlackBy( leds, NUM_LEDS, 20);
byte dothue = 0;
for( int i = 0; i < 8; i++) {
leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
dothue += 32;
}
}
本文作者: 永生
本文链接: https://yys.zone/detail/?id=309
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)