I used an infrared LED as transmitter and IR TV-like receiver module. Both parts are available at RadioSchack. The IR waves emitted by the LED reflect from an object and are caught by the receiver. The IR LED emits 940nm wavelength, has radiant power output 16mW at 100ma (max 1.2A), forward voltage 1.2V, and viewing angle to 1/2 intensity 45°. The IR receiver module has passband 950nm±50nm and supply voltage and current of 2.4-5.5V and 0.6ma (under no signal output), respectively.
The IR receiver module is actually a pretty complicated device. It has a maximum sensitivity not to a steady IR signal, but to a one modulated by 38KHz. It contains filters to filter out 38KHz carrier and considers everything else as a noise and ignores those signals. The reception range is rated by 46.2' (approx. 13m). However, this is the case when the module receives a direct waveform transmitted by a remote control unit. In our application the module receives a reflected waveform which reduces its range to about a feet. To minimize errors in signal detection the voltage powering the module must be very good filtered out. The transistor along with the cap and resistor on the schematic do the job.
Therefore, we have to form a 38KHz waveform and direct it to the LED. The 38KHz frequency corresponds to approx. 26μsec period. Out of those 26μsec the IR LED must alternate its on/off state every 13μsec. This is achieved in a program by a loop consisting of 13 instructions. Each instruction that does not modify the PC (program counter) takes 1μsec, otherwise it takes 2μsec. This is true by running the PIC from internal 4MHz oscillator. The schematics is simple and the layout is straightforward and not shown here. We form a package of 10 pulses (the upper oscillogram) and then wait for a considerable time letting the receiver module process the reflected signals. It takes some time indicated by the bottom oscillogram. The horizontal speed of the oscilloscope is 50μsec/div, so it takes about 105μsec for the receiver module to process the reflection. Once a signal is detected, the module output becomes low. Another consequence from these oscillograms is that the IR receiver needs about 250μsec to recover and setting its output high after a signal detection.
At each iteration of the wave-forming loop we also check the output of the IR receiver module. If it gets low, the counter of received pulses increments on 1. If after sending a package of 10 pulses the counter value is 2 or higher, a signal detection is reported and the red LED connected to RC0 gets on. The values 10 and 2 are determined experimentally to achieve a reliable detection. A moving robot equipped with such sensor will get a number of single reflections per package from various objects, which should be ignored. We report detection of an obstacle only if the reflected waveform appears for a considerable time (during at least two 38KHz periods, which is 20% of the pulse sending cycle). In the program, however, the number of received pulses is compared against 4 because we check the IR receiver output during each of 20 half-periods.
The code is as follows:
TITLE "ir1.asm" ; working with TV IR remote
List P=PIC16F684, R=DEC
INCLUDE "p16f684.inc"
; data segment
CBLOCK 0x20
del ; variable used for delay
pulse, pulses2Send, pulsesReceived
ENDC
; code segment
PAGE
__CONFIG _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF &
_CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
org 0 ; start program at the beginning of mem
bcf STATUS, RP0 ; activate BANK 0
clrf PORTC ; initialize PORT C
movlw 0x07
movwf CMCON0 ; comparators OFF
bsf STATUS, RP0 ; change to BANK 1
clrf ANSEL ^ 0x80 ; make all inputs digital
bcf TRISC ^ 0x80, 5 ; enable RC5 for output
bcf TRISC ^ 0x80, 0 ; enable RC0 for output
bcf STATUS, RP0 ; back to BANK 0
clrf pulse ; start with IR pulse value 0
loop
movlw 10
movwf del
call delay ; 50 msec delay
clrf pulsesReceived
movlw 20
movwf pulses2Send
send_pulses
goto $+1
goto $+1
btfss PORTC, 4 ; is there IR reflected waveform?
incf pulsesReceived, f
movlw b'100000'
xorwf pulse, w ; compose a new pulse value
movwf pulse
movwf PORTC ; output the new pulse value
decfsz pulses2Send, f
goto send_pulses ; end of a 26 cycle (38KHz=26.3mksec)
movlw 4
subwf pulsesReceived, w ; C=1 if more than 2 pulses received
movf PORTC, w
andlw 0xFE
btfsc STATUS, C
iorlw 1 ; turn on LED
movwf PORTC
goto loop ; endless loop
; procedures
delay ; a delay for del milliseconds
movlw 200
sublw 1 ; this loop takes 5us*200 = 1ms
sublw 0 ; for PIC16F684 @ 4 Mhz
btfss STATUS, Z
goto $-3
decfsz del, f
goto delay
return
end