Skip to main content

Grove - デジタル光センサー

note

この文書は AI によって翻訳されています。内容に不正確な点や改善すべき点がございましたら、文書下部のコメント欄または以下の Issue ページにてご報告ください。
https://github.com/Seeed-Studio/wiki-documents/issues

このモジュールは、光強度をデジタル信号に変換するためのI2C光-デジタルコンバーターTSL2561をベースにしています。従来のアナログ光センサー(例:Grove - Light Sensor)とは異なり、このデジタルモジュールは赤外線と全スペクトルの2つの光感知ダイオードを備えているため、選択可能な光スペクトル範囲を特徴としています。

3つの検出モードを切り替えて測定を行うことができます。それらは赤外線モード、全スペクトルモード、人間の目に見えるモードです。人間の目に見えるモードで動作している場合、このセンサーは目で感じるのに近い測定値を提供します。

バージョン

製品バージョン変更点リリース日
Grove - Digital Light Sensor V1.1初期版2015年10月

産業用センサーへのアップグレード可能性

SenseCAP S2110コントローラーS2100データロガーを使用することで、Groveを簡単にLoRaWAN®センサーに変換できます。Seeedはプロトタイピングを支援するだけでなく、SenseCAPシリーズの堅牢な産業用センサーを使用してプロジェクトを拡張する可能性も提供します。

SenseCAP S210xシリーズの産業用センサーは、環境センサーとしての即時使用体験を提供します。光強度検出において高性能かつ堅牢なS2102ワイヤレス光強度センサーをご参照ください。このシリーズには、土壌水分、空気温度と湿度、光強度、CO2、EC、8-in-1気象ステーション用センサーが含まれています。次の成功する産業プロジェクトには最新のSenseCAP S210xをお試しください。

SenseCAP 産業用センサー
S2102 Light

特徴

  • 選択可能な検出モード
  • 400 kHz I2C ファストモードでの高解像度16ビットデジタル出力
  • 広いダイナミックレンジ:0.1 - 40,000 LUX
  • 広い動作温度範囲:-40°C ~ 85°C
  • ユーザー定義の上限および下限しきい値設定が可能なプログラム可能な割り込み機能
  • I2C アドレス:0x29
note

複数の I2C デバイスを使用したい場合は、ソフトウェア I2Cを参照してください。

tip

Grove モジュールの詳細については、Grove システムを参照してください。

仕様

項目最小値典型値最大値単位
電源電圧, VDD3.355.1V
動作温度-30\ 70
SCL,SDA 入力低電圧-0.5\ 0.8V
SCL,SDA 入力高電圧2.3\ 5.1V

対応プラットフォーム

ArduinoRaspberry Pi
caution

上記で対応していると記載されているプラットフォームは、モジュールのソフトウェアまたは理論的な互換性を示しています。ほとんどの場合、Arduino プラットフォーム向けのソフトウェアライブラリまたはコード例のみを提供しています。すべての可能な MCU プラットフォーム向けにソフトウェアライブラリやデモコードを提供することはできません。そのため、ユーザー自身でソフトウェアライブラリを作成する必要があります。

ハードウェア概要

U1: TSL2561 IC、光-デジタル変換器。以下は機能ブロック図です。

  • レジスタマップ

    TSL2561は、シリアルインターフェースを介してアクセスされる16個のレジスタ(うち3つは予約済み)とコマンドレジスタによって制御および監視されます。これらのレジスタはさまざまな制御機能を提供し、ADC変換の結果を確認するために読み取ることができます。レジスタセットの概要は以下の通りです。

  • スペクトル応答曲線

デジタル光センサーの2つのチャンネルは異なる応答特性を持っています。そのため、両方をオンにするか、片方をオフにすることで動作モードを選択できます。

U3: XC6206MR332 IC、正電圧レギュレータ。

Q1,Q2: BSN20 IC、Nチャネルエンハンスメントモード垂直D-MOSトランジスタ。

SCL,SDA: I2C信号インターフェース

はじめに

note

Arduinoを初めて使用する場合は、開始前にArduinoの使い方をご覧になることを強くお勧めします。

Arduinoで遊ぶ

ハードウェア

  • ステップ1. 以下のものを準備してください:
Seeeduino V4ベースシールドGrove - デジタル光センサー
今すぐ購入今すぐ購入今すぐ購入
  • ステップ2. Grove - デジタル光センサーをベースシールドのI2Cポートに接続します。
  • ステップ3. ベースシールドをArduinoに差し込みます。
  • ステップ4. USBケーブルを使用してArduinoをPCに接続します。

ソフトウェア

  • ステップ1. こちらからライブラリをダウンロードしてください:Digital Light Sensor Library;
  • ステップ2. Arduinoライブラリのインストール方法の手順に従ってライブラリをインストールしてください。
  • ステップ3. 以下のパスからコードを直接開きます:File -> Example ->Digital_Light_Sensor->Digital_Light_Sensor
  • または、以下のコードをIDEにコピーしてArduinoにアップロードしてください。
/*
Digital_Light_Sensor.ino
TSL2561用ライブラリ

著作権 (c) 2012 seeed technology inc.
作成者: zhangkun
作成日時:
変更履歴:

MITライセンス (MIT)

このソフトウェアおよび関連文書ファイル(以下「ソフトウェア」)のコピーを取得するすべての人に対し、
無償で使用、コピー、変更、結合、公開、配布、サブライセンス、または販売する権利を許可します。
ただし、以下の条件を満たす必要があります:

上記の著作権表示および本許可表示は、ソフトウェアのすべてのコピーまたは重要な部分に含まれるものとします。

ソフトウェアは「現状のまま」提供され、明示的または黙示的な保証はありません。
商品性、特定目的への適合性、および非侵害性を含むがこれに限定されない保証も含まれません。
著者または著作権者は、ソフトウェアまたはその使用またはその他の取引に関連して発生する
いかなる請求、損害、またはその他の責任についても責任を負いません。
*/

#include <Wire.h>
#include <Digital_Light_TSL2561.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
TSL2561.init();
}

void loop()
{
Serial.print("光の値は: ");
Serial.println(TSL2561.readVisibleLux());
delay(1000);
}
  • ステップ4. シリアルモニターを開いて結果を確認します。

Raspberry Piで遊ぶ

ハードウェア

  • ステップ1. 以下のものを準備してください:
Raspberry PiGrovePi_PlusGrove - デジタル光センサー
今すぐ購入今すぐ購入今すぐ購入
  • 手順に従って開発環境を構成してください。
  • Groveケーブルを使用してセンサーをGrovePi+のI2Cソケットに接続します。

ソフトウェア

caution

Raspberry Pi OS >= Bullseye を使用している場合は、Python3 のみでこのコマンドラインを使用する必要があります。

  • ステップ 1. Setting Software に従って開発環境を構成します。

  • ステップ 1. デモのディレクトリに移動します:

cd yourpath/GrovePi/Software/Python/grove_i2c_digital_light_sensor/
  • ステップ 2. コードを確認する:
nano grove_i2c_digital_light_sensor.py  # "Ctrl+x" で終了 #
#!/usr/bin/python
# TSL2561 I2C Light-To-Digital converter library for the Raspberry Pi.
# データシート: https://www.adafruit.com/datasheets/TSL2561.pdf
#
# このライブラリは Cedric Maion の作業に基づいています https://github.com/cmaion/TSL2561
#
# センサーに関するフォーラムディスカッションは http://www.dexterindustries.com/topic/greehouse-project/ を参照してください

from time import sleep
import smbus
from Adafruit_I2C import Adafruit_I2C
import RPi.GPIO as GPIO
from smbus import SMBus

TSL2561_Control = 0x80
TSL2561_Timing = 0x81
TSL2561_Interrupt = 0x86
TSL2561_Channel0L = 0x8C
TSL2561_Channel0H = 0x8D
TSL2561_Channel1L = 0x8E
TSL2561_Channel1H = 0x8F

TSL2561_Address = 0x29 # デバイスアドレス

LUX_SCALE = 14 # 2^14 でスケール
RATIO_SCALE = 9 # 2^9 でスケール比
CH_SCALE = 10 # 2^10 でチャネル値をスケール
CHSCALE_TINT0 = 0x7517 # 322/11 * 2^CH_SCALE
CHSCALE_TINT1 = 0x0fe7 # 322/81 * 2^CH_SCALE

K1T = 0x0040 # 0.125 * 2^RATIO_SCALE
B1T = 0x01f2 # 0.0304 * 2^LUX_SCALE
M1T = 0x01be # 0.0272 * 2^LUX_SCALE
K2T = 0x0080 # 0.250 * 2^RATIO_SCALE
B2T = 0x0214 # 0.0325 * 2^LUX_SCALE
M2T = 0x02d1 # 0.0440 * 2^LUX_SCALE
K3T = 0x00c0 # 0.375 * 2^RATIO_SCALE
B3T = 0x023f # 0.0351 * 2^LUX_SCALE
M3T = 0x037b # 0.0544 * 2^LUX_SCALE
K4T = 0x0100 # 0.50 * 2^RATIO_SCALE
B4T = 0x0270 # 0.0381 * 2^LUX_SCALE
M4T = 0x03fe # 0.0624 * 2^LUX_SCALE
K5T = 0x0138 # 0.61 * 2^RATIO_SCALE
B5T = 0x016f # 0.0224 * 2^LUX_SCALE
M5T = 0x01fc # 0.0310 * 2^LUX_SCALE
K6T = 0x019a # 0.80 * 2^RATIO_SCALE
B6T = 0x00d2 # 0.0128 * 2^LUX_SCALE
M6T = 0x00fb # 0.0153 * 2^LUX_SCALE
K7T = 0x029a # 1.3 * 2^RATIO_SCALE
B7T = 0x0018 # 0.00146 * 2^LUX_SCALE
M7T = 0x0012 # 0.00112 * 2^LUX_SCALE
K8T = 0x029a # 1.3 * 2^RATIO_SCALE
B8T = 0x0000 # 0.000 * 2^LUX_SCALE
M8T = 0x0000 # 0.000 * 2^LUX_SCALE

K1C = 0x0043 # 0.130 * 2^RATIO_SCALE
B1C = 0x0204 # 0.0315 * 2^LUX_SCALE
M1C = 0x01ad # 0.0262 * 2^LUX_SCALE
K2C = 0x0085 # 0.260 * 2^RATIO_SCALE
B2C = 0x0228 # 0.0337 * 2^LUX_SCALE
M2C = 0x02c1 # 0.0430 * 2^LUX_SCALE
K3C = 0x00c8 # 0.390 * 2^RATIO_SCALE
B3C = 0x0253 # 0.0363 * 2^LUX_SCALE
M3C = 0x0363 # 0.0529 * 2^LUX_SCALE
K4C = 0x010a # 0.520 * 2^RATIO_SCALE
B4C = 0x0282 # 0.0392 * 2^LUX_SCALE
M4C = 0x03df # 0.0605 * 2^LUX_SCALE
K5C = 0x014d # 0.65 * 2^RATIO_SCALE
B5C = 0x0177 # 0.0229 * 2^LUX_SCALE
M5C = 0x01dd # 0.0291 * 2^LUX_SCALE
K6C = 0x019a # 0.80 * 2^RATIO_SCALE
B6C = 0x0101 # 0.0157 * 2^LUX_SCALE
M6C = 0x0127 # 0.0180 * 2^LUX_SCALE
K7C = 0x029a # 1.3 * 2^RATIO_SCALE
B7C = 0x0037 # 0.00338 * 2^LUX_SCALE
M7C = 0x002b # 0.00260 * 2^LUX_SCALE
K8C = 0x029a # 1.3 * 2^RATIO_SCALE
B8C = 0x0000 # 0.000 * 2^LUX_SCALE
M8C = 0x0000 # 0.000 * 2^LUX_SCALE

# バスパラメータ
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
bus = smbus.SMBus(1)
else:
bus = smbus.SMBus(0)
i2c = Adafruit_I2C(TSL2561_Address)

debug = False
cooldown_time = 0.005 # 秒単位で測定
packageType = 0 # 0=T パッケージ, 1=CS パッケージ
gain = 0 # 現在のゲイン: 0=1x, 1=16x [動的に選択]
gain_m = 1 # 現在のゲイン(倍率として)
timing = 2 # 現在の積分時間: 0=13.7ms, 1=101ms, 2=402ms [動的に選択]
timing_ms = 0 # 現在の積分時間(ms単位)
channel0 = 0 # 可視+赤外センサーの現在の生値
channel1 = 0 # 赤外センサーの現在の生値
schannel0 = 0 # 可視+赤外センサーの正規化された現在値
schannel1 = 0 # 赤外センサーの正規化された現在値

def readRegister(address):
try:
byteval = i2c.readU8(address)

sleep(cooldown_time)
if (debug):
print("TSL2561.readRegister: returned 0x%02X from reg 0x%02X" % (byteval, address))
return byteval
except IOError:
print("TSL2561.readRegister: error reading byte from reg 0x%02X" % address)
return -1


def writeRegister(address, val):
try:
i2c.write8(address, val)

sleep(cooldown_time)
if (debug):
print("TSL2561.writeRegister: wrote 0x%02X to reg 0x%02X" % (val, address))
except IOError:

sleep(cooldown_time)
print("TSL2561.writeRegister: error writing byte to reg 0x%02X" % address)
return -1

def powerUp():
writeRegister(TSL2561_Control, 0x03)

def powerDown():
writeRegister(TSL2561_Control, 0x00)

def setTintAndGain():
global gain_m, timing_ms

if gain == 0:
gain_m = 1
else:
gain_m = 16

if timing == 0:
timing_ms = 13.7
elif timing == 1:
timing_ms = 101
else:
timing_ms = 402
writeRegister(TSL2561_Timing, timing | gain << 4)

def readLux():
sleep(float(timing_ms + 1) / 1000)

ch0_low = readRegister(TSL2561_Channel0L)
ch0_high = readRegister(TSL2561_Channel0H)
ch1_low = readRegister(TSL2561_Channel1L)
ch1_high = readRegister(TSL2561_Channel1H)

global channel0, channel1
channel0 = (ch0_high<<8) | ch0_low
channel1 = (ch1_high<<8) | ch1_low

sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: channel 0 = %i, channel 1 = %i [gain=%ix, timing=%ims]" % (channel0, channel1, gain_m, timing_ms))

def readVisibleLux():
global timing, gain

powerUp()
readLux()

if channel0 < 500 and timing == 0:
timing = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Increasing integration time from 13.7ms to 101ms")
setTintAndGain()
readLux()

if channel0 < 500 and timing == 1:
timing = 2
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Increasing integration time from 101ms to 402ms")
setTintAndGain()
readLux()

if channel0 < 500 and timing == 2 and gain == 0:
gain = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: too dark. Setting high gain")
setTintAndGain()
readLux()

if (channel0 > 20000 or channel1 > 20000) and timing == 2 and gain == 1:
gain = 0
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Setting low gain")
setTintAndGain()
readLux()

if (channel0 > 20000 or channel1 > 20000) and timing == 2:
timing = 1
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Reducing integration time from 402ms to 101ms")
setTintAndGain()
readLux()

if (channel0 > 10000 or channel1 > 10000) and timing == 1:
timing = 0
sleep(cooldown_time)
if debug:
print("TSL2561.readVisibleLux: enough light. Reducing integration time from 101ms to 13.7ms")
setTintAndGain()
readLux()

powerDown()

if (timing == 0 and (channel0 > 5000 or channel1 > 5000)) or (timing == 1 and (channel0 > 37000 or channel1 > 37000)) or (timing == 2 and (channel0 > 65000 or channel1 > 65000)):
# overflow
return -1

return calculateLux(channel0, channel1)

def calculateLux(ch0, ch1):
chScale = 0
if timing == 0: # 13.7 msec
chScale = CHSCALE_TINT0
elif timing == 1: # 101 msec
chScale = CHSCALE_TINT1;
else: # assume no scaling
chScale = (1 << CH_SCALE)

if gain == 0:
chScale = chScale << 4 # scale 1X to 16X

# scale the channel values
global schannel0, schannel1
schannel0 = (ch0 * chScale) >> CH_SCALE
schannel1 = (ch1 * chScale) >> CH_SCALE

ratio = 0
if schannel0 != 0:
ratio = (schannel1 << (RATIO_SCALE+1)) / schannel0
ratio = (ratio + 1) >> 1

if packageType == 0: # T package
if ((ratio >= 0) and (ratio <= K1T)):
b=B1T; m=M1T;
elif (ratio <= K2T):
b=B2T; m=M2T;
elif (ratio <= K3T):
b=B3T; m=M3T;
elif (ratio <= K4T):
b=B4T; m=M4T;
elif (ratio <= K5T):
b=B5T; m=M5T;
elif (ratio <= K6T):
b=B6T; m=M6T;
elif (ratio <= K7T):
b=B7T; m=M7T;
elif (ratio > K8T):
b=B8T; m=M8T;
elif packageType == 1: # CS package
if ((ratio >= 0) and (ratio <= K1C)):
b=B1C; m=M1C;
elif (ratio <= K2C):
b=B2C; m=M2C;
elif (ratio <= K3C):
b=B3C; m=M3C;
elif (ratio <= K4C):
b=B4C; m=M4C;
elif (ratio <= K5C):
b=B5C; m=M5C;
elif (ratio <= K6C):
b=B6C; m=M6C;
elif (ratio <= K7C):
b=B7C; m=M7C;

temp = ((schannel0*b)-(schannel1*m))
if temp < 0:
temp = 0;
temp += (1<<(LUX_SCALE-1))
# strip off fractional portion
lux = temp>>LUX_SCALE
sleep(cooldown_time)
if debug:
print("TSL2561.calculateLux: %i" % lux)

return lux

def init():
powerUp()
setTintAndGain()
writeRegister(TSL2561_Interrupt, 0x00)
powerDown()

def main():
init()
while (True):
print("Lux: %i [Vis+IR=%i, IR=%i @ Gain=%ix, Timing=%.1fms]" % (readVisibleLux(), channel0, channel1, gain_m, timing_ms))
sleep(1)

if __name__ == "__main__":
main()
  • ステップ 3. デモを実行します。
sudo python3 grove_i2c_digital_light_sensor.py
  • ステップ 4. 結果は以下の通りです。

回路図オンラインビューア

リソース

プロジェクト

Seeed LoRa IoTea ソリューション: 茶畑に適用される自動情報収集システムです。これは、インテリジェント農業情報収集の一部です。

Intel Edison IoT ハイドロポニックコントローラー: ボストン IoT ハッカソンで Intel Edison を使用して作成された IoT 対応のハイドロポニックコントローラーです。

COI - 光透過率計: Grove スターターキットプラスに含まれる光センサーを使用して光強度の変化を測定する完成品です。

技術サポート & 製品ディスカッション

弊社製品をお選びいただきありがとうございます!製品の使用体験がスムーズになるよう、さまざまなサポートを提供しています。異なる好みやニーズに対応するため、いくつかのコミュニケーションチャネルを用意しています。

Loading Comments...