EM-406A problem.

I am trying to run the tinygps test code with a EM-406A and I keep getting this error spamming the console the light on my gps is on and I have it connected correctly as per the spec sheet. any Ideas as to what I am doing wrong?

Error inside Serial.serialEvent()

java.io.IOException: Bad file descriptor in nativeavailable

at gnu.io.RXTXPort.nativeavailable(Native Method)

at gnu.io.RXTXPort$SerialInputStream.available(RXTXPort.java:1532)

at processing.app.Serial.serialEvent(Serial.java:215)

at gnu.io.RXTXPort.sendEvent(RXTXPort.java:732)

at gnu.io.RXTXPort.eventLoop(Native Method)

at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)

ok now I got the code to run and it says

Testing TinyGPS library v. 9

by Mikal Hart

Sizeof(gpsobject) = 103

in the serial moniter and the gps is on and I think it has a lock (blinking led on gps)

shouldn’t it display the NEMA data now?

I am probably doing something wrong as I am new to all this.

Thanks in advance for your help.

If your code currently has:

NewSoftSerial nss(2, 3);

Try changing it to:

NewSoftSerial nss(3, 2);

This is because the example expects the transmit and receive pins to be in the opposite order.

–Philip;

I tried swapping the pins and it had no effect. Could my gps be running a different baud rate or have some other settings messed up?

Hi again,

Sorry, I just realised I was assuming you were using the module with the [Arduino GPS shield.

It’s possible that the baud rate is different but I think it’s standard to default to 4800 in general.

I think we’d need to see a photo/sketch of how you’ve got things wired up.

Since you’re using the ‘test_with_gps_device’ sketch you can replace the ‘feedgps’ function with this version which will print all it receives to the Serial console.

bool feedgps()
{
  while (nss.available())
  {
    int c = nss.read();
    Serial.print((char) c);
    if (gps.encode(c))
      return true;
  }
  return false;
}

If it prints nonsense then it suggests the baud rate could be the issue.

–Philip;](http://www.sparkfun.com/commerce/product_info.php?products_id=9487)

Below is the code I am using. The gps is connected to the +5v and ground as well as pin 2(rx) and 3(tx)

the gps lights up solid and after a few seconds to about a min it starts blinking.

the console displays this

Testing TinyGPS library v. 9

by Mikal Hart

Sizeof(gpsobject) = 103

#include <NewSoftSerial.h>
#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of NewSoftSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 2(rx) and 3(tx).
*/

TinyGPS gps;
NewSoftSerial nss(2, 3);

void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 2);

void setup()
{
  Serial.begin(115200);
  nss.begin(4800);
  
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  while (millis() - start < 5000)
  {
    if (feedgps())
      newdata = true;
  }
  
  if (newdata)
  {
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0)
  {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print("."); 

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint; 
  } 
}

void gpsdump(TinyGPS &gps)
{
  long lat, lon;
  float flat, flon;
  unsigned long age, date, time, chars;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned short sentences, failed;

  gps.get_position(&lat, &lon, &age);
  Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon); 
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  
  feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors

  gps.f_get_position(&flat, &flon, &age);
  Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.get_datetime(&date, &time, &age);
  Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): "); Serial.print(time);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  feedgps();

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  Serial.print("  Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print("."); Serial.print(static_cast<int>(hundredths));
  Serial.print("  Fix age: ");  Serial.print(age); Serial.println("ms.");
  
  feedgps();

  Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): "); Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed());
  Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): "); printFloat(gps.f_course()); Serial.println();
  Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): ");  printFloat(gps.f_speed_mph());
  Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): "); printFloat(gps.f_speed_kmph()); Serial.println();

  feedgps();

  gps.stats(&chars, &sentences, &failed);
  Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: "); Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}
  bool feedgps()
{
  while (nss.available())
  {
    int c = nss.read();
    Serial.print((char) c);
    if (gps.encode(c))
      return true;
  }
  return false;
}

Hi again,

Thanks for posting the code you are using.

Your description of the GPS module sounds like it’s getting a fix but even if it didn’t get a fix it would still be transmitting data which the modified ‘feedgps’ function should display.

If the baud rate was wrong, data would display but it would be nonsense characters.

That you don’t get any data displayed at all suggests that the Arduino is not receiving any data at all from the GPS. Can you try swapping the TX/RX jumpers again with the new feedgps code?

Are you able to double check the wiring and take a photograph of your wiring and modules?

Outside of that I’m running out of suggestions.

–Philip;

Ive made 2 different wiring harnesses and both test good for continuity. I dont have a digital camera at the moment so I am unable to take a picture of my setup. I have tried swapping the pins but it has no effect. I am starting to think maybe I have a bad unit.

If you’re hooking the unit up directly to the digital pins then there is a good chance you will not receive any data. Arduino uses 5 volt logic (0-5 volts) and the EM-406a uses 2.8 volt logic (0-2.8 volts). You’ll need a level shifter http://www.sparkfun.com/commerce/produc … ts_id=8745 to match the voltage levels to make it work. Also try downloading SIRFDEMO software and test the unit out to make sure it’s working.

The suggestion to consider a level shifter is a good one but I looked at the Arduino GPS Shield that is designed for the 406A and unless I’m missing something it doesn’t use any level shifting: http://www.sparkfun.com/datasheets/DevT … ld-v13.pdf

After taking another look at that schematic and the [406A data sheet I noticed that it says there are two ground pins and they both need to be connected–is this the case in your circuit?

–Philip;](http://www.sparkfun.com/datasheets/GPS/EM-406A_User_Manual.PDF)

I’m actually using an EM-408 which uses the same logic level as the EM-406. If you look at the datasheet for the Arduino the minimum value to register a logic high is 0.6 * Vcc. Assuming Vcc is 5 volts (probably a little lower) the minimum value would be 3.0 volts. Since the power supply, realistically will vary and is probably closer to 4.5 volts that puts you on the hairy edge of working. It should work most of the time (I just tried it on mine and the data was intermittently garbled) but it’s just good practice to use the correct voltage levels. Also you’re transmitting 5 volts from the Arduino to a 2.85 volt tolerant line, probably not the best idea but can be resolved by a simple voltage divider or just removing the Rx wire (unless you’re constantly sending polling requests or configuration information to the GPS) because you really only need the Tx wire to see the data coming out.

EM-406A’s definitely have a level shifting quirkiness. They have an onboard regulator that runs to ~3.3V. You’ll need to use some sort of up-level shifting if your uController is running at 5V.

I ordered a level shifter so I’ll try that once it gets here. both the ground wires are connected and I have been running my Arduino off of usb.

ok I got the level shifter but I am still having the same problem. I have the gps blinking but I only get the test message and no nema data in the arduino serial console.

I have the Tx and rx from the gps connected to the tx in on channel 1 and 2 and the tx outs going to the arduino board. any Ideas as to what I am doing wrong.

At this point I am frustrated enough to buy a GPS breakout board even though it wont fit inside my project just to see if the damn thing works but they are out of stock… :expressionless:

ok time for me to say it… Im officially a moron… I connected pin 1 and pin 4 to ground instead of pin 1 and pin 5 so the tx was never connected. works fine for me now even without logic shifter.

jolijar:
ok time for me to say it… Im officially a moron… I connected pin 1 and pin 4 to ground instead of pin 1 and pin 5 so the tx was never connected.

I think that's just called being human. Welcome to the club. :D

–Philip;