秋月電子通商で扱っているフォトリフレクタTPR-105Fを使ってみました。 秋月では以下の2種類を扱っています。
DAとDBの何が違うのかAIに聞いてみると 「反射型フォトセンサのDAランクとDBランクの違いは、 主に検出距離と検出精度にあります。DAランクは一般的に検出距離が短く、 精度もDBランクに比べて低い傾向があります。一方、DBランクは検出距離が長く、より高精度な検出が可能です。」 とのことです。値段も同じなのDBを使っておけば良いと思います。
TPR-105Fは縦2.7mm、横3.2mmの小さな部品です。

光を出す発光素子と、光を受信する受光素子を持っています。 光を反射する物体(白紙)に近づけると、反射した光を受光し、 光を吸収する物体(黒紙)に近づけると、光を受光できなくなります。

TPR-105Fの仕様書はこちらにあります。

次のpdfのように、白から黒のテストパターンを印刷して準備します。 ただし、インクジェットプリンタではダメでレーザープリンターで印刷します。 インクジェットプリンタでは黒に反応しませんでした。

上の回路の出力をArduinoのA/D変換に接続して電圧を測定します。

センサーと紙の距離は5mm、10mm、15mmを実験しました。距離が短くても長くて感度が悪くなります。 離し過ぎると白を感知できなくなります。近過ぎると黒が検知しずらくなります。 調度良い距離を探さないとなりません。
下の表は、センサーと紙の距離を変えて、黒の濃さの違う所をタッチして A/D変換器の値を直接読んだ値です。5mmではGRB0, RGB:50, RGB:102は675,360,46 と区別できる値して認識できます。しかし、それ以上に薄いと白と変わらなくなってしまいます。 白と黒を判断するならば、5mmでも使うことができます。 10mmでは色の濃さに応じて中間の値が出ることがわかります。 色の濃さを判断したいのであれば、10mmくらいが最適であることがわかります。 15mmも離してしまうと、黒、白を判断できなくなります。
| 黒 | 白 | |||||
| 距離\RGB | 0 | 50 | 102 | 154 | 206 | 255 |
|---|---|---|---|---|---|---|
| 5mm | 675 | 360 | 46 | 35 | 30 | 26 |
| 10mm | 902 | 621 | 300 | 135 | 42 | 38 |
| 15mm | 929 | 922 | 902 | 771 | 645 | 556 |
ただし、センサーにはばらつきがあり、最適値は実験に使ったセンサーに寄るところが大きい可能性があります。
以下の動画は、ArduinoのA/D変換の情報をMIDIに変換して、 Control Change Monitorで表示した動画です。 このグラフは白がY軸上で大きな値に、黒がY軸上ゼロに近い値に表示されます。 センサーと紙の距離は5mmです。上の表にあるように、距離が5mmですのでRGB:154は白に(Y軸上で上に張り付いている)識別されます。
ArduinoはPro Micro
センサーと紙の距離は5mmの時のA/D変換器の最大値と最小値のをMIDIの0x00〰︎0x7Fにアサインします。
#include "MIDIUSB.h"
#define White_Vol 26
#define Black_Vol 675
int a3;
uint8_t rxb=0;
void setup() {
Serial.begin(115200);
}
void loop() {
float fa3;
uint8_t rx3;
midiEventPacket_t CC = {0x0B, 0xB0, 0x01, 0x00}; //CC=1
a3=analogRead(A3);
fa3 = (float)(a3-White_Vol)/(Black_Vol-White_Vol);
if(fa3≥1.0) fa3=1.0;
else if(fa3<0.0) fa3=0.0;
rx3 = (uint8_t)(fa3*0x7F);
if(rx3!=rxb){ //値に変化があった時だけMIDIを送信する
Serial.println(a3);
CC.byte3 = 0x7F-rx3; //黒だと値が小さく、白だと大きい
MidiUSB.sendMIDI(CC);
rxb=rx3;
}
}