The code uses many different standard in order to integrate all of its external components. There were several key components that were required by the main loop (the position estimator). Namely, these were the GPS, the LCD, and the external A/D Converter. In order to best implement this software, we chose a pseudo object-oriented approach. Since C is not a natively object orientated language, this implementation can be difficult to start, but the overall gain in ease of debugging and modularity make it all worth while!
The GPS Receiver
The GPS Receiver is
implemented such that only the necessary external functions are visible from the
top level C file. In the declaration, two extern type variables represent
the entire GPS. This keeps the code less "dense" and more readable, as all
the low level function are hidden away in the GPS.c and .h files.
In these files resides the NMEA 0183 parser. NMEA is a specification released by the The National Marine Electronics Association and specifies its messages in pure ASCII. The 0183 specification has certain GP messages that represent different readings from the GPS receiver. Each message is terminated with a <CR><LF> (carriage return, line feed), and the data itself is comma delineated. This is the defacto standard for modern commercial GPS receivers. For our purposes, the message $GPRMC (Recommended Minimum Specific GPS Transit Data) contains all the necessary headers, summarized below:
Data Pos |
Data |
1 | UTC Time of Position/Fix (hhmmss) |
2 | Status -> A = valid, V = invalid |
3 | Latitude ddmm mmmm format |
4 | Latitude Hemisphere (N or S) |
5 | Longitude ddmm mmmm format |
6 | Latitude Hemisphere (E or W) |
7 | Speed in knots |
8 | Course (0-360 deg) |
9 | UTC Date of position fix (ddmmyy) |
10 | Magnetic Variation (0 to 180 deg) |
11 | Magnetic Variation Direction (E or W) |
12 | Mode Indicateor (A = autonomous, D= Differential, E = estimaed, N = none) |
The LCD
The LCD we used was a
Crystal Fontz CFAG12864B-WGH-N Graphical LCD. We developed this LCD
from the ground up, and developed a neat library to print characters
despite the fact it is a graphics only LCD.
As seen by our functional prototypes, the functions are clearly named
and take simple variables as their arguments. The LCD code has a
character bitmap which it uses to print each character, and this bitmap
is stored in the chip's flash.
We also have a graphical "ruler" which functions as the compass when the GPS is operating. This ruler uses the same "graphics" library, and is also stored in flash. The rotating of this ruler is done entirely dynamically, so 360 copies are NOT stored in flash!
The LCD interface itself was quite challenging, and quite
demanding on the ATMEGA. This cycle takes almost 100 ms, so we buffer the data
before printing it to screen to avoid changing characters mid-print. Further
optimization may be possible given more time, but this was not a primary focus
of the project.
The A/D Converter
Due to the nature of our project, the on-chip analog to digital converter
would not be sufficient for obtaining the full range of our sensors at adequate
precision. Therefore, we chose to use a higher precision A/D converter that we
had laying around our lab. It is a 12 bit, multi-channel A/D with a serial
interface, and in our attempt to keep the program easy to follow, we followed
out object oriented model with this unit as well.
After calling the init and CnvSetup functions, the data is automatically updated
in the ADCdata array. This is accomplished by relying on an internal clock
within the A/D converter which latches the A/D values and throws an interrupt.
We capture the interrupt and update the values in the ADCdata within the AD.c
code.