/*
Aircraft Cabin Pressure Monitoring and Automated Relief System
Target: STM32F103C8T6 "Blue Pill" (Wokwi)
Peripherals: ADC, TIM2 (Timer+Interrupt), UART, PWM (servo), I2C (LCD)
Three-tier severity indication:
Normal - LED off, buzzer silent
Caution - LED blinking (gradual pressure drop)
Emergency- Buzzer sounding (rapid decompression)
*/
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int pressurePin = PA0;
const int ledPin = PB0;
const int buzzerPin = PB1;
const int valveServoPin = PA6;
HardwareTimer *sampleTimer;
volatile bool sampleFlag = false;
Servo valveServo;
LiquidCrystal_I2C lcd(0x27, 16, 2); // SDA=PB7, SCL=PB6 (this board's default I2C1 pins)
float previousPressure = 1013.0;
bool ledBlinkState = false;
const float RATE_EMERGENCY_THRESHOLD = -100.0;
void onTimerTick(void) {
sampleFlag = true;
}
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
digitalWrite(ledPin, LOW);
noTone(buzzerPin);
valveServo.attach(valveServoPin);
valveServo.write(0);
Wire.begin();
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Cabin Pressure");
lcd.setCursor(0, 1);
lcd.print("Booting...");
Serial.println("Cabin Pressure Monitoring System - Boot OK");
//sampleTimer = new HardwareTimer(TIM2);
//sampleTimer->setOverflow(500000, MICROSEC_FORMAT);
//sampleTimer->attachInterrupt(onTimerTick);
//sampleTimer->resume();
}
void loop() {
if (sampleFlag) {
sampleFlag = false;
int rawPressure = analogRead(pressurePin);
float pressure = 600.0 + (rawPressure / 1023.0) * (1013.0 - 600.0);
float rate = (pressure - previousPressure) / 0.5;
previousPressure = pressure;
bool rapidDrop = (rate < RATE_EMERGENCY_THRESHOLD);
bool belowThreshold = (pressure < 750.0);
Serial.print("Pressure: ");
Serial.print((int)pressure);
Serial.print(" hPa | Rate: ");
Serial.print((int)rate);
Serial.println(" hPa/s");
// --- Proportional valve control ---
float openFraction = (750.0 - pressure) / (750.0 - 600.0);
openFraction = constrain(openFraction, 0.0, 1.0);
int valveAngle = (int)(openFraction * 90.0);
if (rapidDrop) {
valveAngle = 90;
}
valveServo.write(valveAngle);
// --- Three-tier severity: LED = caution, buzzer = emergency ---
const char* statusText;
if (rapidDrop) {
digitalWrite(ledPin, LOW);
ledBlinkState = false;
tone(buzzerPin, 2000);
Serial.println("EMERGENCY: RAPID DECOMPRESSION DETECTED!");
statusText = "EMERGENCY!";
} else if (belowThreshold) {
ledBlinkState = !ledBlinkState;
digitalWrite(ledPin, ledBlinkState ? HIGH : LOW);
noTone(buzzerPin);
Serial.println("CAUTION: CABIN PRESSURE LOW!");
statusText = "CAUTION: LOW";
} else {
ledBlinkState = false;
digitalWrite(ledPin, LOW);
noTone(buzzerPin);
statusText = "Status: Normal";
}
Serial.print("Valve angle: ");
Serial.print(valveAngle);
Serial.println(" deg");
// --- LCD status ---
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("P: ");
lcd.print((int)pressure);
lcd.print(" hPa");
lcd.setCursor(0, 1);
lcd.print(statusText);
}
}