|
Since the system is required to send data back and forward between the two units, some form of communication was investigated. Laser & IR Leds.
Initially development focused around using a simple laser diode to transmit the data. There are two ways to modulate a laser, internally and externally. Unfortunately in this project it was not possible to access the internally modulated lasers that the university possesses, therefore it was chosen to externally modulate the laser. This meant some form of optical or acoustic filter was required. After consultation with various members of staff within the department is was ascertained that simply switching the laser on and off could be used to modulate data.
Experiments were carried out with a visible photo-detector and a cheap red class 3A laser diode, with an adjustable focus lens. It soon became clear that the photo-detector was becoming saturated with visible light. After experimentation with various photo-diodes available in the department it was discovered that the laser emitted a small amount of IR light as well as red light.
Several IR filtered photodiodes (BPW34FS) were purchased. These were chosen for the high rise and fall time of 2ns[xxiii]. They also had one of the largest active areas (7mm2) without spending too much. Tests were carried out in the lab with lights at different levels to measure the output from the photodiodes. Photodiodes are essentially a voltage source therefore the voltage was measured across the diode with a voltmeter.

Table 5 - Photodiode Output Test
The change in voltage would be more than enough to detect and classify as a logic LOW or HIGH. The only trouble is that we need to scale the signal up so that a microcontroller or FPGA could detect it as a HIGH, the PIC16F877A high needs to be above 2V[xxiv] to be recognised as a logic HIGH. Biased transistor circuits were looked at however it was decided to use the PICs inbuilt comparator subsystem since it was likely to be used to modulate the signal. A potentiometer was connected with the wiper connected to the VReference signal, this was then adjusted to the voltage in-between the on and off voltages of the photodiode. This meant when the output from the diode exceeded the reference, the output would be 5V, and when it was lower than the reference 0V.
A simple modulation technique was then devised to test the laser as a method of communication. The receiver consisted of the photodiode connected to a PIC and a 7 segment display. The transmitter was the laser diode connected to another PIC also with a 7 segment display. The modulation technique chosen was pulse width modulation (PWM) at baseband. In this scheme, symbols are defined as the width of pulses on the line, this is how servos are controlled. The idle condition on the line was HIGH, the symbols were defined as 0 to F, with 0 being 10ms LOW, and F being 160ms LOW. Each symbol was therefore an integer multiple of 10ms.

Figure 22 - PWM of Laser
Idle was at +5v so that the laser was visible when it wasn’t modulating the data. Initial testing was carried out with a wire link between the transmitter and receiver to verify correct operation of the programs in the PICs (See Figure 24). These tests were successful. The overwhelming majority of symbols transmitted correctly, with only one or two exceptions. Tests were then carried out with the laser transmitter and photodiode receiver, using switches to send each of the symbols in turn and observing the success.
Success was relatively mixed. Several of the symbols transmitted successfully, however around half were wrongly received. Several causes were found, the principal was that there is often capacitors inside the cheap laser diodes limiting switching speeds[xxv]. The laser used wasn’t made specifically for modulation and no data sheet was available. The other cause is believed to be inefficient code, specifically the receiver code. Its operation was fairly simple, when the line drops low wait 10ms and check if it’s still low. This may have introduced errors where the input changed state just after it was checked. The programs are discussed on the next page and a flowchart & listing of the program is included on the attached CD.

Figure 23 - Size of Photodiode
Another key issue became clear at this stage. The size of the receiver was incredibly small compared to the size of the laser. To target this from 1m would require incredible accuracy. It was therefore decided to develop an IR LED communication channel as this was not as accuracy dependant as lasers.

Figure 24 - Laser Comm. Simulation Schematic
The above circuit was simulated in Proteus ISIS and found to function correctly with no errors. The circuit was designed so that the laser could be implemented by swapping the communication line for the laser diode at the Transmitter PIC side, and the photodiode with the comparator subsystem converting the small voltage change to a TTL LOW or HIGH at the receiver side. The newest versions of the PIC programs ‘trans’ and ‘rec’ were modified to accommodate these alterations and also drive a 7 segment display which was obtained.
Transmitter (ptx) Program
|
Wait for SendSwitch to go HIGH
Wait for switch to be released (LOW)
DataValue = PortD
BCD Display on PortB = DataValue
Add one to DataValue (Since 0 is one multiple of 10ms)
Set Output low
Do (DataValue) Times
{ Delay(10mS) }
Set Output High
Return to beginning
|
Receiver (prx) Program
|
Wait for InputSignal to drop LOW
Clear Count
While(InputSignal is LOW)
{ Delay(10mS)
Count = Count + 1 }
DataValue = Count
BCD Display on PortB = DataValue
Return to beginning
|
IR LEDs were chosen to develop as a communication channel due to the fact that they have a wider field of view than the laser and are also easier to detect. A specialised chip was purchased which would decode IR signals modulated to 36kHz. A transmitter was constructed which housed 2 IR LEDs and a driver circuit as the current drawn is too much for most controllers. Each LED draws 100 mA and each pin on the FPGA and microcontroller can’t supply much more that 20mA. The driver circuit consisted of two current limiting resistors and a BC547B transistor to switch the LEDs. A complete schematic appears in Appendix A at the end of this document.
A modulator was required to be able to send data with the IR LEDs. Since the development time would likely take longer for a FPGA than the microcontroller, it was decided to add a microcontroller to the FPGA and have the FPGA issue commands to the microcontroller. The modulation scheme was chosen as RC5 as it is a tried and tested scheme which wouldn’t be too complex to implement. Using RC5 also meant an off the shelf de-modulator chip could be used with only a PIC based decoder to strip the data out. See section ‘2.3.2 Phillips RC5’ for more information on RC5.
To create the RC5 transmitter required several delays to be designed. Since the ON periods were modulated at 36kHz:
This is the period of one pulse. To get the ON and OFF times of the signal we simply divide this by two:
However since we are using a PIC microcontroller running at 20MHz the delay per one instruction is:
Therefore the modulated On Off time was implemented as a 13.6uS delay, rounded to the nearest 0.2uS and with 0.2uS subtracted to allow for the instruction setting the line high and low.
With RC5 the symbols 0 and 1 are defined as a low-high or a high-low of length 1.778ms, where the low and high stages are 889uS long. Therefore the low time was implemented as a 890.2uS delay and the high time (modulated section) was implemented as 34 cycles of a square wave of period 27.2uS. Therefore the total length of the high time was 924.8uS. Slightly longer than the low time however this was due to the delays incurred by the loop control instructions and the I/O instructions of the PIC. See the figure below which contains the bit delays.

Figure 25 - RC5 Bit Delays
34 cycles of the 36kHz wave mean the whole length of the bit 1.835ms. An RC5 command is 14 bits long meaning the complete length of a command is around 25ms. After the complete 14 bits of the waveform is transmitted a delay of 130ms is performed before the next 14bits. Since the PIC is controlled by the FPGA, there is a modulator enable line and 6 lines for passing the command value to be modulated in the command. The address part of the message is hard coded into the PIC as 10101. The receiver in future could be coded to only respond to messages addressed to it.
The receiver is connected to the demodulator chip (HIM602) and the beacon. The chip outputs a HIGH when no signal is being received and a LOW when there is a signal. Since the start bit is a HIGH, when this occurs we delay 1 bit period before sampling the next bit. The mini delay at the beginning ensures we don’t sample on the mid-bit transition since the timings are not 100% accurate. The receiver acknowledges the message transmission by setting the beacon LED low for 2 seconds before returning high.

Figure 26 - Trace of transmitted IR pulses

Figure 27 - IR Transmitter Flowchart
5.2.3 IR Transmitter Pseudocode
Main Program
|
Initialise Ports & Variables
While (Enabled is LOW)
{ Do Nothing } Else {
//Send Start Bits
Call DoOne subroutine
Call DoOne subroutine
//Send Toggle Bit
Call DoZero subroutine
//Send Address Bits (Hardcoded = 01010)
Call DoZero subroutine
Call DoOne subroutine
Call DoZero subroutine
Call DoOne subroutine
Call DoZero subroutine
//Send Data Bits
If (Bit5 == HIGH) Call DoOne subroutine Else Call DoZero subroutine
If (Bit4 == HIGH) Call DoOne subroutine Else Call DoZero subroutine
If (Bit3 == HIGH) Call DoOne subroutine Else Call DoZero subroutine
If (Bit2 == HIGH) Call DoOne subroutine Else Call DoZero subroutine
If (Bit1 == HIGH) Call DoOne subroutine Else Call DoZero subroutine
If (Bit0 == HIGH) Call DoOne subroutine Else Call DoZero subroutine
Delay 130mS
}
|
DoOne
|
//Waste 890.6uS
Do (50 times)
Do (17 times) {
Waste 2 Instructions
}
}
//34 Cycles of ON OFF wave @36kHz
Do (34 times) {
Output = HIGH
Do (16 times) { (Waste 13.4uS)
Waste one instruction
}
Output = LOW
Do (16 times) { (Waste 13.4uS)
Waste one instruction
}
}
|
DoZero
|
//34 Cycles of ON OFF wave @36kHz
Do (34 times) {
Output = HIGH
Do (16 times) { (Waste 13.4uS)
Waste one instruction
}
Output = LOW
Do (16 times) { (Waste 13.4uS)
Waste one instruction
}
}
//Waste 890.6uS
Do (50 times)
Do (17 times) {
Waste 2 Instructions
}
}
|
(The PIC used runs at 20MHz meaning one instruction = 0.2uS)
|
890.6us
|
Instructions Used
|
|
movlw d'50'
movwf delcnt
outlp movlw d'17'
movwf delcnt2
inlp nop
nop
decfsz delcnt2,f
goto inlp
decfsz delcnt,f
goto outlp
|
1
1
50 * 1
50 * 1
50 * 17 * 1
50 * 17 * 1
50 * ((17 – 1) + 2)
50 * (2(17 - 1))
(50 – 1) + 2
2(50 – 1)
|
|
Total = 4453 = 890.6uS
|
|
13.4uS
|
Instructions Used
|
|
movlw d'16'
movwf adelcnt
adel nop
decfsz adelcnt,f
goto adel
nop
nop
|
1
1
16 * 1
(16 – 1) + 2
2(16 – 1)
1
1
|
|
Total = 67 = 13.4uS
|
|
iWait (approximately 130mS delay)
|
Instructions Used
|
|
iwait
movlw d'255'
movwf cnt
cnw nop
movlw d'255'
movwf cnt2
cnw2 nop
nop
nop
nop
nop
nop
nop
decfsz cnt2,f
goto cnw2
nop
decfsz cnt,f
goto cnw
return
|
2
1
1
255 * 1
255 * 1
255 * 1
255 * 255 * 1
255 * 255 * 1
255 * 255 * 1
255 * 255 * 1
255 * 255 * 1
255 * 255 * 1
255 * 255 * 1
255 * ((255-1)+2)
255 * 2(255-1)
255 * 1
(255 – 1) + 2
2(255 – 1)
2
|
|
Total = 651,785 instr.
= 130.36mS
|

Figure 28 - IR Receiver Flowchart
|
Initialise Ports
Loop {
IR Led ON
Visible Led OFF
Wait till Receiver is in default state….. (HIGH)
Clear Storage Registers
IF (receiver output drops LOW) {
Call MiniDelay (1/4 of pulse width)
Call PulseWidthDelay (to get on 2nd start bit)
Call PulseWidthDelay (to get on toggle bit)
If (ReceiverOutput is LOW) Set Toggle = HIGH
else Set Toggle = LOW
Call PulseWidthDelay (to get on address4 bit)
If (ReceiverOutput is LOW) Set address4 = HIGH
else Set address4 = LOW
Call PulseWidthDelay (to get on address3 bit)
If (ReceiverOutput is LOW) Set address3 = HIGH
else Set address3 = LOW
Call PulseWidthDelay (to get on address2 bit)
If (ReceiverOutput is LOW) Set address2 = HIGH
else Set address2 = LOW
Call PulseWidthDelay (to get on address1 bit)
If (ReceiverOutput is LOW) Set address1 = HIGH
else Set address1 = LOW
Call PulseWidthDelay (to get on address0 bit)
If (ReceiverOutput is LOW) Set address0 = HIGH
else Set address0 = LOW
Call PulseWidthDelay (to get on data5 bit)
If (ReceiverOutput is LOW) Set data5 = HIGH
else Set data5 = LOW
Call PulseWidthDelay (to get on data4 bit)
If (ReceiverOutput is LOW) Set data4 = HIGH
else Set data4 = LOW
Call PulseWidthDelay (to get on data3 bit)
If (ReceiverOutput is LOW) Set data3 = HIGH
else Set data3 = LOW
Call PulseWidthDelay (to get on data2 bit)
If (ReceiverOutput is LOW) Set data2 = HIGH
else Set data2 = LOW
Call PulseWidthDelay (to get on data1 bit)
If (ReceiverOutput is LOW) Set data1 = HIGH
else Set data1 = LOW
Call PulseWidthDelay (to get on data0 bit)
If (ReceiverOutput is LOW) Set data0 = HIGH
else Set data0 = LOW
Do (100times) {
Call MiniDelay (1/4 pulse width)
If (ReceiverOutput is not HIGH)
then not valid command, so goto start
}
//Valid Signal
PORTC = Address
PORTD = Data
Delay 3 seconds
IR Led OFF
Visible Led ON
Delay 2 seconds
IR Led ON
Visible Led OFF
}
}//end of loop
|
Note: since the output from the integrated receiver chip is inverted (LOW when a signal is being received) when we sample the signal, we must take this into account. This is why if the ReceiverOutput is LOW we set the Bit as HIGH.
|
¼ Pulse width - 235us
|
Instructions Used
|
|
minidel
movlw d'195'
movwf delcnt3
dellp3 nop
nop
nop
decfsz delcnt3,f
goto dellp3
return
|
2
1
1
195 * 1
195 * 1
195 * 1
(195 – 1) + 2
2(195 – 1)
2
|
|
Total = 1175 = 235uS
|
|
PulseWidth Delay – 1.88mS
|
Instructions Used
|
|
delay
movlw d'31'
movwf delcnt
dellp 2 NOPs
movlw d'42'
movwf delcnt2
dellp2 4 NOPs
decfsz delcnt2,f
goto dellp2
2 NOPs
decfsz delcnt,f
goto dellp
33 NOPs
return
|
2
1
1
31 * 2
31 * 1
31 * 1
31 * 42 * 4
31 * ((42 - 1) + 2)
31 * 2(42 - 1)
31 * 2
(31 - 1) + 2
2(31 - 1)
33
2
|
|
Total = 9400 = 1.88mS
|
The MiniDelay above is used to shift the sampling time further along the waveform so that we do not sample on the mid bit transition. The 1.88mS is slightly longer than the Bit length of 1.835mS. This timing although slightly too long still works as the maximum error after delaying 13 times is 0.585mS (43%) which will not cause an sampling error on the final bit. This error however is quite large and could be easily adjusted by changing the delay length.
There is a further one second delay routine however this is not discussed here as the timing is not critical as long as the AreaScan is calibrated to determine the positive acknowledgement time.
|