2026年8月16日 星期日

MAX485_DS18B20 溫度檢知器屋外發射端程式碼:

 

//MAX485_DS18B20 溫度檢知器屋外發射端程式碼:

#include <SoftwareSerial.h>

#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>

#define DE_RE 2    //DE & RE 合併線接 Arduino 第D2(數位Digital)腳
#define ONE_WIRE_BUS 3   //DS18B20黃線(H.C.C)
#define RO_PIN 7   // 屋外不接收,此腳可不接
#define DI_PIN 8   // 接屋外 MAX485 的 DI 腳

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
SoftwareSerial RS485Serial(RO_PIN, DI_PIN); // 屋外改用軟體序列埠

void setup() {
  Serial.begin(9600);       // 用於電腦除錯
  RS485Serial.begin(9600);  // 用於 RS485 傳輸
 
  pinMode(DE_RE, OUTPUT);
  digitalWrite(DE_RE, LOW); // 預設接收狀態
  sensors.begin();
  Serial.println("屋外發射端啟動...");
}

void loop() {
  sensors.requestTemperatures();
  float tempC = sensors.getTempCByIndex(0);
 
  if (tempC != DEVICE_DISCONNECTED_C) {
    // 輸出到電腦畫面(除錯用)
    Serial.print("目前溫度: ");
    Serial.println(tempC);
   
    // 切換為發射模式
    digitalWrite(DE_RE, HIGH);
    delay(5); // 等待硬體穩定
   
    // 傳送資料(注意:必須用 println 才會送出 \n 換行符)
    RS485Serial.print("T:");
    RS485Serial.print(tempC, 2);
    RS485Serial.println(":C");
   
    // 等待資料完全送出後,切回接收模式
    delay(20);
    digitalWrite(DE_RE, LOW);
  } else {
    Serial.println("⚠️ 錯誤:找不到 DS18B20 感測器!");
  }
  delay(2000);
}

MAX485_DS18B20 溫度檢知器室內接收端程式碼:

 

//MAX485_DS18B20溫度檢知器 室內接收端 (Arduino B)

#include <SoftwareSerial.h>

#define RO_PIN 10   // 接室內 MAX485 的 RO 腳 (耳朵)
#define DI_PIN 11   // 接室內 MAX485 的 DI 腳 (懸空不接)
#define DE_RE  4    // 控制室內 MAX485 的 DE/RE 短路端

// 建立軟體序列埠,命名為 RS485Serial
SoftwareSerial RS485Serial(RO_PIN, DI_PIN);

void setup() {
  Serial.begin(9600);      // 開啟連接電腦的序列埠
  RS485Serial.begin(9600); // 開啟連接 50 米長線的虛擬序列埠
 
  pinMode(DE_RE, OUTPUT);
  digitalWrite(DE_RE, LOW); // 室內機專職「接收監聽」,永久保持低電位
 
  Serial.println("=========================================");
  Serial.println("  室內監控主機:50米長距離溫度系統已就緒  ");
  Serial.println("=========================================");
}

void loop() {
  // 檢查 50 米長線緩衝區是否有屋外傳來的資料
  if (RS485Serial.available() > 0) {
   
    // 讀取一行字串 (直到讀到屋外送來的 \n 換行符為止)
    String inputData = RS485Serial.readStringUntil('\n');
   
    // 去除字串前後可能因為線路雜訊產生的空白字元
    inputData.trim();
   
    // 【長途傳送資料校验機制】
    // 檢查收到的字串長度是否足夠,且開頭必須是 'T',結尾必須是 'C'
    if (inputData.length() >= 7 && inputData.startsWith("T:") && inputData.endsWith(":C")) {
     
      // 擷取中間的溫度數值(剃除掉 "T:" 與 ":C")
      // "T:25.43:C" -> 擷取索引 2 到倒數第 2 個字元之間的內容
      String tempStr = inputData.substring(2, inputData.length() - 2);
     
      // 將字串安全地轉換成浮點數
      float outdoorTemp = tempStr.toFloat();
     
      // 輸出正確解析的即時數據到電腦螢幕上
      Serial.print("🏡 屋外即時溫度: ");
      Serial.print(outdoorTemp);
      Serial.println(" °C");
     
    } else {
      // 如果 50 米線路受到外在電磁干擾(如屋外雷擊、日光燈突波),字串會變形,直接丟棄不處理
      Serial.println("⚠️ [警告] 50米線路偵測到雜訊突波,已自動過濾毀損封包。");
    }
  }
}