June
2004, Issue 167
Wireless
Monitoring System
CONFLICT PREVENTION
To
ensure reliable data circulation, the system must cope
with the possibility of a simultaneous transmission
from two or more traps. Another cause of trouble is
interference from the cluttered license-exempt RF band.
To protect the integrity of the data, the system acts
on both the transmitter and receiver ends.
With
a period determined by its heartbeat function, the transmitter
sends the trap status, encoding it as a packet of 11
width-modulated pulses. It repeats the pulse train numerous
times to add redundancy.
In
order to distinguish RF noise from real data, the receiver
checks the shape of the pulses before accepting them.
Pulses too long or too short are discarded. As an additional
requirement, it rejects any data that isn’t preceded
by a silence gap. Lastly, the receiver must get two
identical data packets consecutively in order to validate
them.
Simple
redundancy like this does not protect against the unwanted
synchronization of two or more transmitters, which,
for example, can happen as a consequence of clock frequency
drifts over long periods. To minimize this problem,
I altered the data repetition rate and heartbeat period
in accordance with trap IDs, as shown in Figure 5.
|

(Click
here to enlarge)
|
Figure
5—To protect data integrity, actions are taken on
the transmitter and receiver ends. The transmitter
repeats its data after a short pause, whose length
varies in accord with ID. The receiver discards
any data that is not repeated. ID-dependent gaps
are also used for longer periodic retransmissions
in order to avoid the parasitic synchronization
of two or more transmitters. |
If
two traps start transmitting at the same time, their
repeated packets overlap at different points at each
repetition because of the variable spacing between them.
The receiver discards this variable interference pattern
because the redundancy check requires two identical
packets to accept data.
There
is always the possibility that a transmission will get
lost as a result of complete overlapping. In that case,
you must wait the long retransmission period (heartbeat)
for another chance at receiving the information. There
will be no collisions on the next heartbeat, because
the heartbeat period differs from one transmitter to
another as it varies according to trap ID. Therefore,
the system occasionally allows heartbeat signals to
be missed as a consequence of external interference,
poor reception, and (although not particularly likely)
trap-to-trap overlaps. The receiver knows that a trap
is still alive from its heartbeat. If more than 6 h
slip away without receiving a single heartbeat, the
receiver deems the trap lost and sends you a signal.
SOFTWARE
BASICS
I
wrote the C code for the transmitter first. I didn’t
have a prototype at the time, so I ran the software
on the Motorola QT demo board, using an oscilloscope
to verify the signals. The demo board runs in User Monitor
mode. It is preloaded with a small monitor program that
fits a handful of unused flash memory bytes and uses
interrupt table relocation to offer single-pin, in-circuit
emulation and programming. I changed the value of InitConfig1
to %00100111 to allow for the use of the STOP instruction.
The
demo board circuit and user-monitor program are detailed
in Jim Sibigtroth’s application note titled “User Mode
Monitor Access for MC68HC908QY/QT Series MCUs.” You
must use the user monitor to load and run the transmitter
and receiver software. To do so, follow the procedure
described in John Suchyta’s application note, “Reprogramming
the M68DEMO908QT4.” The transmitter code structure is
straightforward, although it requires special programming
to optimize power consumption.
I
grouped hardware-specific details in the hardware.c
file, which you may download from the Circuit Cellar
ftp site. It hides port and register initializations,
aliases for all of the pins used, macros for manipulating
them (to disable trigger input pull-ups), functions
and macros to go in Stop and Wait modes, and interrupts.
Where possible, I prefer to handle port pins at the
bit level, setting bits individually instead of setting
the entire port at the same time. This makes the code
more flexible, allowing painless pin swapping when routing
a PCB for production.
The
main.c file, which is the application’s body, implements
the usual big endless loop found on most embedded systems.
At each loop, the MCU awakens from Stop mode and checks
if it has been called by the keyboard interrupt (buttons
pressed, sensor triggered) or the wake-up timer. It
also checks the battery level. If the sensor detects
a mouse or key press (or at almost every hour), the
MCU formats and transmits the trap status.
The
trap status is formatted for transmission, assembling
a start bit, the 7-bit ID, and the trap-triggered and
low-battery flags, in addition to a special test flag
(set when the Rearm button is pressed) that’s used when
configuring the system. As you can see in
Listing 1, the code word is handed to the rf_encoder()
routine, which uses the 16-bit timer combined with the
processor’s Wait mode to generate a train of 33% or
66% duty cycle pulses (see Figure 6).
|

(Click
here to enlarge)
|
Figure
6—Transmitter data is packed in 11-bit code words.
Pulse-width modulation is used for transmission,
with 66% and 33% duty cycle pulses representing
zeros and ones respectively. To add redundancy,
code words are repeated and spaced apart at least
11 ms. (The exact value varies according to the
trap ID.) |
The
monitoring station software is more complex. Refer to
Figure 7 for help understanding its main structure.
The receiver gets the most recent data from the radio
decoder. Should the data match any of the traps stored
in its internal database, the respective record is updated
to reflect the new status. The receiver presents trap
information according to the current user-interface
mode (Automatic or Manual Scroll mode), which determines
how to layout LCD data and react to keyboard clicks.
|

(Click
here to enlarge)
|
Figure
7—The software is in charge of polling the RF module,
updating the trap database, running the user interface,
and performing time-scheduled checks. A different
interface is presented according to the operating
mode: Automatic, Set Up, or Manual. The timeout
flag and RF module data is updated by interrupt
service routines. |
In
order to execute time-scheduled housekeeping routines,
the receiver checks the timeflags structure. Its different
bits are set by the timer interrupt routine to indicate
if twentieths, seconds, minutes, or hours have elapsed.
Every second, the receiver updates a timeout that serves
to restore Automatic mode after a short period of nonuse.
Every hour, the receiver updates the trap heartbeat
counter. Finally, if a trap needs to signal an alarm
condition, the receiver activates the relay output and
repeats the entire cycle from the beginning.
According
to good programming style, I encapsulated the various
functions (radio decoder, trap database manager, flash
memory-based EEPROM emulation, keyboard and LCD drivers,
delay routines, and hardware-related primitives) in
separate files orchestrated by main.c. Note that trap
ID codes are stored in flash memory, which is used as
a sort of EEPROM.[1]
Contrary
to popular belief, C language code and data encapsulation
are not flash memory-hungry ogres. In fact, the complete
application requires only 3 KB. This suits these little
4-KB devices nicely, leaving plenty of space for future
expansions.