#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 秒讀一次
}