Help us understand the problem. What is going on with this article?

Raspberry Pi 2 Model B でI2C 照度センサーモジュール(BH1750)を使う

More than 5 years have passed since last update.

概要

Raspberry pi 2 Model B (Raspbian)での aitendo M1750-5P(BH1750使用 照度センサーモジュール) 設定覚書き


参考

参考にしました、ありがとうございます。


センサーモジュール接続

ここのピンアウト表を参照しました。今回は、1,3,5,9ピンを使用し設定します。
ADDRピンに0.7VCC以上流すとI2Cアドレスが、0x23から0x5Cになります。
ADDRピンは、1Kの抵抗を通ってGNDに繋がっているようです。他のデバイスと重なってないので、接続なし(0x23)で使用します。参照
 ADDR = ‘H’ ( ADDR ≧ 0.7VCC ) の時 “1011100“
 ADDR = 'L' ( ADDR ≦ 0.3VCC ) の時 “0100011“

image

センサーモジュール設定情報

説明書を読んでみます。
シェルスクリプトでも簡単に使用できるRaspberryPiで使いやすいセンサーモジュールだと思います。

説明書が分かり易いので、そのままなのですが、命令一覧になります。

image

1回測定でしたら、電源をオンにし測定命令を与え、測定時間を待ち、結果を取得すればよいようです。
取得した結果は、以下の計算式で計算します。

H-resolution mode 時 1count あたりの照度 = 1 / 1.2 *( 69 / X )
H-resolution mode2時 1count あたりの照度 = 1 / 1.2 *( 69 / X ) / 2
1.2 : 測定確度
69 : MTregの初期値(10進表記)
X :MTregの値

入力光減衰補正機能(感度補正機能)があり、測定時間設定レジスタ(Mtreg)の値を変更することによって利用できます。
感度をN倍にする場合、測定時間もN倍されます。

31〜254の範囲で、初期値は69です。
上の表を参照し、設定したい感度の上位3ビットを"01000"のあとに付与して8ビットを構成し、感度の下位5ビットを"011"のあとに付与して8ビットを構成し設定します。

例えば、感度2倍なら69の倍で138なので、2進表記で"1000_1010"になります。
それを、上位3ビット(100)と下位5ビット(01010)に分け、上記の構成を実施すると、"0100_0100"と"0110_1010"になります。

H-resolution mode2は、10lx 以下の照度検出に適したモードのようです。


センサーモジュール設定手順

SPI有効

SPI有効
$ sudo raspi-config

「8 Advanced Options」 → 「A6 SPI」 → 「SPI enable」

I2C有効

I2C有効
$ sudo raspi-config

「8 Advanced Options」 → 「A7 SPI」 → 「I2C enable」

I2Cモジュール設定

I2Cモジュール読み込み設定
$ sudo nano /etc/modules
snd-bcm2835
i2c-dev

I2Cライブラリインストール

I2Cライブラリインストール
$ sudo sudo apt-get install libi2c-dev

gitインストール

gitインストール
$ sudo apt-get install git-core

アップデート

アップデート
$ sudo apt-get update
$ sudo apt-get upgrade

WiringPiインストール

WiringPiインストール
$ git clone git://git.drogon.net/wiringPi
$ cd wiringPi
$ ./build

ライブラリパス設定

ライブラリパス追加設定
$ sudo nano /etc/ld.so.conf
$ sudo ldconfig
include /etc/ld.so.conf.d/*.conf
/usr/local/lib

センサーモジュールアドレス確認

たぶん、0x23だと思います。

アドレス確認
$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --

再起動

再起動
$ sudo reboot

サンプルコード

このサンプルコードは、1回測定のものです。
シェルスクリプトが上手くできてませんでした。修正しました。
まずは、シェルスクリプトでデータ取得できることを確認します。

bh1750_sample.sh
#!/bin/bash

sudo i2cset -y 1 0x23 0x01 c
sleep 1

sudo i2cset -y 1 0x23 0x20 c
sleep 1

TMP=$(sudo i2cget -y 1 0x23 0x00 w)
MSB="0x$(echo $TMP | cut -c 5-6)"
LSB="0x$(echo $TMP | cut -c 3-4)"
IL=$(((MSB<<8)|LSB))

printf "Illuminance: %.2f lx\n" $(echo "scale=2;$IL / 1.2" | bc)

exit 0

Cでのサンプルコードです。
気になるとこや間違いなどあればコメントいただけると助かります。

bh1750_sample.c
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#define BH1750_ADDRESS              0x23    // SECOND ADDRESS 0x53

#define BH1750_POWER_DOWN           0x00
#define BH1750_POWER_ON             0x01
#define BH1750_RESET                0x07
#define BH1750_CONTINUE_H_RESOLUTION_MODE   0x10
#define BH1750_CONTINUE_H_RESOLUTION_MOD2   0x11
#define BH1750_CONTINUE_L_RESOLUTION_MODE   0x13
#define BH1750_ONETIME_H_RESOLUTION_MODE    0x20
#define BH1750_ONETIME_H_RESOLUTION_MOD2    0x21
#define BH1750_ONETIME_L_RESOLUTION_MODE    0x23
#define BH1750_MTREG                69  // DEFAULT 69 (31 - 254)
#define BH1750_MODE_DIV             1   // MODE2 2
#define BH1750_WAIT_TIME            150 // ms

int main(void) {

    int fd;
    int ret;

    unsigned char set_value[1];
    unsigned char result[2];

    int lData;

    fd = wiringPiI2CSetup(BH1750_ADDRESS);

    // Power On
    if((wiringPiI2CWrite(fd, BH1750_POWER_ON)) < 0) {
        printf("error: power on\n");
    }

    usleep(1000);

    // Set Configuration
    set_value[0] = BH1750_ONETIME_H_RESOLUTION_MODE;
    ret = write(fd, set_value, 1);
    if (ret < 0) {
        printf("error: set configuration value\n");
        return 1;
    } 

    usleep(BH1750_WAIT_TIME * 1000);

    // Get Value
    ret = read(fd, result, 2);
    if (ret < 0) {
        printf("error: read value\n");
        return 1;
    }

    lData = result[0] << 8;
    lData |= result[1];
    printf("Illuminace: %.2f\n", lData / 1.2 * (69 / BH1750_MTREG) / BH1750_MODE_DIV);

    return 0;
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away