1.3" OLED 128×64 SH1106 + AHT20+BMP280 + DS18B20

#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);
}