The transmission code is
explained below and the actual code is contained in Appendix 1.
three buttons on the remote are each connected to an input pin on the
transmitter pic. The signal to the pins is normally high.
The software continuously polls the pins, so when one of the pins goes
low then the code jumps to the corresponding service routine.
If pin 0 is low then arm has been pressed and jump to the arm function,
if pin 2 is low then jump to disable, and if pin 4 is low then jump to panic.
arm, disable and panic functions all behave in a similar way.
The only difference is the characters that are sent.
In the arm function 'ARM' is sent. In
the disable function 'DIS' is sent and within the panic function, 'PNC' is sent.
Each of the strings is sent
twice in a row because of a problem that we were having.
When arm was pressed and then disable, the device would not disable until
another button was pressed. It was
a simple solution to a problem that was difficult to pin point.
There were some calculations
that had to be done in order to ensure that we were transmitting (and receiving)
at 2400 baud.
These equations are from the pic data sheets. There was some sample code that allows transmission at certain baud rates by changing the constants calculated below.
Clockout = Fosc/4 = 4MHz/4 = 1MHz
Baud_Cycles = Clockout/Baud = 1MHz/2400 = 416.67
Baud_X = 3 + 11x = Baud_Cycles; x = 135 (transmitter delay between transmitting each bit)
Table 2: Equations
for Delay Constants
2400 baud was the maximum
transmission rate that our transmitter could handle. We are transmitting LSB
(least significant bit) first and the string includes 1 start bit which is a
one, 8 data bits and a stop bit which is a zero.
The start and stop bits are sent with each character and we did not use
any parity bits.
In order to synchronize the
transmitter and receiver it is necessary to send approximately 10 ms of 0x55 (as
a bit stream 01010101) and then one byte of 0xFF (as a bit stream 11111111) so
that the receiver can be properly synchronized.
To ensure that during data
transmission the receiver and transmitter stay synchronized throughout the
transmission, all of the data is Manchester encoded.
This means that a 1 is sent as 2 bits, 10, and a 0 is sent as 01.
This ensures that the signal is always toggling and that a 1 never
follows a 1, nor a 0 follow a 0, more than once in a bitstream.
Figure 6: Visual
Example of Manchester Encoding 
"A Manchester encoded
signal contains frequent level transitions, which allow the receiver to extract
the clock signal using a Digital Phase Locked Loop (DPLL) 
and correctly decode the value and timing of each bit. To allow reliable
operation using a DPLL, the transmitted bit stream must contain a high density
of bit transitions. Manchester encoding ensures this, allowing the receiving
DPLL to correctly extract the clock signal.
The penalty for introducing frequent transitions, is that the Manchester coded signal consumes more bandwidth than the original signal (in NRZ). " 
The receiver code is
explained below, but the actual code is contained in Appendix 1.
The following table includes all of the equations needed to calculate the
delays for the receiver code.
Baud_4 = 3 + 3x = 1.25 *Baud_Cycles; x = 173 (receiver delay to wait for first valid bit after receiving start bit)
Baud_3 = 3 + 3x = 0.5 *Baud_Cycles; x = 68 (receiver delay to wait for start bit)
Baud_Y = 9 + 3x = Baud_Cycles; x = 135 (receiver delay to wait for each of the 8 data bits)
The receiver code makes use
of the external interrupt pin and an internal interrupt, timer0.
The receiver is constantly
polling the input pin which it receives data from the transmitter on.
When a signal comes in that triggers from low to high the pic knows that
it has received the start bit. It
then turns off all interrupts and checks the first character and jumps to the
respective piece of code. For
example if it gets a Manchester encoded 'A' (hexadecimal 69) and then goes
through the code for receiving 'ARM'. Once the entire string had been
successfully received, the code will enable interrupts and set the appropriate
signals to cause the actions listed in Table 1.
An example is when 'ARM' is received, the power to the ignition will be
cut off and an LED will turn on to acknowledge that the car has been armed.
The sensors on the doors are wired to the external interrupt pin on the receiving pic. When one of the doors opens, provided the car has been armed, an interrupt is triggered which causes the horn to honk and the hazard lights to go off for a limited amount of time.