Improved Parallax GPS raw reader

This more efficient code allows passing specific parameters by reference and uses a smaller buffer. Additional data could be referenced from the buffer and returned, if desired.

void get_gps_info(float *lat,float *lon,float *utc_mo, float *utc_da, float *utc_hr, float *utc_mn){

	/*
      get gps info from Parallax GPS receiver module -- coded for baby orangutan B
		inputs: none
		outputs: latitude,longitude,utc_month,utc_day,utc_hour,utc_minute
		GPS Info: http://www.parallax.com/Portals/0/Downloads/docs/prod/acc/GPSManualV1.1.pdf
      AVR Library Command Reference: http://www.robotshop.ca/content/PDF/pololu-avr-library-command-reference-1220.pdf
		Module must have clear view of sky and be level
		
		Baby O  <->    GPS	<->	7805	<->	Battery (14AH, AGM)
		PD0------------sio			Vin---------+12V
		vin------------vin---------+5Vout
		Gnd------------Gnd---------Gnd---------Gnd
							|	
		PC0---LED		Raw
	*/

   //format of Parallax GPS GPMRC string...
   //$GPMRC,HHMMSS,A,DDMM.MMMM,S,DDDMM.MMMM,S,KKK.K,HHH.H,DDMMYY,,,A*64
   //012345678901234567890123456789012345678901234567890123456789012345
   //          1         2         3         4         5         6      
   // $GPRMC string locations for following data items...

   int utc_hours=7, utc_minutes=9, latitude=16, latitude_hemisphere=26, longitude=28, longitude_hemisphere=39, utc_day=53, utc_month=55;

   serial_set_baud_rate(4800);
   char gps[66]; // array to store $GPRMS string
   char buf[1];
   char type[6] = "$GPRMC";
   int type_matched = 0;
   int byte_count;
   int i;

   while(!type_matched)
	{
		do // test for valid data before continuing...
		{
			serial_receive(buf,1);
			byte_count = serial_get_received_bytes();
			while(byte_count == 0) byte_count = serial_get_received_bytes();
		} while (buf[0] > 127); // invalid data
		
      while (buf[0]!='$')
      { // scan forward to next $...
         serial_receive(buf,1);
   	   byte_count = serial_get_received_bytes();
	      while(byte_count == 0) byte_count = serial_get_received_bytes();
      }
      gps[0]=buf[0];
      // is this $GPRMC?
      type_matched = 1;
      for (i=1;i<sizeof(type);i++)
      {
         serial_receive(buf,1);
   	   byte_count = serial_get_received_bytes();
	      while(byte_count == 0) byte_count = serial_get_received_bytes();
         gps[i]=buf[0];
         if(type[i]!=gps[i])
         {
            type_matched = 0;
            break;
         }
      }
      if (type_matched)
      {
         // get the rest of the line...
         for (i=sizeof(type);i<sizeof(gps);i++)
         {
            serial_receive(buf,1);
      	   byte_count = serial_get_received_bytes();
	         while(byte_count == 0) byte_count = serial_get_received_bytes();
            gps[i] = buf[0];
         }
      }
   }
 
   *lat = (gps[latitude+0]-48)*10+(gps[latitude+1]-48)+(float)((gps[latitude+2]-48)*10+(gps[latitude+3]-48))/60;
   if(gps[latitude_hemisphere]=='S') *lat=-*lat; // apply sign

   *lon = (gps[longitude+0]-48)*100+(gps[longitude+1]-48)*10+(gps[longitude+2]-48) \
         +(float)((gps[longitude+3]-48)* 10+(gps[longitude+4]-48))/60;
   if(gps[longitude_hemisphere]=='W') *lon = -*lon; // apply sign

   *utc_mo = (gps[utc_month   + 0]-48)*10+(gps[utc_month   + 1]-48);
   *utc_da = (gps[utc_day     + 0]-48)*10+(gps[utc_day     + 1]-48);
   *utc_hr = (gps[utc_hours   + 0]-48)*10+(gps[utc_hours   + 1]-48);
   *utc_mn = (gps[utc_minutes + 0]-48)*10+(gps[utc_minutes + 1]-48);
}