Skip to main content

 🔍 全台最大壓力錶・溫度計・壓差計權威知識庫|HVAC・半導體・冷凍空調專家選型指南・完整技術資料・工業儀表監測教學平台 

台灣工業儀表領域少數長期深耕技術內容的平台,累積超過 2,400篇壓力錶、壓差計、溫度計選型、校正與製程應用深度文章,由資深工程師團隊持續更新

 
 

樓宇自動化入門:房間溫度控制器的集成

從選型到串接實踐|MQTT、REST API、Modbus 協議完整指南

第 1 章|樓宇自動化系統基礎概念

1.1 什麼是樓宇自動化系統(Building Automation System, BAS)

樓宇自動化系統是一種利用 計算機技術、控制技術、網路通訊技術 對建築物內的各個機械、電氣設備進行自動監測、控制和管理的系統。在辦公樓、商場、醫院、工廠、資料中心等場景中,BAS 系統透過採集溫度、濕度、壓力等多種物理參數,實現 能源效率最大化、人員舒適度提升、安全隱患預警 的目標。

系統組件功能說明應用場景
感測器層採集溫度、濕度、空氣品質等參數每個房間、走廊、機房
控制層根據設定規則調整冷暖氣、風扇、燈光中央空調、新風機組、照明系統
通訊層傳輸感測值、執行控制指令以太網、RS485、ZigBee、LoRaWAN
管理層儀表板監控、告警、報表統計中央管理主機、雲平台、手機 App

1.2 樓宇自動化為何關鍵

現代建築面臨的挑戰包括:

  • 能源成本飆升 — 不當的溫度設定造成 15-30% 的額外耗能
  • 人員舒適度難以保障 — 局部溫度差異大,容易造成投訴
  • 故障反應遲緩 — 傳統人工巡檢無法及時發現冷卻系統故障
  • 維護成本高 — 缺乏數據支撐的預防性維護難以實施

透過部署 BAS 系統,企業可以:

  • 減少 20-40% 的能源消耗
  • 提高人員舒適度評分
  • 縮短故障發現時間至分鐘級別
  • 實施預測性維護,降低停機時間

第 2 章|房間溫度控制器的核心原理

2.1 房間溫度控制器(Room Temperature Controller)的定義與分類

房間溫度控制器是一種安裝在房間內部的 溫度感測與自動調節 裝置,它可以:

  • 即時測量房間溫度
  • 根據預設溫度範圍自動開啟/關閉冷氣或暖氣
  • 將溫度數據傳送到中央 BAS 主機或雲平台
  • 接收來自管理系統的遠端控制指令
控制器類型感測器通訊方式適用場景
簡易型(ON/OFF)NTC 熱敏電阻有線 DC 信號小型房間、單一溫度控制
PID 型Pt100 RTD / 熱電偶4-20mA / 0-10V辦公樓、醫院、工廠
智慧型(聯網)精密 Pt100 / NTCModbus / MQTT / REST API現代辦公、資料中心、商業綜合體
無線型Pt100 / ThermistorZigBee / LoRaWAN / Wi-Fi無法佈線的場所、臨時區域

2.2 PID 控制算法簡介

房間溫度控制器通常採用 PID(Proportional-Integral-Derivative)控制算法

🔧 PID 控制公式
u(t) = Kp * e(t) + Ki * ∫e(t)dt + Kd * de(t)/dt
                其中:
                  e(t) = 設定溫度 - 實際溫度(誤差)
                  Kp = 比例增益
                  Ki = 積分增益
                  Kd = 微分增益

PID 控制的優勢:

  • 平穩控制 — 不會導致溫度劇烈波動
  • 快速響應 — 快速達到目標溫度
  • 自適應調整 — 根據誤差自動修正

第 3 章|溫度感測器與溫度傳送器的選型

3.1 常見溫度感測器對比

感測器類型測量範圍精度響應時間成本優勢
Pt100 RTD(IEC 級)-200 ~ +850°C±0.15 ~ ±0.35°C1-3 秒中等精度高、穩定、線性好
熱電偶(K 型)-200 ~ +1372°C±2-3°C0.5-2 秒測量範圍廣、成本低
NTC 熱敏電阻-40 ~ +125°C±1-2°C0.1-1 秒極低回應快、體積小
精密 NTC(B 值誤差 <1%)-40 ~ +85°C±0.2-0.3°C0.5-1 秒成本低、精度可控

3.2 房間溫度控制的推薦方案

對於典型的辦公樓、商場、醫院場景,推薦採用 Pt100 RTD(IEC 級)或精密 NTC 熱敏電阻

✓ ATLANTIS 推薦組合 A:基礎方案
  • 感測器:ATLANTIS RTD-907A(Pt100 IEC Class A)
  • 溫度傳送器:ATLANTIS STT(4-20mA 輸出,-20 ~ +80°C)
  • 連接方式:2/3/4 線制選項,M12 防水連接器
  • 精度等級:±0.15°C @ 25°C
  • 應用:標準辦公樓、商場、醫院大廳

查詢產品詳情

✓ ATLANTIS 推薦組合 B:高精度方案
  • 感測器:ATLANTIS RTD-907A + 補償導線
  • 溫度傳送器:ATLANTIS STT(精密 0.1% 信號線性度)
  • 保護:不鏽鋼 SS304 套管
  • 輸出方式:4-20mA 或 0-10V 可選
  • 應用:資料中心、精密實驗室、精密製造廠房

查詢產品詳情

第 4 章|BAS 通訊協議與串接方案

4.1 主流 BAS 通訊協議對比

協議名稱傳輸方式通訊距離實時性適用場景
Modbus RTURS485 有線500m(中繼可延伸)高(毫秒級)工廠、多層樓宇,設備密集
Modbus TCP乙太網(TCP/IP)無限制高(毫秒級)現代樓宇、資料中心、雲整合
MQTT乙太網(TCP/IP)無限制中(秒級)IoT 應用、發布-訂閱模式、邊界計算
REST APIHTTP/HTTPS無限制中(秒級)雲平台、行動應用、跨廠商整合
ZigBee / LoRaWAN無線(2.4GHz / 868MHz)10-100m無佈線區域、臨時場景

4.2 推薦的串接架構

對於新建或改造樓宇,推薦採用 Modbus TCP(乙太網)或 MQTT + REST API 混合 架構:

🏗️ 推薦架構圖(文字表示)
┌─────────────────────────────────────────────┐
                │  樓宇管理平台(Drupal / Node.js / Django)   │  (雲端或本地)
                │         監控儀表板 / 告警 / 報表              │
                └──────────────┬──────────────┬────────────────┘
                               │              │
                        Modbus TCP      MQTT / REST API
                               │              │
                    ┌──────────┴──────────┬───┴─────────┐
                    │                     │              │
                ┌───▼─────────┐ ┌────────▼────┐  ┌─────▼────┐
                │ 網關設備     │ │ MQTT Broker │  │  API     │
                │(工業網關)   │ │ (Mosquitto) │  │ 閘道器   │
                └───┬─────────┘ └─────────────┘  └──────────┘
                    │ Modbus RTU (RS485)
                    │
                    ├──────────┬────────────┬──────────┐
                    │          │            │          │
                ┌───▼──┐ ┌───▼──┐ ┌──────▼──┐ ┌────▼──┐
                │房間  │ │房間  │ │ 走廊    │ │機房   │
                │控制1 │ │控制2 │ │控制器   │ │控制器 │
                └──────┘ └──────┘ └─────────┘ └───────┘
                   ↓        ↓         ↓          ↓
                 [感測器] [感測器] [感測器] [感測器]
                    

第 5 章|自行串接的程式碼實踐

5.1 Python + MQTT 客戶端(溫度採集)

場景說明: 在房間控制器上運行 Python 腳本,定時採集 Pt100 RTD 溫度數據,透過 MQTT 發送到中央 Broker。

📝 Python MQTT 溫度採集程式(mqtt_temp_collector.py)
#!/usr/bin/env python3
                # -*- coding: utf-8 -*-
                """
                MQTT 溫度採集器 - 用於房間溫度控制器
                適用於 Raspberry Pi、工控主機、邊界計算設備
                """
                import paho.mqtt.client as mqtt
                import time
                import json
                import logging
                from datetime import datetime
                from smbus import SMBus  # I2C 溫度感測器讀取
                # 設定日誌
                logging.basicConfig(
                    level=logging.INFO,
                    format='%(asctime)s - %(levelname)s - %(message)s'
                )
                logger = logging.getLogger(__name__)
                class MQTTTempCollector:
                    def __init__(self, broker_host, broker_port=1883, device_id="room_01"):
                        self.broker_host = broker_host
                        self.broker_port = broker_port
                        self.device_id = device_id
                        self.topic = f"atlantis/bms/{device_id}/temperature"
                        self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
                        # 設置回調函數
                        self.client.on_connect = self.on_connect
                        self.client.on_disconnect = self.on_disconnect
                        self.client.on_message = self.on_message
                        self.is_connected = False
                        self.target_temp = 22.0  # 預設目標溫度
                        self.i2c_bus = SMBus(1)  # Raspberry Pi I2C 匯流排 1
                        self.sensor_addr = 0x48  # I2C 溫度感測器地址(可調整)
                    def on_connect(self, client, userdata, flags, rc):
                        if rc == 0:
                            logger.info(f"成功連接到 MQTT Broker: {self.broker_host}")
                            self.is_connected = True
                            # 訂閱設定溫度命令
                            client.subscribe(f"atlantis/bms/{self.device_id}/set_temp")
                        else:
                            logger.error(f"連接失敗,錯誤碼: {rc}")
                    def on_disconnect(self, client, userdata, rc):
                        if rc != 0:
                            logger.warning(f"意外斷線: {rc}")
                        self.is_connected = False
                    def on_message(self, client, userdata, msg):
                        """接收遠端設定溫度命令"""
                        try:
                            payload = json.loads(msg.payload.decode())
                            self.target_temp = payload.get("temperature", 22.0)
                            logger.info(f"收到遠端溫度設定: {self.target_temp}°C")
                        except Exception as e:
                            logger.error(f"解析遠端命令出錯: {e}")
                    def read_temperature_i2c(self):
                        """從 I2C 溫度感測器讀取溫度"""
                        try:
                            # 假設使用 LM75 溫度感測器(I2C)
                            data = self.i2c_bus.read_i2c_block_data(self.sensor_addr, 0, 2)
                            raw_temp = (data[0] << 8) | data[1]
                            temperature = raw_temp >> 7  # 左移 7 位得到溫度值
                            return round(temperature * 0.5, 1)
                        except Exception as e:
                            logger.error(f"讀取溫度感測器失敗: {e}")
                            return None
                    def read_temperature_analog(self, adc_channel=0):
                        """從類比輸入(例如 ADC)讀取 Pt100 RTD 溫度"""
                        try:
                            # 使用 ADS1115 12-bit ADC 讀取 4-20mA 信號
                            # 需要另外安裝: pip install adafruit-circuitpython-ads1x15
                            import board
                            import busio
                            import adafruit_ads1x15.ads1115 as ads1115
                            i2c = busio.I2C(board.SCL, board.SDA)
                            ads = ads1115.ADS1115(i2c)
                            # 讀取 A0 通道,映射到溫度範圍
                            raw = ads.value
                            # 線性映射: 4mA (0V) → 0°C, 20mA (5V) → 100°C
                            voltage = (raw / 32767.0) * 5.0
                            temperature = ((voltage - 0.8) / 3.92) * 100
                            return round(temperature, 2)
                        except Exception as e:
                            logger.error(f"讀取類比溫度失敗: {e}")
                            return None
                    def publish_data(self):
                        """發布溫度數據到 MQTT"""
                        temp = self.read_temperature_i2c()
                        if temp is None:
                            return
                        payload = {
                            "timestamp": datetime.now().isoformat(),
                            "device_id": self.device_id,
                            "actual_temperature": temp,
                            "target_temperature": self.target_temp,
                            "status": "OK"
                        }
                        try:
                            self.client.publish(
                                self.topic,
                                json.dumps(payload),
                                qos=1,
                                retain=False
                            )
                            logger.info(f"發布數據: {temp}°C (目標: {self.target_temp}°C)")
                        except Exception as e:
                            logger.error(f"發布失敗: {e}")
                    def run(self, interval=5):
                        """啟動採集迴圈"""
                        try:
                            self.client.connect(self.broker_host, self.broker_port, keepalive=60)
                            self.client.loop_start()
                            logger.info(f"開始溫度採集,採樣間隔: {interval}秒")
                            while True:
                                if self.is_connected:
                                    self.publish_data()
                                time.sleep(interval)
                        except KeyboardInterrupt:
                            logger.info("收到停止信號,正在關閉...")
                        finally:
                            self.client.loop_stop()
                            self.client.disconnect()
                            logger.info("已斷開連接")
                # 使用範例
                if __name__ == "__main__":
                    # 替換為你的 MQTT Broker 地址
                    collector = MQTTTempCollector(
                        broker_host="192.168.1.100",
                        device_id="room_101"
                    )
                    collector.run(interval=5)  # 每 5 秒採集一次

5.2 Node.js + Express + Modbus TCP(控制器伺服器)

場景說明: 在邊界閘道器或控制伺服器上運行 Node.js,透過 Modbus TCP 與房間控制器通訊,同時提供 REST API 給上層應用。

📝 Node.js Modbus TCP 伺服器(modbus_gateway.js)
// modbus_gateway.js
                // MQTT/Modbus 整合閘道器 - 用於樓宇自動化
                const express = require('express');
                const ModbusRTU = require('modbus-serial');
                const mqtt = require('mqtt');
                const cors = require('cors');
                const app = express();
                app.use(express.json());
                app.use(cors());
                const PORT = 3000;
                const MODBUS_HOST = '192.168.1.50';  // 工控主機 IP
                const MODBUS_PORT = 502;
                const MQTT_BROKER = 'mqtt://192.168.1.100';
                // 全域狀態
                const state = {
                  devices: {},
                  connected: {
                    modbus: false,
                    mqtt: false
                  }
                };
                // Modbus RTU Master
                const master = new ModbusRTU();
                master.connectTCP(MODBUS_HOST, { port: MODBUS_PORT })
                  .then(() => {
                    console.log('Modbus TCP 已連接');
                    state.connected.modbus = true;
                  })
                  .catch(err => {
                    console.error('Modbus TCP 連接失敗:', err);
                  });
                // MQTT 用戶端
                const mqttClient = mqtt.connect(MQTT_BROKER);
                mqttClient.on('connect', () => {
                  console.log('MQTT 已連接');
                  state.connected.mqtt = true;
                  // 訂閱所有溫度數據
                  mqttClient.subscribe('atlantis/bms/+/temperature', (err) => {
                    if (err) console.error('訂閱失敗:', err);
                  });
                });
                mqttClient.on('message', (topic, message) => {
                  try {
                    const data = JSON.parse(message.toString());
                    const deviceId = data.device_id;
                    // 存儲設備狀態
                    state.devices[deviceId] = {
                      ...state.devices[deviceId],
                      actualTemp: data.actual_temperature,
                      targetTemp: data.target_temperature,
                      lastUpdate: new Date()
                    };
                    console.log(`[${deviceId}] 溫度: ${data.actual_temperature}°C`);
                  } catch (e) {
                    console.error('MQTT 訊息解析失敗:', e);
                  }
                });
                // REST API 端點
                // 1. 讀取所有設備狀態
                app.get('/api/devices', (req, res) => {
                  res.json({
                    connected: state.connected,
                    devices: state.devices
                  });
                });
                // 2. 讀取特定設備溫度(Modbus RTU)
                app.get('/api/devices/:deviceId/temperature', async (req, res) => {
                  try {
                    const { deviceId } = req.params;
                    const slaveId = parseInt(deviceId) || 1;
                    // 讀取 Modbus 暫存器 (寄存器 100: 實際溫度 * 100)
                    master.setID(slaveId);
                    const data = await master.readHoldingRegisters(100, 2);
                    const actualTemp = data.data[0] / 100;
                    const targetTemp = data.data[1] / 100;
                    res.json({
                      deviceId,
                      actualTemp: parseFloat(actualTemp.toFixed(2)),
                      targetTemp: parseFloat(targetTemp.toFixed(2)),
                      status: 'OK'
                    });
                  } catch (error) {
                    res.status(500).json({
                      error: error.message
                    });
                  }
                });
                // 3. 設定目標溫度(Modbus RTU)
                app.post('/api/devices/:deviceId/set-temperature', async (req, res) => {
                  try {
                    const { deviceId } = req.params;
                    const { temperature } = req.body;
                    const slaveId = parseInt(deviceId) || 1;
                    if (temperature < 15 || temperature > 30) {
                      return res.status(400).json({
                        error: '溫度範圍必須在 15-30°C 之間'
                      });
                    }
                    // 寫入 Modbus 暫存器 (寄存器 101: 目標溫度 * 100)
                    master.setID(slaveId);
                    await master.writeRegister(101, Math.round(temperature * 100));
                    res.json({
                      deviceId,
                      setTemp: temperature,
                      status: 'SET_OK',
                      timestamp: new Date().toISOString()
                    });
                  } catch (error) {
                    res.status(500).json({
                      error: error.message
                    });
                  }
                });
                // 4. 獲取設備詳細資訊
                app.get('/api/devices/:deviceId', (req, res) => {
                  const device = state.devices[req.params.deviceId];
                  if (!device) {
                    return res.status(404).json({ error: '設備未找到' });
                  }
                  res.json(device);
                });
                // 5. 系統健康檢查
                app.get('/api/health', (req, res) => {
                  res.json({
                    status: 'OK',
                    connected: state.connected,
                    uptime: process.uptime(),
                    timestamp: new Date().toISOString()
                  });
                });
                // 定時讀取 Modbus 數據
                setInterval(async () => {
                  if (!state.connected.modbus) return;
                  try {
                    for (let slaveId = 1; slaveId <= 4; slaveId++) {
                      master.setID(slaveId);
                      const data = await master.readHoldingRegisters(100, 2)
                        .catch(() => null);
                      if (data) {
                        state.devices[`slave_${slaveId}`] = {
                          slaveId,
                          actualTemp: data.data[0] / 100,
                          targetTemp: data.data[1] / 100,
                          lastUpdate: new Date()
                        };
                      }
                    }
                  } catch (err) {
                    console.error('Modbus 讀取迴圈錯誤:', err);
                  }
                }, 10000);  // 每 10 秒讀取一次
                app.listen(PORT, () => {
                  console.log(`\n▶ 樓宇自動化網關已啟動 | http://0.0.0.0:${PORT}`);
                  console.log(`├─ REST API: /api/*`);
                  console.log(`├─ Modbus TCP: ${MODBUS_HOST}:${MODBUS_PORT}`);
                  console.log(`└─ MQTT Broker: ${MQTT_BROKER}\n`);
                });

5.3 Arduino + Modbus RTU 從機(房間控制器韌體)

場景說明: 在 Arduino 或工控主機上實現 Modbus RTU 從機,搭配 Pt100 RTD 感測器,接收主機指令並執行溫度控制邏輯。

📝 Arduino Modbus 從機韌體(room_controller.ino)
/*
                 * 樓宇自動化房間溫度控制器 - Arduino 版本
                 * 硬體:Arduino Mega 2560 + MAX31865 RTD 驅動模組
                 * 通訊:Modbus RTU (RS485)
                 *
                 * 安裝庫:
                 *   - ArduinoModbus (官方)
                 *   - Adafruit_MAX31865 (RTD 驅動)
                 */
                #include 
                #include 
                #include "Adafruit_MAX31865.h"
                // Modbus 設置
                const int MODBUS_SLAVE_ID = 1;
                const long BAUD_RATE = 9600;
                // RTD 驅動 (SPI 接口)
                Adafruit_MAX31865 rtd = Adafruit_MAX31865(10, 11, 12, 13);  // CS, MOSI, MISO, SCK
                // 繼電器控制輸出引腳
                const int COOL_RELAY = 22;    // 冷氣繼電器
                const int HEAT_RELAY = 23;    // 暖氣繼電器
                // Modbus 暫存器
                const int HOLDING_REGISTERS_COUNT = 10;
                uint16_t holdingRegisters[HOLDING_REGISTERS_COUNT];
                // 系統狀態
                float currentTemperature = 0.0;
                float targetTemperature = 22.0;
                unsigned long lastReadTime = 0;
                const unsigned long READ_INTERVAL = 1000;  // 每 1000ms 讀取一次
                void setup() {
                  Serial.begin(BAUD_RATE);
                  // 初始化 RTD
                  if (!rtd.begin(MAX31865_3WIRE)) {
                    Serial.println("ERROR: RTD 初始化失敗!");
                    while (1) delay(100);
                  }
                  // 初始化繼電器
                  pinMode(COOL_RELAY, OUTPUT);
                  pinMode(HEAT_RELAY, OUTPUT);
                  digitalWrite(COOL_RELAY, LOW);
                  digitalWrite(HEAT_RELAY, LOW);
                  // 初始化 Modbus RTU 從機
                  if (!ModbusRTUServer.begin(MODBUS_SLAVE_ID, BAUD_RATE)) {
                    Serial.println("ERROR: Modbus 初始化失敗!");
                    while (1) delay(100);
                  }
                  // 初始化 Modbus 暫存器
                  for (int i = 0; i < HOLDING_REGISTERS_COUNT; i++) {
                    ModbusRTUServer.configureHoldingRegisters(i, 1);
                  }
                  Serial.println("樓宇自動化房間控制器已就緒");
                  Serial.print("Slave ID: ");
                  Serial.println(MODBUS_SLAVE_ID);
                }
                void loop() {
                  // 處理 Modbus 請求
                  ModbusRTUServer.poll();
                  // 定期讀取溫度
                  if (millis() - lastReadTime >= READ_INTERVAL) {
                    readTemperature();
                    lastReadTime = millis();
                  }
                  // 執行 PID 溫度控制
                  controlTemperature();
                  // 更新 Modbus 暫存器
                  updateRegisters();
                  delay(10);
                }
                void readTemperature() {
                  uint8_t fault = rtd.readFault();
                  if (fault) {
                    Serial.print("RTD 故障代碼: 0x");
                    Serial.println(fault, HEX);
                    // 故障排查
                    if (fault & MAX31865_FAULT_HIGHTHRESH) {
                      Serial.println("  ├─ 溫度超過上限");
                    }
                    if (fault & MAX31865_FAULT_LOWTHRESH) {
                      Serial.println("  ├─ 溫度低於下限");
                    }
                    if (fault & MAX31865_FAULT_RTDINLOW) {
                      Serial.println("  ├─ RTD 電阻過低(開路故障)");
                    }
                    if (fault & MAX31865_FAULT_REFIN) {
                      Serial.println("  └─ REFIN 異常(接線問題)");
                    }
                    rtd.clearFault();
                  } else {
                    currentTemperature = rtd.temperature(100.0, 430.0);
                    Serial.print("溫度: ");
                    Serial.print(currentTemperature);
                    Serial.println("°C");
                  }
                }
                void controlTemperature() {
                  float error = targetTemperature - currentTemperature;
                  const float HYSTERESIS = 0.5;  // 溫度遲滯
                  // 簡單的 ON/OFF 控制(實際應用可改為 PID)
                  if (error > HYSTERESIS) {
                    // 溫度過低,啟動暖氣
                    digitalWrite(HEAT_RELAY, HIGH);
                    digitalWrite(COOL_RELAY, LOW);
                  }
                  else if (error < -HYSTERESIS) {
                    // 溫度過高,啟動冷氣
                    digitalWrite(COOL_RELAY, HIGH);
                    digitalWrite(HEAT_RELAY, LOW);
                  }
                  else {
                    // 溫度適中,關閉兩個繼電器
                    digitalWrite(COOL_RELAY, LOW);
                    digitalWrite(HEAT_RELAY, LOW);
                  }
                }
                void updateRegisters() {
                  // 暫存器配置(Modbus 標準)
                  // Reg 100: 實際溫度 (°C * 100)
                  holdingRegisters[0] = (uint16_t)(currentTemperature * 100);
                  ModbusRTUServer.holdingRegisterWrite(0, holdingRegisters[0]);
                  // Reg 101: 目標溫度 (°C * 100)
                  targetTemperature = ModbusRTUServer.holdingRegisterRead(1) / 100.0;
                  holdingRegisters[1] = (uint16_t)(targetTemperature * 100);
                  // Reg 102: 控制狀態 (bit 0=冷氣, bit 1=暖氣)
                  uint16_t status = 0;
                  if (digitalRead(COOL_RELAY) == HIGH) status |= 0x01;
                  if (digitalRead(HEAT_RELAY) == HIGH) status |= 0x02;
                  ModbusRTUServer.holdingRegisterWrite(2, status);
                  // Reg 103: 故障狀態 (0=OK, 1=故障)
                  uint8_t fault = rtd.readFault();
                  ModbusRTUServer.holdingRegisterWrite(3, fault ? 1 : 0);
                }
                // 故障恢復函式
                void handleRTDFault() {
                  Serial.println("--- RTD 故障診斷 ---");
                  Serial.print("電阻值: ");
                  Serial.print(rtd.readRTD());
                  Serial.println(" Ω");
                  // 建議動作
                  Serial.println("排查步驟:");
                  Serial.println("1. 檢查 RTD 傳感器接線(2/3/4 線制)");
                  Serial.println("2. 確認引線是否斷開或接觸不良");
                  Serial.println("3. 檢查 MAX31865 模組電源");
                  Serial.println("4. 更換 RTD 傳感器");
                }

第 6 章|實務案例與 ROI 分析

6.1 案例一:現代辦公樓自動化改造

🏢 案例背景

一棟 15 層的現代辦公樓,共 300 間辦公室,原有的中央空調系統沒有房間級別的溫度控制, 導致多數房間溫度難以調節,員工投訴率高。管理方決定部署樓宇自動化系統。

項目改造前改造後
平均溫度波動±3-5°C±0.5-1°C
年能耗350 萬度電260 萬度電
員工滿意度62%89%
故障反應時間2-4 小時10-30 分鐘
年度節能電費
¥234 萬
減少的人員成本
¥45 萬
總投資成本
¥180 萬
ROI 週期
9.2 個月

核心方案: 每間房間安裝 ATLANTIS RTD-907A 溫度感測器 + STT 溫度傳送器, 透過 Modbus TCP 連接到中央 BAS 網關,實現房間級別的溫度調節和遠端監控。

6.2 案例二:資料中心冷卻系統監控

🖥️ 案例背景

某大型互聯網公司的資料中心,運行 500+ 台服務器,冷卻系統由 20 台冷卻塔和冷凍水系統組成。 原先依靠人工巡檢,導致某次冷卻水溫度異常未被及時發現,導致服務中斷。

監控點位感測器類型數量安裝成本
冷卻進水溫度Pt100 RTD8¥8,000
冷卻回水溫度Pt100 RTD8¥8,000
機房環境溫度精密 NTC12¥6,000
冷凍水壓力壓力傳感器6¥12,000
避免的停機損失
¥500 萬
年度節能效益
¥180 萬
系統總投資
¥60 萬
投資回報年限
1.5 個月

第 7 章|常見問題與故障排查

7.1 溫度偏差過大(±2°C 以上)

❓ Q1: 為什麼房間溫度總是比設定溫度高或低 2°C 以上?

+

常見原因及排查方法:

  1. 感測器精度問題
    • 使用校準套裝驗證感測器精度
    • 確保使用 IEC Class A 或更高的 Pt100 RTD
    • 檢查感測器補償導線是否完整
  2. 安裝位置不當
    • 感測器應遠離熱源(空調出風口、陽光直射)
    • 最佳位置是房間中央,離地 1.2-1.5m 高度
    • 避免接近外牆和玻璃窗
  3. PID 參數不當
    • 調整 Kp、Ki、Kd 參數
    • 增加 Ki 可加快收斂速度
    • 增加 Kd 可減少超調
  4. 冷暖氣執行器滯後
    • 確認風閥開度是否完全
    • 檢查風管是否堵塞
    • 確認冷凍水 / 熱水流量

❓ Q2: RTD 感測器顯示 "-999°C" 或其他異常值是什麼情況?

+

故障診斷流程:

症狀可能原因解決方案
讀值為 -999°C感測器開路檢查接線,確保連接器接觸良好
讀值跳變接觸不良或干擾重新插拔連接器,遠離高頻設備
讀值恆定不變傳感器失效或感應端損傷更換感測器

❓ Q3: Modbus 通訊經常超時是什麼原因?

+

排查步驟:

  1. 檢查網路連通性:ping 192.168.1.50
  2. 確認 Modbus 埠號(預設 502 或 502 以上)
  3. 檢查防火牆規則是否阻斷
  4. 降低輪詢頻率,增加超時時間
  5. 確認 RS485 接線是否正確(A、B、GND)

❓ Q4: 多間房間溫度控制不同步,如何調試?

+

常見原因:

  • 不同房間的感測器精度不一致 → 統一更換為同一型號
  • 控制器軟體版本不同 → 更新到最新版本
  • 冷暖氣分佈流量不均 → 調整各風閥開度
  • 環境負荷差異大 → 對不同房間調整 PID 參數

❓ Q5: 如何選擇 2 線制、3 線制還是 4 線制 RTD?

+

對比與建議:

連接方式導線數精度成本適用場景
2 線制2低(引線阻抗影響)最低簡易應用、<10m 距離
3 線制3中(部份補償)標準應用、<50m 距離
4 線制4高(完全補償)較高高精度、長距離應用

建議: 樓宇自動化應優先採用 3 線制或 4 線制 Pt100, 配合 ATLANTIS RTD-907A 和補償導線,確保精度。

🏆 ATLANTIS 樓宇自動化完整推薦方案

✓ 完整系統套裝
  • 感測器模組: RTD-907A(Pt100 IEC Class A)×N
  • 信號轉換: STT 溫度傳送器(4-20mA / 0-10V)×N
  • 連接方式: M12 防水連接器、2/3/4 線制選項
  • 通訊整合: Modbus RTU / TCP / MQTT / REST API
  • 配件: 不鏽鋼 SS304 保護套管、補償導線
  • 應用範疇: 辦公樓、商場、醫院、工廠、資料中心
  • 核心優勢: 高精度(±0.15°C)、長期穩定性、防爆認證可選、免費技術支援

📞 聯絡業務團隊 - Ian(業務一部) 📞 聯絡業務團隊 - Nori(業務二部)

結論

樓宇自動化是現代建築管理的必然趨勢,房間溫度控制器作為整個系統的基層傳感和控制單元, 其選型和安裝質量直接影響整個系統的效能。透過本文的詳細講解,你應該已經了解:

  • BAS 系統的核心構成和優勢
  • 房間溫度控制器的工作原理和分類
  • 感測器選型的決策矩陣
  • 主流通訊協議的對比與應用
  • 自行串接的完整程式碼實踐
  • 實務案例中的 ROI 分析
  • 常見故障的診斷與排查方法

下一步行動: 如果你的企業正在規劃樓宇自動化項目,ATLANTIS 提供從感測器選型、 系統設計、工程實施到售後維護的完整方案。歡迎與我們的業務團隊聯絡, 根據你的具體需求定製最優解決方案。

準備開始你的樓宇自動化項目?

ATLANTIS 擁有 31 年工業儀器製造經驗,提供業界領先的溫度測量和控制解決方案。

🎯 立即詢價 - 獲取免費評估報告 

業務一部 (Ian) | 業務二部 (Nori)
re-atlantis.tw | © 2026 ATLANTIS Co., Ltd.