Introduction
Design and implement an intelligent HVAC control system with PID temperature regulation, occupancy sensors, and BMS integration. This comprehensive guide covers everything from design through implementation, testing, and deployment.
Design and implement an intelligent HVAC control system with PID temperature regulation, occupancy sensors, and BMS integration.
Design and implement an intelligent HVAC control system with PID temperature regulation, occupancy sensors, and BMS integration. This comprehensive guide covers everything from design through implementation, testing, and deployment.
Central AHU (Air Handling Unit) supplies conditioned air to zones via ductwork. Zone terminal boxes regulate airflow. Control hierarchy: Zone level (temperature and air quality → zone damper position), AHU level (supply air temperature, static pressure, fan speed), Chiller/Boiler level (cooling/heating plant). Each level controlled by PID: zone temperature setpoint → zone damper → AHU supply temperature setpoint → chiller capacity. Modern buildings use DDC (Direct Digital Control) instead of pneumatic controls.
10 components required for this project.
| # | Component | Purpose | Qty |
|---|---|---|---|
| 1 | VRF/Split AC system (existing) | HVAC equipment to control | x1 |
| 2 | Modbus RTU thermostat (Honeywell T6800) | Temperature setpoint interface | x1 |
| 3 | CO2 Sensor (MH-Z19B, Modbus) | Occupancy detection by CO2 level | x4 |
| 4 | Temperature/Humidity Sensors (SHT31, zone) | Multi-zone monitoring | x8 |
| 5 | VFD (Variable Frequency Drive, 3-phase) | AHU fan speed control | x1 |
| 6 | Raspberry Pi 4 (BMS server) | Building Management System host | x1 |
| 7 | Modbus TCP/RTU gateway | Sensor network integration | x1 |
| 8 | Occupancy PIR Sensors | Room occupancy detection | x6 |
| 9 | Demand-controlled ventilation damper | Zone air volume control | x4 |
| 10 | BACNET stack (open-source) | Industry standard BAS protocol | x1 |
Follow these 4 steps carefully.
Central AHU (Air Handling Unit) supplies conditioned air to zones via ductwork. Zone terminal boxes regulate airflow. Control hierarchy: Zone level (temperature and air quality → zone damper position), AHU level (supply air temperature, static pressure, fan speed), Chiller/Boiler level (cooling/heating plant). Each level controlled by PID: zone temperature setpoint → zone damper → AHU supply temperature setpoint → chiller capacity. Modern buildings use DDC (Direct Digital Control) instead of pneumatic controls.
DCV adjusts ventilation rate based on actual occupancy (measured by CO2 level). CO2 baseline: outdoor ≈ 420 ppm. Occupied space: 1000 ppm indicates 1 person per 5m³ space. ASHRAE 62.1: maintain CO2 < 1100 ppm for acceptable indoor air quality. DCV logic: CO2 > 1000 ppm → increase outdoor air intake (open fresh air damper). CO2 < 700 ppm (unoccupied) → reduce outdoor air to 30% minimum. Energy savings: reducing ventilation in unoccupied spaces saves 20–40% HVAC energy.
Zone temperature control PID: error = setpoint - current_zone_temp. Output: damper position (0–100%). Tuning: zone thermal mass is large (slow system). Use conservative gains: Kp=5% damper change per 1°C error, Ti=15 minutes, Td=2 minutes. Anti-windup: integral clamped when damper at limits. Cascade control: AHU supply temperature setpoint computed by outer (zone) controller, inner (AHU supply air) PID controls chilled water valve. Scheduling: setback at night (allow temperature to drift 2°C from setpoint).
Modbus RTU: RS-485 serial, master-slave. Master (Raspberry Pi via RS-485 adapter) polls each slave device (CO2 sensors, zone controllers, VFD) every 5 seconds. Read registers: temperature, CO2, damper position. Write registers: setpoints, damper commands, VFD speed. Modbus TCP: same protocol over Ethernet. Python modbus library (pymodbus): read_holding_registers(address, count, unit=slave_id). Log all data to InfluxDB. Grafana dashboard: room temperatures, CO2 levels, energy consumption, equipment status.
Core code for hvac_controller.py:
from pymodbus.client import ModbusSerialClient import time, json from simple_pid import PID class ZoneController: def __init__(self, zone_id, modbus_client, slave_addr): self.zone_id = zone_id self.client = modbus_client self.slave = slave_addr self.temp_pid = PID(5, 0.1, 2, setpoint=22.0) self.temp_pid.output_limits = (0, 100) # Damper 0-100% def read_sensors(self): """Read temperature, CO2 from Modbus registers""" temp_reg = self.client.read_holding_registers(0, 2, slave=self.slave) co2_reg = self.client.read_holding_registers(2, 2, slave=self.slave) temperature = temp_reg.registers[0] / 10.0 # 0.1°C resolution co2_ppm = co2_reg.registers[0] # ppm return temperature, co2_ppm def set_damper(self, position_pct): """Set zone damper to 0-100% position via Modbus""" scaled = int(position_pct * 100) # 0-10000 internal self.client.write_register(10, scaled, slave=self.slave) def control_loop(self): temp, co2 = self.read_sensors() # Temperature control damper_pos = self.temp_pid(temp) # CO2 override: force minimum ventilation if air quality poor if co2 > 1000: damper_pos = max(damper_pos, 50) # Minimum 50% for ventilation print(f"Zone {self.zone_id}: CO2 high ({co2}ppm) - increasing ventilation") self.set_damper(damper_pos) return {"zone": self.zone_id, "temp": temp, "co2": co2, "damper": damper_pos} client = ModbusSerialClient(port="/dev/ttyUSB0", baudrate=9600) client.connect() zones = [ZoneController(i, client, i+1) for i in range(1, 5)] while True: for zone in zones: print(zone.control_loop()) time.sleep(30)
Test HVAC Control System Design by verifying each subsystem individually before full integration.
Verify power voltages, check ground connections, use serial monitor for debug.
An interactive simulator will be available here — simulate circuits and run code in-browser without hardware.