#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 0
#include <U8g2lib.h>
#include <Wire.h>
// SH1106 128x64 I2C 对象
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#include <Adafruit_AHTX0.h>
#include <Adafruit_BMP280.h> // 新增:BMP280库
Adafruit_AHTX0 aht;
Adafruit_BMP280 bmp; // 新增:BMP280对象
const int adcPin = 1; // GPIO1 (ADC1_CH1)
char lcdbuffer[64];
int v_gap = 5;
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEAdvertising.h>
#include "esp_sleep.h"
BLEAdvertising* pAdvertising;
uint8_t device_id = 3;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// 平均滤波函数
int readADC_Avg(int pin) {
int sum = 0;
for (int i = 0; i < 10; i++) {
sum += analogRead(pin);
delay(2);
}
return sum / 10;
}
void setup() {
Serial.begin(115200);
Wire.begin(3, 4); // SDA = GPIO3, SCL = GPIO4
u8g2.begin();
u8g2.enableUTF8Print(); // 支持中文(需要中文字体)
sensors.begin();
// 初始化AHT20
if (!aht.begin()) {
Serial.println("AHT20 not found");
}
// 初始化BMP280 - 尝试常见地址0x76和0x77 [citation:8]
if (!bmp.begin(0x76)) {
Serial.println("BMP280 at address 0x76 not found, trying 0x77...");
if (!bmp.begin(0x77)) {
Serial.println("BMP280 not found, check wiring!");
}
}
esp_sleep_wakeup_cause_t wakeup_reason = esp_sleep_get_wakeup_cause();
Serial.printf("Wakeup reason: %d\n", wakeup_reason);
BLEDevice::init("ESP32C3-SLAVE");
pAdvertising = BLEDevice::getAdvertising();
pAdvertising->setScanResponse(false);
// 设置ADC配置
analogReadResolution(12);
analogSetAttenuation(ADC_11db);
}
void loop() {
Serial.println("-----------------------------");
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tf);
// === 读取AHT20温湿度 ===
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);
Serial.print("AHT20 Temp: ");
Serial.print(temp.temperature);
Serial.print(" °C, Hum: ");
Serial.print(humidity.relative_humidity);
Serial.println(" %");
sprintf(lcdbuffer, "AHT20 Temp:%d", int(temp.temperature));
u8g2.drawStr(0, v_gap + 8, lcdbuffer);
sprintf(lcdbuffer, "AHT20 Hum: %d", int(humidity.relative_humidity));
u8g2.drawStr(0, v_gap + 16, lcdbuffer);
// === 读取BMP280气压和温度(可选,用于对比)===
float bmpPressure = bmp.readPressure() / 100.0F; // 转换为hPa [citation:4][citation:6]
float bmpTemperature = bmp.readTemperature(); // 读取BMP280温度
Serial.print("BMP280 Pressure: ");
Serial.print(bmpPressure);
Serial.println(" hPa");
Serial.print("BMP280 Temp: ");
Serial.print(bmpTemperature);
Serial.println(" °C");
sprintf(lcdbuffer, "BMP280 Temp:%d", int(bmpTemperature));
u8g2.drawStr(0, v_gap + 24, lcdbuffer);
sprintf(lcdbuffer, "BMP280 Press: %d", int(bmpPressure));
u8g2.drawStr(0, v_gap + 32, lcdbuffer);
// === 读取ADC电压 ===
int adcValue = readADC_Avg(adcPin);
float vout = adcValue * (2.5 / 4095.0);
float vin = vout * 11.0 * 1.196;
Serial.print("ADC: ");
Serial.print(adcValue);
Serial.print(" Vout: ");
Serial.print(vout);
Serial.print(" V Vin: ");
Serial.print(vin);
Serial.println(" V");
sprintf(lcdbuffer, "Voltage: %d", int(vin));
u8g2.drawStr(0, v_gap + 48, lcdbuffer);
// === 读取DS18B20温度 ===
static uint8_t count = 0;
sensors.requestTemperatures();
delay(750);
float tempC = sensors.getTempCByIndex(0);
if (tempC == DEVICE_DISCONNECTED_C || tempC == 85.0 || tempC == 0.0) {
Serial.println("DS18B20读取失败,跳过本次广播");
delay(1000);
return;
}
sprintf(lcdbuffer, "DS18 Temp: %d", int(tempC));
u8g2.drawStr(0, v_gap + 40, lcdbuffer);
// 准备BLE广播数据(使用AHT20的温度和BMP280的气压)
uint8_t ds18b20_temp_int = (uint8_t)tempC;
uint8_t ds18b20_temp_dec = (uint8_t)((tempC - ds18b20_temp_int) * 10);
uint8_t pressure_hpa = (uint8_t)bmpPressure; // 气压整数部分
uint8_t payload[5]; // 改为5字节以容纳气压数据
payload[0] = device_id;
payload[1] = ds18b20_temp_int;
payload[2] = ds18b20_temp_dec;
payload[3] = pressure_hpa; // 气压值
payload[4] = count++;
BLEAdvertisementData advData;
String strPayload = String((char*)payload, 5);
advData.setManufacturerData(strPayload);
pAdvertising->setAdvertisementData(advData);
pAdvertising->setMinInterval(160);
pAdvertising->setMaxInterval(160);
pAdvertising->start();
Serial.printf("DS18B20 Temp = %d.%d °C\n", ds18b20_temp_int, ds18b20_temp_dec);
Serial.printf("Pressure = %d hPa\n", pressure_hpa);
delay(200);
pAdvertising->stop();
u8g2.sendBuffer();
delay(1000);
}