Arduino 2560 and problems with serial GPS EM-406

Hi people,

I have a arduino 2560, and I am not able to communicate with a GPS receiver EM-406.

I took the code from the internet to communicate with the gps, but it did not work. Then I tried to communicate with the gps more simply using the "MultiSerialMega" example in the various serial port .. but can not collect data from GPS.

I've used Logic Level Converter to the output of the gps 2.8v to 5v.

I've tested the TX pin of the GPS with a speaker and I get a repeating sound. So I think everything is fine with the gps.

Someone can tell me what am I doing wrong?

I'm new in the programming world. :cold_sweat:

I took the code from the internet to communicate with the gps, but it did not work.

The code, huh? Which code would that be?

Then I tried to communicate with the gps more simply using the "MultiSerialMega" example in the various serial port

You are going to have to be more specific than that. Explain exactly where you found that example.

I've used Logic Level Converter to the output of the gps 2.8v to 5v.

You'll need to show how the logic level converter, the GPS, and the Arduino are connected. A schematic and/or clear picture (no rats nest of all red wires).

I've tested the TX pin of the GPS with a speaker and I get a repeating sound. So I think everything is fine with the gps.

Hardly any kind of scientific test. Post a link to the GPS you are testing this way. Also, go get a multimeter.

Someone can tell me what am I doing wrong?

Could be any number of things. Not enough detail here to tell. Except for how you are confirming that the GPS works, of course.

Where did you connect the TX of the GPS? To the TX pin of the Arduino? And how did you feed the Arduino? With a separate power supply, or with a USB cable?

Because if you connected the TX to the RX on the Arduino, the USB converter is in the middle (more on one end) of what you are trying to accomplish.

On the other hand, if you used one of the other serial ports, this is not an issue.

What logic level converter did you use? How did you wired it up? Is the logic level converter fast enough for the GPS baud rate? If the GPS puts out 3,3V, you may be able to get away without a level converter to 5V. Not too sure about it though...

How did you connect the ground of the GPS? Did you connect it to the board?

A multimeter isn't going to help you much... an oscilloscope would be ideal, but still, it's better than a speaker. :P

What's the baud rate that the GPS transmits? Did you set the port in the Arduino for that baud rate?

Without these and more info, we can't do much to help you.

Sorry for not putting the details of my project, and thanks for still answering.

I am using this version of arduino 2560:

This GPS receiver:

And this Logic Level Converter:

I’m using the serial port 1 pins of the Arduino 2560, RX pin 19 and pin 18 is TX.

The circuit:

I used this code:

Aaron Weiss
SparkFun Electronics

Example GPS Parser based off of TinyGPS examples.

Parses NMEA sentences from an EM406 running at 4800bps into readable
values for latitude, longitude, elevation, date, time, course, and

For the SparkFun GPS Shield. Make sure the switch is set to DLINE.

Once you get your longitude and latitude you can paste your
coordinates from the terminal window into Google Maps. Here is the
link for SparkFun’s location.,+-105.20997

Uses the NewSoftSerial library for serial communication with your GPS,
so connect your GPS TX and RX pin to any digital pin on the Arduino,
just be sure to define which pins you are using on the Arduino to
communicate with the GPS module.

changed values to RXPIN = 2 and TXPIN = to correspond with
hardware v14+. Hardware v13 used RXPIN = 3 and TXPIN = 2.


// In order for this sketch to work, you will need to download
// NewSoftSerial and TinyGPS libraries from and put them
// into the hardware->libraries folder in your ardiuno directory.
// Here are the lines of code that point to those libraries.
#include <NewSoftSerial.h>
#include <TinyGPS.h>

// Define which pins you will use on the Arduino to communicate with your
// GPS. In this case, the GPS module’s TX pin will connect to the
// Arduino’s RXPIN which is pin 3.
#define RXPIN 19
#define TXPIN 18
//Set this value equal to the baud rate of your GPS
#define GPSBAUD 4800

// Create an instance of the TinyGPS object
TinyGPS gps;
// Initialize the NewSoftSerial library to the pins you defined above
NewSoftSerial uart_gps(RXPIN, TXPIN);

// This is where you declare prototypes for the functions that will be
// using the TinyGPS library.
void getgps(TinyGPS &gps);

// In the setup function, you need to initialize two serial ports; the
// standard hardware serial port (Serial()) to communicate with your
// terminal program an another serial port (NewSoftSerial()) for your
// GPS.
void setup()
// This is the serial rate for your terminal program. It must be this
// fast because we need to print everything before a new sentence
// comes in. If you slow it down, the messages might not be valid and
// you will likely get checksum errors.
//Sets baud rate of your GPS

Serial.println(“GPS Shield QuickStart Example Sketch v12”);
Serial.println(" …waiting for lock… “);

// This is the main loop of the code. All it does is check for data on
// the RX pin of the ardiuno, makes sure the data is valid NMEA sentences,
// then jumps to the getgps() function.
void loop()
while(uart_gps.available()) // While there is data on the RX pin…
int c =; // load the data into a variable…
if(gps.encode(c)) // if there is a new valid sentence…
getgps(gps); // then grab the data.

// The getgps function will get and print the values we want.
void getgps(TinyGPS &gps)
// To get all of the data into varialbes that you can use in your code,
// all you need to do is define variables and query the object for the
// data. To see the complete list of functions see keywords.txt file in
// the TinyGPS and NewSoftSerial libs.

// Define the variables that will be used
float latitude, longitude;
// Then call this function
gps.f_get_position(&latitude, &longitude);
// You can now print variables latitude and longitude
Serial.print("Lat/Long: “);
Serial.print(”, ");

// Same goes for date and time
int year;
byte month, day, hour, minute, second, hundredths;
// Print data and time
Serial.print(“Date: “); Serial.print(month, DEC); Serial.print(”/”);
Serial.print(day, DEC); Serial.print("/"); Serial.print(year);
Serial.print(" Time: “); Serial.print(hour, DEC); Serial.print(”:");
Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC);
Serial.print("."); Serial.println(hundredths, DEC);
//Since month, day, hour, minute, second, and hundr

// Here you can print the altitude and course values directly since
// there is only one value for the function
Serial.print("Altitude (meters): "); Serial.println(gps.f_altitude());
// Same goes for course
Serial.print("Course (degrees): "); Serial.println(gps.f_course());
// And same goes for speed
Serial.print("Speed(kmph): "); Serial.println(gps.f_speed_kmph());

// Here you can print statistics on the sentences.
unsigned long chars;
unsigned short sentences, failed_checksum;
gps.stats(&chars, &sentences, &failed_checksum);
//Serial.print("Failed Checksums: ");Serial.print(failed_checksum);
//Serial.println(); Serial.println();

That picture makes it a little hard to tell what is connected where. The product page for the Mega mini indicates that it is a 5 volt device. The product page for the GPS says that it is a 5 volt device.

What is the logic level converter for?

NewSoftSerial is not usually needed for the Mega, which already has 4 hardware serial ports, and certainly can not be used with any hardware serial pins. It only works, if you have the modified-for-Mega version on certain pins (I don't remember which ones). Why are you trying to use it?

From the top of my head, and like paulS said the level converter is useless in this application and according to the comments on the Sparkfun product page is probably one of the reasons why it is causing problems. So ditch it!!

Next, use the hardware serial port instead of new soft serial.

Thanks for the replies.

At first I used the GPS receiver directly into the microcontroller, but after several tests are unable to get the GPS signal.

In the datasheet of the GPS says:" TTL level, Output voltage level: 0V ~ 2.85V"

I thought that was the problem, and bought the level converter. But still not working. :roll_eyes:

I tried using this example made ??specifically for the arduino Mega:


  • Mega multple serial test*

Receives from the main serial port, sends to the others.
Receives from serial port 1, sends to the main serial (Serial 0).

This example works only on the Arduino Mega

The circuit:
* Any serial device attached to Serial port 1
* Serial monitor open on Serial port 0:

created 30 Dec. 2008
by Tom Igoe

This example code is in the public domain.

void setup() {

  • // initialize both serial ports:*
  • Serial.begin(4800);*
  • Serial1.begin(4800);*
    void loop() {
  • // read from port 1, send to port 0:*
  • if (Serial1.available()) {*
  • int inByte =;*
  • Serial.print(inByte, BYTE);*
  • }*

But nothing appears on the serial window, and TX arduino LED does not blink. I do not understand this.

Ok... an oscilloscope may be in order here.

Did you check the schematic for the level translator? From the comments in Sparkfun, it seemed like there were some resistors there that were causing some problems on the communication. That may be a possible cause for the problem. Although I think that the Arduino can still receive data from the GPS and you'd have to worry about sending data to the GPS. (I couldn't find the electrical characteristics for the serial port)

Try this:

Connect UART 1 to UART 2 and create a program that transmits data between them. This way, you'll be able to verify you UART is working properly.

Next, get an oscilloscope and check the output from the GPS. If you have an FTDI cable, try connecting the GPS directly to the computer.

Without knowing for sure that the GPS is sending data, is hard to know where the problem might be.

Also, you may receive in 4800 bps from the GPS, but you can use a higher baud rate to transmit to the computer.

For the logic level converter to work properly you need to voltage sources. You have 5 volts connected to HV but nothing (should be 3.3 v) connected to LV.

...and you need to connect pin 5 from the GPS to ground.

bubulindo: Try this:

Connect UART 1 to UART 2 and create a program that transmits data between them. This way, you'll be able to verify you UART is working properly.

Thanks, I'll try to check the serial port this way. I'm new in electronics does not have an oscilloscope for now.

wayneft: For the logic level converter to work properly you need to voltage sources. You have 5 volts connected to HV but nothing (should be 3.3 v) connected to LV.

You're right. But I have no way to feed this pin to 2.8V. Do you think this may affect the transmission of GPS data to the microcontroller?

I think the 5 pin is connected internally to pin 1, but now i put it to the negative too.

Connect it to 3.3 volts and you should be fine.

The level converter is needed if you are trying to send a 5V signal to a 3.3V device. The GPS is a 5V tolerant device, since it's supply voltage is 4.5 to 6 volts. That is outputs only a 2.85V signal might be a problem, since the Arduino expects anything about 60% of it's supply voltage to be HIGH. The 2.85 value is slightly below this threshold, but generally works.

Hi people,

Been some time without working on my project.

But now I realized that my program did not work because I used the library “NewSoftSerial” to emulate a serial port using pins that are already hardware serial ports!

Sorry to be so inexperienced … and thank you for all your support.

Here is the code I am using. He receives the GPS data on port serie1 that corresponds to pin 19 of atmel 2560. And sends to the serial monitor.

#include “TinyGPS.h”
TinyGPS gps;
unsigned long fix_age, time, date, speed;
void getgps(TinyGPS &gps);
void setup() {

  • Serial.begin(4800);*
  • Serial1.begin(4800);*
    void loop(){
  • byte month, day, hour, minute, second, decsec;*
  • int year;*
  • if (Serial1.available() > 0){ *
  • char c =;*
  • if (gps.encode(c))*
  • {*
  • gps.get_datetime(&date, &time);*
  • gps.crack_datetime(&year, &month, &day, &hour, &minute, &second);*
  • Serial.print("Date: "); Serial.print(static_cast(month));*
  • Serial.print("/"); Serial.print(static_cast(day));*
  • Serial.print("/"); Serial.print(year); Serial.print(" Time: ");*
  • Serial.print(static_cast(hour)); Serial.print(":");*
  • Serial.print(static_cast(minute)); Serial.print(":");*
  • Serial.print(static_cast(second));*
  • float falt = gps.f_altitude(); // +/- altitude in meters*
  • float velocidade = gps.f_speed_kmph();*
  • Serial.print(" Altitude: ");*
  • Serial.println(falt);*
  • Serial.print("Velocidade: ");*
  • Serial.println(velocidade);*


  • }}}}*

After spending several hours today trying to get a 406a gps module working on a Mega 2560 I can tell you what worked. Connect to the Serial1/SPI Port and connect the pin on the gps module marked Transmit to the Receive Pin on the Mega (pin 19) and the Receive Pin on the gps module to the Transmit Pin on the Mega (pin 18) and the code from here will work just fine. -

This is the modified code and works great on mine - just cut and paste

#include <string.h>
#include <ctype.h>
//int ledPin = 13; // LED test pin
int rxPin = 18; // RX PIN
int txPin = 19; // TX TX
int byteGPS=-1;
char linea[300] = “”;
char comandoGPR[7] = “$GPRMC”;
int cont=0;
int bien=0;
int conta=0;
int indices[13];
void setup() {
//pinMode(ledPin, OUTPUT); // Initialize LED pin
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
for (int i=0;i<300;i++){ // Initialize a buffer for received data
linea*=’ ';*

  • } *
    void loop() {
  • //digitalWrite(ledPin, HIGH);*
  •; // Read a byte of the serial port*
  • if (byteGPS == -1) { // See if the port is empty yet*
  • delay(100);*
  • } else {*
  • linea[conta]=byteGPS; // If there is serial port data, it is put in the buffer*
  • conta++; *
  • Serial.print(byteGPS, BYTE);*
  • if (byteGPS==13){ // If the received byte is = to 13, end of transmission*
  • //digitalWrite(ledPin, LOW);*
  • cont=0;*
  • bien=0;*
  • for (int i=1;i<7;i++){ // Verifies if the received command starts with $GPR*
    _ if (linea*==comandoGPR[i-1]){_
    if(bien==6){ // If yes, continue and process the data*_
    * for (int i=0;i<300;i++){*
    _ if (linea*==’,’){ // check for the position of the “,” separator*
    * indices[cont]=i;
    if (linea==’’){ // … and the “"
    Serial.println(”"); // … and write to the serial port*

    * Serial.println("");
    for (int i=0;i<12;i++){
    case 0 :Serial.print("Time in UTC (HhMmSs): ");break;
    case 1 :Serial.print("Status (A=OK,V=KO): ");break;
    case 2 :Serial.print("Latitude: ");break;
    case 3 :Serial.print("Direction (N/S): ");break;
    case 4 :Serial.print("Longitude: ");break;
    case 5 :Serial.print("Direction (E/W): ");break;
    case 6 :Serial.print("Velocity in knots: ");break;
    case 7 :Serial.print("Heading in degrees: ");break;
    case 8 :Serial.print("Date UTC (DdMmAa): ");break;
    case 9 :Serial.print("Magnetic degrees: “);break;
    case 10 :Serial.print(”(E/W): ");break;
    case 11 :Serial.print(“Mode: “);break;
    case 12 :Serial.print(“Checksum: “);break;
    for (int j=indices;j<(indices[i+1]-1);j++){
    conta=0; // Reset the buffer*

    * for (int i=0;i<300;i++){ //
    linea=’ ';

    Really confusing how the pins are labelled but once you reverse them they work great!_

Really confusing how the pins are labelled but once you reverse them they work great!

That shouldn't be confusing. Tx is short for transmitting and is like talking with your mouth, Rec means receiving and is like listening with your ears. Two different people can only communicate if one's mouth is sending to the others ears, and visa verse. Two 'talkers' wired to each other doesn't make sense and neither does having two 'listeners' wired to each other.

Your Arduino and your GPS is just like two separate people in that regard. So Tx to Rec and Rec to Tx is both correct and logical.

That make sense?