LPC824 TMP102温度センサー

トラ技のmbedライブラリの作成方法の勉強会資料を参考にTMP102温度センサーを使ってみる。

作成したサンプルライブラリ

https://os.mbed.com/users/yasubumi/code/test_TMP102/

参考リンク

「トラ技_mbedライブラリの作成方法の勉強会」資料

TMP102センサーの情報ページ
上記リンクの古い基板を使ってます。

TMP102データシート

TMP102結線サンプル

回路作成

結線サンプルを元にブレッドボード上に回路を作成する。左に見えるLEDは通電確認用。
/media/uploads/yasubumi/tmp102.jpg

接続方法は以下
TMP102 <-> LPC824
GND <-> GND
V+ <-> Vout(3.3V)
SDA <-> dp4
SCL <-> dp5
ADD0 <-> GND

動作確認

まずは、既存のライブラリで動くか確認する。

#include "mbed.h"
#include "TMP102.h"

TMP102 temp(dp4, dp5, 0x91);

int main() {
    while(1) {
        printf("Temp: %f\n\r", temp.read());
        wait(1.0);
    }
}

動作確認できました。センサを指で触れると温度が上がります。
/media/uploads/yasubumi/tmp102_run1.png

基本動作の検証

回路の動作確認ができたので、既存のモジュールを外してベタのコードで基本動作の確認をしていきます。

#include "mbed.h"

// TMP102 I2C slave address(ADD0 connected to GND)
#define ADDR_TMP102     0x90

// TMP102 registers
#define TMP102_Temp     0x00
#define TMP102_Conf     0x01
#define TMP102_Tlow     0x02
#define TMP102_Thigh    0x03

// Init I2C (SDA: dp4, SCL: dp5)
I2C i2c(dp4, dp5);

int main() {
    while(1) {
        i2c.write(ADDR_TMP102, 0x00, 1); //Pointer to the temperature register

        char reg[2]={0,0};
        i2c.read(ADDR_TMP102, reg, 2); // read two bytes data

        // calculate temperature
        int16_t res = ((int8_t)reg[0] << 4) | ((uint8_t)reg[1] >> 4);
        float temp = (float) ((float)res * 0.0625);

        printf("Temp: %f\n\r", temp);
        wait(1.0);
    }
}

mbedでのI2Cのスレーブアドレス
まずここではまった。コードでいうと4行目
mbedのI2Cアドレス仕様が一般的でない模様。
通常のスレーブアドレスは7bit (+Read/Write判別が1bit)なのだが、mbedではスレーブアドレスを8bitで指定して、最下位1bitは無視される(?)っぽい。
TMP102のデータシートを見ると、ADD0をGNDに接続した場合のスレーブアドレスは2進数で「1001000」(7桁)なので、これをHEXに直すと0x48となる。でもこの値をスレーブアドレスとしてもデータが受信できなかった。
mbedでのI2C通信向けスレーブアドレスには、最下位ビットを追加して「10010000」or「10010001」とする必要がある。これらをHEXに直すと0x90 or 0x91となる。アドレスをこれらに書き換えたらデータ取得できるようになった。(90と91はどちらにしても通信可能)
2017/11/19ここまで。温度を計算している部分は既存モジュールの計算式コピペなので、次回ビット演算の意味を確認しよう。

温度計算部 以下2017/11/25
読み込んだデータをビット演算して温度を求めている部分を理解。
まず、TMP102の温度データ構造は12bit。それを8bit 2回に分けて取り込んでいる。(コード20行目)
上位8bitはそのまま、下位4bitはその下に4bit付けた8bitにして出力されるので、これを元の12bitデータに戻す操作をしているのがコードの23行目。
((int8_t)reg[0] << 4)で上位8bitを4bit繰り上げて12bit化
((uint8_t)reg[1] >> 4)で下位8bitを4bit繰り下げて4bit化
これらの論理和を取って、上位8bitと下位4bitを合体。で、それを16bit整数resとして保存してる。
なるほど

上記で元の出力データが作れたので、0.0625をかけて温度(℃)に変換してあげれば完了(コード24行目)

クラス化

C++とオブジェクト指向プログラミングの知識が必要ずら。もう忘れたよ。。

初期化リスト
コンストラクタの後ろにくっつけてメンバ変数を初期化できるやつ。なんで必要なのかググったけど書いてある意味が分からない。まだ先は長い。
まずはクラス化して動くようになったので良しとしよう。

最適化

スレーブアドレス違いに備えてコンストラクタにスレーブアドレスを渡せるようにする。
そういえばコンストラクタは複数の宣言を書けるんだったか。

解説追加

コメントを/**から*/で書くと自動で解説に変換してくれる。
詳しくは公式の解説
書いたコメントを解説に変換するには、コンパイルボタンにある「ドキュメントをアップデート」ボタン。

サンプルコード中のコメントは//で書けばサンプルコードにも残る。


Please log in to post comments.