#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// -------------------- 硬件引脚定义 --------------------
const int DATA_PIN = 13; // DS18B20数据引脚
const int BUZZER_PIN = 14; // 蜂鸣器控制引脚
const int BUTTON_PIN = 32; // 功能按钮引脚(上拉输入)
// -------------------- OLED屏幕配置 --------------------
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// -------------------- 温度传感器初始化 --------------------
OneWire oneWire(DATA_PIN);
DallasTemperature sensors(&oneWire);
// -------------------- 温度参数配置 --------------------
float highTempThreshold = 30.0; // 高温阈值(摄氏度)
float lowTempThreshold = 10.0; // 低温阈值(摄氏度)
bool isCelsius = true; // 温度单位标志
unsigned long lastButtonPress = 0; // 按钮防抖计时
const int debounceDelay = 50; // 防抖延迟(ms)
void setup() {
Serial.begin(115200);
sensors.begin();
// OLED初始化
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 error"));
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// 引脚初始化
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.println("over");
displayWelcomeMessage();
}
void loop() {
// 按钮检测与单位切换
handleButtonPress();
float temperature = readTemperature();
if (!isnan(temperature)) {
displayTemperature(temperature);
if (checkTemperatureAlert(temperature)) {
triggerAlert();
}
} else {
displaySensorError();
}
delay(1000);
}
// -------------------- 按钮处理函数 --------------------
void handleButtonPress() {
if (digitalRead(BUTTON_PIN) == LOW &&
(millis() - lastButtonPress) > debounceDelay) {
isCelsius = !isCelsius;
lastButtonPress = millis();
Serial.print("change:");
Serial.println(isCelsius ? "C" : "F");
}
}
// -------------------- 温度显示函数(支持单位切换) --------------------
void displayTemperature(float tempC) {
display.clearDisplay();
// 单位转换
float displayTemp = isCelsius ? tempC : (tempC * 9/5) + 32;
String unitSymbol = isCelsius ? "°C" : "°F";
// 主温度显示
display.setTextSize(2);
display.setCursor(0, 0);
display.print("Temp: ");
display.print(displayTemp, 1); // 显示1位小数
display.println(unitSymbol);
// 阈值显示(动态转换)
display.setTextSize(1);
display.setCursor(0, 30);
display.print("Threshold: ");
float low = isCelsius ? lowTempThreshold : (lowTempThreshold * 9/5) +32;
float high = isCelsius ? highTempThreshold : (highTempThreshold *9/5)+32;
display.print(low, 1);
display.print("-");
display.print(high, 1);
display.println(unitSymbol);
display.display();
}
// -------------------- 其他函数保持不变 --------------------
void displayWelcomeMessage() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Temperature Monitor");
display.setTextSize(2);
display.setCursor(0, 20);
display.println("Initializing...");
display.display();
delay(2000);
}
float readTemperature() {
sensors.requestTemperatures();
DeviceAddress firstSensor;
if (!sensors.getAddress(firstSensor, 0)) {
Serial.println("no found device");
return NAN;
}
float temp = sensors.getTempC(firstSensor);
return temp != DEVICE_DISCONNECTED_C ? round(temp * 10) / 10.0 : NAN;
}
bool checkTemperatureAlert(float temp) {
return (temp > highTempThreshold || temp < lowTempThreshold);
}
void triggerAlert() {
for (int i = 0; i < 3; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
delay(200);
}
}
void displaySensorError() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 20);
display.println("Sensor Error");
display.display();
}