Char value is 32 bits long?!@?!?

Alright, because this forum is super gay, I have lost this post and am re-writting it because it does not allow active links to be posted until I have posted however many links.

That being said, I am connecting a EM406A GPS to an arduino Nano. I am using the code found on a site which I cannot post but you can find it by searchign for "arduino EM406A" in bing and clicking on the second link result.

This works great except for the Message ID. The Message ID characters are incorrect. I have ran through a lot of the code am finding a strange problem. When I print the char out in BIN form, it is 32 bits long.

For example, the first letter should be G: 1000111
But prints out as: 11111111111111111111111110000111

And instead of the value of G being 01000111 it is 11000111 which is a different character. I don't know if this has to do with my serial read, or something else conflicting. Please let me know if you have any ideas.

Welcome on board.

Starting your first post in the forum by calling it "super gay" is probably not the best way to get people to respond to your problem in a positive an constructive way.

There are currently some server problems that the responsible people are aware of and they are working hard on dealing with them.

You can post links after your first post, this mechanism is to prevent spambots from taking over the forum.

If you post your Arduino code it will be much easier for us to help you.

G being 01000111 it is 11000111

What MikMo said.

However, both the binary patterns you posted (0x47 and 0xC7) are ASCII representations of the letter 'G'.
The second is simply an ASCII 'G' with odd parity.
If you bitwise-AND your incoming characters with 0x7F, your character comparisons will work.

The "32 bits long" is simply due to sign-extension in the print method.

Thank you for your replies. I was a bit frustrated at the point I posted.

The binary pattern 0x47 is G and 0xC7 is Ç, are you saying these are the same letters? Should I be bitwise-anding all of my characters with 0x7F? I don't understand what the bitwise-AND does. Could you elaborate on that a little?

True ASCII is only the codes 0..127 (0x00..0x7F).
Somewhere in the spec of your GPS unit it probably says the interface protocol is 7 data bits, odd parity.
If you bitwise-AND with 0x7F (01111111 binary), your incoming characters will have bit 7 (the most-significant bit) set to zero, but all the other bits will remain unchanged.

Truth table for AND:

A B &

0 0 0
0 1 0
1 0 0
1 1 1

[edit]After doing a bit of digging, NMEA is supposed to use eight bits, no parity.
Do all the characters you receive have bit 7 set, or only some?
It could be you have a slight bit-rate mismatch - can you post your sketch? (don't forget to use the Code (#) button )[/edit]

Here is my code:

//Team Magnomap
//October 25, 2009
//Texas A&M University

#include <ctype.h>
#include <string.h>

#define bit9600Delay 84
#define halfBit9600Delay 42
#define bit4800Delay 188
#define halfBit4800Delay 94

byte GPSrx = 9;
byte GPStx = 10;
byte SWval;
//char dataformat[7] = "$ÇPG";
char dataformat[7] = "$GPGGA";
char messageline[80] = "";
char thesubstring[6] = "";
int i= 0;

void setup() {
  pinMode(GPSrx,INPUT);
  pinMode(GPStx,OUTPUT);
  digitalWrite(GPStx,HIGH);
  digitalWrite(13,HIGH); //turn on debugging LED
  Serial.begin(9600);
  
  dataformat[0] = 00100100;
  dataformat[1] = 11000111;
  dataformat[2] = 11010000;
  dataformat[3] = 11000111;
  dataformat[4] = 11000111;
  dataformat[5] = 11000001;
}

void SWprint(int data, byte rx, byte tx)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit4800Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
      digitalWrite(tx,HIGH); // send 1
    }
    else{
      digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit4800Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit4800Delay);
}

char SWread(byte rx, byte tx)
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit4800Delay);
    for (int offset = 0; offset < 8; offset++) {
      delayMicroseconds(bit4800Delay);
      val |= digitalRead(rx) << offset;

        //val =  val | (digitalRead(rx)<<offset);
        
        
        
        
    }
    //wait for stop bit + extra
    delayMicroseconds(bit4800Delay);
    delayMicroseconds(bit4800Delay);
    return val;
  }
}

void char2string(byte rx, byte tx)
{
  i = 0;
  messageline[0] = SWread(rx, tx);
  if (messageline[0] == 36) //string starts with $
  {
    
    while(messageline[i] != 13 & i<80) //carriage return or max size
    {
      i++;
      messageline[i] = SWread(rx, tx);
    }
    messageline[i+1] = 0; //make end to string
  }
  
}
void loop()
{
  digitalWrite(13,HIGH);
   //only print string with the right dataformat
   
   char2string(GPSrx, GPStx);
Serial.println(messageline);
/*
   if (strncmp(messageline, dataformat, 6) == 0)
   {
       Serial.println(messageline);
   }
*/
 //Serial.print(SWread(GPSrx, GPStx),BYTE); //use this to get all GPS output, comment out from char2string till here
//Serial.println(SWread(GPSrx, GPStx));
}

And here are a few lines of the results I am getting. Everything looks good except for the Message ID.

$ÇÐGSÖ,3,1,12,29,71,204,46,21,43,318,49,18,42,261,40,06,62,190,76
$ÇPGSÖ,3,2,12,26,46,166,,24,45,076,,15,40,317,,10,36,040,7F
$GÐÇSV,3,3,12,02,29,094,,05,08,217,,30,07,208,,16,07,302,78
$GPRÍC,015832.125,A,3037.1242,Î,09620.3205,W,0.27,109.83,261009,,
$GÐGGA,015833.125,3037.1242,Î,09620.3205,W,1,03,3.0,23.3,Í,-23.3,Í,,0000
52
$ÇPGSÁ,A,2,18,21,29,,,,,,,,,,3.2,3.0,1.0
31 //GSA-GNSS DOP (Table B-5)
$GÐÒMC,015833.125,A,3037.1242,N,09620.3205,W,0.16,176.45,261009,,1A
$GPGÇÁ,015834.128,3037.1242,N,09620.3205,W,1,03,3.0,23.3,M,-23.3,M,,0000
58
$GPÇÓA,Á,2,18,21,29,,,,,,,,,,3.2,3.0,1.0
31
$ÇPRMÃ,015834.128,Á,3037.1242,Î,09620.3205,×,0.19,185.51,261009,,16
$ÇPGÇÁ,015835.128,3037.1242,N,09620.3205,W,1,03,3.0,23.3,M,-23.3,M,,0000
59
$GPGÓA,A,2,18,21,29,,,,,,,,,,3.2,3.0,1.0
31
$ÇÐRMÃ,015835.128,Á,3037.1242,N,09620.3205,×,0.22,121.59,261009,,19
$ÇPGGÁ,015836.125,3037.1242,N,09620.3205,W,1,03,3.0,23.3,M,-23.3,Í,,0000
57
$GPGÓÁ,A,2,18,21,29,,,,,,,,,,3.2,3.0,1.031
$ÇÐRMC,015836.125,Á,3037.1242,N,09620.3205,W,0.17,143.56,261009,,1A
$ÇÐGGÁ,015837.125,3037.1242,N,09620.3205,W,1,03,3.0,23.3,Í,-23.3,Í,,0000
56
$ÇPGÓÁ,A,2,18,21,29,,,,,,,,,,3.2,3.0,1.0
31

And not all of the characters have the 128 bit as one. Every once and a while you can see the first character comes out as a G as it should.

One bit at 9600 baud is 104 microseconds, not 84 - is that the mismatch?
20 microseconds seems a very long time to compensate for latency in "digitalRead".
After only about 5 bits, you'd be one bit period early sampling.

  dataformat[0] = 00100100;
  dataformat[1] = 11000111;
  dataformat[2] = 11010000;
  dataformat[3] = 11000111;
  dataformat[4] = 11000111;
  dataformat[5] = 11000001;

"dataformat" is defined as an array of 8 bit variables.

Ah you can disregard the dataformat, I was testing something there. It should just be:

char dataformat[7] = "$GPGGA";

The GPGGA is the message id that we are looking for

As far as the baud, is there a chart of baud rates for the different baud settings somewhere?

As far as this code is concerned I don't think that would be the problem because we are using the default settings in the EM406a which is 4800 baud.

is there a chart of baud rates for the different baud settings somewhere

Probably not, because different software will take different times to do its processing.

Bit time is the reciprocal of the baud rate, so 1 bit at 4800 baud lasts 1/4800 = 208.3us.

It isn't the GPS device that is likely to be at fault; it is more likely your too-short data bit timings.

Just out of interest, why the roll-your-own approach to serial comms, when you could just use the SoftwareSerial library?
It is tested, and already has compensation for the processing overhead per bit (looks to be 50 cycles per bit, or 3us at 16MHz).

Good call, we added 4 to our delay times and the code is running great now.