Sunday, June 26, 2011

MTK NMEA checksum calculation

The MTK NMEA checksum can be calculated by using the following procedure:

The NMEA Checksum is calculated on a character by character basis using an XOR operator. Each character is fed into an XOR with the current checksum value. The checksum is initialized to all zeros. The characters that exist between the "$" and "*" are the only characters to be used in the calculation. These values are in ASCII, thus each character is represented as an 8-bit value. The resulting checksum is an 8-bit HEX value which is represented as 2 ASCII characters. Below is an example of this procedure:

$PMTK000*32


0000 0000 <==Checksum
0101 0000 <==P

0101 0000 <==Checksum
0100 1101 <==M

0001 1101 <==Checksum
0101 0100 <==T

0100 1001 <==Checksum
0100 1011 <==K

0000 0010 <==Checksum
0011 0000 <==0

0011 0010 <==Checksum
0011 0000 <==0

0000 0010 <==Checksum
0011 0000 <==0

0011 0010 <==Checksum

This results in a checksum of 32 which matches what was shown above.

And for those folks that use MATLAB, HERE is a very basic program that I wrote up that does this for you.

Enjoy!

Saturday, June 25, 2011

GPS to 16x2 Character LCD Using an FPGA


This is a project that uses a Spartan-3E FPGA Board (Xylo-LM) to grab the serial stream transmitted by a Locosys LS20031 GPS Module and parse the messages for the latitude and longitude. The latitude and longitude values are then feed into a 16x2 Character LCD display on a push of a button.

Note: The GPS coordinates shown will not lead you to me. The GPS module at the time of recording this, was not locked onto my coordinates...so don't try hunting me down..else you will find yourself in the Atlantic =P

Below is a basic block diagram that helps to illustrate what the FPGA does in the system. The FPGA has 3 modules: A Serial Module, a Parser Module, and an LCD Controller Module. The serial module is only responsible for acquiring the serial data at the specified baud rate. Over sampling is used in the FPGA to help minimize bit errors.  The serial module passes the raw data to the parser module. At this point in time the raw data is the NMEA messages (with the overhead information removed, i.e. stopbit/startbit). The parser module waits for the occurrence of a '$' which indicates the start of an MTK/NMEA message. Once the '$' is received, the parser extracts the message type and checks for a "GGA" message. If the current message is a GGA message, then we extract the Latitude and Longitude based on the standard format of the GGA message. This is currently being done by counting the characters; however, counting the comma delimiters work just as well. The parser module passes the latitude and longitude data to the LCD module as it is received on the serial line. The LCD controller module handles the initialization process required to set the LCD module into an operative mode, and it handles all the timing and writing data to the display.



This is an on-going project and I plan to add many more features to it. Below are some changes that I plan on making in the future.

Future Improvements/Additions:

  • Write the serial stream from the serial module to a Block Memory or RAM
  • Read the data in a Block Memory or RAM and feed the data into the Parser Module.
  • Perform mathematical operations on the acquired data, such as computing the displacement from the current location to the last saved location.

For those interested in knowing more about this project, or want more information about certain aspects of the HDL code that I wrote, please don't hesitate to post a comment.

For those interested in the LCD controller module's code, go here: LCD Controller.
Or to download all of the related HDL files, go here: GPS2LCD_Files.zip

My project was featured on Sparkfun's Main Page! Pretty cool and I got some good constructive criticism.

Thursday, May 19, 2011

Using an MCP3002 ADC for Interfacing an FPGA with a Photocell

The MCP3002 ADC Chip is a very handy device. You can interface with it via a very simple SPI (Serial Peripheral Interface) protocol. The Verilog module that I designed to interface with this chip works beautifully.

The module I created uses both channels of the MCP3002 in an "interlaced" single-ended mode. The module is strictly configured to work with a local oscillator of 24MHz, but minor adjustments to the process that converts the local clock to a 1.2MHz clock is all that needs to be modified. The 1.2MHz clock is the maximum frequency that the IC can operate at while powered at 2.7V as specified in the datasheet (pg3) under the "Timing Parameters". In my case my FPGA uses 3.3V logic so Fclk(max) should reside somewhere between this and 3.2MHz. If we assume a linear relationship between voltage and operating frequency, then the maximum expected operating frequency at 3.3V would be ~1.688MHz, thus operating at 1.2MHz "should" be a safe level of operation while pushing the IC to work at its maximum.

As far as the code goes, it is really self explanatory. I would recommend anyone that is attempting to use this code to have a copy of the datasheet on hand so that you can see the relationship from my code and the datasheet's timing diagram. Figure 5-1 was specifically used to design this Verilog Module.

On a hardware interfacing note, be sure to pay attention to Figure 4-2 in the datasheet, this clearly states that the ADC's CH0 and CH1 input signals NEED to be buffered (i.e. use an opamp in a buffer configuration or similar). If you skip this, your maximum operating frequency will be lower that the one defined in the datasheet.

The code that I provide here is free to use however you would like, but I would appreciate it if you give me credit for my work. Also constructive criticism is welcome, if you see something that could be done better another way, let me know.

Download: MCP3002 ADC Module