/**
* 智能环境监测与控制系统
* 芯片:STM32C031C6 (NUCLEO-C031C6)
* 框架:Arduino
*
* 功能:
* - 读取光敏电阻和LM35温度传感器
* - OLED显示实时数据
* - 按键切换显示模式(温度/光照/阈值设置)
* - 超限报警(LED闪烁+蜂鸣器)
* - 串口数据记录
*/
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
// ========== 引脚定义 ==========
#define PIN_LIGHT_SENSOR PA0 // 光敏电阻
#define PIN_TEMP_SENSOR PA1 // LM35温度传感器
#define PIN_LED PA2 // 报警LED
#define PIN_BUZZER PA3 // 蜂鸣器
#define PIN_BUTTON PC13 // 板载按键(按下为LOW)
// ========== 参数配置 ==========
#define ADC_MAX 4095 // 12位ADC最大值
#define VOLTAGE_REF 3.3 // 参考电压3.3V
#define TEMP_SCALE 0.01 // LM35: 10mV/℃,即0.01V/℃
#define LIGHT_THRESHOLD 2000 // 光照阈值(暗环境触发)
#define TEMP_THRESHOLD 30 // 温度阈值(℃)
// ========== OLED配置 ==========
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// ========== 全局变量 ==========
enum DisplayMode {
MODE_TEMP, // 温度模式
MODE_LIGHT, // 光照模式
MODE_SETTING // 阈值设置模式
};
DisplayMode currentMode = MODE_TEMP;
bool alarmActive = false;
uint16_t lightValue = 0; // 光敏电阻ADC值
float temperature = 0.0; // 温度值(℃)
uint16_t lightThreshold = LIGHT_THRESHOLD;
float tempThreshold = TEMP_THRESHOLD;
unsigned long lastSerialTime = 0;
unsigned long lastAlarmBlink = 0;
bool ledState = false;
// ========== 函数声明 ==========
void readSensors();
void updateDisplay();
void updateAlarm();
void handleButton();
void printSerialData();
void playBeep(int frequency, int duration);
// ========== 初始化 ==========
void setup() {
// 串口初始化
Serial.begin(115200);
Serial.println("\n=== 智能环境监测与控制系统 ===");
Serial.println("芯片: STM32C031C6 (NUCLEO-C031C6)");
Serial.println("系统启动中...\n");
// 引脚初始化
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_BUZZER, OUTPUT);
pinMode(PIN_BUTTON, INPUT_PULLUP); // PC13内部上拉
// ADC初始化(12位分辨率)
analogReadResolution(12);
// OLED初始化
Wire.setSCL(PB6);
Wire.setSDA(PB7);
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println("OLED初始化失败!");
while (1) {
digitalWrite(PIN_LED, HIGH);
delay(100);
digitalWrite(PIN_LED, LOW);
delay(100);
}
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("System Ready");
display.display();
// 启动提示:LED闪烁3次
for (int i = 0; i < 3; i++) {
digitalWrite(PIN_LED, HIGH);
delay(200);
digitalWrite(PIN_LED, LOW);
delay(200);
}
Serial.println("系统就绪!\n");
delay(500);
}
// ========== 主循环 ==========
void loop() {
// 1. 读取传感器
readSensors();
// 2. 处理按键(带消抖)
handleButton();
// 3. 更新报警状态
updateAlarm();
// 4. 更新OLED显示
updateDisplay();
// 5. 串口数据输出(每秒一次)
if (millis() - lastSerialTime > 1000) {
lastSerialTime = millis();
printSerialData();
}
delay(50); // 主循环稳定延时
}
// ========== 传感器读取函数 ==========
void readSensors() {
// 读取光敏电阻ADC值
lightValue = analogRead(PIN_LIGHT_SENSOR);
// 读取LM35温度传感器
int adcValue = analogRead(PIN_TEMP_SENSOR);
float voltage = (adcValue * VOLTAGE_REF) / ADC_MAX;
temperature = voltage / TEMP_SCALE; // LM35: 10mV/℃
// 数据有效性检查(LM35正常工作范围-55℃~150℃)
if (temperature < -55 || temperature > 150) {
temperature = 0; // 无效数据
}
}
// ========== OLED显示函数 ==========
void updateDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// 标题栏
display.setCursor(0, 0);
display.println("Env Monitor System");
display.drawLine(0, 10, 128, 10, SSD1306_WHITE);
// 根据模式显示不同内容
switch (currentMode) {
case MODE_TEMP:
display.setTextSize(2);
display.setCursor(0, 20);
display.print("Temp:");
display.print(temperature, 1);
display.println(" C");
display.setTextSize(1);
display.setCursor(0, 45);
display.print("Threshold: ");
display.print(tempThreshold, 1);
display.println(" C");
display.print("Light ADC: ");
display.println(lightValue);
break;
case MODE_LIGHT:
display.setTextSize(2);
display.setCursor(0, 20);
display.print("Light:");
display.print(map(lightValue, 0, ADC_MAX, 0, 100));
display.println("%");
display.setTextSize(1);
display.setCursor(0, 45);
display.print("ADC: ");
display.print(lightValue);
display.print(" / ");
display.println(ADC_MAX);
display.print("Threshold: ");
display.println(lightThreshold);
break;
case MODE_SETTING:
display.setTextSize(1);
display.setCursor(0, 20);
display.println("Threshold Settings:");
display.print("Temp: ");
display.print(tempThreshold, 1);
display.println(" C");
display.print("Light: ");
display.println(lightThreshold);
display.print("Press key to adjust");
break;
}
// 报警状态指示
if (alarmActive) {
display.fillRect(110, 0, 18, 10, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
display.setCursor(112, 1);
display.print("ALARM");
}
display.display();
}
// ========== 报警处理函数 ==========
void updateAlarm() {
bool newAlarm = false;
String alarmReason = "";
// 检查光照是否超限(暗环境)
if (lightValue > lightThreshold) {
newAlarm = true;
alarmReason = "Low Light!";
}
// 检查温度是否超限
if (temperature > tempThreshold) {
newAlarm = true;
alarmReason = "High Temp!";
}
// 更新报警状态
if (newAlarm != alarmActive) {
alarmActive = newAlarm;
if (alarmActive) {
Serial.print("!!! ALARM TRIGGERED: ");
Serial.println(alarmReason);
} else {
Serial.println(">>> Alarm cleared <<<");
}
}
// 报警执行:LED闪烁 + 蜂鸣器
if (alarmActive) {
if (millis() - lastAlarmBlink > 200) {
lastAlarmBlink = millis();
ledState = !ledState;
digitalWrite(PIN_LED, ledState);
if (ledState) {
playBeep(1000, 100); // 1kHz蜂鸣100ms
} else {
noTone(PIN_BUZZER);
}
}
} else {
digitalWrite(PIN_LED, LOW);
noTone(PIN_BUZZER);
ledState = false;
}
}
// ========== 按键处理(带消抖) ==========
void handleButton() {
static unsigned long lastButtonTime = 0;
static bool lastButtonState = HIGH;
bool currentState = digitalRead(PIN_BUTTON);
// 按键按下检测(下降沿 + 消抖)
if (currentState == LOW && lastButtonState == HIGH &&
(millis() - lastButtonTime > 300)) {
lastButtonTime = millis();
// 切换显示模式
switch (currentMode) {
case MODE_TEMP:
currentMode = MODE_LIGHT;
Serial.println("Mode: LIGHT");
break;
case MODE_LIGHT:
currentMode = MODE_SETTING;
Serial.println("Mode: SETTING");
break;
case MODE_SETTING:
currentMode = MODE_TEMP;
Serial.println("Mode: TEMPERATURE");
break;
}
}
lastButtonState = currentState;
}
// ========== 串口数据输出 ==========
void printSerialData() {
Serial.print("=== Sensor Data ===");
Serial.print(" Temp: ");
Serial.print(temperature, 1);
Serial.print("°C");
Serial.print(" | Light ADC: ");
Serial.print(lightValue);
Serial.print(" (");
Serial.print(map(lightValue, 0, ADC_MAX, 0, 100));
Serial.print("%)");
Serial.print(" | Alarm: ");
Serial.print(alarmActive ? "ACTIVE" : "Normal");
// 阈值显示
Serial.print(" | Thresholds: ");
Serial.print(tempThreshold);
Serial.print("°C / ");
Serial.println(lightThreshold);
}
// ========== 蜂鸣器发声函数 ==========
void playBeep(int frequency, int duration) {
tone(PIN_BUZZER, frequency, duration);
}
// ========== 预留:阈值调整函数(可通过串口命令实现) ==========
void adjustThreshold(char type, float value) {
if (type == 'T' || type == 't') {
tempThreshold = value;
Serial.print("Temperature threshold set to: ");
Serial.println(tempThreshold);
} else if (type == 'L' || type == 'l') {
lightThreshold = (uint16_t)value;
Serial.print("Light threshold set to: ");
Serial.println(lightThreshold);
}
}