Main Page
|
Course Admin
|
Contest Rules
|
Project Resources
|
Team Info
|
Picture Gallery
|
Contact Info
 
  You are here: RoboTag Main Page > Project Resources > Technical > Infrared Beacon


Infrared Beacon

The infrared beacon is a critical part of the RoboTag project and is easily the most important aspect of the competition. This document details the design and construction of a PIC-based infrared beacon that will detect up to seven other beacons within 1/10th of a second. The beacons work within line-of-sight, don't detect their own signal, and don't interfere with most commercially available IR navigation sensors.

This document is broken down into the following sections:



Introduction and Design Objectives

One of the most challenging aspects of the RoboTag project is the detection of other robots. How does a robot know where to aim the tagging device? How does a predator hunt down a prey? How does the prey escape? Obviously there needs to be a method of detecting other robots.

It would be extremely difficult for robots to detect each other without active communication. Sure, a predator could stay still and use a motion detector to 'watch' the surroundings, but who's to say that they prey couldn't also sit still? Other detection methods like vision systems, heat detectors, and etc, would be much too difficult to implement for this course.

So each robot needs to emit a signal, and each robot needs to be able to detect a signal. The design objectives are as follows:

  • robots must be able to detect signals from up to 7 other robots
  • robots must be able to detect signals within 1/10th of a second
  • robots must not detect their own signal
  • the signal should only work within line-of-sight
  • the signal must be detectable from 3 inches to 12 feet
  • the signal must not interfere with any other sensor
Therefore we can't use RF signals (they would penetrate the arena walls) and visible light signals would interfere with the tagging device and lights in the room (was I tagged, or is that another robot flashing at me?). An infrared signal was identified as our best bet.



Infrared Light & Associated Problems

Infrared radiation lies between the visible and microwave portions of the electromagnetic spectrum. We'll be using a detector that has peak sensitivity at a wavelength of 940nm, so we'll use IR LEDs that emit at 940nm.

However, there are a number of problems with an infrared signal:

  • a number of robots are using infrared navigation sensors
  • fluorescent lights, the sun, cameras, etc, emit large amounts of IR
  • infrared signals 'bounce' off surfaces
    • (which is how IR navigation sensors work)

It's important to use modulated IR light to avoid interference from other IR sensors and from lights, the sun, etc. For example, if we were using plain infrared light (ie: we emitted light at 940nm), it would be very difficult to determine the difference between another robot or a desk lamp. Modulated IR is commonly used in IR navigation sensors.

To avoid conflicting with IR navigation sensors, we will be modulating our infrared signal at 56.8kHz. Since we're interfacing with digital devices (and we're not doing any mixing, filtering, etc), we'll use a square-wave signal. So our modulated IR signal would look something like this:

There's still the problem of infrared signals bouncing off the arena walls, which is difficult to address. If we use a material that doesn't reflect infrared light then the IR navigation sensors won't work. The solution? There isn't really one. Even slowly moving robots wouldn't see an infrared reflection from another robot for very long, so it won't be too bad.

Robots which do see the reflection of another robot's beacon can obviously use this to their advantage. The scenario above shows the robot on the right seeing the signal from the robot on the left (and vice versa). Remember that both robots won't be able to tell whether or not the other robot is in the original location, or the mirrored location (shown in red).



The Technical Specification

The technical specification is based around the design objectives of the beacon:

  • robots must be able to detect signals from up to 7 other robots
  • robots must be able to detect signals within 1/10th of a second
  • robots must not detect their own signal
  • the signal should only work within line-of-sight
  • the signal must be detectable from 3 inches to 12 feet
  • the signal must not interfere with any other sensor
In the previous section we addressed the interference and line-of-sight requirements of the design.

When building the specification it was important to consider the number of other robots that must be detected, and the time in which the detection must occur. I used the 0.1 second detection time based on the average reaction time of a human -- if we can react to something within 100msec, then our robots should be able to do the same.

Having each beacon be able to detect 7 other beacons means that we can have eight robots playing at a time! That was the maximum number of 'bots that I could imagine in one 12'x12' arena. "Pandemonium" just isn't accurate enough.

It was also important to ensure that a robot wouldn't be able to detect its own beacon. Because the beacons reflect off the arena walls it is important to turn off the beacon detector when emitting the beacon signal. This works perfectly with the non-multitasking PIC microprocessor which can only perform one task at a time anyway.

In regards to the detection range, I recommend multiple high-output IR LEDs (like the one I recommend later in this document) driven with 50-100mA. While the continuous rating on the LEDs is only 50mA, you could probably drive them at 2A without much problem. Remember our 6.25ms bursts of IR are modulated, so the LED wouldn't be on for very long. In my lab tests, I've detected another beacon at 12'+ with as little as 60mA of LED current.

So the technical specification of the beacon is as follows:

  • consecutively, each beacon must:
    • emit 6.25ms of modulated infrared light
      • 940nm light modulated at ~56.8kHz (55.5kHz is okay)
      • emitted 360-degrees around the robot
        (minimum of 50% beam power in any direction)
      • must be detectable at 12+ feet with a standard device (50+mA/LED)
    • looks for infrared light from another robot
        (for N blocks of 6.25ms each, N is assigned by course coordinator)
    • emit 6.25ms of modulated infrared light (as spec'd above)
    • looks for infrared light from another robot
        (for 14-N blocks of 6.25ms each)
    • repeat the process

But this means that when the beacon is transmitting, it won't detect other beacons that are also transmitting. (ie: the beacon can't 'talk' and 'listen' at the same time) One way around this problem would be to synchronize the beacons to start at the same time. This, however, is a real pain in the ass, so we'll use a timing solution instead.

The timing solution (shown below) works if you consider the following worst-case scenario. Assume all eight robots are within line-of-sight of each other. Assume that, by luck, the first 6.25ms pulse of infrared light occurs at the same time. By changing the time between pulses (ie: each robot waits a different amount of time before sending out another pulse), we can ensure that each robot will detect ALL the others, within 100ms.

This can be shown in a chart form as follows:


The coloured blocks indicate when the particular robot is transmitting, and the white blocks indicate when the robot is 'looking'.

The above chart shows each robot transmitting from 0 to 6.25ms, then 'looking' for a differing amount of time before transmitting another 6.25ms pulse. This allows us to have eight robots in the same area that will ALWAYS detect each other within 100ms.

In case you're wondering, yes, that is the maximum number of robots that can interact (given the 6.25ms operating time with a 100ms loop time). If we added a ninth robot that transmitted from 0-6.25ms and from 56.25-62.5ms, it could 'collide' with robot #7.



An Example Solution

My proof-of-concept solution features two beacons that each have a single detector and single emitter. Each beacon, detailed below, uses a 4MHz PIC to drive a single IR LED and detect a signal from a single LITEON receiver. You will obviously want to extend my work to handle multiple IR LEDs (additional hardware), and multiple receivers (additional hardware and software). You should consider using the 20MHz PIC16F84 to interface with more than one detector.

The schematic, below, shows how the PIC hardware interfaces to the LITEON IR detector module (LTM-97AS-56) via RA0. Note the power supply noise suppression in the RC filter connected to the LITEON detector. The PIC drives a red LED whenever another beacon is detected - this output is connected to RB2.

The PIC also drives the IR LED, connected to RB0, via a simple BJT. I use a 1kohm resistor to limit the current required to drive the transistor, and a 39ohm transistor to limit the current flowing through the IR LED. You will need to develop a more robust biasing network for additional LEDs, of course.

Beacon schematic:

The assembly language source code, shown below, has been assembled to a HEX file that can be downloaded in the form of a zipfile: beacon.zip, 12Kb. The source is also shown below:

NOTE: The code below is written for a PIC16F84A with a 4.0MHz resonator. If you add additional inputs, remember that the PIC is a CMOS device and all inputs must go somewhere!


; beacon.asm
;
; Written Jan 2-5th, 2001 by wsitch@engsoc.carleton.ca
; Copyright (c) 2001 by William Sitch.  All rights reserved.
;
; RoboTag information: http://robotag.carleton.ca/
;
; operates on a 100ms cycle (detection in 100ms)
;  1x6.25ms process.......: drives an IR beacon at 55.5kHz
;  Nx6.25ms processes.....: looks for another beacon
;  1x6.25ms process.......: drives an IR beacon at 55.5kHz
;  (14-N)x6.25ms processes: looks for another beacon
;
; N={0..7}, use a different value for each co-existing beacon
;
;
; initialize
;------------
	list    p=16f84a        ; initialize to the correct PIC type
	radix   hex             ; default to HEX format
;
; MPASM configuration
;---------------------
	__config H'3FF9'	; set the configuration bits
				; CPoff, PWRTEoff, WDToff, XTosc
;
; compiler equates
;------------------
STATUS  equ     0x03
PORTA   equ     0x05
PORTB   equ     0x06
W       equ     0x00
F       equ     0x01
Z       equ     0x02
C       equ     0x00
;
LITEON  equ     0x00            ; pin0 on porta is LITEON IR input
LEDout  equ     0x00            ; pin0 on portb is IR LED output
Tdetect equ     0x02            ; pin2 on portb is target detect output
;
nsamprq equ     0x04            ; 5-6/6 samples must see IR to inc(avgIR)
nIRreq  equ     0x78            ; 120/249 chkIRs see avgIR to see target!
;
; define variables
;------------------
n55ks   equ     0x0C            ; number of 55kHz oscillations left
nchks   equ     0x0D            ; number of chkblip executions left
avgIR   equ     0x0E            ; number of 25us chkIRs that see avgIR
nsamp   equ     0x0F            ; number of samples that see IR
tdetect equ     0x10            ; target detected (0F / 1T)
;
;
; define reset instructions at 0x000
;------------------------------------
	org     0x000
reset
	goto    start
;
; define the interrupt start at 0x004
;-------------------------------------
	org     0x004
start
;
; main code
;-----------
	movlw   b'00000001'
	tris    PORTA           ; porta: pin0 input, others output
	movlw   b'00000000'
	tris    PORTB           ; portb: all output

; make the first 'blip'
				; 2us in goto at end of loop
blip	call	doblip		; +6.248ms = 6.250ms total

; look for other 'blips'
; *** change this to alter the timing of your beacon!
; *** (but ensure that a total of 14 seeblips are called)
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total

; make the second 'blip'
	nop
	nop			; 2us, to even out the 'goto blip'
	call	doblip		; +6248us = 6.250ms total	

; look for other 'blips'
; *** change this to alter the timing of your beacon!
; *** (but ensure that a total of 14 seeblips are called)
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total
	call	seeblip		; 6.250ms total

; do it all again
	goto	blip		; 2us (+6248 in next call)


; doblip -- generates 346 55.5kHz square waves (346*18us=6.228ms)
;--------
doblip                          ; [2us] call
	movlw   0xFF
	movwf   n55ks           ; 2us, puts 255 into n55ks

osc     nop                     ; 1us, delay to make 4us (in osc loop)
	call    make55k         ; 14us, oscillate at 55.5kHz, 4us needed
	decfsz  n55ks,F         ; 1us, decs n55ks, skip next if == 0
	goto    osc             ; 2us, repeat

		; we've created 255 oscillations for a total
		; of 4589us (the last loop decfsz takes 2, no goto)

morblip                         ; we need 2us more for the prev. osc
	movlw   0x5B
	movwf   n55ks           ; 2us, puts 91 (346-255) into n55ks
oscmore call    make55k         ; 14us, oscillate, baby! 4us needed
	nop                     ; 1us
	decfsz  n55ks,F         ; 1us, decs n55ks, skip next if ==0
	goto    oscmore         ; 2us, repeat

		; we've performed 91 more oscillations for
		; 1637us (the last loop decfsz takes 2, no goto)

	call	delay8u
	nop
	nop
	nop
	nop
	nop			; 13us

	bcf     PORTB,Tdetect   ; 1us, turn off the target detect

	return                  ; [2us] return, 6246us+7us=6253us!


; make55k -- generates a 55.5kHz square wave
make55k bsf     PORTB,LEDout    ; 1us, sets the output = 1
	call    delay8u         ; eats up 8us, 9us total
	bcf     PORTB,LEDout    ; 1us, sets the output = 0
	return                  ; 2us return, 2us call, 4 missing


; delay8u -- pauses for 8usec total, including the call & return
delay8u nop                     ; 3us + 2us call (PC changes)
	nop                     ; 4us
	nop                     ; 5us
	nop                     ; 6us
	return                  ; 8us total, when returned



; seeblip -- performs 249 25us chkIRs (249*25us=6225us)
;---------
seeblip                         ; [2us] call
	clrf    avgIR           ; 1us, sets avgIR = 0

	movlw   0xF9
	movwf   nchks           ; 2us puts 249 into nchks

chk     call    chkIR           ; 22us, counts avgIR blips
	decfsz  nchks,F         ; 1us, decs nchks, skip next if ==0
	goto    chk             ; 2us, repeat

	; now avgIR has value 0..249, the number of times that
	; chkIR found nsamp>nsamprq (over six measurements)
	; (it took 6224us - the last cycle takes 24us)

	movf    avgIR,W         ; 1us, puts avgIR into W
	sublw   nIRreq          ; 1us, W = nIRreq - avgIR
				; if W<0, target detected!
	btfss   STATUS,C        ; 2us (1us) skip if C=1: avgIR<=nIRreq
	goto    detectd         ; (2us) goto detectd if C=0: avgIR>nIRreq
		
		;no enemy detected                                
	bcf     PORTB,Tdetect   ; 1us, clear detect bit
	goto    chkdone         ; 2us

		;enemy detected!
detectd bsf     PORTB,Tdetect   ; 1us, set detect bit
	nop                     ; kill time to even things out

chkdone                         ; <6237us>
	call    delay8u         ; 8us
	nop
	nop
	nop
	nop
	return                  ; [2us] return, 6250us exactly!


; chkIR -- takes six measurements and compares results with nsamprq
;               if nsamp>nsamprq, then avgIR = avgIR + 1
chkIR                           ; [2us] call
	clrf    nsamp           ; 1us, nsamp=0
				; <3us>
	btfss   PORTA,LITEON    ; 2us (1us) skips if LITEON=1 (no IR)
	incf    nsamp,F         ; (1us) adds one to nsamp if liteon=0!
	btfss   PORTA,LITEON    ; 2us (1us) skips if LITEON=1 (no IR)
	incf    nsamp,F         ; (1us) adds one to nsamp if liteon=0!
				; <7us>
	btfss   PORTA,LITEON    ; 2us (1us) skips if LITEON=1 (no IR)
	incf    nsamp,F         ; (1us) adds one to nsamp if liteon=0!
	btfss   PORTA,LITEON    ; 2us (1us) skips if LITEON=1 (no IR)
	incf    nsamp,F         ; (1us) adds one to nsamp if liteon=0!
				; <11us>
	btfss   PORTA,LITEON    ; 2us (1us) skips if LITEON=1 (no IR)
	incf    nsamp,F         ; (1us) adds one to nsamp if liteon=0!
	btfss   PORTA,LITEON    ; 2us (1us) skips if LITEON=1 (no IR)
	incf    nsamp,F         ; (1us) adds one to nsamp if liteon=0!
				; <15us>
	nop                     ; throw away a cycle
				; <16us>
	movf    nsamp,W         ; 1us, puts nsamp into W
	sublw   nsamprq         ; 1us, W = nsamprq - nsamp
				; if W<0, avgIR detected
	btfss   STATUS,C        ; 2us (1us) skip if C=1: nsamp<=nsamprq
	incf    avgIR,F         ; (1us) set avgIR+=1 if C=0: nsamp>nsamprq
				; <20us>
	return                  ; [2us] return


	end
; end of beacon.asm

The code above is fairly simple: the function doblip makes 6.250ms of modulated IR light. The PIC outputs a square wave signal with an 18us period - which corresponds with 55.5kHz, which is acceptable for our needs. doblip actually creates 346 oscillations (346*18us = 6.228ms) and the overhead uses up the remaining 22us.

The seeblip function, above, interfaces with the LITEON device to detect another beacon. Each seeblip function operates for exactly 6.250ms, and takes 249 samples. Each sample, a function call to chkIR, is 25us in length and consists of 6 measurements. This requires 249*25us = 6.225ms, and the overhead uses up the remaining 25us.

If a chkIR function measures 5 or 6 low (ie: 0) values from the LITEON, indicating that modulated IR is present, then that particular sample is assumed to have detected part of an IR beacon. The number of samples that detect IR is counted, and a positive detection is made when more than 120 of 249 samples detect IR.

In order to tighten or relax the required amount of IR to signal a detection, the programmer should modify the nsamprq (and maybe the nIRreq) variables, as follows:

  • The nsamprq variable indicates how many measurements must detect IR for the cluster to 'detect' part of a signal. If you set nsamprq to 4 (default), then you require 5 or 6 (out of 6) measurements to see IR. This means 2/3 of the 25us sample must see IR.
  • The nIRreq variable indicates how many samples are required to 'detect' a beacon signal. If you set nIRreq to 120 (default), then you require at least 120 chkIR function calls to measure more than nsamprq instances of IR. This means a little less than 1/2 of the 6.250ms must see IR.

Note that if the nIRreq variable is greater than 121 then it might be possible to not detect another beacon! This can be shown as follows. If we assume that two beacons, #6 and #7 in the timing diagram above, are perfectly NOT synchronized, we might expect the following signal overlap:

This means that robot #7 would transmit for the first half of robot #6's first pulse. So #7 would only see the second half of #6's pulse. This means that we must program our detectors to look for this worst-case scenario, where we would only see two half-pulses from another beacon.

When re-working the above code, take care to observe the timing requirements detailed in this document. Every 'block' of time, whether the PIC is emitting or detecting, should be exactly 6250us, including the time to call and return from the function. In order to allow others to lock onto the 100ms repeating signal, the timing MUST be as close to perfect as possible. This will be checked during the software review phase of the marking.



Miscellaneous Advice and Recommended Parts

Making the infrared LEDs and the LITEON device work in harmony is difficult. The range requirements are 12+ feet, but you should aim for 5 meters in full sunlight. To help, I've put together the following recommendations.

  • Don't drive the LEDs and LITEON from the same power source, the LITEON really doesn't like the power supply fluctuations caused by the high current-drawing LEDs. You can drive the LEDs specified below with 12V and 2A, but it's not required -- a better idea would be to use your motor batteries (whatever the voltage) and aim for 60mA per LED.

  • Shield the LITEON from any overhead fluorescent lights, they'll put out enough IR that some will appear to the LITEON to be modulated at your frequency. Remember to shield all around the LITEON, even behind and to the sides. The metal casing doesn't completely block IR.

  • Don't let your LED shine anywhere near your LITEON. Even though I was transmitting and receiving at different times, the LED would 'flood' the LITEON when transmitting and the LITEON wouldn't recover in time before the LED was transmitting again. Even with 42ms between transmissions, the LITEON wouldn't recover enough to detect a faint signal. If you shield the LEDs from the LITEON, the operating range increases.

  • Of course, drive the LEDs through transistors. Because we're making a 55.5kHz signal (from the PIC) with a total burst time of 6.25ms - you could hit each IR LED with up to 2A of peak forward current! Yes, two amps! If you decide to do this (it's not really needed), you should consider optoisolating your PIC.

Other recommendations and miscellaneous advice:

  • use the recommended parts I specify below
  • be sure to use the LITEON-recommended power supply noise rejection scheme
      (the 47ohm resistor and the 47uF capacitor - check the datasheet/schematic)
  • use a darlington pair buffer (like the ULN-2803A) to drive the LEDs
    • amplify the output from the PIC, then have that current drive nine other darlington pairs (one for each LED)
  • make sure your LED power supply can handle the current draw!
    • 9 LEDs at 100mA each is almost 1A! That's a lot of current.

Selecting the best parts for the IR beacon is important. If you're using an IR LED that doesn't transmit at 940nm, for example, the LITEON receiver module won't work as well.

The parts I've used in my lab tests (and which I recommend), are:

  • LITEON 56.8kHz Infrared Receiver Module - LTM-97AS-56 (DigiKey: 160-1155-ND)

    The LITEON IR module can detect modulated IR at 8 meters (30-degree cone) or 6 meters in a 45-degree cone. However, it is susceptable to other infrared light, so you should take care to correctly shield your detectors.

  • 940nm IR emitting diode - LTE-302-M (DigiKey: 160-1063-ND)

    The emitter I recommend gives 100% intensity at the beam center, 90% intensity at 10-degrees off center, and 50% intensity at 20-degrees off center. So when they advertise a 40-degree beam width, they mean 50% intensity at 20-degrees from beam center. Yes, this does mean you'll need lots of the LEDs. I'd recommend nine. Yes, this does mean you may need to provide more than 1A (peak) to the emitters.


 
Main Page
|
Course Admin
|
Contest Rules
|
Project Resources
|
Team Info
|
Picture Gallery
|
Contact Info