Arduino UNO R4 Minimaでセンサ・インターフェーシング ㉚ 光センサ LTR303

 Adafruitから周辺光センサ LTR303(Lite-On)を利用します。

AdafruitのStemma QT/Qwiicボード

 LTR303ボード解説のページ

 Stemma QT/Qwiic(JST SH 4ピン)コネクタは2か所に装着されていて、どちらにつないでもかまいません。このコネクタを使ってI2Cで制御する場合、特に、ジャンパ線をつなぐなどは不要です。

 コネクタは、表と裏のどちらも差し込めそうですが、ピンが内部の上部に並んでいるので、差し込める方向は一意です。ロック機構はないですが、すぐに抜けるということはありません。

光センサLTR303のおもなスペック

 LTR303のデータシート

  • 動作電圧 2.4~3.6V
  • 動作温度範囲  -30~70°C
  • 測定可能範囲 0.01~64000Lux
  • インターフェース I2C(1~400kHz)
  • スレーブ・アドレス 0x29

使用環境

  • Arduino UNO R4 Minima
  • Arduino IDE 2.2.1
  • Windows10 22H2

接続

 Arduino UNO R4 MinimaのI2C信号とセンサ・ボードをJSTコネクタでつなぎます(Stemma QT/Qwiicボードの写真の比率は異なる)。

スレーブ・アドレスを確認

 従来からよく使われているi2cScanner.inoを動かしてスレーブ・アドレスを確認します。電源は3.3Vです。

  0x29を見つけてきました。

 


ライブラリの用意

 LTR303で検索して、見つかった  Adafruit LTR329 and LTR303ライブラリをインストールします。

 インストールを始めたとき、関連のライブラリや依存関係をインストールするかというパネルが出た場合は、全てをインストールを選びます。


サンプル・スケッチ①

 メニューのファイル->スケッチ例から、Adafruit LTR329 and LTR303のltr303_simpletset.inoを選択します。

  コンパイル、実行します。

 

 光センサLTR303には、CH0とCH1の二つのセンサが搭載されていて、それぞれ、最大感度の波長が次の図のように異なります(データシートから転載)。

サンプル・スケッチ②

 メニューのファイル->スケッチ例から、Adafruit LTR329 and LTR303のltr303_advanced_test.inoを選択します。

  setup{}の最初に、1行追加します。

void setup() {
  Serial.begin(115200);
  while (!Serial)  delay(10); // wait for serial port to open
 
 コンパイル、実行します。
 以降のスケッチは、このサンプルを修正しながら作っていきます。

4桁の7セグメントLED表示器をつないで測定結果を表示する

 連載の第4回目の記事を参照しながら表示器を接続します。

Arduino UNO R4 Minimaでセンサ・インターフェーシング ④ 温湿度センサSi7021の測定結果を7セグメントLEDに表示


 スケッチです。

 7セグメントLED表示器は、第12回 温湿度センサ SHTC3でスレーブ・アドレスが重なったので、デフォルトの0x70から、ジャンパのA0をショートして0x71に変更してあります。デフォルトのまま使うときは0x70で使ってください。


/***************************************************
  This is an example for the LTR303 light sensor that reads both channels
  and demonstrates how to set gain, interrupts and check data validity
  Designed specifically to work with the LTR-303 light sensor from Adafruit
  ----> https://www.adafruit.com/product/5610
 ****************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_LTR329_LTR303.h" Adafruit_7segment matrix = Adafruit_7segment(); Adafruit_LTR303 ltr = Adafruit_LTR303(); void setup() { Serial.begin(115200); while (!Serial) delay(10); // wait for serial port to open Serial.println("Adafruit LTR-303 advanced test + 7segment LED"); if ( ! ltr.begin() ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); } Serial.println("Found LTR sensor!"); ltr.setGain(LTR3XX_GAIN_96); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } // The LTR-303 has interrupt output support, we can enable the pin output! ltr.enableInterrupt(true); // The INT pin also has a polarity setting. For active LOW set to 'false', // for active HIGH set to 'true' ltr.setInterruptPolarity(false); // Then set the low threshold (values BELOW this trigger an interrupt) ltr.setLowThreshold(2000); // and set the high threshold (values ABOVE this trigger an interrupt) ltr.setHighThreshold(30000); Serial.print("Thresholds: "); Serial.print(ltr.getLowThreshold()); Serial.print(" & "); Serial.println(ltr.getHighThreshold()); // Finally, default is an interrupt on every value that is under/over the // threshold ranges. However, you're more likely to get spurious IRQs, so // we can set it to require "N counts in a row" before an IRQ. 1 count is // IRQ for each reading, 2 count means we need two outside readings in a row, etc // up to 16. ltr.setIntPersistance(4); Serial.print("Consecutive counts for IRQ: "); Serial.println(ltr.getIntPersistance()); matrix.begin(0x71); matrix.setBrightness(0x05); // default 0x0E } void loop() { bool valid; uint16_t visible_plus_ir, infrared; if (ltr.newDataAvailable()) { valid = ltr.readBothChannels(visible_plus_ir, infrared); if (valid) { Serial.print("CH0 Visible + IR: "); Serial.print(visible_plus_ir); Serial.print("\t\tCH1 Infrared: "); Serial.println(infrared); matrix.print(visible_plus_ir, DEC); matrix.writeDisplay(); delay(2000); matrix.print(infrared, DEC); matrix.writeDisplay(); delay(2000); } } delay(100); }

 実行例です。

グラフィック・ディスプレイに測定結果を表示

 次の記事を参考に、グラフィック・ディスプレイに測定した明るさを表示します。

  Arduino UNO R4 Minimaでセンサ・インターフェーシング ⑤ 温湿度センサSi7021の測定結果をグラフィック・ディスプレイに表示

 スケッチです。


/***************************************************
  This is an example for the LTR303 light sensor that reads both channels
  and demonstrates how to set gain, interrupts and check data validity
  Designed specifically to work with the LTR-303 light sensor from Adafruit
  ----> https://www.adafruit.com/product/5610
 ****************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "Adafruit_LTR329_LTR303.h" #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_LTR303 ltr = Adafruit_LTR303(); void setup() { Serial.begin(115200); while (!Serial) delay(10); // wait for serial port to open Serial.println("Adafruit LTR-303 advanced test + ssd1306"); if ( ! ltr.begin() ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); } Serial.println("Found LTR sensor!"); ltr.setGain(LTR3XX_GAIN_96); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } // The LTR-303 has interrupt output support, we can enable the pin output! ltr.enableInterrupt(true); // The INT pin also has a polarity setting. For active LOW set to 'false', // for active HIGH set to 'true' ltr.setInterruptPolarity(false); // Then set the low threshold (values BELOW this trigger an interrupt) ltr.setLowThreshold(2000); // and set the high threshold (values ABOVE this trigger an interrupt) ltr.setHighThreshold(30000); Serial.print("Thresholds: "); Serial.print(ltr.getLowThreshold()); Serial.print(" & "); Serial.println(ltr.getHighThreshold()); // Finally, default is an interrupt on every value that is under/over the // threshold ranges. However, you're more likely to get spurious IRQs, so // we can set it to require "N counts in a row" before an IRQ. 1 count is // IRQ for each reading, 2 count means we need two outside readings in a row, etc // up to 16. ltr.setIntPersistance(4); Serial.print("Consecutive counts for IRQ: "); Serial.println(ltr.getIntPersistance()); display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); display.clearDisplay(); display.drawRect(0, 0, display.width(), display.height(), SSD1306_WHITE); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(SSD1306_WHITE); // Draw white text display.setCursor(3,3); display.println("CH0 Visible + IR:"); display.setCursor(4,34); display.println("CH1 Infrared: "); display.display(); delay(200); } void loop() { bool valid; uint16_t visible_plus_ir, infrared; if (ltr.newDataAvailable()) { valid = ltr.readBothChannels(visible_plus_ir, infrared); if (valid) { Serial.print("CH0 Visible + IR: "); Serial.print(visible_plus_ir); Serial.print("\t\tCH1 Infrared: "); Serial.println(infrared); display.setTextColor(SSD1306_WHITE); // Draw white text display.setTextSize(2); // Draw 2X-scale text display.setCursor(10,17); display.fillRect(10, 17, 70, 16, SSD1306_BLACK); display.println(visible_plus_ir); display.setCursor(10, 46); display.fillRect(10, 46, 100, 16, SSD1306_BLACK); display.println(infrared); display.display(); } } delay(1000); }

 実行例です。
 

前へ

Arduino UNO R4 Minimaでセンサ・インターフェーシング ㉙ 光センサ TSL2591

次へ

Arduino UNO R4 Minimaでセンサ・インターフェーシング ㉛ 近接センサ VCNL4040