GPS Receiver Interfacing With Microcontroller and Displaying Data On LCD and PC (MAE 5483 Term Final Project Report)
GPS Receiver Interfacing With Microcontroller and Displaying Data On LCD and PC (MAE 5483 Term Final Project Report)
GPS Receiver Interfacing With Microcontroller and Displaying Data On LCD and PC (MAE 5483 Term Final Project Report)
GPS Receiver Interfacing With Microcontroller And Displaying Data On LCD And PC
SHUVRA BANIK 5/1/2012
Abstract
The Global Positioning System (GPS) is a navigation system which provides location and time information using satellites orbiting the earth. A GPS receiver can locate satellites and their distances from its position and based on those distances, it uses a simple mathematical calculation called Trilateration by which can provide location information very accurately. GPS receivers are getting very popular nowadays for their simplicity to use. In this project a basic GPS receiver unit has been interfaced with a microcontroller and the data found have been shown in both LCD and PC.
Table Of Contents
Page Number Introduction Components Hardware Working Principles How To Locate Circuit Diagram GPS Receiver (Garmin GPS 18 LVC, 5m) LCD Module (4*20 Serial LCD Module (BPP-420) v4.0) Project Setup NMEA 0183 Protocol Initial Programming Strategy RDA Interrupts External Interrupts Direct Data Read Final Programming Outline Changes Made After Final Presentation Explanation OF Final Code Main Function Option, Display Related Functions GPS Parsing Functions Other Supportive Functions 4 5 5 7 7 8 8 8
9 10 11 11 12 13 15 15 17 17 17 18 18
LCD Functions All Functions Summary Final Output LCD Display PC Display Conclusion References Appendix Final Code
19 20 21 21 24 27 28 29 29
Introduction
A GPS system is a space-based satellite navigation system developed by U.S. Department of Defense in 1973 which became fully operational in 1994. Its basically a constellation of 27 satellites (24 are active at a time and 3 are standby). Each of these satellites makes two complete rotations every day around the Earth in some predefined orbits and the orbits are arranged in such a way that at anytime, anywhere on Earth, there are at least four satellites visible in the sky. Low Power Radio Signal at 1575.42 MHz in the UHF band is used to send signal from satellites to GPS receiver. In this project a Garmin GPS 18 LVC, 5m GPS receiver has been interfaced with a CCS PIC18F4520 Development Kit. Sentences have been sent to GPS receiver to control which output sentences it should transmit. Sentences from the GPS receiver have been parsed with different string manipulations and resulting data have been showed in both LCD and PC.
Components
Hardware
Breadboard A 3.25X2.125 400PNT breadboard has been used to place the electronic circuits.
Figure 1: Breadboard Wires Wires have been used to connect electronic devices on the breadboard.
Figure 2: Wires GPS Receiver A Garmin GPS 18 LVC, 5m has been used as GPS receiver.
LCD Module A 4*20 Serial LCD Module (BPP-420) v4.0 has been used.
Figure 4: 4*20 Serial LCD Module (BPP-420) v4.0 Development Kit One CCS PIC18F4520 Development Kit has been used.
Working Principles
How To Locate
A GPS receiver receives radio signals from visible satellites and to locate a place on earth, at least distances from 3 satellites are required. To measure the distances, a GPS receiver measures the time required by the signal to reach from satellite to it. As, Velocity = Distance / Time, So, Distance = Velocity * Time. Here velocity of radio signal = Velocity of light. The process is called Trilateration. A figure of 2D Trilateration is given in the figure. Actually to locate a place on the earth, 3D Trilateration is used but the basic principal is like 2D Trilateration.
Figure 6: 2D Trilateration
Circuit Connection
The circuit connection of project is shown below.
Project Setup
A picture of the final setup is given below.
Figure 7: Setup
10
Figure 9: Ring Buffer Used RDA interrupt code is given below. For the GPS receiver used in this project, RDA interrupts didnt trigger at all. But the code was okay as it was tested for getting interrupts from keyboard.
#include <18f4520.h> #include <string.h> #fuses HS,NOLVP,NOWDT,PUT #use delay(clock=20000000) #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,STREAM=pc) #use rs232(baud=4800,parity=N,INVERT,rcv=PIN_C3,STREAM=gps,ERRORS)
void main() { enable_interrupts(INT_RDA); enable_interrupts(GLOBAL); fprintf(pc,"\r\n\Running...\r\n"); // The program will delay for 10 seconds and then display // any data that came in during the 10 second delay do { delay_ms(10000); fprintf(pc,"\r\nBuffered data => "); while(bkbhit) fputc(bgetc(),pc); } while (TRUE); }
External Interrupts
To solve problem with RDA Interrupts, CCS forum site was visited and it was found that a lot of users faced similar problem. So, new idea was to use External Interrupts. Same code for RDA Interrupts had 12
been used except INT_RDA was replaced by INT_EXT and a Jumper was used to connect output pin PIN_C3 of GPS receiver with External Interrupt pin PIN_B0 of microcontroller. And interrupts were triggered this time. But some problems arose to work with External Interrupts like: Characters were missed from the sentences during interrupts. Old data was replaced in ring buffer system sometimes which erased desired data. disable_interrupts(INT_EXT) and disable_interrupt(GLOBAL) didnt stop External Interrupts immediately.
#include <18f4520.h> #fuses HS,NOLVP,NOWDT,PUT #use delay(clock=20000000) #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,STREAM=pc) #use rs232(baud=4800,parity=N,INVERT,rcv=PIN_C3,STREAM=gps,ERRORS)
void main() { char c; delay_ms(3000); do { c = fgetc(gps); // Get character from PC fputc(c,pc); // Send it back to the PC } while(TRUE); }
This code basically logs data continuously in the PC screen. Same sentences are repeated over time. Some logged data are given below.
13
$GPGSV,3,1,12,05,04,305,00,06,00,000,00,07,67,350,00,08,34,311,00*75 $GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70 $GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72 $PGRMT,GPS 18LVC - software ver. 2.90,P,P,R,R,P,C,28,R*77 $GPRMC,070837,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*7A $GPGGA,070837,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*42 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPGSV,3,1,12,05,04,305,00,06,00,000,00,07,67,350,00,08,34,311,00*75 $GPGSV,3,2,12,09,00,000,00,10,00,000,00,11,00,000,00,12,00,000,00*70 $GPGSV,3,3,12,13,00,000,00,14,00,000,00,15,00,000,00,28,20,254,44*72 $GPRMC,070838,V,3607.4154,N,09704.1496,W,,,180514,004.9,E*75 $GPGGA,070838,3607.4154,N,09704.1496,W,0,00,,,M,,M,,*4D
14
After enabling all output sentences, these data streams are repeated over time. Some logged data are given below. Highlighted sentences are new (Not default factory enabled sentences).
$PGRMV,,,*72 $PGRMF,,,290412,212300,,3607.8116,N,09704.7553,W,A,0,,,,*36 $PGRMB,,,,,,K,,,*2D $PGRMM,WGS 84*06 $GPRMC,212301,V,3607.8116,N,09704.7553,W,,,290412,004.9,E*73 $GPGGA,212301,3607.8116,N,09704.7553,W,0,00,,,M,,M,,*4E $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPGSV,3,1,12,03,37,134,00,06,36,113,00,07,23,281,34,10,15,315,00*71 $GPGSV,3,2,12,13,43,319,00,16,65,049,00,19,10,162,00,20,31,216,00*75 $GPGSV,3,3,12,23,76,326,00,30,37,045,00,32,22,189,00,51,47,197,00*72 15
$PGRME,,M,,M,,M*00 $GPGLL,3607.8116,N,09704.7553,W,212301,V*2E $GPVTG,,T,,M,,N,,K*4E $PGRMV,,,*72 $PGRMF,,,290412,212301,,3607.8116,N,09704.7553,W,A,0,,,,*37 $PGRMB,,,,,,K,,,*2D $PGRMM,WGS 84*06 $GPRMC,212302,V,3607.8116,N,09704.7553,W,,,290412,004.9,E*70 $GPGGA,212302,3607.8116,N,09704.7553,W,0,00,,,M,,M,,*4D $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPGSV,3,1,12,03,37,134,00,06,36,113,00,07,23,281,34,10,15,315,00*71
16
Main Function
Main function calls display functions to show the options on the LCD and PC. It receives chosen options from the user. Then it displays chosen options. Based on chosen option, it sends command to gps_input() function to store the desired sentence. Then it displays desired sentence and sends command to sub_string_finder() function to separate desired information of the user. It displays that information. It also does other tasks like calling utc_to_cst_time_converter() function to convert UTC Time to CST Time. Main function runs a continuous loop to show the options again when one complete cycle is done.
17
CST Time 7 PM 8 PM 9 PM 10 PM 11 PM 12 AM 1 AM 2 AM 3 AM 4 AM 5 AM 6 AM 7 AM 8 AM 9 AM 10 AM 11 AM 12 PM 1 PM 2 PM 3 PM 4 PM 5 PM 6 PM
UTC Time 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Offset
+7
-5
-17
LCD Functions
There are four functions for LCD display. These are void clear_func(), backlight_on(), new_line() and lcd_positioner(). clear_func() It clears LCD screen. backlight_on() It turns on the backlight of LCD. new_line() Move cursor to new line. lcd_positioner() It places cursor on right hand side of the LCD to print options from 5 to 8. 19
Main Functi on
LCD Functions
20
Final Output
LCD Display
One complete operation displayed on LCD has shown here.
21
22
23
PC Display
One complete operation displayed on PC has shown here.
GPS Choose 1,2,3,4,5,6,7 or 8 & then A,B,C or D 1. $GPRMC 2. $GPGGA 3. $GPGSA 4. $GPGSV 5. $PGRMT 6. $GPVTG 7. $GPGLL 8. $PGRMF r Wrong option! Please try again.... 1. $GPRMC 2. $GPGGA 3. $GPGSA 24
4. $GPGSV 5. $PGRMT 6. $GPVTG 7. $GPGLL 8. $PGRMF 2 A. UTC Time B. Latitude C. Longitude D. No. of Satellites g Wrong option! Please try again.... A. UTC Time B. Latitude C. Longitude D. No. of Satellites B You chose option 2B $GPGGA Latitude Calculated checksum in decimal 126 Original checksum in decimal 126 EQUAL! Selected NMEA 0183 Sentence => $GPGGA,094756,3607.7943,N,09704.7737,W,1,04,5.7,319.5,M,-26.3,M,,*7E 3607.7943 ddmm.mmmm N Thanks!
25
26
Conclusion
Before starting the project, I had no idea about how a GPS receiver works. Working on this project has helped me to achieve a clear conception about this. The project was mainly based on coding. I have written standalone functions and then combined all those functions to make the final code and it works fine. It was quite a good learning experience.
27
References
References found to be helpful for this project are: 1) GPS 18 Technical Specification by Garmin 2) http://electronics.howstuffworks.com/gadgets/travel/gps.htm 3) http://en.wikipedia.org/wiki/Global_Positioning_System
28
Appendix
Final Code
/* GPS_FINAL.C ---------------------by Shuvra Banik, MS Student, MAE, Oklahoma State University -------------------------------------------------------------------------------------
Program Summary: --------------------------This program will show 8 options from 1 to 8 at the beginning to choose any of these in both LCD and PC. Each option represents a GPS sentence received from the GPS receiver. When user chooses any of these options, he/she will get 4 submenus from A to D to see different information of chosen GPS sentence. User will have to choose any of these submenus. This program can handle wrong inputs. When both inputs are got from the user correctly, this program will display chosen options with corresponding strings. Then the program will do checksum calculation and will display result in both LCD and PC. If the checksum calculation is okay, it will proceed and will display the desired GPS sentence. Then it will show the desired information from the desired GPS sentence and finally it will return back to show 8 options again. This loop will continue until the power supply is cut off.
Connection Settings: ----------------------------GPS Receiver (Garmin GPS 18 LVC, 5m): ------------------------------------------------------Black (3) ---------- Ground of Microcontroller Red ---------- 5 V of Microcontroller White ---------- PIN_C3 of Microcontroller (Signal Output) Green ---------- PIN_C2 of Microcontroller (Signal Input) Yellow ---------- Not Used
LCD Module (4*20 Serial LCD Module (BPP-420) v4.0): --------------------------------------------------------------------------Black ---------- Ground of Microcontroller Black ---------- 5 V of Microcontroller White ---------- PIN_C0 of Microcontroller */
#include <18f4520.h>
#include <string.h> // Standard string operations #include <stdlib.h> // String to numer conversion operations #fuses HS,NOLVP,NOWDT,PUT // Set fuses #use delay(clock=20000000) // 20 MHz clock
/*----- Serial communications -----*/ #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,STREAM=pc) // PC #use rs232(baud=4800,parity=N,INVERT,xmit=PIN_C2,rcv=PIN_C3,STREAM=gps,ERRORS) // GPS #use rs232(baud=9600,parity=N,xmit=PIN_C0,INVERT,STREAM=lcd) // LCD
/*----- LCD constants -----*/ #define CLR 12 #define BLON 14 #define CR 13 #define CURSOR_POSITION_ENTRY 16 #define CURSOR_POSITION_BASE 64 #define REQ_CURSOR_POSITION 11
/*----- Global string lengths -----*/ #define MAX_BUFFER 82 #define SUB_BUFFER 11 #define OPTION_STRING_LENGTH 20 #define MAX_UNIT_STRING 20 #define MAX_TIME_STRING 7
/*----- Global string declarations -----*/ char store_data[MAX_BUFFER]; char sub_string[SUB_BUFFER]; char option_string[OPTION_STRING_LENGTH]; char unit_string[MAX_UNIT_STRING]; char cst_time_string[MAX_TIME_STRING];
/*----- Option, display related function declarations -----*/ void gps_output_ctrl_func(void); char option_showing_func(char start_char,char end_char,char selector_char); void select_func(char opt1,char opt2,int position_flag);
30
/*----- GPS parsing function declarations -----*/ void gps_input(*checker); void sub_string_finder(void);
/*----- Other supportive function declarations -----*/ int checksum_checker(void); unsigned int8 atoi_hex(char *string); void utc_to_cst_time_converter(char *sub_string);
/*----- LCD function declarations -----*/ void clear_func(void); void backlight_on(void); void new_line(void); void lcd_positioner(int position_increment);
void main() { // Main function variable declarations char opt1,opt2,dummy='0'; char checker[7]; char utc_time_string[]="hhmmss UTC";
clear_func(); // Clears up LCD screen delay_ms(2000); // Time given to turn on back light at the beginning backlight_on(); // Turns on backlight fprintf(pc,"\r\nGPS\r\n "); fprintf(lcd,"GPS"); new_line(); // Moves to new line in LCD fprintf(pc,"\r\nChoose 1,2,3,4,5,6,7 or 8 & then A,B,C or D\r\n "); fprintf(lcd,"Choose 1,2,3,4,5,6, 7 or 8 & then A,B,C or D"); gps_output_ctrl_func(); // Controls which sentences GPS unit should transmit
while(TRUE) { clear_func(); opt1=option_showing_func('1','8',dummy); // Displays 8 options from 1 to 8 for 8 GPS sentences // Gets opt1 opt2=option_showing_func('A','D',opt1); // Displays 4 submenus from A to D under each sentence
31
// Gets opt2 fprintf(pc,"\r\nYou chose option "); // Shows chosen option fprintf(lcd,"You chose option "); fprintf(pc,"%c%c\r\n\r\n ",opt1,opt2); fprintf(lcd,"%c%c",opt1,opt2); new_line(); select_func(opt1,dummy,0); // Sending position_flag=0 fprintf(pc,option_string); fprintf(lcd,option_string); fprintf(pc," "); fprintf(lcd," "); strcpy(checker,option_string); // Saves chosen first option_string to send to gps_input() select_func(opt1,opt2,1); // Sending position_flag=1 to get unit_string, comma_position // and sub_string_comma_position fprintf(pc,option_string); fprintf(pc,"\r\n "); fprintf(lcd,option_string); delay_ms(5000);
gps_input(checker); // Stores the desired GPS sentence in store_data string clear_func(); fprintf(pc,"\r\nSelected NMEA 0183 Sentence =>\r\n "); fprintf(pc,"\r\n%s\r\n ",store_data); clear_func(); fprintf(lcd,"NMEA 0183 Sentence =>"); delay_ms(2000); clear_func(); fprintf(lcd,"%s",store_data); delay_ms(5000); sub_string_finder(); // Finds desired data like time or latitude etc. from store_data string fprintf(pc,"\r\n%s %s ",sub_string,unit_string); clear_func(); fprintf(lcd,"%s %s",sub_string,unit_string);
// Prints CST time with UTC time if(strcmp(unit_string,utc_time_string)==0) { utc_to_cst_time_converter(sub_string); // Converts UTC time string to CST time string fprintf(pc,"\r\n\r\n%s %s ",cst_time_string,"hhmmss CST"); new_line(); fprintf(lcd,"%s %s",cst_time_string,"hhmmss CST");
32
// Used for printing second sub_string like in case of latitude, both latitude // and hemisphere will be printed if (sub_string_comma_position!=0) { comma_position=sub_string_comma_position; sub_string_finder(); fprintf(pc,"%s ",sub_string); new_line(); fprintf(lcd,"%s",sub_string); sub_string_comma_position=0; }
/*----- Option, display related functions -----*/ // Controls which sentences GPS unit should transmit // Here all output sentences have been enabled void gps_output_ctrl_func() { int i; //char output_contoller_string[]="$PGRMO,,2*75\r\n"; // Stops all output char output_contoller_string[]="$PGRMO,,3*74\r\n"; // Enables all output //char output_contoller_string[]="$PGRMO,,4*73\r\n"; // Restores factory default output sentences for (i=0;i<10;++i) { fprintf(gps,"%s",output_contoller_string); // Sends to GPS } delay_ms(3000); }
// Displays 8 options from 1 to 8 for 8 GPS sentences // Displays 4 submenus from A to B under each sentence // Takes user inputs char option_showing_func(char start_char,char end_char,char selector_char)
33
{ // option_showing_func variable declarations char i,option; int position_increment=0; // Initially no position_increment is needed
for(;;) { for(i=start_char;i<end_char+1;++i) { fprintf(pc,"\r\n%c. ",i); // For printing on right hand side of LCD if(!(i>='5'&& i<='8')) // i!='5' && i!='6' && i!='7' && i!='8' { fprintf(lcd,"%c. ",i); } if (selector_char=='0') { select_func(i,selector_char,0); // Sending position_flag=0 // Pulls out appropriate option_string } else { select_func(selector_char,i,0); // Sending position_flag=0 // Pulls out appropriate option_string } fprintf(pc,option_string); fprintf(pc,"\r\n "); // For printing on right hand side of LCD if(!(i>='5'&& i<='8')) { fprintf(lcd,option_string); new_line(); } else { lcd_positioner(position_increment); // Positions cursor at certain location on LCD fprintf(lcd,"%c. ",i); fprintf(lcd,option_string); position_increment=position_increment+20; // Prints on right hand side of LCD } } option=fgetc(pc);
34
clear_func(); if(option>=start_char && option<=end_char) { break; } else { fprintf(pc,"\r\nWrong option! Please try again....\r\n "); fprintf(lcd,"Wrong option! Please try again...."); delay_ms(3000); clear_func(); position_increment=0; // Using it cause if not used, for two // consecutive wrong input, alignment in LCD can be changed continue; // Sends back user to options again for wrong input } } return option; // Sends user input to Main function }
// For each option from 1 to 8, there are 4 submenus from A to D // Pulls out appropriate option_string, unit_string // Pulls out appropriate comma_position, sub_string_comma_position void select_func(char opt1,char opt2,int position_flag) { switch(opt1) { case '1': strcpy(option_string,"$GPRMC"); switch(opt2) { case 'A': strcpy(option_string,"UTC Time"); if(position_flag) { strcpy(unit_string,"hhmmss UTC"); comma_position=1; } break;
35
} break;
case '2': strcpy(option_string,"$GPGGA"); switch(opt2) { case 'A': strcpy(option_string,"UTC Time"); if(position_flag) { strcpy(unit_string,"hhmmss UTC"); comma_position=1; } break;
36
case '3': strcpy(option_string,"$GPGSA"); switch(opt2) { case 'A': strcpy(option_string,"Mode"); if(position_flag) { strcpy(unit_string,"M=Manual,A=Auto"); comma_position=1; } break;
37
case '4': strcpy(option_string,"$GPGSV"); switch(opt2) { case 'A': strcpy(option_string,"Sat. In View"); if(position_flag) { strcpy(unit_string,""); comma_position=3; } break;
38
comma_position=5; } break;
case '5': strcpy(option_string,"$PGRMT"); switch(opt2) { case 'A': strcpy(option_string,"Model & Version"); if(position_flag) { strcpy(unit_string,""); comma_position=1; } break;
if(position_flag) {
39
case 'D': strcpy(option_string,"Stored Data Lost"); if(position_flag) { strcpy(unit_string,"R=Retained,L=Lost"); comma_position=4; } break; } break;
case '6': strcpy(option_string,"$GPVTG"); switch(opt2) { case 'A': strcpy(option_string,"Dead Option!"); if(position_flag) { strcpy(unit_string,""); comma_position=0; } break;
40
comma_position=0; } break;
case '7': strcpy(option_string,"$GPGLL"); switch(opt2) { case 'A': strcpy(option_string,"Latitude"); if(position_flag) { strcpy(unit_string,"ddmm.mmm"); comma_position=1; sub_string_comma_position=2; } break;
41
case 'C': strcpy(option_string,"Pos. Fix Time"); if(position_flag) { strcpy(unit_string,"hhmmss UTC"); comma_position=5; } break;
case '8': strcpy(option_string,"$PGRMF"); switch(opt2) { case 'A': strcpy(option_string,"Pos. Fix Date"); if(position_flag) { strcpy(unit_string,"ddmmyy UTC"); comma_position=3; } break;
42
comma_position=4; } break;
/*----- GPS parsing functions -----*/ // Takes first option string checker from Main functions // Compares checker with the incoming GPS sentences // If matches, stores the desired GPS sentence in store_data string void gps_input(*checker) { // gps_input() variable declarations char c; char temp[7]; int i=0; int state=0; int checksum_result;
while(TRUE) {
43
c=fgetc(gps); if(c=='$') // Starts storing data if the input character is '$' state=1; if(state) { store_data[i]=c; if(i<6) temp[i]=c; ++i; if (i==6) { temp[i]='\0'; if((strcmp(temp,checker))!=0) // Compares if sentence being stored is desired {i=0; state=0;} } if(state && c=='\r') // Ends storing if '\r' is received { store_data[i]='\0'; i=0; state=0; checksum_result=checksum_checker(); // Gets checksum_result from checksum_checker() // Compares original checksum with calculated checksum for parity checking if(checksum_result) { break; } else { continue; } } } } }
// Finds desired data like time or latitude etc. from store_data string void sub_string_finder(void) { //sub_string_finder variable declarations int i,j=0,count=0,store_data_length; store_data_length=strlen(store_data);
44
if (comma_position==0) { strcpy(sub_string,"Not Available"); return; } for (i=0;i<store_data_length;++i) { if(store_data[i]==',') ++count; // Checks if current comma_position equals to desired comma_position if (count==comma_position) { ++i;
while(store_data[i]!=',') // Stores data until next ',' is found { sub_string[j]=store_data[i]; ++j; ++i; }
/*----- Other supportive functions -----*/ // Compares original checksum with calculated checksum for parity checking int checksum_checker() { // checksum_checker() variable declarations int i=0; int checksum_result; unsigned int8 checksum=0; unsigned int8 original_checksum; char *store_data_ptr=store_data+1; // Points 2nd character of store_data string char original_checksum_string[3];
// Xoring loop until '*' is found in store_data string while (*store_data_ptr != '*')
45
clear_func(); // Prints calculated checksum fprintf(pc,"\r\nCalculated checksum in decimal %d\r\n ", checksum); fprintf(lcd,"Cal. checksum %d", checksum); new_line(); store_data_ptr++; //Now pointing checksum data in store_data string // Getting original checksum from store_data in string format while (*store_data_ptr != '\0') { original_checksum_string[i]=*store_data_ptr; store_data_ptr++; ++i; }
original_checksum_string[i]='\0'; // Converts a string of two hex characters to a unsigned int8 original_checksum=atoi_hex(original_checksum_string); // Prints original checksum fprintf(pc,"\r\nOriginal checksum in decimal %d\r\n ", original_checksum); fprintf(lcd,"Ori. checksum %d", original_checksum); new_line(); // Compares original checksum with calculated checksum for parity checking if(checksum==original_checksum) { fprintf(pc,"\r\nEQUAL!\r\n "); fprintf(lcd,"EQUAL!"); delay_ms(5000); clear_func(); checksum_result=1; }
46
fprintf(lcd,"Trying..."); checksum_result=0; }
return checksum_result; }
// Converts a string of two hex characters to a unsigned int8 unsigned int8 atoi_hex(char *string) { // atoi_hex() variable declarations unsigned int8 converted_num = 0; int i;
for (i=0; i<2; i++,string++) { if (*string >= 'A') converted_num=16*converted_num+(*string)-'A'+10; else converted_num=16*converted_num+(*string)-'0'; } return converted_num; }
// Converts UTC time string to CST time string // Here sub_string is in "hhmmss" format in UTC void utc_to_cst_time_converter(char *sub_string) { // utc_to_cst_time_converter variable declarations int i,utc_hr_int,cst_hr_int; int negative_offset=5; // For CST time with daylight saving char *ptr; char utc_min_sec_string[5]; char utc_hr_string[3]; char cst_hr_string[3]; char temp[3]; ptr=sub_string+2; // Points first minute character in sub_string
47
{ utc_min_sec_string[i]=*ptr; ++ptr; } utc_min_sec_string[i]='\0'; strncpy (utc_hr_string, sub_string,2); // Stores "hh" string in utc_hr_string from sub_string utc_hr_int=atoi(utc_hr_string); // Converts "hh" string in utc_hr_string to integer format
// Offsets utc_hr_int to find CST hours if(utc_hr_int<06) { cst_hr_int=utc_hr_int+negative_offset+2; // Here utc_hr_int+negative_offset+2 = 7 } else if(utc_hr_int>05 && utc_hr_int<18) { cst_hr_int=utc_hr_int-negative_offset; } else { cst_hr_int=utc_hr_int-(12+negative_offset); // Here 12+negative_offset = 17 }
if(strlen(cst_hr_string)<2) //Adds extra 0 with "h" to show in "hhmmss" format if only one h is found { strcpy(temp,"0"); strcat(temp,cst_hr_string); strcpy(cst_hr_string,temp); } // Concatenates CST hour string "hh" with rest "mmss" string //to get final CST time string strcpy(cst_time_string,cst_hr_string); strcat(cst_time_string,utc_min_sec_string); }
48
/*----- LCD functions -----*/ // Clears up LCD screen void clear_func() { int i; for(i=0;i<10;++i) { fprintf(lcd,"%c",CLR); } }
// Positions cursor at certain location on LCD void lcd_positioner(int position_increment) { fprintf(lcd,"%c",CURSOR_POSITION_ENTRY); fprintf(lcd,"%c",CURSOR_POSITION_BASE+REQ_CURSOR_POSITION+position_increment); }
49