Software Serial Two Port Recieve with GPS and Xbee

I'm using a RBBB and trying to alternately read in from a GPS module (using the TinyGPS library) and an Xbee, both over SoftwareSerial.

I'm aware of http://arduino.cc/en/Tutorial/TwoPortReceive and have previously used this method to successfully read in from two GPS modules, however I don't seem to be able to get the GPS and Xbee combination working.

For this stripped down version of the code I'd like to see output to serial monitor similar to the following if I send a '1' and then a '2' via XBee:

.
.
.
listening to xbee
Xbee available
1
read gps
time: 18584900, pos (f): 51.xxxxxx, -2.xxxxxx
listening to xbee
Xbee available
2
read gps
time: 18585000, pos (f): 51.xxxxxx, -2.xxxxxx
.
.
. etc

However, this is what I get:
.
.
.
listening to xbee
Xbee data not available
read gps
time: 18585000, pos (f): 51.xxxxxx, -2.xxxxxx
listening to xbee
Xbee data not available
read gps
time: 18585300, pos (f): 51.xxxxxx, -2.xxxxxx
.
.
.

I can get the GPS data, but not the Xbee. (I've checked the Xbee wiring etc). Everything I've tried gives me that 'Xbee data not available' debugging line.

Here's the code:

#include <SoftwareSerial.h> //includes the software serial library
#include <TinyGPS.h>  // includes the TinyGPS library

/* 
 Based on TinyGPS by Mikal Hart
 */

TinyGPS gps;
SoftwareSerial gpsmodule(10, 9);  
SoftwareSerial XbeeSerial(4, 3);

// a byte to receive data:
char inByte = 0;

//some variables...

float flat, flon; // +/- latitude/longitude in degrees
unsigned long date, time, age; // what they say on the tin
long lat, lon; // +/- lat/long in 100000ths of a degree

int GPSpower = 6;

void setup()  //this section of code runs once when you start the microcontroller
{
  Serial.begin(115200);  // serial communication between the microcontroller and the computer
  gpsmodule.begin(4800); // serial communication between the gps module and the microcontroller
  XbeeSerial.begin(9600);


  pinMode(GPSpower, OUTPUT); 
  digitalWrite(GPSpower, HIGH);
} //end setup


void loop() //this section of code runs ad infinitum, looping until you make it stop
{
  XbeeSerial.listen();
  Serial.println("listening to xbee"); 
  // get any incoming data from xbee:
  if (XbeeSerial.available() > 0) {
    Serial.println("Xbee available"); 
    // read a byte
    inByte = XbeeSerial.read();
    Serial.println(inByte); 
  }

  else {
    Serial.println("Xbee data not available"); 
  }

  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  Serial.println("read gps ");
  gpsmodule.listen();
  for (unsigned long start = millis(); millis() - start < 1500;)
  {
    while (gpsmodule.available())
    {
      char c = gpsmodule.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }

  }

  if (newData)
  {
    Serial.print("time: ");
    gps.get_datetime(&date, &time, &age); 
    Serial.print(time); 
    Serial.print(", ");  
    Serial.print("pos (f): ");
    gps.f_get_position(&flat, &flon, &age);  
    Serial.print(flat, 6);  
    Serial.print(", ");  
    Serial.println(flon, 6); 

  } //end newData


} //end loop

Have I messed up on the 2 port receive implementation somewhere?
Thanks.

If you summarize your code, it looks like

void loop() //this section of code runs ad infinitum, looping until you make it stop
{
  XbeeSerial.listen();
  if (XbeeSerial.available() > 0)
  {
  }

  gpsmodule.listen();
  for (unsigned long start = millis(); millis() - start < 1500;)
  {
      // listen for 1.5 seconds
  }
}

You spend hardly any time listening to the XBee. It's no wonder you never hear anything from it.

Ah, thanks PaulS, that triggered a memory for me and I went back to the Arduiniana nss documentation and I think I understand now.

So, whereas with a single serial source the incoming data gets buffered (is that the right word?) and it'll sit there until the loop comes around to it again, with two sources the buffer gets emptied when you switch to listening to a different device, so the signal only gets heard if it arrives during the time when the arduino is explicitly listening to it.

So, I need to repeat my broadcast at a frequency that's shorter than the amount of time I'm listening. For example I changed the code to

XbeeSerial.listen();
  Serial.println("listening to xbee"); 
    for (unsigned long start = millis(); millis() - start < 3000;)
  {
    } 
  // get any incoming data from xbee:
  if (XbeeSerial.available() > 0) {
    Serial.print("Xbee data:  "); 
    // read a byte
    inByte = XbeeSerial.read();
    Serial.println(inByte); 
  }

  else {
    Serial.println("Xbee data not available"); 
  }

And prodded at the number keys at about 1Hz. This seems to work. (Think I'm going to need another Arduino on the broadcasting end, though!)

Thanks for pointing me in the right direction!

so the signal only gets heard if it arrives during the time when the arduino is explicitly listening to it.

Yes, that is right.

More and more, Arduinos are coming with multiple hardware serial ports. The Mega would allow you to have both devices connected to hardware serial ports and still be able to talk to the PC on Serial.

PaulS:
More and more, Arduinos are coming with multiple hardware serial ports. The Mega would allow you to have both devices connected to hardware serial ports and still be able to talk to the PC on Serial.

Sounds good!
In this instance my brief includes small (I'm putting them inside things) and cheap (making several of them), but it's a good point and could be a useful reminder for future projects - thanks!