You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

261 lines
7.8 KiB
Arduino

4 months ago
//马达开 马达开
//马达关 马达关
//马达运行时间 马达时间
//马达开关次数 马达次数
//当前时间 北京时间
#include "Arduino.h"
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Ticker.h>
// 定义LED引脚
#define DHTPIN D4 //说明数据接口为8266开发板的D4口也可以写为#define DHTPIN 2既8266芯片的IO口2
const int second = 30; //定时频率
// 新增变量:程序开始时间
unsigned long programStartTime = 0;
// 新增变量:亮灯次数
unsigned long ledOnCount = 0;
// 新增变量:累计亮灯时间
unsigned long totalLedOnTime = 0;
// 休眠时间
const int night = 20;
const int morning = 6;
// 定义时间间隔(毫秒)
const unsigned long intervalOn = 600000;
const unsigned long intervalOff = 3000000;
// 变量用于存储上次LED状态改变的时间
unsigned long previousMillis = 0;
// 变量用于跟踪LED当前状态
bool ledState = HIGH;
//抽水马达状态
const char *kai = "马达打开中";
const char *guan = "马达关闭中";
//定义WIFI信息
const char *ssid = "CU_A9TU"; // Enter SSID here
const char *password = "452131wW"; //Enter Password here
// MQTT Broker Settings
const char *mqtt_broker = "192.168.3.24";
const char *mqtt_topic = "/device/esp8266/001";
const char *mqtt_username = "wenfei";
const char *mqtt_password = "452131wW";
const int mqtt_port = 1883; //端口
Ticker myTicker;
WiFiClient espClient;
PubSubClient mqtt_client(espClient);
//北京时间校准
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
String currentTime;
String openTime;
//发送抽水马达状态
void sendMadaStatus(const char *str) {
if(mqtt_client.connected()) {
mqtt_client.publish(mqtt_topic, str);
timeClient.update();
Serial.println(timeClient.getFormattedTime());
Serial.println(str);
}
}
// 新增定时器回调函数
void timerCallback() {
timeClient.update();
currentTime = timeClient.getFormattedTime();
String hours = currentTime.substring(0, 2);
int hour = hours.toInt();
//判断是否处于休眠时间段
Serial.println(hour);
if ((hour >= night) || (hour < morning)) {
Serial.println("sleeping");
if(ledState == LOW) {
// 关闭LED
ledState = HIGH;
digitalWrite(D4, ledState);
}
// 这里可以添加休眠代码例如ESP32的深度睡眠
//ESP.deepSleep(1 * 60 * 1000000); // 休眠30秒
return;
}
// 获取当前时间
Serial.println("aliving");
unsigned long currentMillis = millis();
if (ledState == HIGH) {
// 如果LED当前是关闭状态检查是否到了打开的时间
if (currentMillis - previousMillis >= intervalOff) {
// 记录上次状态改变的时间
previousMillis = currentMillis;
ledState = LOW;
digitalWrite(D4, ledState);
sendMadaStatus(kai);
timeClient.update();
currentTime = timeClient.getFormattedTime();
sendMadaStatus(currentTime.c_str());
}
} else {
// 如果LED当前是打开状态检查是否到了关闭的时间
if (currentMillis - previousMillis >= intervalOn) {
// 增加亮灯次数
ledOnCount++;
// 累计亮灯时间
totalLedOnTime += intervalOn;
// 记录上次状态改变的时间
previousMillis = currentMillis;
ledState = HIGH;
digitalWrite(D4, ledState);
sendMadaStatus(guan);
timeClient.update();
currentTime = timeClient.getFormattedTime();
sendMadaStatus(currentTime.c_str());
}
}
}
//长时间断后 再开启WIFI无法连接的问题
void connectToWiFi() {
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: ");
Serial.println(WiFi.localIP());
}
void connectToMQTT() {
while (!mqtt_client.connected()) {
String client_id = "esp8266-client-" + String(WiFi.macAddress());
Serial.printf("Connecting to MQTT Broker as %s.....\n", client_id.c_str());
if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
Serial.println("Connected to MQTT broker");
timeClient.update();
openTime = timeClient.getFormattedTime();
mqtt_client.subscribe(mqtt_topic);
mqtt_client.publish(mqtt_topic, openTime.c_str()); // Publish message upon successful connectionc_str()
} else {
Serial.print("Failed, rc=");
Serial.print(mqtt_client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void mqttCallback(char *mqtt_topic, byte *payload, unsigned int length) {
String str;
Serial.print("Message received on mqtt_topic: ");
Serial.println(mqtt_topic);
Serial.print("Message: ");
for (unsigned int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
str += (char)payload[i];
}
//马达开
if (str == "马达开") {
digitalWrite(D4, LOW);
sendMadaStatus(kai);
}
//马达关
if (str == "马达关") {
digitalWrite(D4, HIGH);
sendMadaStatus(guan);
}
//马达运行时间
if (str == "马达时间") {
sendMadaStatus(((String)totalLedOnTime).c_str());
}
//马达开关次数
if (str == "马达次数") {
sendMadaStatus(((String)ledOnCount).c_str());
}
//当前时间
if (str == "北京时间") {
timeClient.update();
currentTime = timeClient.getFormattedTime();
sendMadaStatus(currentTime.c_str());
}
// if(str=="重启")
// {
// esp_restart();
// }
if (str == "状态") {
String maDa = "";
if(ledState == LOW) {
maDa = "马达关";
} else {
maDa = "马达开";
}
timeClient.update();
currentTime = timeClient.getFormattedTime();
String maDaStatus = "";
maDaStatus = "当前时间" + currentTime;
//马达状态
maDaStatus += ("\n 开机时间: " + openTime);
maDaStatus += ("\n 马达状态: " + maDa);
maDaStatus += ("\n 马达累计运行时间: " + (String)(totalLedOnTime / 1000) + "");
maDaStatus += ("\n 马达累计运行次数: " + (String)ledOnCount);
sendMadaStatus(maDaStatus.c_str());
}
if (str == "help") {
String help = "help 马达开 马达关 马达时间 马达次数 北京时间 状态 重启 ";
sendMadaStatus(help.c_str());
}
Serial.println("\n-----------------------");
Serial.println(str);
}
void setup() {
Serial.begin(115200);
Serial.print("开机成功");
// 记录程序开始时间
programStartTime = millis();
// 将LED引脚设置为输出模式
pinMode(D4, INPUT);
ledState = HIGH;
digitalWrite(D4, HIGH);
// 假设使用Arduino的定时器库这里简单模拟启动定时器
// 实际使用时需要根据具体定时器库修改
// 这里假设每1000ms调用一次定时器回调函数
myTicker.attach(second, timerCallback); // Call callbackFunction every 1 second
///连接WIFI
connectToWiFi();
// Set Root CA certificate
//espClient.setCACert(ca_cert);
// 初始化NTP客户端
timeClient.begin();
// 设置时区偏移量,例如北京时间为 +8 小时,单位为秒
timeClient.setTimeOffset(28800);
timeClient.update();
openTime = timeClient.getFormattedTime();
///mqtt连接
mqtt_client.setServer(mqtt_broker, mqtt_port);
mqtt_client.setKeepAlive(60);
mqtt_client.setCallback(mqttCallback); // Corrected callback function name
connectToMQTT();
}
void loop() {
mqtt_client.loop();
delay(10000);
//连接WIFI
if (WiFi.status() != WL_CONNECTED) {
connectToWiFi();
}
if (WiFi.status() == WL_CONNECTED) {
//连接mqtt
if (!mqtt_client.connected()) {
connectToMQTT();
}
}
}