/**
* STM32 单芯片安防系统
* 第一环节:门磁(PA1) + 红外(PA2) 触发舵机(PB1)旋转60°,5秒后复位,同时串口发送"CAMERA WORK"
* 第二环节:串口接收 "alarm" → LCD报警 + 红蓝LED闪烁;接收 "owner" → LCD显示欢迎
* 两部分独立并行,互不干扰
*/
#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// ==================== 引脚定义 ====================
#define DOOR_SENSOR_PIN PA1
#define PIR_SENSOR_PIN PA2
#define SERVO_PIN PB1
#define LCD_SDA_PIN PB7
#define LCD_SCL_PIN PB6
#define RED_LED_PIN PA0
#define BLUE_LED_PIN PA3
#define ALARM_BTN_PIN PB5
#define OWNER_BTN_PIN PB4
// ==================== 全局对象 ====================
Servo lightServo;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ==================== 第一环节状态机 ====================
enum DoorState {
DOOR_IDLE,
DOOR_OPEN,
DOOR_TRIGGERED
};
DoorState doorState = DOOR_IDLE;
unsigned long servoStartTime = 0;
bool servoMoved = false;
// ==================== 报警状态 ====================
bool alarmActive = false;
unsigned long alarmBlinkTime = 0;
bool redOn = true;
// ==================== 串口接收缓冲 ====================
String serialBuffer = "";
// ==================== 初始化 ====================
void setup() {
pinMode(DOOR_SENSOR_PIN, INPUT_PULLDOWN);
pinMode(PIR_SENSOR_PIN, INPUT_PULLUP);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(BLUE_LED_PIN, OUTPUT);
pinMode(ALARM_BTN_PIN, INPUT_PULLUP);
pinMode(OWNER_BTN_PIN, INPUT_PULLUP);
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(BLUE_LED_PIN, LOW);
Serial.begin(9600);
Wire.begin(LCD_SDA_PIN, LCD_SCL_PIN);
lcd.init();
lcd.backlight();
lcd.print("System Ready");
lightServo.attach(SERVO_PIN);
lightServo.write(0);
Serial.println("safeguard_system ready");
}
// ==================== 处理串口指令 ====================
void processCommand(String cmd) {
cmd.trim();
cmd.toLowerCase();
Serial.print("Received: ");
Serial.println(cmd);
if (cmd == "alarm") {
if (!alarmActive) {
alarmActive = true;
Serial.println("ESP32_TX——>STRANGER——>STM32_PA10_RX");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alert! Intruder");
lcd.setCursor(0, 1);
lcd.print("Stranger detected");
alarmBlinkTime = millis();
redOn = true;
digitalWrite(RED_LED_PIN, HIGH);
digitalWrite(BLUE_LED_PIN, LOW);
}
} else if (cmd == "owner") {
alarmActive = false;
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(BLUE_LED_PIN, LOW);
Serial.println("ESP32_TX——>OWNER——>STM32_PA10_RX");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Owner Welcome");
}
}
// ==================== 主循环 ====================
void loop() {
// ---------- 第一环节:门磁 + 红外 → 舵机 ----------
switch (doorState) {
case DOOR_IDLE:
if (digitalRead(DOOR_SENSOR_PIN) == HIGH) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("DOOR OPEN");
doorState = DOOR_OPEN;
}
break;
case DOOR_OPEN:
if (digitalRead(DOOR_SENSOR_PIN) == HIGH) {
if (digitalRead(PIR_SENSOR_PIN) == HIGH) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Moving heat");
lcd.setCursor(0, 1);
lcd.print("source detected");
Serial.println("门被打开");
Serial.println("检测到热源活动");
lightServo.write(60);
servoStartTime = millis();
servoMoved = true;
Serial.println("STM32_PA9_TX——>CAMERA WORK——>ESP32_RX");
Serial.println("电路闭合-补光灯开启");
doorState = DOOR_TRIGGERED;
}
} else {
doorState = DOOR_IDLE;
}
break;
case DOOR_TRIGGERED:
if (servoMoved && (millis() - servoStartTime >= 5000)) {
lightServo.write(0);
servoMoved = false;
doorState = DOOR_IDLE;
}
break;
}
// ---------- 第二环节:读取串口指令或按钮 ----------
// 检测 ALARM 按钮
if (digitalRead(ALARM_BTN_PIN) == LOW) {
if (!alarmActive) {
alarmActive = true;
Serial.println("ESP32_TX——>STRANGER——>STM32_RX");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alert! Intruder");
lcd.setCursor(0, 1);
lcd.print("Stranger detected");
alarmBlinkTime = millis();
redOn = true;
digitalWrite(RED_LED_PIN, HIGH);
digitalWrite(BLUE_LED_PIN, LOW);
delay(200);
}
}
// 检测 OWNER 按钮
if (digitalRead(OWNER_BTN_PIN) == LOW) {
alarmActive = false;
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(BLUE_LED_PIN, LOW);
Serial.println("ESP32_TX——>OWNER——>STM32_RX");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Owner Welcome");
delay(200);
}
// 串口接收字符串(支持 "alarm" 和 "owner")
while (Serial.available()) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
if (serialBuffer.length() > 0) {
processCommand(serialBuffer);
serialBuffer = "";
}
} else {
serialBuffer += c;
}
}
while (Serial1.available()) {
char c = Serial1.read();
if (c == '\n' || c == '\r') {
if (serialBuffer.length() > 0) {
processCommand(serialBuffer);
serialBuffer = "";
}
} else {
serialBuffer += c;
}
}
// ---------- 红蓝LED交替闪烁(报警时) ----------
if (alarmActive) {
if (millis() - alarmBlinkTime >= 500) {
redOn = !redOn;
digitalWrite(RED_LED_PIN, redOn ? HIGH : LOW);
digitalWrite(BLUE_LED_PIN, redOn ? LOW : HIGH);
alarmBlinkTime = millis();
}
}
delay(10);
}
Loading
stm32-bluepill
stm32-bluepill