Problem getting SoftwareSerial to work

Hello All

I have just started on a serial communication project and have an issue which I need some help with. Most likely it is at a fundamental level.

My platform is - Eleven (100% Arduino Uno Compatible) not user what revision.
I am using IDE version 1.0.4

For initial debugging I am use a Garmin GPS 72 in simulator mode, as a source of serial data. This provides me with a constant stream of serial data in a known format. I have set up the GPS to send “Text Out” at “4800” Baud and I get the following data when I use putty and a Serial to USB converter:

@130427060050S9944449E99943537S015+00025E0000N0000U0000
@130427060051S9944449E99943537S015+00025E0000N0000U0000
@130427060052S9944449E99943537S015+00025E0000N0000U0000
@130427060053S9944449E99943537S015+00025E0000N0000U0000
@130427060054S9944449E99943537S015+00025E0000N0000U0000
@130427060055S9944449E99943537S015+00025E0000N0000U0000
@130427060056S9944449E99943537S015+00025E0000N0000U0000

Where only the time changes.

I got data above by:

  1. Connecting a laptop and GPS together with a USB to Serial converter
  2. Using Putty set to 8 (bits) No (parity) 1 (stop bit) XON/XOFF (flow control) at 4800 baud

Then I uploaded the following code to my Arduino. This is based in the Software Serial example code:

/*
Receives from software serial, sends to hardware serial.
The circuit:
* Arduino RX is digital pin 10 - connect to TX of GPS 72 Brown, Pin 2 of DB 9   (Green)
* Arduino TX is digital pin 11 - connect to RX of GPS 72 White, Pin 3 of DB 9  (Red)
*/

#include <SoftwareSerial.h>

#define rxPin 10
#define txPin 11
SoftwareSerial GarminSerial =  SoftwareSerial(rxPin, txPin);

int  counter=0;
char  CharFromGPS;
void setup()  
{
 Serial.begin(4800);
 Serial.println("It's Alive!");

 pinMode(rxPin, INPUT);
 pinMode(txPin, OUTPUT);
 GarminSerial.begin(4800);
}

void loop() // run over and over
{
  if (GarminSerial.available())
    Serial.write(GarminSerial.read());
}

My problem is that I get nothing like the output from Putty

The output I get on the Serial Monitor is: (casting the output to int)
117-101-251-187-182-22-246-54-86-150-182-214-150-149-54-118-118-118-118-214-86-117-69-187-187-150-86-150-22-150-245-214-86-150-246-246-246-182-86-86-125-125-251-251-54-245-246-246-246-86-245-246-246-246-86-183-15-0-

117-101-251-187-182-22-246-54-86-150-150-246-150-149-54-118-118-118-118-214-86-117-69-187-187-150-86-150-22-150-245-214-86-150-246-246-246-182-86-86-125-125-251-251-54-245-246-246-246-86-245-246-246-246-86-183-15-0-

117-101-251-187-182-22-246-54-86-150-150-214-150-149-54-118-118-118-118-214-86-117-69-187-187-150-86-150-22-150-245-214-86-150-246-246-246-182-86-86-125-125-251-251-54-245-246-246-246-86-245-246-246-246-86-183-15-0-

117-101-251-187-182-22-246-54-86-150-150-182-150-149-54-118-118-118-118-214-86-117-69-187-187-150-86-150-22-150-245-214-86-150-246-246-246-182-86-86-125-125-251-251-54-245-246-246-246-86-245-246-246-246-86-183-15-0-

This look almost like ASCII codes, by do not translate to correct text output.

So I have a fundamental error somewhere in my setup.

This gives the correct output:
Garmin-> serial cable -> serial 2 USB converter -> laptop USB port -> putty

This gives the incorrect output
Garmin-> serial cable -> GND to GND, TX on Garmin to Arduino RX pin 10

I original posted this in the devices forum but this is probably a better place for it.

Happy to try anything to get this to work.

Does the Garmin use TTL (5V) Serial or RS232? The logic levels would be inverted if you tried to connect an RS232 signal to an Arduino TTL Serial input. That would produce strange results.

Turn your Serial up to 9600 or faster.

  Serial.write(GarminSerial.read());

Not every character your Garmin sends is printable. Serial.write() makes no attempt to make the bytes it sends to Serial monitor printable, while Serial monitor expects ASCII characters.

You wanted Serial.print(), not write().

johnwasser:
Does the Garmin use TTL (5V) Serial or RS232? The logic levels would be inverted if you tried to connect an RS232 signal to an Arduino TTL Serial input. That would produce strange results.

I did not know that there was a difference. The Garmin uses RS232. Looking at the binary results it does not look like a simple inversion. However I guess that the stop bit would also be inverted. Also the correct string contains 440 bit and the corrupt ones has 464.

Would this also mean that using the hardware serial chip on pins 0 and 1 would also fail?

If this is the problem is there any easy way to find out. Or will I need to build a RS232 to TTL converter like this one
http://www.google.co.nz/imgres?imgurl=http://www.valerioriva.it/wp-content/circuit_232.jpg&imgrefurl=http://www.valerioriva.it/2009/06/rs232-ttl-logic-converter/&h=299&w=392&sz=24&tbnid=fyy0lqGALI9HtM:&tbnh=85&tbnw=111&zoom=1&usg=__4f1pRtZufUXWn_fy6XS-ZQOv1Fw=&docid=r6CprWhAboMBzM&sa=X&ei=u5OAUfuhEIyMkgWuqYHgCw&ved=0CC4Q9QEwAw

Yes, you should use a RS232 to TTL level shifter. RS232 can go as high as +/-12V which would be bad for an Arduino input.

As an experiment you turn on the (undocumented?) data inversion feature in SoftwareSerial:

SoftwareSerial GarminSerial =  SoftwareSerial(rxPin, txPin, true);

A simple voltage divider?...

cjdelphi:
A simple voltage divider?...

...won't work to make negative voltages safe for the Arduino.

johnwasser:

cjdelphi:
A simple voltage divider?...

...won't work to make negative voltages safe for the Arduino.

A diode in Series to only allow a positive or near 0v voltage then?

johnwasser:
Does the Garmin use TTL (5V) Serial or RS232? The logic levels would be inverted if you tried to connect an RS232 signal to an Arduino TTL Serial input. That would produce strange results.

You hit the nail on the head with this answer John. I found a tutoral on the Arduino site (which I can not find now) and breadboarded a MAX232 chip. After a little tweaking of the code I got exatcly what I was expecting.

Thanks for your time and effort.
Craig