近接センサーを簡単に安く作れないかと思案していたとき家電の赤外線リモコンを壁に向けても使えることを思い出した。もしかしたら反射型の近接センサーが作れるんじゃね?と早速実験してみたところ...大成功!!
以外に感度も良くて50センチ程度なら安定して反応してくれるしより距離を稼ぐには発光部から受光部への赤外線の回り込みを抑え込む必要があるが1メートル越えもいけそうな感じだ。
【動作の様子】
【部品】
赤外線リモコン受信モジュール GP1UXC41QS
3mm赤外線LED 940nm OSI5FU3A11C
市販されている近接(距離)センサーは消費電流も比較的大きいものばかりだが近接を検出するだけならこちらの方法のほうがより安く低消費電力な物が作れるはず。
回路は、PWM(38KHz)出力によりLEDを直接駆動していて、受光部が一番感度良く反応するよう約1msの発光と約25msの休止期間を繰り返しながら受光部の反応を確認している。
距離が短くて良いならLEDの電流制限抵抗(R2)を大きくして発光を弱くするとより安定して使いやすくなる。
ちなみに近くで家電のリモコンを操作しても影響が出ないようにしたつもり。
【Arduino Pro Micro 用のサンプルスケッチ】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#define DATA 0xFF #define LED PB0 #define IRIN PB5 #define IROUT PB6 #define TOFF 25 // ms static uint8_t count; static uint8_t mask; static uint8_t data; static volatile uint8_t detected; ISR(TIMER0_COMPA_vect) { if (count == 0) { if ((mask >>= 1) == 0) mask = 0x80; if (DATA & mask) DDRB |= _BV(IROUT); } else if (count == 1) { data <<= 1; if (!(PINB & _BV(IRIN))) data |= 1; if (mask == 1) detected = (data == DATA); DDRB &= ~_BV(IROUT); } if (++count == TOFF) count = 0; } void setup() { /* timer interrupt (16MHz=1.024ms) */ TCCR0A = 0; // standard mode OCR0A = 0; TIFR0 |= _BV(OCF0A); TIMSK0 |= _BV(OCIE0A); /* PWM(38KHz) -> PB6 */ TCCR1B = 0; TCNT1 = 0; OCR1B = (ICR1 = (F_CPU / 1) / 38000) >> 1; TCCR1A = _BV(COM1B1) | _BV(WGM11); TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // x1; } void loop() { if (detected) PORTB &= ~_BV(LED); else PORTB |= _BV(LED); } |