#include <Arduino.h>
#include <math.h> // For log function
#include <Servo.h> // For controlling the servo fan
#include <LiquidCrystal.h> // For 16x2 LCD
// ----- CONFIGURATION -----
const int NTC_PIN = PA1; // Analog pin connected to NTC voltage divider
const int LED_PIN = PA5; // Digital pin for alarm LED
const int FAN_SERVO_PIN = PB1; // PWM pin controlling the servo fan
const int BUZZER_PIN = PA6; // Digital pin for buzzer
// LCD pins: RS, EN, D4, D5, D6, D7
LiquidCrystal lcd(PA0, PA3, PB4, PB5, PB6, PB7);
const float VCC = 3.3;
const float R_FIXED = 10000;
const float R0 = 10000;
const float BETA = 3950;
const float T0 = 298.15;
const float TEMP_BLINK_START = 50;
const float TEMP_MAX = 80;
const int BLINK_MAX = 150;
const int BLINK_MIN = 500;
const int SERVO_MIN_ANGLE = 0;
const int SERVO_MAX_ANGLE = 180;
const float BUZZER_START_TEMP = 60;
const float BUZZER_MAX_TEMP = TEMP_MAX;
// ----- GLOBALS -----
Servo fanServo;
int servoAngle = SERVO_MIN_ANGLE;
bool direction = true;
// ----- SETUP -----
void setup() {
Serial.begin(115200);
analogReadResolution(12); // STM32 ADC is 12-bit (0-4095)
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
fanServo.attach(FAN_SERVO_PIN);
fanServo.write(servoAngle);
lcd.begin(16, 2);
lcd.print("Temp Monitor");
}
// ----- LOOP -----
void loop() {
// ----- Read temperature -----
int adcValue = analogRead(NTC_PIN);
float Vout = (adcValue / 4095.0) * VCC;
float Rntc = (R_FIXED * Vout) / (VCC - Vout);
float tempK = 1 / ((1 / T0) + (1 / BETA) * log(Rntc / R0));
float tempC = tempK - 273.15;
Serial.print("Temperature: ");
Serial.print(tempC, 2);
Serial.println(" °C");
// ----- LCD DISPLAY -----
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(tempC, 1);
lcd.print((char)223); // degree symbol
lcd.print("C");
lcd.setCursor(0, 1);
if (tempC < 50) {
lcd.print("Status: Normal ");
} else if (tempC < 70) {
lcd.print("Warning: Heating");
} else {
lcd.print("OVERLOAD! Critical");
}
// ----- LED ALERT LOGIC -----
if (tempC < TEMP_BLINK_START) {
digitalWrite(LED_PIN, LOW);
delay(1000);
} else {
float tempForBlink = tempC;
if (tempForBlink > TEMP_MAX) tempForBlink = TEMP_MAX;
int blinkDelay = map(tempForBlink * 10, TEMP_BLINK_START * 10, TEMP_MAX * 10, BLINK_MIN, BLINK_MAX);
digitalWrite(LED_PIN, HIGH);
delay(blinkDelay / 2);
digitalWrite(LED_PIN, LOW);
delay(blinkDelay / 2);
}
// ----- BUZZER LOGIC -----
if (tempC >= BUZZER_START_TEMP) {
int buzzerDelay = map(tempC * 10, BUZZER_START_TEMP * 10, BUZZER_MAX_TEMP * 10, 200, 50);
digitalWrite(BUZZER_PIN, HIGH);
delay(buzzerDelay / 2);
digitalWrite(BUZZER_PIN, LOW);
delay(buzzerDelay / 2);
} else {
digitalWrite(BUZZER_PIN, LOW);
}
// ----- SERVO FAN SIMULATION -----
float tempForFan = tempC;
if (tempForFan < TEMP_BLINK_START) tempForFan = TEMP_BLINK_START;
if (tempForFan > TEMP_MAX) tempForFan = TEMP_MAX;
int stepSize = map(tempForFan * 10, TEMP_BLINK_START * 10, TEMP_MAX * 10, 5, 20);
int servoDelay = map(tempForFan * 10, TEMP_BLINK_START * 10, TEMP_MAX * 10, 5, 0);
if (direction) {
servoAngle += stepSize;
if (servoAngle >= SERVO_MAX_ANGLE) direction = false;
} else {
servoAngle -= stepSize;
if (servoAngle <= SERVO_MIN_ANGLE) direction = true;
}
fanServo.write(servoAngle);
delay(servoDelay);
}Loading
stm32-bluepill
stm32-bluepill