From eec83b3539cb9c9b371545f22bd13b5ba2a613ae Mon Sep 17 00:00:00 2001 From: chenxin Date: Tue, 21 Jan 2025 17:31:53 +0800 Subject: [PATCH] ok --- src/BH1750.cpp | 131 +++++++++++++++++++++++++++---------------------- src/main.cpp | 126 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 175 insertions(+), 82 deletions(-) diff --git a/src/BH1750.cpp b/src/BH1750.cpp index 63e0a9e..3f59025 100644 --- a/src/BH1750.cpp +++ b/src/BH1750.cpp @@ -80,59 +80,70 @@ bool BH1750::begin(Mode mode, byte addr, TwoWire* i2c) { * @param mode Measurement mode */ bool BH1750::configure(Mode mode) { + // default transmission result to a value out of normal range + byte ack = 5; + int retries = 3; - // default transmission result to a value out of normal range - byte ack = 5; + // Check measurement mode is valid + switch (mode) { + case BH1750::CONTINUOUS_HIGH_RES_MODE: + case BH1750::CONTINUOUS_HIGH_RES_MODE_2: + case BH1750::CONTINUOUS_LOW_RES_MODE: + case BH1750::ONE_TIME_HIGH_RES_MODE: + case BH1750::ONE_TIME_HIGH_RES_MODE_2: + case BH1750::ONE_TIME_LOW_RES_MODE: - // Check measurement mode is valid - switch (mode) { + while (retries > 0) { + // Send mode to sensor + I2C->beginTransmission(BH1750_I2CADDR); + __wire_write((uint8_t)mode); + ack = I2C->endTransmission(); - case BH1750::CONTINUOUS_HIGH_RES_MODE: - case BH1750::CONTINUOUS_HIGH_RES_MODE_2: - case BH1750::CONTINUOUS_LOW_RES_MODE: - case BH1750::ONE_TIME_HIGH_RES_MODE: - case BH1750::ONE_TIME_HIGH_RES_MODE_2: - case BH1750::ONE_TIME_LOW_RES_MODE: + if (ack == 0) { + break; + } - // Send mode to sensor - I2C->beginTransmission(BH1750_I2CADDR); - __wire_write((uint8_t)mode); - ack = I2C->endTransmission(); + retries--; + _delay_ms(100); // Wait before retrying + } - // Wait a few moments to wake up - _delay_ms(10); - break; + // Wait a few moments to wake up + _delay_ms(10); + break; - default: - // Invalid measurement mode - Serial.println(F("[BH1750] ERROR: Invalid mode")); - break; - } + default: + // Invalid measurement mode + Serial.println(F("[BH1750] ERROR: Invalid mode")); + return false; + } - // Check result code - switch (ack) { - case 0: - BH1750_MODE = mode; - lastReadTimestamp = millis(); - return true; - case 1: // too long for transmit buffer - Serial.println(F("[BH1750] ERROR: too long for transmit buffer")); - break; - case 2: // received NACK on transmit of address - Serial.println(F("[BH1750] ERROR: received NACK on transmit of address")); - break; - case 3: // received NACK on transmit of data - Serial.println(F("[BH1750] ERROR: received NACK on transmit of data")); - break; - case 4: // other error - Serial.println(F("[BH1750] ERROR: other error")); - break; - default: - Serial.println(F("[BH1750] ERROR: undefined error")); - break; - } + // Check result code + if (ack == 0) { + BH1750_MODE = mode; + lastReadTimestamp = millis(); + return true; + } - return false; + // Print error message based on the result code + switch (ack) { + case 1: // too long for transmit buffer + Serial.println(F("[BH1750] ERROR: too long for transmit buffer")); + break; + case 2: // received NACK on transmit of address + Serial.println(F("[BH1750] ERROR: received NACK on transmit of address")); + break; + case 3: // received NACK on transmit of data + Serial.println(F("[BH1750] ERROR: received NACK on transmit of data")); + break; + case 4: // other error + Serial.println(F("[BH1750] ERROR: other error")); + break; + default: + Serial.println(F("[BH1750] ERROR: undefined error")); + break; + } + + return false; } /** @@ -299,20 +310,20 @@ void bh1750_init(BH1750& sensorA, BH1750& sensorB, int sdaA, int sclA, int sdaB, sensorB.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire1); } -float getLightLevel(BH1750& sensor, const char* sensorName) { - if (sensor.measurementReady()) { - float lightLevel = sensor.readLightLevel(); - if (lightLevel >= 0) { - return lightLevel; // 正常返回光照强度 - } - } - //return -2.0; -} +// float getLightLevel(BH1750& sensor, const char* sensorName) { +// if (sensor.measurementReady()) { +// float lightLevel = sensor.readLightLevel(); +// if (lightLevel >= 0) { +// return lightLevel; // 正常返回光照强度 +// } +// } +// //return -2.0; +// } -void printLightLevels(BH1750& sensorA, BH1750& sensorB) { - float lightA = getLightLevel(sensorA, "Sensor A"); - float lightB = getLightLevel(sensorB, "Sensor B"); +// void printLightLevels(BH1750& sensorA, BH1750& sensorB) { +// float lightA = getLightLevel(sensorA, "Sensor A"); +// float lightB = getLightLevel(sensorB, "Sensor B"); - // 打印光照强度信息 - Serial.printf("A: %.0f lux :: B: %.0f lux\n", lightA, lightB); -} \ No newline at end of file +// // 打印光照强度信息 +// Serial.printf("A: %.0f lux :: B: %.0f lux\n", lightA, lightB); +// } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 6a779b9..7dfac6c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,15 @@ #include #include "MCP45HVX1.h" #include "INA226.h" +#include + +// 灯泡计时器相关变量 +unsigned long activeDuration = 0; // 累计使用时长(秒) +unsigned long lastMillis = 0; // 上次更新计时时间 +bool isActive = false; // 是否正在计时 + +// Ticker 用于定时检查电流状态 +Ticker currentCheckTicker; // MCP45HVX1 数字电位器 MCP45HVX1 digiPot(0x3F); @@ -20,7 +29,7 @@ AsyncWebServer server(80); const char* ssid = "SERVIRST-CT"; const char* password = "servirst8888"; -// BH1750 +// DS18B20 温度传感器 #define ONE_WIRE_BUS 8 OneWire oneWire(ONE_WIRE_BUS); DS18B20 sensor(&oneWire); @@ -34,7 +43,6 @@ BH1750 bh1750_b; #define TJC_RX_Pin 41 - // HTML 页面内容 const char index_html[] PROGMEM = R"rawliteral( @@ -43,7 +51,12 @@ const char index_html[] PROGMEM = R"rawliteral( ESP32 Data Display

实时数据显示

+

累计使用时长: 加载中...

+

温度: 加载中... °C

光照强度(A): 加载中... lx

光照强度(B): 加载中... lx

@@ -113,7 +139,41 @@ const char index_html[] PROGMEM = R"rawliteral( +// 清空累计使用时长 +void resetActiveDuration() { + activeDuration = 0; +} +// 检查电流并更新计时状态 +void checkCurrent() { + float current = INA.getCurrent_mA(); + if (current > 1000.0) { + if (!isActive) { + // 开始计时 + isActive = true; + lastMillis = millis(); + } + } else { + if (isActive) { + // 停止计时并累加 + activeDuration += (millis() - lastMillis) / 1000; + isActive = false; + } + } + + // 如果正在计时,实时更新计时 + if (isActive) { + activeDuration += (millis() - lastMillis) / 1000; + lastMillis = millis(); + } +} + +// 将秒数格式化为小时和分钟 +String formatDuration(unsigned long seconds) { + unsigned long hours = seconds / 3600; + unsigned long minutes = (seconds % 3600) / 60; + return String(hours) + " 小时 " + String(minutes) + " 分钟"; +} // 初始化Web void WebServer_Init(const char* ssid, const char* password) @@ -124,7 +184,7 @@ void WebServer_Init(const char* ssid, const char* password) delay(1000); Serial.println("Connecting to WiFi..."); } - Serial.println("Connected to WiFi"); + Serial.print("Address: "); Serial.println(WiFi.localIP()); // 根路径的页面 @@ -185,6 +245,17 @@ void WebServer_Init(const char* ssid, const char* password) request->send(200, "text/plain", power); }); + // 获取累计时长接口 + server.on("/duration", HTTP_GET, [](AsyncWebServerRequest *request) { + request->send(200, "text/plain", formatDuration(activeDuration)); + }); + + // 清空累计时长接口 + server.on("/resetDuration", HTTP_POST, [](AsyncWebServerRequest *request) { + resetActiveDuration(); + request->send(200, "text/plain", "Duration reset"); + }); + // 接收设置Wiper的请求 server.on("/setWiper", HTTP_POST, [](AsyncWebServerRequest *request) { if (request->hasParam("value", true)) { @@ -201,10 +272,20 @@ void WebServer_Init(const char* ssid, const char* password) } +// 陶晶池串口屏显示二维码 +void TCJ_ShowQR(void) +{ + char addr[64]; + IPAddress ip = WiFi.localIP(); + sprintf(addr, "qr0.txt=\"http://%d.%d.%d.%d/\"\xff\xff\xff", ip[0], ip[1], ip[2], ip[3]); + TJC.print(addr); +} + //陶晶池串口屏发送 void TJC_Show(void) { char str[128]; + sprintf(str, "t0.txt=\"%.2f\"\xff\xff\xff", sensor.getTempC());//用sprintf来格式化字符串,给t0的txt属性赋值 TJC.print(str); //把字符串发送出去 @@ -228,7 +309,6 @@ void TJC_Show(void) } - void setup(void) { Serial.begin(115200); @@ -241,24 +321,27 @@ void setup(void) // INA226 初始化 INA.setMaxCurrentShunt(10, 0.002); // 设置最大电流和分流电阻 + + //sensor.begin(); + // BH1750 初始化 + //bh1750_init(bh1750_a, bh1750_b, 36, 35, 21, 20); //1750初始化。sda, scl + //Wire.begin(36,35); + Wire1.begin(21, 20); + bh1750_a.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire); + bh1750_b.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire1); + + //WebServer 初始化 + WebServer_Init(ssid, password); + + // 启动定时器,每秒检查电流状态 + currentCheckTicker.attach(1, checkCurrent); // 串口屏初始化 TJC.begin(115200, SERIAL_8N1, TJC_RX_Pin, TJC_TX_Pin); while (TJC.read() >= 0); //因为串口屏开机会发送88 ff ff ff,所以要清空串口缓冲区 TJC.print("page main\xff\xff\xff"); //发送命令让屏幕跳转到main页面 - - //sensor.begin(); - // BH1750 初始化 - bh1750_init(bh1750_a, bh1750_b, 36, 35, 21, 20); //1750初始化。sda, scl - // Wire.begin(36,35); - // Wire1.begin(21, 20); - // bh1750_a.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire); - // bh1750_b.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x23, &Wire1); - - //WebServer 初始化 - WebServer_Init(ssid, password); - + TCJ_ShowQR(); } @@ -274,11 +357,11 @@ void loop(void) // MCP45HVX1 操作 //digiPot.writeWiper(127); // 随机设置 Wiper 值,random(0, 256) //delay(500); - Serial.print("Current Wiper Value: "); - Serial.println(digiPot.readWiper()); + Serial.print("Current Wiper Value: "); + Serial.println(digiPot.readWiper()); // INA226 数据读取 - Serial.println("\nBUS\tSHUNT\tCURRENT\tPOWER"); + Serial.println("\nBUS\tSHUNT\tCURRENT\tPOWER"); Serial.print(INA.getBusVoltage(), 3); Serial.print("\t"); Serial.print(INA.getShuntVoltage_mV(), 3); @@ -289,7 +372,6 @@ void loop(void) Serial.println(); - TJC_Show(); //串口屏 delay(1000);