Files
LampControler/src/main.cpp

347 lines
10 KiB
C++
Raw Normal View History

2025-01-14 13:46:57 +08:00
#include "DS18B20.h"
#include "BH1750.h"
#include "Wire.h"
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
//#include "TCJ_Show.h"
//#include "ESP32_WebServer.h"
2025-01-20 17:25:14 +08:00
#include <Arduino.h>
2025-01-15 16:52:01 +08:00
#include "MCP45HVX1.h"
2025-01-20 17:25:14 +08:00
#include "INA226.h"
2025-01-21 17:31:53 +08:00
#include <Ticker.h>
2025-01-23 16:36:27 +08:00
#include <Preferences.h> // 用于存储非易失性数据
2025-02-08 16:24:54 +08:00
#include "TJC_Show.h"
#include "RunTime.h"
2025-01-21 17:31:53 +08:00
2025-02-07 15:02:44 +08:00
2025-01-21 17:31:53 +08:00
// Ticker 用于定时检查电流状态
Ticker currentCheckTicker;
2025-01-20 17:25:14 +08:00
// MCP45HVX1 数字电位器
2025-01-23 16:36:27 +08:00
MCP45HVX1 digiPot(0x3E);
2025-01-15 16:52:01 +08:00
2025-01-20 17:25:14 +08:00
// INA226 电流监控器
2025-02-08 16:24:54 +08:00
INA226 INA(0x40);
2025-01-14 13:46:57 +08:00
AsyncWebServer server(80);
const char* ssid = "SERVIRST-CT";
const char* password = "servirst8888";
2025-01-21 17:31:53 +08:00
// DS18B20 温度传感器
2025-01-15 16:52:01 +08:00
#define ONE_WIRE_BUS 8
2025-01-14 13:46:57 +08:00
OneWire oneWire(ONE_WIRE_BUS);
2025-02-08 16:24:54 +08:00
DS18B20 ds18b20(&oneWire);
2025-01-14 13:46:57 +08:00
BH1750 bh1750_a;
BH1750 bh1750_b;
2025-02-07 15:02:44 +08:00
// 风扇控制引脚
#define FAN_PIN1 15
#define FAN_PIN2 16
// 蜂鸣器引脚
#define BUZZER_PIN 17
2025-02-08 16:24:54 +08:00
extern RunTime runtime;
int activeDuration;
Preferences prefs;
2025-02-07 15:02:44 +08:00
2025-01-14 13:46:57 +08:00
// HTML 页面内容
const char index_html[] PROGMEM = R"rawliteral(
2025-01-20 17:25:14 +08:00
<!DOCTYPE html>
<html>
<head>
<title>ESP32 Data Display</title>
<meta charset="UTF-8">
<script>
2025-01-21 17:31:53 +08:00
async function fetchData()
{
const durationResponse = await fetch('/duration');
const durationText = await durationResponse.text();
document.getElementById('activeDuration').innerText = durationText;
2025-01-20 17:25:14 +08:00
const tempResponse = await fetch('/temperature');
const tempText = await tempResponse.text();
document.getElementById('temperature').innerText = tempText;
const lightAResponse = await fetch('/lightA');
const lightAText = await lightAResponse.text();
document.getElementById('lightA').innerText = lightAText;
const lightBResponse = await fetch('/lightB');
const lightBText = await lightBResponse.text();
document.getElementById('lightB').innerText = lightBText;
2025-01-14 13:46:57 +08:00
2025-01-20 17:25:14 +08:00
const wiperResponse = await fetch('/wiper');
const wiperText = await wiperResponse.text();
document.getElementById('wiper').innerText = wiperText;
const busResponse = await fetch('/busVoltage');
const busText = await busResponse.text();
document.getElementById('busVoltage').innerText = busText;
const shuntResponse = await fetch('/shuntVoltage');
const shuntText = await shuntResponse.text();
document.getElementById('shuntVoltage').innerText = shuntText;
const currentResponse = await fetch('/current');
const currentText = await currentResponse.text();
document.getElementById('current').innerText = currentText;
const powerResponse = await fetch('/power');
const powerText = await powerResponse.text();
document.getElementById('power').innerText = powerText;
}
2025-01-21 17:31:53 +08:00
async function setWiper()
{
2025-01-20 17:25:14 +08:00
const wiperValue = document.getElementById('wiperValue').value;
const response = await fetch('/setWiper', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'value=' + encodeURIComponent(wiperValue)
});
if (response.ok) {
alert('Wiper value set successfully!');
} else {
alert('Failed to set Wiper value!');
}
}
2025-01-21 17:31:53 +08:00
async function resetDuration()
{
const response = await fetch('/resetDuration', { method: 'POST' });
if (response.ok) {
alert('累计使用时长已清空');
} else {
alert('清空失败');
}
}
2025-01-20 17:25:14 +08:00
setInterval(fetchData, 1000);
</script>
</head>
<body onload="fetchData()">
<h1>实时数据显示</h1>
2025-01-21 17:31:53 +08:00
<p>累计使用时长: <span id="activeDuration">加载中...</span></p>
<button onclick="resetDuration()">清空累计时长</button>
2025-01-20 17:25:14 +08:00
<p>温度: <span id="temperature">加载中...</span> °C</p>
<p>光照强度(A): <span id="lightA">加载中...</span> lx</p>
<p>光照强度(B): <span id="lightB">加载中...</span> lx</p>
<p>电位器Wiper值: <span id="wiper">加载中...</span></p>
<p>总线电压: <span id="busVoltage">加载中...</span> V</p>
<p>分流电压: <span id="shuntVoltage">加载中...</span> mV</p>
<p>电流: <span id="current">加载中...</span> mA</p>
<p>功率: <span id="power">加载中...</span> mW</p>
<h2>设置Wiper值</h2>
<input type="number" id="wiperValue" placeholder="输入Wiper值" />
<button onclick="setWiper()">设置</button>
</body>
</html>
)rawliteral";
// 初始化Web
void WebServer_Init(const char* ssid, const char* password)
2025-01-14 13:46:57 +08:00
{
WiFi.begin(ssid, password); // WiFi
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
Serial.println("Connecting to WiFi...");
}
2025-01-21 17:31:53 +08:00
Serial.print("Address: ");
2025-01-14 13:46:57 +08:00
Serial.println(WiFi.localIP());
// 根路径的页面
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
request->send_P(200, "text/html", index_html);
});
// 温度接口
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request)
{
2025-02-08 16:24:54 +08:00
String temp = String(ds18b20.getTempC());
2025-01-14 13:46:57 +08:00
request->send(200, "text/plain", temp);
});
// 光照强度(传感器A)
server.on("/lightA", HTTP_GET, [](AsyncWebServerRequest *request)
{
String lightA = String(bh1750_a.readLightLevel());
request->send(200, "text/plain", lightA);
});
// 光照(传感器B)
server.on("/lightB", HTTP_GET, [](AsyncWebServerRequest *request)
{
String lightB = String(bh1750_b.readLightLevel());
request->send(200, "text/plain", lightB);
});
2025-01-20 17:25:14 +08:00
// 配置Wiper接口
server.on("/wiper", HTTP_GET, [](AsyncWebServerRequest *request)
{
String wiper = String(digiPot.readWiper());
request->send(200, "text/plain", wiper);
});
server.on("/busVoltage", HTTP_GET, [](AsyncWebServerRequest *request)
{
String busVoltage = String(INA.getBusVoltage(), 3);
request->send(200, "text/plain", busVoltage);
});
server.on("/shuntVoltage", HTTP_GET, [](AsyncWebServerRequest *request)
{
String shuntVoltage = String(INA.getShuntVoltage_mV(), 3);
request->send(200, "text/plain", shuntVoltage);
});
server.on("/current", HTTP_GET, [](AsyncWebServerRequest *request)
{
String current = String(INA.getCurrent_mA(), 3);
request->send(200, "text/plain", current);
});
server.on("/power", HTTP_GET, [](AsyncWebServerRequest *request)
{
String power = String(INA.getPower_mW(), 3);
request->send(200, "text/plain", power);
});
2025-01-21 17:31:53 +08:00
// 获取累计时长接口
server.on("/duration", HTTP_GET, [](AsyncWebServerRequest *request) {
2025-02-08 16:24:54 +08:00
request->send(200, "text/plain", runtime.formatDuration(runtime.getActiveDuration()));
2025-01-21 17:31:53 +08:00
});
// 清空累计时长接口
server.on("/resetDuration", HTTP_POST, [](AsyncWebServerRequest *request) {
2025-02-08 16:24:54 +08:00
runtime.resetActiveDuration();
2025-01-21 17:31:53 +08:00
request->send(200, "text/plain", "Duration reset");
});
2025-01-20 17:25:14 +08:00
// 接收设置Wiper的请求
server.on("/setWiper", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("value", true)) {
int wiperValue = request->getParam("value", true)->value().toInt();
digiPot.writeWiper(wiperValue);
request->send(200, "text/plain", "Wiper value set");
} else {
request->send(400, "text/plain", "Missing value parameter");
}
});
2025-01-14 13:46:57 +08:00
server.begin();
2025-01-20 17:25:14 +08:00
//Serial.println("Web server started");
2025-01-14 13:46:57 +08:00
}
2025-02-07 15:02:44 +08:00
// 风扇控制
void FansControl(void) {
2025-02-08 16:24:54 +08:00
if (ds18b20.getTempC() > 25) {
2025-02-07 15:02:44 +08:00
digitalWrite(FAN_PIN1, HIGH);
digitalWrite(FAN_PIN2, HIGH);
} else {
digitalWrite(FAN_PIN1, LOW);
digitalWrite(FAN_PIN2, LOW);
}
}
2025-02-08 16:24:54 +08:00
// 蜂鸣器
2025-02-07 15:02:44 +08:00
void Buzzer(void) {
2025-02-08 16:24:54 +08:00
if (ds18b20.getTempC() > 20) {
digitalWrite(BUZZER_PIN, HIGH);
//tone(BUZZER_PIN, 1000, 1000);
2025-02-07 15:02:44 +08:00
} else {
2025-02-08 16:24:54 +08:00
digitalWrite(BUZZER_PIN, LOW);
//noTone(BUZZER_PIN);
2025-02-07 15:02:44 +08:00
}
}
2025-02-08 16:24:54 +08:00
TJC_Show tjcShow(TJC, ds18b20, bh1750_a, bh1750_b, digiPot, INA);
2025-01-20 17:25:14 +08:00
2025-01-14 13:46:57 +08:00
void setup(void)
{
2025-02-08 16:24:54 +08:00
Serial.begin(115200);
2025-01-23 16:36:27 +08:00
2025-01-20 17:25:14 +08:00
// 初始化 I2C 总线
Wire.begin(5, 4); // SDA SCL
2025-02-08 16:24:54 +08:00
// INA226 初始化
INA.setMaxCurrentShunt(10.0, 0.005); // 设置最大电流和分流电阻
2025-01-20 17:25:14 +08:00
// MCP45HVX1 初始化
digiPot.begin(5, 4);
2025-02-08 16:24:54 +08:00
// 启动定时器,每秒检查电流状态
//currentCheckTicker.attach(1, checkCurrent);
currentCheckTicker.attach(1, []() { runtime.checkCurrent(); });
2025-01-14 13:46:57 +08:00
//sensor.begin();
2025-01-20 17:25:14 +08:00
// BH1750 初始化
2025-01-21 17:31:53 +08:00
//bh1750_init(bh1750_a, bh1750_b, 36, 35, 21, 20); //1750初始化。sda, scl
//Wire.begin(36,35);
2025-01-23 16:36:27 +08:00
Wire1.begin(36, 35);
2025-01-21 17:31:53 +08:00
bh1750_a.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire);
bh1750_b.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire1);
2025-01-15 16:52:01 +08:00
2025-01-20 17:25:14 +08:00
//WebServer 初始化
WebServer_Init(ssid, password);
2025-01-21 17:31:53 +08:00
2025-02-08 16:24:54 +08:00
// 初始化 runtime NVS
runtime.begin();
2025-01-21 17:31:53 +08:00
// 串口屏初始化
2025-02-08 16:24:54 +08:00
tjcShow.TJC_Show_Init();
2025-01-20 17:25:14 +08:00
2025-02-08 16:24:54 +08:00
tjcShow.showQR();
2025-01-14 13:46:57 +08:00
}
void loop(void)
{// put your main code here, to run repeatedly:
2025-02-08 16:24:54 +08:00
ds18b20.printTemperature(); //ds18b20温度
2025-01-14 13:46:57 +08:00
//printLightLevels(bh1750_a, bh1750_b); //bh1750照度
Serial.printf("A: %.0f lux :: B: %.0f lux \n",
bh1750_a.readLightLevel(),
bh1750_b.readLightLevel());
2025-01-20 17:25:14 +08:00
// MCP45HVX1 操作
//digiPot.writeWiper(127); // 随机设置 Wiper 值,random(0, 256)
2025-02-08 16:24:54 +08:00
2025-01-21 17:31:53 +08:00
Serial.print("Current Wiper Value: ");
Serial.println(digiPot.readWiper());
2025-01-20 17:25:14 +08:00
// INA226 数据读取
2025-01-21 17:31:53 +08:00
Serial.println("\nBUS\tSHUNT\tCURRENT\tPOWER");
2025-02-07 15:23:30 +08:00
Serial.print(INA.getBusVoltage(), 3); //总线电压 MAX 36V
2025-01-20 17:25:14 +08:00
Serial.print("\t");
2025-02-07 15:23:30 +08:00
Serial.print(INA.getShuntVoltage_mV(), 3); //分流电压
2025-01-20 17:25:14 +08:00
Serial.print("\t");
2025-02-07 15:23:30 +08:00
Serial.print(INA.getCurrent_mA(), 3); //通过分流器的电流
2025-01-20 17:25:14 +08:00
Serial.print("\t");
2025-02-07 15:23:30 +08:00
Serial.print(INA.getPower_mW(), 3); //Current x BusVoltage
2025-01-20 17:25:14 +08:00
Serial.println();
2025-02-08 16:24:54 +08:00
tjcShow.showINFO(activeDuration); //串口屏
FansControl();
Buzzer();
2025-01-14 13:46:57 +08:00
delay(1000);
2025-01-20 17:25:14 +08:00
}