Garbage returning from GPS EM406-A (Arduino UNO) - SOLVED

Hello,

I`m having a hard time trying to read data from the EM-406A. The unit seems to be working - at least partially, but I get nothing but 'garbage' from it.

First I´ve connected only EM´s pins 1 and 5 to GND and 2 to +5V. The EM406 red led lit, and after a couple of hours in an open environment it started to blink, indicating a fixed position.

Problem starts when I try to read the NMEA strings. First I connected EM pin 4 to one of Arduino´s digital I/O pin and tried a bunch of ways to read the serial data ( SoftwareSerial, reading with digitalRead() from pin considering the asynchronous serial protocal, etc ) with no success. To isolate the problem I tried the simple code below suggested by wayneft in another thread:

void setup(){
  digitalWrite(0,LOW);
  pinMode(0,INPUT);
  digitalWrite(1,LOW);
  pinMode(1,INPUT);
}

void loop(){
  while(1);
}

After connecting the GPS Tx to the Tx pin on my UNO I´ve got the same 'garbage' in the serial monitor, no matter the baud rate used - the expected baud rate should be 4800.

Now, I use 'garbage' between '' because there seems to be a pattern in the strings I´m getting. For instance, this is some of the data from the serial monitor:

[[bunch of non printable]]?ª¨Èè?A??$H9???Eº?Ad J¨-ª¨h(­-??ÍN(/(? +?(ª¨È)-ò$rÈJJJÅE[[bunch of non printable]] ???(-ò誨H[[bunch of non printable]]È????Eº?ÇèHÕ?âÿ¨h(­mÚ?Í^(/(Ú?HAIª¨È)-ò?rÈJJJÅE

So, there are sequences like "ÈJJJÅE" that repeat along the stream. That indicates that there is a pattern underneath. I´m aware about the GPS´ 2.85V level and Arduino expecting 5, but there are so many reports of success in using this unit without any level circuitry that I expected that to work.

Any thoughts?

Thanks in advance,

Is the GPS output TTL or the inverted rs232?

From http://www.sparkfun.com/datasheets/GPS/EM-406A_User_Manual.PDF

Protocol Electrical level TTL level, Output voltage level: 0V ~ 2.85V RS-232 level Baud rate 4,800 bps

Maybe the logic is inverted, I´ll try that tomorrow. That would explain the pattern. But what puzzles me is that there are many reports of this GPS model being used, with source, and none implement an inverted logic.

Hi, I saw forum stuff a year ago that said it was inverted if you took the direct TTL level signal, and the optional RS232 interface inverted it back...

The fact that you see repetitive garbage sounds like inversion also...

Regards, Terry King ...In The Woods In Vermont terry@yourduino.com

For simple tx inversion you can drop by radio shack for an npn transistor and two 10k resistors like below.

http://www.scienceprog.com/alternatives-of-max232-in-low-budget-projects/

Thanks for all that replied.

Well, I tried to solve the issue by software with no success. The code below is a stripped down
version of code posted elsewhere as an example on how to get data from the EM406-A. I´ve
changed it to read all data in a buffer first, to avoid timing issues, and changed the logic of
detecting IDLE and START bits. Got no valid data for all combinations.

#define bit4800Delay 188
#define halfBit4800Delay 94

byte rx = 7;

// Control logic for IDLE, START BIT, etc.
byte IDLE;
byte START;

// EM406 serial content is stored here
#define MAX_SIZE 1100
byte output[ MAX_SIZE ];

void setup() {
  pinMode( rx, INPUT );
  Serial.begin( 9600 );
  // Init buffer with all 1s
  for( int i = 0; i < MAX_SIZE; i++ ) {
    output[i] = 255;
  }
}

char SWread() {
  byte val = 0;
  while (digitalRead(rx) == IDLE );
  //wait for start bit
  if( digitalRead(rx) == START ) {
    delayMicroseconds( halfBit4800Delay );
    for (int offset = 0; offset < 8; offset++) {
	delayMicroseconds( bit4800Delay );
	val |= digitalRead( rx ) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit4800Delay);
    delayMicroseconds(bit4800Delay);
    return val;
  } else {
    return 'A';
  }
}

void loop()
{
  // Inverted logic for IDLE and START bits. Tried
  // also with IDLE=HIGH and START=LOW
  IDLE = LOW;
  START = HIGH;
  for( int i = 0; i < MAX_SIZE; i++ ) {
    output[i] = SWread();    
  }
  Serial.println( "Direct" );
  for( int i = 0; i < MAX_SIZE; i++ ) {
    Serial.print( output[i], BYTE );
  }
  Serial.println( "Inverse" );
  for( int i = 0; i < MAX_SIZE; i++ ) {
    byte inv = ~output[i];
    Serial.print( inv, BYTE );
  }
  while( 1 ) {
  }
}

With or without the inversion guess the way to go is first convert the signal levels to
0~5V just to be sure.

In the meantime it would be great to have any report on the use of this module
with the Uno.

First thing I would do is verify the GPS is working. Download the below code and connect the GPS Tx pin to the Arduino Tx pin. Next open up serial monitor and cycle through the baud rates until you see valid NMEA sentences. I believe the default baud rate is 4800. If/when you see valid sentences then you'll know it's working and the baud rate the unit is configured to.

void setup(){
  pinMode(0,INPUT);
  digitalWrite(0,LOW);
  pinMode(1,INPUT);
  digitalWrite(1,LOW);
}

void loop(){
  while(1);
}

Hello Wayne, that was my starting point - at least for the forum post, before that I´ve tried a lot of things. problem is I get 'garbage with pattern'. The unit seems to be working, at least it blinks when in an open environment meaning that it has satellite lock. by the way, the test you suggest assume a direct logic, right? That is, 0V meaning bit 0 and 2.8V meaning bit 1. I´m a bit confused on how to interpret this info from the datasheet:

Protocol Electrical level TTL level, Output voltage level: 0V ~ 2.85V RS-232 level Baud rate 4,800 bps Output message NMEA 0183 GGA, GSA, GSV, RMC, VTG, GLL

What does it mean the RS-232 reference in "TTL level, Output voltage level: 0V ~ 2.85V, RS-232 level". Isn´t it enough to say the TTL levels?

Could something have issued the $PSRF100,0 command and put the GPS into SiRF Binary mode? Perhaps you can set ti back to 4800 baud NMEA.

Wow.don't know how I missed that . It maybe in binary mode.download the sirfdemo software and try to reconfigure it. You'll also need to connect the rx line to the rx line with the sketch downloaded.you'll have to put it across a voltage divider first to bring the voltage down.

wayneft: First thing I would do is verify the GPS is working. Download the below code and connect the GPS Tx pin to the Arduino Tx pin. Next open up serial monitor and cycle through the baud rates until you see valid NMEA sentences. I believe the default baud rate is 4800. If/when you see valid sentences then you'll know it's working and the baud rate the unit is configured to.

void setup(){
  pinMode(0,INPUT);
  digitalWrite(0,LOW);
  pinMode(1,INPUT);
  digitalWrite(1,LOW);
}

void loop(){   while(1); }

I was having the same problem and found this code very usefull.

I´m using broken gps-bluetooth module, and could no make it work at the datasheet baudrate(4800). After some reading i saw that bluetooth uses 115200bps, and for some strange reason my module was outputing NMEA sentences at that speed, of course inverse logic.

I´ve already made it work via arduino with the mentioned code and with the following schema via serial port: Im only using the TTL TxD line for simplicity.

Hope this helps.

Yes, binary mode is a possibility. I´ve sent the "$PSRF100,1..." commands to make sure that NMEA is being used, but the behaviour remains.

Thanks for the sirfdemo reference, I´ll try that. Is this the tool you´re talking about?

http://www.falcom.de/support/software-tools/sirf/

YES, it is alive! Working with SiRF protocol at 9600 baud. With the code suggested by wayneft running and making sirfdemo listen to the console COM port the GPS data is displayed. Now the next step is to switch it back to NMEA protocol, or simply work with SiRF. I´ll post the updates.

I tried to change the EM406 back to NMEA through sirfdemo but with no success. Anyway, saw in another forum a message mentioning that everything fails you could switch it back to NMEA by disconnecting the power and waiting for 3 days.

http://diydrones.com/profiles/blogs/putting-your-em406-gps-back-in

Doing that worked in my case. The first try after that worked as expected, with the NMEA messages coming at 4800 bps.

At least for my case, monitoring the serial traffic using the Tx and Rx Arduino pins was possible with no need to any level conversion. It was simply a matter of connecting the right pins.

Thanks again for all that replied.