#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// --- REQUIRED FONT INCLUDE ---
// This is the file that contains the smooth font data.
#include <Fonts/FreeSansBold9pt7b.h>
// -----------------------------
// --- I2C OLED Display Definitions ---
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, 0x3C);
// --- Sensor Object Initialization ---
Adafruit_BMP085 bmp;
// --- Pin Definitions ---
const int POT_PIN = A0;
const int BUZZER_PIN = 8;
const int LED_GREEN = 9;
const int LED_YELLOW = 10;
const int LED_RED = 11;
// --- Global Variables & Constants ---
const float MAX_UPPER_RANGE = 1095.0;
const int ALERT_TONE = 1000;
float setpointPressure = 1000.0;
float pressureBand = 10.0;
// --- FUNCTION PROTOTYPES ---
void updateOLED(float currentP, float lowerL, float upperL, int status);
void updateAlerts(float currentP, float lowerL, float upperL);
// =========================================================
// SETUP FUNCTION
// =========================================================
void setup() {
Serial.begin(9600);
// --- Initialize Outputs ---
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(LED_RED, OUTPUT);
noTone(BUZZER_PIN);
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, LOW);
// --- Initialize BMP180 ---
if (!bmp.begin()) {
Serial.println("Could not find BMP180 sensor!");
digitalWrite(LED_RED, HIGH);
while (1);
}
Serial.print("Baseline Pressure Set: ");
Serial.print(setpointPressure);
Serial.println(" hPa");
// --- Initialize OLED ---
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
while (true);
}
display.display();
delay(1000);
display.clearDisplay();
}
// =========================================================
// LOOP FUNCTION (Main Logic)
// =========================================================
void loop() {
float currentPressure = bmp.readPressure() / 100.0F;
int rawBand = analogRead(POT_PIN);
pressureBand = map(rawBand, 0, 1023, 5, 50);
float lowerLimit = setpointPressure - pressureBand;
float potUpperLimit = setpointPressure + pressureBand;
float upperLimit = min(potUpperLimit, MAX_UPPER_RANGE);
int status;
if (currentPressure >= upperLimit) {
status = 2; // High Alert (Red LED)
} else if (currentPressure <= lowerLimit) {
status = 1; // Low Alert (Yellow LED)
} else {
status = 0; // Normal (Green LED)
}
updateAlerts(currentPressure, lowerLimit, upperLimit);
updateOLED(currentPressure, lowerLimit, upperLimit, status);
delay(1000);
}
// =========================================================
// CUSTOM FUNCTIONS
// =========================================================
/**
* @brief Drives the physical outputs (LEDs and Passive Buzzer) based on status
*/
void updateAlerts(float currentP, float lowerL, float upperL) {
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, LOW);
noTone(BUZZER_PIN);
if (currentP >= upperL) {
digitalWrite(LED_RED, HIGH);
tone(BUZZER_PIN, ALERT_TONE);
}
else if (currentP <= lowerL) {
digitalWrite(LED_YELLOW, HIGH);
tone(BUZZER_PIN, ALERT_TONE);
}
else {
digitalWrite(LED_GREEN, HIGH);
}
}
/**
* @brief Updates the OLED display with current pressure and limits
* Uses a custom GFX font for the main pressure reading.
*/
void updateOLED(float currentP, float lowerL, float upperL, int status) {
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
// --- 1. Current Pressure (Smooth Font) ---
// Sets the custom font for the large reading
display.setFont(&FreeSansBold9pt7b);
display.setTextSize(1);
display.setCursor(0, 15); // Adjust Y-position to account for font height
display.print("P: ");
display.print((int)currentP);
display.print(" hPa");
// --- 2. Status Indicator (Switch back to standard font) ---
display.setFont(); // Clears the custom font setting
display.setTextSize(1);
display.setCursor(0, 25);
display.print("Status: ");
if (status == 2) {
display.print("HIGH ALERT");
} else if (status == 1) {
display.print("LOW ALERT");
} else {
display.print("NORMAL");
}
// --- 3. Limit Settings (Standard Font) ---
display.setTextSize(1);
display.setCursor(0, 40);
display.print("UPPER: ");
display.print((int)upperL);
display.print(" hPa");
display.setCursor(0, 55);
display.print("LOWER: ");
display.print((int)lowerL);
display.print(" hPa");
display.display();
}