#include <PID_v1.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Pin Configuration
const int tempPin = A0; // LM35 sensor
const int heaterPin = 9; // PWM output for heating element
const int upButton = 2; // Setpoint increase
const int downButton = 3; // Setpoint decrease
// PID Variables
double Setpoint = 30.0; // Initial target temperature
double Input, Output;
double Kp = 500, Ki = 1, Kd = 0.1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// Temperature Reading
float temperature = 0;
unsigned long lastUpdate = 0;
// Button Handling
unsigned long lastDebounceTime = 0;
const int debounceDelay = 50;
void setup() {
Serial.begin(9600);
// Initialize OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED failed"));
while(1);
}
display.clearDisplay();
// Initialize PID
myPID.SetOutputLimits(0, 255);
myPID.SetSampleTime(1000);
myPID.SetMode(AUTOMATIC);
// Initialize Pins
pinMode(heaterPin, OUTPUT);
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
// Initial display update
updateDisplay();
}
void loop() {
// Update temperature every second
if(millis() - lastUpdate >= 1000) {
temperature = readTemperature();
Input = temperature;
myPID.Compute();
lastUpdate = millis();
}
handleButtons();
analogWrite(heaterPin, Output);
updateDisplay();
}
float readTemperature() {
int raw = analogRead(tempPin);
return (raw * 500.0) / 1024.0; // Convert to Celsius
}
void handleButtons() {
// Debounce check
if((millis() - lastDebounceTime) < debounceDelay) return;
// Up button pressed
if(digitalRead(upButton) == LOW) {
Setpoint += 0.5;
lastDebounceTime = millis();
}
// Down button pressed
if(digitalRead(downButton) == LOW) {
Setpoint -= 0.5;
lastDebounceTime = millis();
}
// Constrain setpoint between 0-100°C
Setpoint = constrain(Setpoint, 0, 100);
}
void updateDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// Current Temperature
display.setCursor(0, 0);
display.print("Actual: ");
display.print(temperature, 1);
display.print("C");
// Setpoint
display.setCursor(0, 20);
display.print("Target: ");
display.print(Setpoint, 1);
display.print("C");
// PID Output
display.setCursor(0, 40);
display.print("Power: ");
display.print((Output/255)*100, 0);
display.print("%");
// PID Parameters
display.setCursor(0, 55);
display.print("PID: ");
display.print(Kp, 0);
display.print("/");
display.print(Ki, 1);
display.print("/");
display.print(Kd, 1);
display.display();
}