This commit is contained in:
2025-05-13 16:55:49 +08:00
parent 1c2201afc9
commit bf5270f337
16 changed files with 463 additions and 384 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"window.zoomLevel": 0
}

View File

@ -224,9 +224,9 @@ void DS18B20::printTemperature()
{
requestTemperatures(); // 发送请求以开始温度转换
//float temperature = getTempC(); // 获取温度(摄氏度)
//Serial.print("Temp: ");
Serial.print(getTempC());
Serial.println("");
Serial.printf("Temp: %.2f\n", getTempC());
//Serial.print(getTempC());
//Serial.println("℃ ");
}

65
src/DS3502.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "DS3502.h"
DS3502::DS3502(uint8_t address) {
_address = address;
_wire = &Wire; // 使用默认的 Wire 对象
}
/**
* 初始化 I2C设置 SDA 和 SCL 引脚。
*/
bool DS3502::begin(uint8_t sda_pin, uint8_t scl_pin) {
_wire->begin(sda_pin, scl_pin); // 初始化 I2C总线设置
return true;
}
/**
* 获取电位器当前的 Wiper 值
*/
uint8_t DS3502::getWiper() {
_wire->beginTransmission(_address);
_wire->write(DS3502_WIPER); // 请求 Wiper 寄存器
_wire->endTransmission(false); // 持续连接
_wire->requestFrom(_address, (uint8_t)1); // 读取一个字节
return _wire->read();
}
/**
* 设置新的 Wiper 值,范围为 0 到 127
*/
void DS3502::setWiper(uint8_t new_wiper_value) {
//if (new_wiper_value > 127) return; // 超出范围则不进行操作
_wire->beginTransmission(_address);
_wire->write(DS3502_WIPER); // 指定写入 Wiper 寄存器
_wire->write(new_wiper_value); // 写入新的值
_wire->endTransmission();
}
/**
* 设置电位器的默认值IVR这会在上电时设置 Wiper 默认值
*/
void DS3502::setWiperDefault(uint8_t new_wiper_default) {
if (new_wiper_default > 127) return; // 超出范围则不进行操作
// 切换模式到默认模式
_wire->beginTransmission(_address);
_wire->write(DS3502_MODE); // 设置寄存器为 Mode Select 寄存器
_wire->write(0x00); // 设置为写入默认值
_wire->endTransmission();
// 设置新的默认 Wiper 值
_wire->beginTransmission(_address);
_wire->write(DS3502_WIPER); // 设置 Wiper 寄存器
_wire->write(new_wiper_default); // 写入新的默认值
_wire->endTransmission();
delay(100); // 等待 EEPROM 写入完成
// 恢复模式
_wire->beginTransmission(_address);
_wire->write(DS3502_MODE);
_wire->write(0x80); // 恢复到正常操作模式
_wire->endTransmission();
}

30
src/DS3502.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef DS3502_H
#define DS3502_H
#include <Wire.h>
#define DS3502_ADDRESS 0x28 // 默认 I2C 地址
#define DS3502_MODE 0x00 // Mode Selector Register
#define DS3502_WIPER 0x00 // Wiper Register
class DS3502 {
public:
DS3502(uint8_t address = DS3502_ADDRESS); // 构造函数声明
bool begin(uint8_t sda_pin, uint8_t scl_pin);
// 获取电位器的当前值
uint8_t getWiper();
// 设置电位器的值
void setWiper(uint8_t new_wiper_value);
// 设置默认电位器值IVR
void setWiperDefault(uint8_t new_wiper_default);
private:
uint8_t _address;
TwoWire* _wire;
};
#endif

View File

@ -1,24 +0,0 @@
#include "DigitalPot.h"
TPL0401A::TPL0401A(uint8_t i2cAddress) : _i2cAddress(i2cAddress)
{
}
uint16_t TPL0401A::writeWiper(uint16_t wiperValue) {
Wire1.beginTransmission(0x2E); // device address TPL04001-A #46 (0x2E), TPL04001-B #46 (0x2E)
Wire1.write(byte(0x00)); // sends instruction. 0x00 = Write
Wire1.write(wiperValue); // sends value
Wire1.endTransmission(); // end transmission
_wiperValue = wiperValue; // 更新成员变量
// Print the current pot value
Serial.print("pot: ");
Serial.println(wiperValue);
return wiperValue;
}
uint16_t TPL0401A::readWiperValue() const {
return _wiperValue;
}

View File

@ -1,19 +0,0 @@
#ifndef DIGITALPOT_H
#define DIGITALPOT_H
#include "Wire.h"
#include <Arduino.h>
class TPL0401A {
public:
TPL0401A(uint8_t i2cAddress);
uint16_t writeWiper(uint16_t wiperValue);
uint16_t readWiperValue() const;
private:
uint8_t _i2cAddress;
uint16_t _wiperValue;
};
extern TPL0401A digiPot;
#endif

35
src/LightControl.cpp Normal file
View File

@ -0,0 +1,35 @@
// LightControl.cpp
#include "LightControl.h"
#include "Arduino.h"
LightControl::LightControl(BH1750& sensor, DS3502& pot)
: lightSensor(sensor), digitalPot(pot) {}
void LightControl::setTargetLight(float target) {
targetLightLevel = target;
}
float LightControl::getCurrentLight() {
return lightSensor.readLightLevel();
}
void LightControl::adjustWiper() {
float currentLight = getCurrentLight();
float error = targetLightLevel - currentLight;
// 计算输出变化量(比例控制)
int delta = (int)(abs(error) * Kp);
if (delta < 1) delta = 1; // 最小调节步长
if (error > 0) {
// 需要增加亮度 -> 减小电位器阻值
lastWiperValue = max(0, lastWiperValue - delta);
} else if (error < 0) {
// 需要减少亮度 -> 增大电位器阻值
lastWiperValue = min(127, lastWiperValue + delta);
}
digitalPot.setWiper(lastWiperValue);
Serial.printf("Current Light: %.0f lux | Wiper Value: %d\n", currentLight, lastWiperValue);
}

31
src/LightControl.h Normal file
View File

@ -0,0 +1,31 @@
// LightControl.h
#ifndef LIGHTCONTROL_H
#define LIGHTCONTROL_H
#include <BH1750.h>
#include "DS3502.h"
class LightControl {
public:
// 构造函数
LightControl(BH1750& sensor, DS3502& pot);
// 设置目标照度
void setTargetLight(float target);
// 获取当前照度
float getCurrentLight();
// 执行一次调节
void adjustWiper();
private:
BH1750& lightSensor; // 引用 BH1750 传感器对象
DS3502& digitalPot; // 引用 DS3502 数字电位器对象
float targetLightLevel; // 目标照度值
int lastWiperValue = 0; // 上一次 Wiper 值
float Kp = 0.5; // 比例增益(可根据实际情况调整)
};
#endif

View File

@ -1,193 +0,0 @@
/******************************************************
Arduino library for MCP45HVX1 digital potentiometers
Author: Jonathan Dempsey JDWifWaf@gmail.com
Version: 1.0.1
License: Apache 2.0
*******************************************************/
#include "MCP45HVX1.h"
#define DEBUG 0
/* 7 Bit I2C Operation Components ......................................... */
/* TCON configuration.................. */
#define TCON_R0HW (0x08) // Shutdown Resistor Force
#define TCON_R0A (0x04) // Terminal A Connection
#define TCON_R0W (0x02) // Wiper Connection
#define TCON_R0B (0x01) // Terminal B Connection
#define GCALL_TCON (0x60)
#define GCALL_WIPER (0x40)
#define GCALL_WIPERUP (0x42)
#define GCALL_WIPERDWN (0x44)
#define GCALL_COM_WRITE (0x02)
#define GCALL_COM_RWRITE (0x03)
#define GCALL_COM_WIPERINC (0x42)
#define GCALL_COM_WIPERDEC (0x44)
#define MEM_WIPER (0x00)
#define MEM_TCON (0x40)
#define COM_WRITE (0x00)
#define COM_READ (0x0C)
#define COM_WIPERINC (0x04)
#define COM_WIPERDEC (0x08)
/* Setup ............................................................... */
MCP45HVX1::MCP45HVX1(uint8_t address) : _address(address) {};
void MCP45HVX1::begin(int sda, int scl, TwoWire &inWire) {
MCPWire = &inWire; // 使用传递的 I2C 对象实例
if (sda != -1 && scl != -1) {
MCPWire->begin(sda, scl); // 自定义 SDA 和 SCL 引脚
} else {
MCPWire->begin(); // 默认 I2C 引脚初始化
}
MCPWire->setClock(MCPCSPEED); // 设置 I2C 时钟速度
}
/* Wiper Register..........................................................*/
void MCP45HVX1::writeWiper(uint8_t wiperValue)
{
this->MCPWire->beginTransmission(_address);
this->MCPWire->write(MEM_WIPER | COM_WRITE);
this->MCPWire->write(wiperValue);
this->MCPWire->endTransmission();
}
uint8_t MCP45HVX1::readWiper()
{
uint8_t buff = 0;
this->MCPWire->beginTransmission(_address);
this->MCPWire->write(MEM_WIPER | COM_READ);
this->MCPWire->endTransmission(false);
this->MCPWire->requestFrom(_address, (uint8_t)2);
if(this->MCPWire->available())
{
buff = this->MCPWire->read(); // First byte is 0x00
#if DEBUG
Serial.print("\nRead Wiper MSB: ");
Serial.println(buff);
#endif
buff = this->MCPWire->read(); // Second byte contains the wiper value
#if DEBUG
Serial.print("Read Wiper LSB: ");
Serial.println(buff);
#endif
}
return buff;
}
void MCP45HVX1::incrementWiper(uint8_t incriments)
{
this->MCPWire->beginTransmission(_address);
for(uint8_t x = 0; x < incriments; x++)
{
this->MCPWire->write(MEM_WIPER | COM_WIPERINC);
}
this->MCPWire->endTransmission();
}
void MCP45HVX1::decrementWiper(uint8_t decriments)
{
this->MCPWire->beginTransmission(_address);
for(uint8_t x = 0; x < decriments; x++)
{
this->MCPWire->write(MEM_WIPER | COM_WIPERDEC);
}
this->MCPWire->endTransmission();
}
/* TCON Register...........................................................*/
uint8_t MCP45HVX1::readTCON()
{
uint8_t buff = 0;
this->MCPWire->beginTransmission(_address);
this->MCPWire->write(MEM_TCON | COM_READ);
this->MCPWire->endTransmission(false);
this->MCPWire->requestFrom(_address, (uint8_t)2);
if(this->MCPWire->available())
{
buff = this->MCPWire->read(); // First byte is always 0x00
#if DEBUG
Serial.print("\nRead TCON MSB: ");
Serial.println(buff);
#endif
buff = this->MCPWire->read(); // Second byte contains the wiper value (for compatability)
#if DEBUG
Serial.print("Read TCON LSB: ");
Serial.println(buff);
#endif
}
return buff;
}
void MCP45HVX1::defaultTCON()
{
this->TCON_lib_reg.R0HW = true;
this->TCON_lib_reg.R0A = true;
this->TCON_lib_reg.R0B = true;
this->TCON_lib_reg.R0W = true;
write_TCON_Register();
}
void MCP45HVX1::writeTCON(TCON_Register *inReg)
{
memcpy(&this->TCON_lib_reg, inReg, sizeof(this->TCON_lib_reg));
write_TCON_Register();
}
void MCP45HVX1::write_TCON_R0HW(bool isOn)
{
this->TCON_lib_reg.R0HW = isOn;
write_TCON_Register();
}
void MCP45HVX1::write_TCON_R0A(bool isOn)
{
this->TCON_lib_reg.R0A = isOn;
write_TCON_Register();
}
void MCP45HVX1::write_TCON_R0W(bool isOn)
{
this->TCON_lib_reg.R0W = isOn;
write_TCON_Register();
}
void MCP45HVX1::write_TCON_R0B(bool isOn)
{
this->TCON_lib_reg.R0B = isOn;
write_TCON_Register();
}
void MCP45HVX1::write_TCON_Register()
{
uint8_t buff = 0xFF;
this->TCON_lib_reg.R0HW ? (buff |= TCON_R0HW) : (buff ^= TCON_R0HW);
this->TCON_lib_reg.R0A ? (buff |= TCON_R0A) : (buff ^= TCON_R0A);
this->TCON_lib_reg.R0B ? (buff |= TCON_R0B) : (buff ^= TCON_R0B);
this->TCON_lib_reg.R0W ? (buff |= TCON_R0W) : (buff ^= TCON_R0W);
#if DEBUG
Serial.print("Writing TCON: "); Serial.println(buff);
#endif
this->MCPWire->beginTransmission(_address);
this->MCPWire->write(MEM_TCON | COM_WRITE);
this->MCPWire->write(buff);
this->MCPWire->endTransmission();
}

View File

@ -1,94 +0,0 @@
/******************************************************
Arduino library for MCP45HVX1 digital potentiometers
Author: Jonathan Dempsey JDWifWaf@gmail.com
Version: 1.0.1
License: Apache 2.0
*******************************************************/
#ifndef _MCP45HVX1_H
#define _MCP45HVX1_H
#include <Arduino.h>
#include <Wire.h>
#define MCPCSPEED 100000 // I2C clock speed
class MCP45HVX1
{
public:
/* TCON Register Resistor Configuration ............................... */
typedef struct
{
bool R0HW = true;
bool R0A = true;
bool R0B = true;
bool R0W = true;
}TCON_Register;
/* Setup ............................................................... */
MCP45HVX1(uint8_t address = 0x3e);
void begin(int sda = -1, int scl = -1, TwoWire &inWire = Wire);
/* Wiper Register ...................................................... */
uint8_t readWiper();
void writeWiper(uint8_t wiperValue);
void incrementWiper(uint8_t incriments = 1);
void decrementWiper(uint8_t decriments = 1);
/* TCON Register ....................................................... */
uint8_t readTCON();
void writeTCON(TCON_Register *inReg);
void defaultTCON();
void inline shutdown()
{
write_TCON_R0HW(false);
};
void inline startup()
{
write_TCON_R0HW(true);
};
void inline connectTerminalA()
{
write_TCON_R0A(true);
};
void inline disconnectTerminalA()
{
write_TCON_R0A(false);
};
void inline connectTerminalB()
{
write_TCON_R0B(true);
};
void inline disconnectTerminalB()
{
write_TCON_R0B(false);
};
void inline connectWiper()
{
write_TCON_R0W(true);
};
void inline disconnectWiper()
{
write_TCON_R0W(false);
};
protected:
private:
uint8_t _address;
TwoWire* MCPWire;
TCON_Register TCON_lib_reg;
void write_TCON_Register();
void write_TCON_R0HW(bool state);
void write_TCON_R0A(bool state);
void write_TCON_R0W(bool state);
void write_TCON_R0B(bool state);
};
#endif

View File

@ -1,12 +1,13 @@
#include "TJC_Show.h"
#include "WiFiControl.h"
extern RunTime runtime;
extern TPL0401A digiPot;
extern DS3502 ds3502;
extern uint16_t wiperValue;
TJC_Show::TJC_Show(DS18B20& ds18b20, BH1750& bh1750_a, BH1750& bh1750_b, TPL0401A& digiPot, INA226& INA)
: _serial(TJC_SERIAL), _ds18b20(ds18b20), _bh1750_a(bh1750_a), _bh1750_b(bh1750_b), _digiPot(digiPot), _INA(INA) {}
TJC_Show::TJC_Show(DS18B20& ds18b20, BH1750& bh1750_a, BH1750& bh1750_b, DS3502& ds3502, INA226& INA)
: _serial(TJC_SERIAL), _ds18b20(ds18b20), _bh1750_a(bh1750_a), _bh1750_b(bh1750_b), _ds3502(ds3502), _INA(INA) {}
void TJC_Show::init() {
_serial.begin(115200, SERIAL_8N1, TJC_RX_PIN, TJC_TX_PIN);
@ -31,6 +32,15 @@ void TJC_Show::showQR() {
void TJC_Show::showInfo() {
char str[128];
if (SELECTED_WIFI_MODE == WIFI_MODE_STA){
snprintf(str, sizeof(str), "t15.txt=\"MODE_STA:%s\"\xff\xff\xff", WiFi.localIP());
sendCommand(str);
}
else if(SELECTED_WIFI_MODE == WIFI_MODE_AP){
snprintf(str, sizeof(str), "t15.txt=\"MODE_AP:%s\"\xff\xff\xff", WiFi.softAPIP());
sendCommand(str);
}
snprintf(str, sizeof(str), "t0.txt=\"%.2f\"\xff\xff\xff", _ds18b20.getTempC());
sendCommand(str);
@ -42,16 +52,16 @@ void TJC_Show::showInfo() {
snprintf(str, sizeof(str), "t14.txt=\"%s\"\xff\xff\xff", runtime.formatDuration(runtime.getActiveDuration()));
sendCommand(str);
snprintf(str, sizeof(str), "t8.txt=\"%d\"\xff\xff\xff", _digiPot.readWiperValue());
snprintf(str, sizeof(str), "t8.txt=\"%d\"\xff\xff\xff", _ds3502.getWiper());
sendCommand(str);
snprintf(str, sizeof(str), "t9.txt=\"%.3f\"\xff\xff\xff", _INA.getBusVoltage());
snprintf(str, sizeof(str), "t9.txt=\"%.2f\"\xff\xff\xff", _INA.getBusVoltage());
sendCommand(str);
snprintf(str, sizeof(str), "t10.txt=\"%.3f\"\xff\xff\xff", _INA.getShuntVoltage_mV());
snprintf(str, sizeof(str), "t10.txt=\"%.2f\"\xff\xff\xff", _INA.getShuntVoltage_mV());
sendCommand(str);
snprintf(str, sizeof(str), "t11.txt=\"%.3f\"\xff\xff\xff", _INA.getCurrent_mA());
snprintf(str, sizeof(str), "t11.txt=\"%.2f\"\xff\xff\xff", _INA.getCurrent());
sendCommand(str);
snprintf(str, sizeof(str), "t12.txt=\"%.3f\"\xff\xff\xff", _INA.getPower_mW());
snprintf(str, sizeof(str), "t12.txt=\"%.2f\"\xff\xff\xff", _INA.getPower());
sendCommand(str);
}

View File

@ -4,7 +4,7 @@
#include <Arduino.h>
#include "BH1750.h"
#include "DS18B20.h"
#include "DigitalPot.h"
#include "DS3502.h"
#include "INA226.h"
#include <WiFi.h>
#include "RunTime.h"
@ -16,7 +16,7 @@
class TJC_Show {
public:
TJC_Show(DS18B20& ds18b20, BH1750& bh1750_a, BH1750& bh1750_b, TPL0401A& digiPot, INA226& INA);
TJC_Show(DS18B20& ds18b20, BH1750& bh1750_a, BH1750& bh1750_b, DS3502& DS3502, INA226& INA);
void init();
void showQR();
void showInfo();
@ -26,7 +26,7 @@ private:
DS18B20& _ds18b20;
BH1750& _bh1750_a;
BH1750& _bh1750_b;
TPL0401A& _digiPot;
DS3502& _ds3502;
INA226& _INA;
void clearSerialBuffer();
void sendCommand(const char* command);

View File

@ -1,17 +1,70 @@
#include "WiFiControl.h"
const char* STA_SSIDS[STA_WIFI_COUNT] = {"SERVIRST-CT", "IRIS"};
const char* STA_PASSWORDS[STA_WIFI_COUNT] = {"servirst8888", "irishk*******"};
void WiFi_Init()
{
#if SELECTED_WIFI_MODE == WIFI_MODE_STA
WiFi.begin(STA_SSID, STA_PASSWORD); // WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
if (!connectToKnownNetworks()) {
switchToAPMode();
}
Serial.print("Address: ");
Serial.println(WiFi.localIP());
#elif SELECTED_WIFI_MODE == WIFI_MODE_AP
WiFi.softAP(AP_SSID, AP_PASSWORD);
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
#else
switchToAPMode();
#endif
}
bool connectToKnownNetworks()
{
Serial.println("Scanning nearby networks...");
int numNetworks = WiFi.scanNetworks();
if (numNetworks == 0) {
Serial.println("No networks found.");
return false;
}
Serial.print("Found ");
Serial.print(numNetworks);
Serial.println(" networks.");
for (int i = 0; i < numNetworks; ++i) {
String scannedSSID = WiFi.SSID(i);
for (int j = 0; j < STA_WIFI_COUNT; ++j) {
if (scannedSSID == STA_SSIDS[j]) {
Serial.print("Found known network: ");
Serial.println(scannedSSID);
WiFi.begin(STA_SSIDS[j], STA_PASSWORDS[j]);
unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < 10000) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
return true;
} else {
Serial.println("Failed to connect.");
}
}
}
}
Serial.println("Could not connect to any known network.");
return false;
}
void switchToAPMode()
{
Serial.println("Switching to AP mode.");
WiFi.softAP(AP_SSID, AP_PASSWORD);
Serial.print("AP IP address: ");
Serial.println(WiFi.softAPIP());
}

View File

@ -1,19 +1,51 @@
// #include <WiFi.h>
// #define WIFI_MODE_STA 1
// #define WIFI_MODE_AP 2
// // 选择WiFi模式取消注释需要的模式
// #define SELECTED_WIFI_MODE WIFI_MODE_STA
// //#define SELECTED_WIFI_MODE WIFI_MODE_AP
// // STA模式下的SSID和密码
// // #define STA_SSID "SERVIRST-CT"
// // #define STA_PASSWORD "servirst8888"
// #define STA_SSID "IRIS"
// #define STA_PASSWORD "irishk*******"
// // AP模式下的SSID和密码
// #define AP_SSID "APSSID"
// #define AP_PASSWORD "APPassword"
// void WiFi_Init(void);
// WiFiControl.h
#ifndef WIFICONTROL_H
#define WIFICONTROL_H
#include <WiFi.h>
#define WIFI_MODE_STA 1
#define WIFI_MODE_AP 2
#define WIFI_MODE_STA 0
#define WIFI_MODE_AP 1
// 选择WiFi模式,取消注释需要的模式
// 默认选择WiFi模式
#define SELECTED_WIFI_MODE WIFI_MODE_STA
//#define SELECTED_WIFI_MODE WIFI_MODE_AP
// STA模式下的SSID和密码
#define STA_SSID "SERVIRST-CT"
#define STA_PASSWORD "servirst8888"
// 设置多个 Wi-Fi 账号密码
#define STA_WIFI_COUNT 2
extern const char* STA_SSIDS[STA_WIFI_COUNT];
extern const char* STA_PASSWORDS[STA_WIFI_COUNT];
// AP模式下的SSID和密码
#define AP_SSID "APSSID"
#define AP_PASSWORD "APPassword"
void WiFi_Init(void);
bool connectToKnownNetworks(void);
void switchToAPMode(void);
#endif

View File

@ -4,7 +4,7 @@
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <Arduino.h>
#include "MCP45HVX1.h"
#include "INA226.h"
#include <Ticker.h>
#include <Preferences.h> // 用于存储非易失性数据
@ -12,17 +12,15 @@
#include "RunTime.h"
#include "WebServer.h"
#include "WiFiControl.h"
#include "DigitalPot.h"
#include "DS3502.h"
#include "LightControl.h"
// Ticker 用于定时检查电流状态
Ticker currentCheckTicker;
// MCP45HVX1 数字电位器
MCP45HVX1 mcp45hvx1(0x3C);
//TPL0401A 数字电位器
TPL0401A digiPot(0x2E);
// DS3502 数字电位器
DS3502 ds3502(0x28);
// INA226 电流监控器
INA226 INA(0x40);
@ -38,6 +36,9 @@ DS18B20 ds18b20(&oneWire);
BH1750 bh1750_a;
BH1750 bh1750_b;
// 按键引脚
#define INCREASE_BUTTON_PIN 3
#define DECREASE_BUTTON_PIN 46
// 风扇控制引脚
#define FAN_PIN1 15
@ -50,6 +51,12 @@ extern RunTime runtime;
Preferences prefs;
TJC_Show tjcShow(ds18b20, bh1750_a, bh1750_b, ds3502, INA);
// 比例调节bh1750_a
LightControl lightCtrl(bh1750_a, ds3502);
bool autoAdjustEnabled = false; // 是否启用自动调节,默认关闭
float targetLightValue = 2000; // 默认目标照度
void WebServer_Init(void) {
// 根路径的页面
@ -77,7 +84,7 @@ void WebServer_Init(void) {
// 配置Wiper接口
server.on("/wiper", HTTP_GET, [](AsyncWebServerRequest *request) {
String wiper = String(digiPot.readWiperValue());
String wiper = String(ds3502.getWiper());
request->send(200, "text/plain", wiper);
});
@ -116,7 +123,7 @@ void WebServer_Init(void) {
server.on("/setWiper", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("value", true)) {
int wiperValue = request->getParam("value", true)->value().toInt();
digiPot.writeWiper(wiperValue);
ds3502.setWiper(wiperValue);
request->send(200, "text/plain", "Wiper value set");
} else {
request->send(400, "text/plain", "Missing value parameter");
@ -129,7 +136,7 @@ void WebServer_Init(void) {
// 风扇控制
void FansControl(void) {
if (ds18b20.getTempC() > 25) {
if (ds18b20.getTempC() > 30) {
digitalWrite(FAN_PIN1, HIGH);
digitalWrite(FAN_PIN2, HIGH);
} else {
@ -140,7 +147,7 @@ void FansControl(void) {
// 蜂鸣器
void Buzzer(void) {
if (ds18b20.getTempC() > 20) {
if (ds18b20.getTempC() > 45) {
digitalWrite(BUZZER_PIN, HIGH);
//tone(BUZZER_PIN, 1000, 1000);
} else {
@ -149,8 +156,33 @@ void Buzzer(void) {
}
}
//按键控制
void ButtonControl(void) {
// 按键检测
static int lastWiperValue = ds3502.getWiper();
static const int step = 5; // 步进值
if (digitalRead(INCREASE_BUTTON_PIN) == LOW) {
int currentWiperValue = ds3502.getWiper();
if (currentWiperValue < 127) {
ds3502.setWiper(currentWiperValue + step);
lastWiperValue = currentWiperValue + step;
Serial.printf("Increased Wiper Value: %d\n", lastWiperValue);
}
delay(200); // 防抖动
}
if (digitalRead(DECREASE_BUTTON_PIN) == LOW) {
int currentWiperValue = ds3502.getWiper();
if (currentWiperValue > 0) {
ds3502.setWiper(currentWiperValue - step);
lastWiperValue = currentWiperValue - step;
Serial.printf("Decreased Wiper Value: %d\n", lastWiperValue);
}
delay(200); // 防抖动
}
}
TJC_Show tjcShow(ds18b20, bh1750_a, bh1750_b, digiPot, INA);
void setup(void)
@ -160,7 +192,7 @@ void setup(void)
// 初始化 I2C 总线
Wire.begin(5, 4); // SDA SCL
mcp45hvx1.begin(5, 4);
ds3502.begin(5, 4);
// INA226 初始化
INA.setMaxCurrentShunt(10.0, 0.005); // 设置最大电流和分流电阻
@ -192,7 +224,18 @@ void setup(void)
tjcShow.init();
tjcShow.showQR();
digiPot.writeWiper(30);
ds3502.setWiper(2);
delay(300);
Serial.printf("pot: %d\n", ds3502.getWiper());
pinMode(FAN_PIN1, OUTPUT);
pinMode(FAN_PIN2, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// 初始化按键引脚
pinMode(INCREASE_BUTTON_PIN, INPUT_PULLUP);
pinMode(DECREASE_BUTTON_PIN, INPUT_PULLUP);
}
@ -205,11 +248,11 @@ void loop(void)
bh1750_a.readLightLevel(),
bh1750_b.readLightLevel());
// MCP45HVX1 操作
//digiPot.writeWiper(127); // 随机设置 Wiper 值,random(0, 256)
mcp45hvx1.writeWiper(random(0, 127));
Serial.print("Current Wiper Value: ");
Serial.println(mcp45hvx1.readWiper());
// // MCP45HVX1 操作
// //digiPot.writeWiper(127); // 随机设置 Wiper 值,random(0, 256)
// ds3502.setWiper(random(0, 127));
// Serial.print("Current Wiper Value: ");
// Serial.println(ds3502.getWiper());
// INA226 数据读取
@ -218,9 +261,9 @@ void loop(void)
Serial.print("\t");
Serial.print(INA.getShuntVoltage_mV(), 3); //分流电压
Serial.print("\t");
Serial.print(INA.getCurrent_mA(), 3); //通过分流器的电流
Serial.print(INA.getCurrent(), 3); //通过分流器的电流
Serial.print("\t");
Serial.print(INA.getPower_mW(), 3); //Current x BusVoltage
Serial.print(INA.getPower(), 3); //Current x BusVoltage
Serial.println();
@ -229,6 +272,12 @@ void loop(void)
FansControl();
Buzzer();
ButtonControl();
if (autoAdjustEnabled) {
lightCtrl.adjustWiper(); // 比例调节
}
delay(1000);
}

View File

@ -1,3 +1,104 @@
// #ifndef WEBPAGES_H
// #define WEBPAGES_H
// #include <Arduino.h>
// const char index_html[] PROGMEM = R"rawliteral(
// <!DOCTYPE html>
// <html>
// <head>
// <title>ESP32 Data Display</title>
// <meta charset="UTF-8">
// <script>
// async function fetchData()
// {
// const durationResponse = await fetch('/duration');
// const durationText = await durationResponse.text();
// document.getElementById('activeDuration').innerText = durationText;
// 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;
// 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;
// }
// async function setWiper()
// {
// 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!');
// }
// }
// async function resetDuration()
// {
// const response = await fetch('/resetDuration', { method: 'POST' });
// if (response.ok) {
// alert('累计使用时长已清空');
// } else {
// alert('清空失败');
// }
// }
// setInterval(fetchData, 1000);
// </script>
// </head>
// <body onload="fetchData()">
// <h1>实时数据显示</h1>
// <p>累计使用时长: <span id="activeDuration">加载中...</span></p>
// <button onclick="resetDuration()">清空累计时长</button>
// <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"; // 添加分号
// #endif // WEBPAGES_H
#ifndef WEBPAGES_H
#define WEBPAGES_H
@ -90,7 +191,7 @@ const char index_html[] PROGMEM = R"rawliteral(
<p>: <span id="current">...</span> mA</p>
<p>: <span id="power">...</span> mW</p>
<h2>Wiper值</h2>
<input type="number" id="wiperValue" placeholder="输入Wiper值" />
<input type="range" id="wiperValue" min="0" max="127" step="1" value="2" />
<button onclick="setWiper()"></button>
</body>
</html>