PC Laptop Motherboard PID Temperature Controller with Arduino

In modern electronics, especially in laptops, controlling the temperature of components like the motherboard is crucial for optimal performance and longevity. Overheating can lead to system failures or reduced efficiency. One effective method for maintaining an ideal temperature range is using a PID (Proportional, Integral, Derivative) Controller. This article explores the implementation of a PID-based temperature controller for a laptop motherboard cooling system using an Arduino. Such controller system is important for the computer or laptop to maintain the motherboard and its component temperature to room temperature as they gets heated as more application are run on the PC/laptop. So this has real application which can be extended to other system. We’ll also delve into the relevant code and explain its various components.

To learn more about how to implement PID controllers for temperature control, you can check out these related resources:

What is PID Temperature Control? A PID controller is an automated control system that continuously adjusts a system's output based on the difference between the current temperature (measured value) and the setpoint (desired temperature). It ensures that the output reaches the setpoint efficiently, reducing oscillation and providing a stable, accurate result.

In the context of laptop cooling, a PID temperature controller can regulate the speed of a cooling fan, thereby maintaining a consistent temperature on the motherboard, which in turn prevents overheating and damage to the components.

arduino pid controller

Key Components: To implement this temperature control system using an Arduino, we use the following components:

  1. Arduino (any model like Arduino Uno, Nano, or Mega)
  2. Thermistor: A temperature-sensing resistor whose resistance changes with temperature.
  3. PC/Laptop Fan: An actuator that increases or decreases the airflow based on the temperature.
  4. Potentiometer: Used to set the desired temperature (setpoint).
  5. OLED Display: Displays real-time temperature data and the PID controller output.
  6. Resistors: 1kohm, 10kohm for current limiting and voltage divider circuit
  7. MOSFET: IRF549N or similar for turning on/off the motor with PWM signal
  8. Diode: 1N4007 to protect Arduino from sudden reverse spikes
  9. Capacitor: 0.1uF x 2 for smoothing the signal across the motor and for filtering supply noise on breadboard 

Circuit Diagram: The circuit diagram of the PC/Laptop motherboard cooling system using Arduino as PID controller is as shown below.

PC Laptop Motherboard PID Temperature Controller with Arduino

If you are having trouble with the OLED display check out the Beginner's Guide to Testing an OLED Display with Arduino tutorial. Similarly the basics of using the diode, MOSFET circuit, capacitor is explained in Arduino Nano with TIP122 DC Motor speed Control tutorial.

Code Explanation: The following code outlines the implementation of a PID controller for temperature regulation using an Arduino and a thermistor.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
#include <PID_v1.h>

#define OLED_RESET 4
Adafruit_SH1106 display(OLED_RESET);

const int thermistorPin = A0;  // Pin where the thermistor voltage divider is connected (analog pin A0)
const int potPin = A2;         // Potentiometer input pin
const int fanPin = 9;          // Fan output pin

// Tuning parameters
float Kp = 10;  // Proportional gain
float Ki = 1.5; // Integral gain
float Kd = 1;   // Differential gain
// Record the set point as well as the controller input(y) and output(u)
double Setpoint, x, y;
// Create a controller that is linked to the specified Input, Ouput and Setpoint
PID myPID(&x, &y, &Setpoint, Kp, Ki, Kd, DIRECT);
const int sampleRate = 1; // Time interval of the PID control

// Define the aggressive and conservative Tuning Parameters
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;

// Thermistor parameters (for 10k thermistor, adjust as necessary for your thermistor)
const int resistorValue = 10000;    // 10k ohm resistor (adjust for your setup)
const float referenceVoltage = 3.3; // Voltage reference (can be 3.3V for some Arduinos)
const float nominalResistance = 10000.0;  // Nominal resistance at 25°C
const float bCoefficient = 3950.0; // B-coefficient (check thermistor datasheet)

void setup() {
  // Setup serial at 9600 bps
  Serial.begin(9600);
  analogReference(EXTERNAL);

  // Initialize display
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);  // Initialize with the I2C address 0x3C (for the 128x64)
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextSize(1); // Set text size to 1
  display.setTextColor(WHITE);
  display.setCursor(20, 10); // Center the text
  display.println("Temperature PID");
  display.setCursor(30, 20); // Center the text
  display.println("Controller");
  display.setCursor(20, 30); // Center the text
  display.println("ee-diary.com");
  display.display();
  delay(2000);

  myPID.SetMode(AUTOMATIC);  // Turn on the PID control
  myPID.SetSampleTime(sampleRate); // Assign the sample rate of the control
}

void loop() {
  // Read temperature from thermistor
  int sensorValue = analogRead(thermistorPin);  // Read the analog value from the thermistor voltage divider
  float voltage = (sensorValue / 1023.0) * referenceVoltage;  // Convert the value to voltage
  float resistance = (referenceVoltage / voltage - 1) * resistorValue;  // Calculate the resistance of the thermistor

  // Calculate temperature using the simplified Steinhart-Hart equation (you can use more precise methods if necessary)
  float temperature = 1.0 / (log(resistance / nominalResistance) / bCoefficient + 1.0 / 298.15) - 273.15;  // Convert to Celsius

  // Check if the reading is valid (optional)
  if (temperature < -55 || temperature > 150) {  // Arbitrary range check, adjust as needed
    Serial.println("Failed to read from thermistor!");
    display.clearDisplay();
    display.setCursor(0, 10);
    display.println("Sensor Error!");
    display.display();
    delay(1000);  // Wait before retrying
    return;  // Skip the rest of the loop if sensor fails
  }

  // Update the setpoint from the potentiometer (map to 0-100°C range)
  Setpoint = map(analogRead(potPin), 0, 1023, 0, 100); // Map from 0 to 100°C

  // Convert the temperature to the format for PID (x)
  x = temperature;  // Now `x` contains the temperature value

  // Determine the tuning parameters based on the gap
  double gap = abs(Setpoint - y); // Distance away from setpoint
  if (gap < 5) {
    // We're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  } else {
    // We're far from setpoint, use aggressive tuning parameters
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }

  // PID calculation
  myPID.Compute(); // Calculates the PID output at a specified sample time

  // Constrain and convert the PID output to integer for PWM
  int pwm = (int)constrain(y, 0, 255); // Ensure that the PID output stays within the valid PWM range
  analogWrite(fanPin, pwm); // Use the PID output for fan control

  // Display on Serial Monitor
  Serial.print("Temperature: ");
  Serial.print(x, 2);  // Limit to 2 decimal places
  Serial.print("°C, ");
  Serial.print("Setpoint: ");
  Serial.print(Setpoint, 2);  // Limit to 2 decimal places
  Serial.print(", ");
  Serial.print("Output: ");
  Serial.print(y, 2);  // Limit to 2 decimal places
  Serial.print(", ");
  Serial.print("Gap: ");
  Serial.println(gap, 2);  // Limit to 2 decimal places

  // Convert floating-point values to string with 2 decimal places using dtostrf()
  char setpointStr[10];
  char tempStr[10];
  char outputStr[10];
  dtostrf(Setpoint, 4, 2, setpointStr);  // Convert Setpoint to string with 2 decimal places
  dtostrf(x, 4, 2, tempStr);            // Convert temperature (x) to string with 2 decimal places
  dtostrf(pwm, 3, 0, outputStr);          // Convert output (y) to string with 2 decimal places

  // Clear the display before writing new values to avoid overlap
  display.clearDisplay();  
  // Display new data
  display.setCursor(0, 10);
  display.print("Setpoint: ");
  display.print(setpointStr);  // Display the Setpoint string
  display.print((char)247); // degree symbol
  display.print("C");          // Add unit after the value

  display.setCursor(0, 30); // Change cursor position for the next line
  display.print("Temp.: ");
  display.print(tempStr);  // Display the temperature string
  display.print((char)247); // degree symbol
  display.print("C");      // Add unit after the value

  display.setCursor(0, 50); // Change cursor position for the next line
  display.print("Output PWM: ");
  display.print(outputStr);  // Display the output string

  display.display();  // Refresh the display with new data

  delay(1000); // Reduced delay to allow for faster updates, if needed
}

Code Breakdown:

  1. Temperature Measurement with Thermistor:

    • The thermistor is part of a voltage divider circuit. The resistance of the thermistor changes with temperature, and this change is read as an analog value.
    • The Steinhart-Hart equation is used to convert the thermistor's resistance into temperature.
  2. PID Control:

    • The PID controller adjusts the fan speed based on the temperature readings and the setpoint.
    • The controller uses three parameters:
      • Proportional (Kp): Responds to the current error.
      • Integral (Ki): Accounts for the accumulation of past errors.
      • Derivative (Kd): Predicts future errors.
  3. Setpoint and Display:

    • The setpoint (desired temperature) is adjusted using a potentiometer.
    • The real-time temperature and PID output are displayed on an OLED screen for user feedback.

Video Demonstration:

 The following video demonstrates how the Arduino based PID controller works and how it keeps a constant pre-set temperature to the PC/Laptop motherboard.

Conclusion: The integration of a PID controller with Arduino and a thermistor for laptop motherboard temperature management provides an efficient solution for maintaining stable thermal conditions. This approach can optimize the cooling systems in laptops and prevent overheating by controlling the fan speed based on precise temperature measurements. For more detailed guides on PID tuning and setup, visit these helpful articles:

Post a Comment

Previous Post Next Post