Fastserial is messing me up

I’m using Arduino 1.0.3 and whenever I try to #include<SomeotherFoo.h> that doesn’t use Fastserial.h , I get errors about unint_8 . How do I not use FastSerial.h in my programs? How do I revert to the standard Arduino Serial? What is the name and location of the Standard that FastSerial replaces not so seemlessly?

Thanks

@Harry,
If you are working with the ArduPilot code, you need to use this version of the Arduino 1.0.3 IDE: http://ardupilot.com/downloads/?did=45 if you are not already using it.
Regards,
TCIII GM

I get the same errors with the modified 1.0.3 IDE. Fastserial is not compatible with the libraries I’m trying to use. That makes it really frustrating and googling tells me it’s a common problem. Is the standard Arduino library it’s modifying, Serial.h? I went so far as to try to rewrite AP_GPS_NMEA without classes. It almost worked but I only get 0’s for everything.

I maybe solved it. I went back to the original Ardupilot 2.7.1 and looked at how it parses NMEA . That doesn’t use Fastserial.h . I’m getting GPS data now and it’s good. I’m not sure about some of the other GPS data and what format it’s in but it’s a start.

I hate that library. :imp:

Here’s how I fixed it. I took the AP_GPS_NMEA code and stripped out all the class stuff and went through all the related files looking for variable definitions. It seems to work now. I’m getting position and some other GPS related stuff.

			///< true if we have a position fix
unsigned int imu_health = 65012;

void update(void)
{
	char c;
	int numc;
	int i;

	numc = Serial.available();
	
	if (numc > 0){
		for (i = 0; i < numc; i++){
			c = Serial.read();
			if (c == '$'){											// NMEA Start
				bufferidx = 0;
				buffer[bufferidx++] = c;
				GPS_checksum = 0;
				GPS_checksum_calc = true;
				continue;
				}
			if (c == '\r'){										 // NMEA End
				buffer[bufferidx++] = 0;
				parse_nmea_gps();


   	                Serial.print("!!!VER:");
	                Serial.print(SOFTWARE_VER);  //output the software version
	                Serial.print(",");
  			Serial.print("LAT:");
			Serial.print((float)current_loc.latitude);
			Serial.print(",LON:");
			Serial.print((float)current_loc.longitude);
			Serial.print(",ALT:");
			Serial.print((float)current_loc.altitude/1000);    // meters
			Serial.print(",COG:");
			Serial.print((float)ground_course/1000);	// degrees
			Serial.print(",SOG:");
			Serial.print((float)ground_speed/100);
			Serial.print(",FIX:");
			Serial.print((int)fix);				// 1 = good fix
			Serial.print(",SAT:"); 
			Serial.print(num_sats);
			Serial.print (",");
		        Serial.print(",IMUH:");
		        Serial.print((imu_health>>8)&0xff);
		        Serial.print(",");
	                Serial.print("TOW:");
	                Serial.print(time);
	                Serial.println("***"); 


			} else {
				if (bufferidx < (GPS_BUFFERSIZE - 1)){
					if (c == '*')
						GPS_checksum_calc = false;		// Checksum calculation end
					buffer[bufferidx++] = c;
					if (GPS_checksum_calc){
						GPS_checksum ^= c;						// XOR 
					}
				} else {
					bufferidx = 0;	 // Buffer overflow : restart
				}
			}
		}
	}
}

void parse_nmea_gps(void)
{
	uint8_t NMEA_check;
	long aux_deg;
	long aux_min;
	char *parseptr;
	static unsigned long GPS_timer = 0; //used to turn off the LED if no data is received. 
	

	if (strncmp(buffer,"$GPGGA",6)==0){					// Check if sentence begins with $GPGGA
		if (buffer[bufferidx-4]=='*'){					 // Check for the "*" character
			NMEA_check = parseHex(buffer[bufferidx - 3]) * 16 + parseHex(buffer[bufferidx - 2]);		// Read the checksums characters
			if (GPS_checksum == NMEA_check){			// Checksum validation
				//Serial.println("buffer");
				//_setTime();
                               GPS_timer = DIYmillis();
				valid_read = true;
				new_data = true;	// New GPS Data
				parseptr = strchr(buffer, ',')+1;
				//parseptr = strchr(parseptr, ',')+1;
				time = parsenumber(parseptr, 2);					// GPS UTC time hhmmss.ss
				parseptr = strchr(parseptr, ',')+1;
				aux_deg = parsedecimal(parseptr, 2);			// degrees
				aux_min = parsenumber(parseptr + 2, 4);		 // minutes (sexagesimal) => Convert to decimal
				//latitude = aux_deg * 10000000 + (aux_min * 50) / 3;	 // degrees + minutes / 0.6	( * 10000000) (0.6 = 3 / 5)
				current_loc.latitude = aux_deg * 10000000 + (aux_min * 50) / 3;	 // degrees + minutes / 0.6	( * 10000000) (0.6 = 3 / 5)
				
                                parseptr = strchr(parseptr, ',')+1;
				if ( * parseptr == 'S')
					latitude = -1 * latitude;							// South latitudes are negative
				parseptr = strchr(parseptr, ',')+1;
				// W longitudes are Negative
				aux_deg = parsedecimal(parseptr, 3);			// degrees
				aux_min = parsenumber(parseptr + 3, 4);		 // minutes (sexagesimal)
				//longitude = aux_deg * 10000000 + (aux_min * 50) / 3;	// degrees + minutes / 0.6 ( * 10000000)
				current_loc.longitude = aux_deg * 10000000 + (aux_min * 50) / 3;	// degrees + minutes / 0.6 ( * 10000000)
				
                                //longitude = -1*longitude;									 // This Assumes that we are in W longitudes...
				parseptr = strchr(parseptr, ',')+1;
				if ( * parseptr == 'W')
					longitude = -1 * longitude;							// West longitudes are negative
				parseptr = strchr(parseptr, ',')+1;
				fix = parsedecimal(parseptr, 1);
				parseptr = strchr(parseptr, ',')+1;
				num_sats = parsedecimal(parseptr, 2);
				parseptr = strchr(parseptr, ',')+1; 
				HDOP = parsenumber(parseptr, 1);					// HDOP * 10
				parseptr = strchr(parseptr, ',')+1;
				//altitude = parsenumber(parseptr, 1) * 100;	// altitude in decimeters * 100 = milimeters
				current_loc.altitude = parsenumber(parseptr, 1) * 100;	// altitude in decimeters * 100 = milimeters
				
                                if (fix < 1)
					quality = 0;			// No FIX
				else if(num_sats < 5)
					quality = 1;			// Bad (Num sats < 5)
				else if(HDOP > 30)
					quality = 2;			// Poor (HDOP > 30)
				else if(HDOP > 25)
					quality = 3;			// Medium (HDOP > 25)
				else
					quality = 4;			// Good (HDOP < 25)
			} else {
				//_error("GPSERR: Checksum error!!\n");
			}
		}
	} else if (strncmp(buffer,"$GPVTG",6)==0){				// Check if sentence begins with $GPVTG
		//Serial.println(buffer);
		if (buffer[bufferidx-4]=='*'){					 // Check for the "*" character
			NMEA_check = parseHex(buffer[bufferidx - 3]) * 16 + parseHex(buffer[bufferidx - 2]);		// Read the checksums characters
			if (GPS_checksum == NMEA_check){			// Checksum validation
				//_setTime();
                                GPS_timer = DIYmillis();
				valid_read = true;
				new_data = true;	// New GPS Data
				parseptr = strchr(buffer, ',')+1;
				ground_course = parsenumber(parseptr, 1) * 10;			// Ground course in degrees * 100
				parseptr = strchr(parseptr, ',')+1;
				parseptr = strchr(parseptr, ',')+1;
				parseptr = strchr(parseptr, ',')+1;
				parseptr = strchr(parseptr, ',')+1;
				parseptr = strchr(parseptr, ',')+1;
				parseptr = strchr(parseptr, ',')+1;
				ground_speed = parsenumber(parseptr, 1) * 100 / 36; // Convert Km / h to m / s ( * 100)
				//GPS_line = true;
			} else {
				//_error("GPSERR: Checksum error!!\n");
			}



		}
	} else {
		bufferidx = 0;
		//_error("GPSERR: Bad sentence!!\n");
                GPS_timer = DIYmillis(); //Restarting timer...
	}

   

  

}

 // Parse hexadecimal numbers
uint8_t parseHex(char c) {
		if (c < '0')
			return (0);
		if (c <= '9')
			return (c - '0');
		if (c < 'A')
			 return (0);
		if (c <= 'F')
			 return ((c - 'A')+10);
}

// Decimal number parser
long parsedecimal(char *str, uint8_t num_car) {
	long d = 0;
	uint8_t i;
	
	i = num_car;
	while ((str[0] != 0) && (i > 0)) {
		if ((str[0] > '9') || (str[0] < '0'))
			return d;
		d *= 10;
		d += str[0] - '0';
		str++;
		i--;
	}
	return d;
}

// Function to parse fixed point numbers (numdec=number of decimals)
long parsenumber(char *str, uint8_t numdec) {
	long d = 0;
	uint8_t ndec = 0;
	
	while (str[0] != 0) {
		 if (str[0] == '.'){
			 ndec = 1;
		} else {
			if ((str[0] > '9') || (str[0] < '0'))
				return d;
			d *= 10;
			d += str[0] - '0';
			if (ndec > 0)
				ndec++;
			if (ndec > numdec)	 // we reach the number of decimals...
				return d;
		}
		str++;
	}
	return d;
}

I say it seems to be working. For some reason it’s not parsing the “W” . I know the longitude should show as negative if the $GPRMC contains a W and it’s not. Anybody have any idea why?

I found it. I set it up like in Ardupilot 2.7.1 which uses Struct for lat and lon and forgot to add current_loc.longitude to the little bit that parses the W.

Looks like someone has a better more general solution for Fastserial.h

http://diydrones.com/forum/topics/compiling-arduimu-sketch-with-arduino-1-0-3

For what it’s worth, the solution to FastSerial.h in the link works great. http://diydrones.com/forum/topics/compiling-arduimu-sketch-with-arduino-1-0-3

In case it gets deleted or something I’ll quote the instructions.

[quote] 1. Install the new Arduino (Current version 1.0.3)
2 Copy old library folders from old Arduino install folder to the new one. The libraries you are going to need are AP_GPS, AP_Math, AP_Compass and FastSerial.
3. Open Arduino 1.0 (or restart it if you already had it opened) and open your ArduIMU sketch. You should see these libraries in the list of libraries used by Arduino.
4. Go to the HMC5883 tab and replace all instances of Wire.send to Wire.write and Wire.receive to Wire.read
5.Go to your FastSerial folder (the one you copied to the Arduino library folder. Open file FastSerial.h in your favorite text editor and change the line virtual void write(unit8_t c); to virtual size_t write(unit8_t c); Save the file
6. Open FastSerial.cpp and change void FastSerial::Write(unit8_t c) to size_t FastSerial::Write(unit8_t c) A couple of lines below in the same function change return; to return 0; and at the bottom of the function right before the bracket add return i;
7. In the same file (FastSerial.cpp) go back to the top and change #include “WProgram.h” to #include “Arduino.h” Save the file and close. Now go through all the library folders which you added (AP_GPS, AP_Math, AP_Compass) Open every *.cpp file in every folder and do the same thing (change WProgram.h to Arduino.h) with the exception of APM_Compass.cpp
8. Open APM_Compass.cpp delete #include “WProgram.h” and add #include “Arduino.h” before extern “C” {
9. Now parse through the text of the file (APM_Compass.cpp) and repeat step 4 (find and replace all instances of Wire.send to Wire.write and Wire.receive to Wire.read [/quote]

I had to #include <Arduino.h> instead of “Arduino.h” and then it worked. At this point I consider the issue solved since it works and I’m now able to use the AP_GPS and FastSerial library in sketches written on Arduino 1.0.3 It was a major pain in the @$$ before.