本篇示範在樹莓派 Raspberry Pi 中以 C 語言抓取 HTU21D 溫度與濕度感測器的資料,自己打造物聯網溫濕度計。

HTU21D 是一個同時可以測量溫度與溼度的感測器,樹莓派或 Arduino 等開發板可透過 i2c 傳輸協定讀取上面的資料,在物聯網(IOT)的應用中可以很方便結合其他的設備,實現智慧居家與自動控制。


這是我手上的兩個 MEAS HTU21D 溫度與濕度感測器,其溫度的誤差直是 ±0.3℃,而相對濕度的誤差值則為 ±2%。

MEAS HTU21D 溫度與濕度感測器

這個感測器是好久以前買的,現在才拿出來使用。

MEAS HTU21D 溫度與濕度感測器

以下我們示範在樹莓派上安裝 HTU21D 溫濕度感測器,並且讀取其中的量測資料。

安裝 HTU21D 溫濕度感測器

Step 1
將 HTU21D 插在麵包板上,再用杜邦線連接樹莓派。

MEAS HTU21D 溫度與濕度感測器

HTU21D 在使用上就跟一般的 i2c 設備一樣,用杜邦線接上樹莓派對應的針腳即可,這是簡單的接線圖。

接線圖

接好線之後,就可以繼續進行軟體上的設定了。

MEAS HTU21D 溫度與濕度感測器與樹莓派

Step 2

使用 raspi-config 的管理選單,啟用核心的 i2c 模組:

sudo raspi-config

Step 3
選擇「Interfacing Options」。

Step 4
選擇「I2C」。

Step 5
選擇「Yes」啟用 I2C 介面。

Step 6
安裝 i2c 相關工具的套件:

sudo apt-get install i2c-tools

Step 7
偵測 i2c 設備:

sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

正常的話在 0x40 的位置應該會出現 40,這樣就表示 HTU21D 已經可以正常透過 i2c 傳輸資料了。

讀取 HTU21D 溫度與濕度資料

接下來我們要透過 i2c 讀取 HTU21D 感測器的資料,在開發程式之前,請先詳讀 HTU21D 的 datasheet,如果您在程式碼中看到一些奇怪的數值,通常都可以在 datasheet 中找到說明。

C 語言版本

以下是使用 C 語言讀取 HTU21D 感測器資料的程式碼:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#include "wiringPi.h"
#include "wiringPiI2C.h"

#define   HTU21D_I2C_ADDR 0x40

#define   HTU21D_TEMP     0xF3
#define   HTU21D_HUMID    0xF5

// 取得溫度(攝氏)
double getTemperature(int fd) {
    unsigned char buf [4];

    // 送出測量溫度指令
    wiringPiI2CWrite(fd, HTU21D_TEMP);

    // 等待 0.1 秒
    delay(100);

    // 讀取資料
    read(fd, buf, 3);

    // 根據 datasheet 的說明,將資料轉換為攝氏溫度
    unsigned int temp = (buf [0] << 8 | buf [1]) & 0xFFFC;
    return -46.85 + 175.72 * temp / 65536.0;
}

// 取得濕度(相對濕度)
double getHumidity(int fd) {
    unsigned char buf [4];

    // 送出測量濕度指令
    wiringPiI2CWrite(fd, HTU21D_HUMID);

    // 等待 0.1 秒
    delay(100);

    // 讀取資料
    read(fd, buf, 3);

    // 根據 datasheet 的說明,將資料轉換為相對濕度
    unsigned int humid = (buf [0] << 8 | buf [1]) & 0xFFFC;
    return -6.0 + 125.0 * humid / 65536.0;
}

int main () {
    wiringPiSetup();
    int fd = wiringPiI2CSetup(HTU21D_I2C_ADDR);
    if ( 0 > fd ) {
        fprintf (stderr, "Unable to open I2C device: %sn", strerror (errno));
        exit (-1);
    }
    printf("Temp: %5.2f Cn", getTemperature(fd));
    printf("Humid: %5.2f %%n", getHumidity(fd));
    return 0;
}

將這段 C 程式碼儲存為 htu.c,接著使用 gcc 編譯:

gcc -o htu -lwiringPi htu.c

使用 sudo 取得 root 權限執行:

sudo ./htu

輸出為:

Temp: 23.16 C
Humid: 55.49 %

Leon Anavi 有將他寫好的 C 語言程式碼放在 GitHub 網站上,這裡的 HTU21D 範例程式碼就是參考他的版本修改而來的,而他的 GitHub 網站上還有非常多其他物聯網應用的範例程式碼,推薦大家可以上去看看。

參考資料:adafruitRaspberry Piinstructables