Michael Guerero
Published © GPL3+

Mini HVAC

A small-scale HVAC system utilizing a closed-loop feedback PID controller that can maintain a set-point temperature within the box.

BeginnerShowcase (no instructions)2,363
Mini HVAC

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Adafruit MCP9808 High Accuracy I2C Temperature Sensor Breakout Board
×1
Antec 140mm PC Fan
×1
Arduino MotorShield Rev3
Arduino MotorShield Rev3
×1
75 Watt Desk Lamp
×1

Story

Read more

Code

Mini HVAC PID Control

Arduino
PID control
#include <AFMotor.h>
#include <Wire.h>
#include "Adafruit_MCP9808.h"

Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();
AF_DCMotor fan(2);

unsigned long currMillis;
unsigned long prevMillis = 0;
double kp = 410;
double ki = 2*kp/20; 
double kd = kp*20/8;
double dt = 0.01;          // Specify sample time in seconds (fixed)
double dtmillis = dt*1000;  // Sample time in milliseconds
int setpoint;
float input;
float Output;
float err;
float pTerm;
int IntThresh;
float integrated_err;
float dTerm;
float iTerm;
float last_err;


void setup(){
  Serial.begin(9600);
  
  if (!tempsensor.begin()) {
    Serial.println("Couldn't find MCP9808!");
    while (1);
  }
  fan.run(RELEASE);
  fan.setSpeed(0);
}

void loop(){
setpoint = 30;               // Specified by user, r(t)
  float c = tempsensor.readTempC();
  Serial.print("Temp: "); 
  Serial.println(c); Serial.println("*C\t");
input = (c);                 // Read by your sensor, y(t) ... analogRead(...)
err = (input - setpoint);    // Compute Error, e(t) = r(t) - y(t)
delay(200);
// ====================== Compute Proportional term: ========================
pTerm = kp * (err);                 
// ====================== Compute Integral term: ===========================
IntThresh = .3;                      // Set value for max intergral term
if (abs(err) > IntThresh)            // Crude way to prevent integrator 'windup'
{                                    
    integrated_err += err;           // Accumulate the error integral
}
else 
{
    integrated_err = 0;              // Zero it if out of bounds 
}
iTerm = ki * integrated_err;         // Compute actual Integral term
// ====================== Compute Derivative term: ===========================
dTerm = kd * (err - last_err)*dt;  
// ====================== Compute PID control command, u(t): =================
Output = constrain(pTerm + iTerm + dTerm, 0, 255);       
fan.run(FORWARD);
fan.setSpeed(Output);    // Use u(t) to drive the plant, i.e. analogWrite(Output), motor.run(Output), etc...

last_err = err;      // Set last_err to err for next time through loop

Credits

Michael Guerero
3 projects • 44 followers
Earned my BS in Mechanical Engineering from Cal Poly Pomona in 2018. Currently working for the California Air Resources Board.
Contact

Comments

Please log in or sign up to comment.