# MLX90614 非接觸式紅外測溫感測器

<figure><img src="https://1275793585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LaZQFBYOS3O0ksiEmR1%2Fuploads%2FqJKovbqNGJeVG1W1O0W3%2Fimage.png?alt=media&#x26;token=3f6c64cd-1895-47ab-8efc-b652d03e332d" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %} <mark style="color:red;">**注意：本感測器不能用於醫療目的。**</mark>
{% endhint %}

### **MLX90614 非接觸式紅外測溫感測器電路圖**

* Raspberry Pi Pico W
* Raspberry Pi Pico W 擴充板
* MLX90614 非接觸式紅外測溫感測器

{% hint style="success" %}
*<mark style="color:$warning;">**MLX90614 非接觸式紅外測溫感測器是I2C訊號輸入。本範例之模組SDA腳位需接至Raspberry Pi Pico擴充板D4腳位，模組SCL腳位需接至Raspberry Pi Pico擴充板D5腳位。**</mark>*
{% endhint %}

<figure><img src="https://1275793585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LaZQFBYOS3O0ksiEmR1%2Fuploads%2FxhdUGZArTFAaB3tlal3V%2Fimage.png?alt=media&#x26;token=0d7ce4ca-91cc-49c1-94f9-0bc415cabb09" alt="" width="471"><figcaption></figcaption></figure>

### **Arduino 程式如下**

```
#include <Wire.h>

// 讀取 MLX90614 溫度
// scale: 0 = 攝氏, 1 = 華氏, 2 = 絕對溫標 (K)
// compensation: 溫度補償值
// addr: I2C 位址 (預設 0x5A)
// obj: 暫存器位址 (0x07 = 物體溫度, 0x06 = 環境溫度)
float getMLX90614(byte scale, float compensation, uint8_t addr, uint8_t obj) {
  // 先寫入要讀的暫存器位址
  Wire.beginTransmission(addr);
  Wire.write(obj);
  // 使用 repeated start，不釋放 bus
  if (Wire.endTransmission(false) != 0) {
    // 傳輸失敗，回傳 NaN
    return NAN;
  }

  // 要求讀取 3 個 byte：Low, High, PEC
  if (Wire.requestFrom((int)addr, 3) != 3) {
    // 沒拿到 3 個 byte，回傳 NaN
    return NAN;
  }

  int data_low  = Wire.read();
  int data_high = Wire.read();
  int pec       = Wire.read();   

  // 組合原始值 (最高 bit 是 flag，用 0x7F 遮掉)
  double val = (double)(((data_high & 0x7F) << 8) + data_low);

  // MLX90614: Temp(K) = raw * 0.02
  const double factor = 0.02;
  float kelvin = (val * factor) - 0.01;
  float celcius = kelvin - 273.15;
  float fahrenheit = (celcius * 1.8) + 32.0;

  if (scale == 0)      // 攝氏
    return celcius + compensation;
  else if (scale == 1) // 華氏
    return fahrenheit + compensation;
  else if (scale == 2) // 絕對溫標 K
    return kelvin + compensation;

  // 預設回傳攝氏
  return celcius + compensation;
}

void setup() {
  Serial.begin(115200);

  // 指定 Pico W 上的 I2C 腳位：
  // SDA -> D4, SCL -> D5
 // Wire.setSDA(D4);
 // Wire.setSCL(D5);
  Wire.begin();         // 啟動 I2C
  // 如果要強制 100k，可加：Wire.setClock(100000);

  delay(500);
  Serial.println("Pico W + MLX90614 test (SDA=D4, SCL=D5)");
}

void loop() {
  // 讀物體溫度（攝氏），位址 0x5A，暫存器 0x07
  float tC = getMLX90614(0, 0, 0x5A, 0x07);

  Serial.print("Object Temp = ");
  Serial.print(tC);
  Serial.println(" *C");

  delay(500);  // 每 0.5 秒讀一次
}

```

### **程式執行結果**

在序列埠監控視窗會顯示MLX90614 非接觸式紅外測溫感測器所測量到物體溫度（Object Temp）單位為攝氏（°C），並每 0.5 秒更新一次，數字會依環境或手靠近而微幅變動。。

<figure><img src="https://1275793585-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LaZQFBYOS3O0ksiEmR1%2Fuploads%2FFeW3SRgB6DINfFxH0btG%2Fimage.png?alt=media&#x26;token=cb7441c8-4702-4aa2-aba2-ce3b8e6a6869" alt="" width="419"><figcaption></figcaption></figure>
