#include <PID_v1.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
// OLED Display Settings
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Pin Definitions
const int ntcPin = A0; // NTC thermistor analog pin
const int heaterPin = 9; // PWM pin for heater control
const int buttonUpPin = 2; // Button to increase setpoint
const int buttonDownPin = 3; // Button to decrease setpoint
// PID Variables
double setpoint = 30.0; // Initial setpoint temperature
double input, output;
double Kp = 2.0, Ki = 0.5, Kd = 1.0; // PID tuning parameters
PID myPID(&input, &output, &setpoint, Kp, Ki, Kd, DIRECT);
// NTC Thermistor Variables
const double beta = 3950.0; // Beta value for the NTC thermistor
const double nominalResistance = 10000.0; // Resistance at 25°C
const double nominalTemp = 25.0; // Temperature for nominal resistance
const double seriesResistor = 10000.0; // Series resistor value
// Button Variables
bool lastButtonUpState = HIGH;
bool lastButtonDownState = HIGH;
void setup() {
// Initialize Serial Monitor
Serial.begin(9600);
// Initialize OLED Display
// Initialize OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED failed"));
while(1);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("PID Temp Control");
display.display();
delay(2000);
// Initialize PID
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, 255); // PWM range
// Initialize Buttons
pinMode(buttonUpPin, INPUT_PULLUP);
pinMode(buttonDownPin, INPUT_PULLUP);
// Initialize Heater Pin
pinMode(heaterPin, OUTPUT);
}
void loop() {
// Read Temperature
input = readTemperature();
// Compute PID
myPID.Compute();
// Control Heater
analogWrite(heaterPin, output);
// Adjust Setpoint with Buttons
adjustSetpoint();
// Update OLED Display
updateDisplay();
// Small delay for stability
delay(100);
}
double readTemperature() {
int analogValue = analogRead(ntcPin);
double resistance = seriesResistor / (1023.0 / analogValue - 1.0);
double temperature = 1.0 / (1.0 / (nominalTemp + 273.15) + log(resistance / nominalResistance) / beta) - 273.15;
return temperature;
}
void adjustSetpoint() {
bool buttonUpState = digitalRead(buttonUpPin);
bool buttonDownState = digitalRead(buttonDownPin);
if (buttonUpState == LOW && lastButtonUpState == HIGH) {
setpoint += 1.0; // Increase setpoint by 1°C
}
if (buttonDownState == LOW && lastButtonDownState == HIGH) {
setpoint -= 1.0; // Decrease setpoint by 1°C
}
lastButtonUpState = buttonUpState;
lastButtonDownState = buttonDownState;
}
void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
display.print("Temp: ");
display.print(input);
display.println(" C");
display.setCursor(0, 20);
display.print("Set: ");
display.print(setpoint);
display.println(" C");
display.setCursor(0, 40);
display.print("Output: ");
display.print(output);
display.display();
}