UBX protocol help: configuring a NEO 6M Arduino GPS Module... Fletcher checksum?

Oh, fer cryin' out loud! I answered this over here! As I said,

Using 32-bit CS variables is perhaps wasteful, but it does not generate incorrect checksums. He masks them at the end of the computation, in both cases (sending and receiving).

Did you even try it? Here are the calculations with 32-bit ints:

Byte CK A CK B
------ ------ ------
6 6 6
1 7 13
3 10 23
0 10 33
240 250 283
1 251 534
0 251 785

If you mask those last two bytes, you get 251 and 17 (0xFB and 0x11). Those are the correct bytes, Justin. They are the same bytes you would get even if you masked after each addition:

Byte CK A CK B
------ ------ ------
6 6 6
1 7 13
3 10 23
0 10 33
240 250 27
1 251 22
0 251 17

Actually, he could have used 64-bit long long or 16-bit int integers and computed the same CS. More wastefully, but it would have computed the same result. He should have used 8-bit unsigned char, like Brad Burleson's code above, or like NeoGPS does here. Then, no masking would have been required anywhere.

The reason it doesn't matter is that the lower 8 bits are added the same way, regardless of sums that carry into the higher bits. At the end, you only look at the lower 8 bits and mask off the upper bits. They just don't matter.

I do think the ublox spec is misleading, as it suggests exactly what you said:

ublox Neo-6/7/8 Protocol:
26 UBX Checksum
The checksum is calculated over the packet, starting and including the CLASS field, up until, but excluding, the Checksum Field.

The checksum algorithm used is the 8-Bit Fletcher Algorithm, which is used in the TCP standard (RFC 1145 1). This algorithm works as follows:

   Buffer[N] contains the data over which the checksum is to be calculated.

The two CK_ values are 8-Bit unsigned integers, only! If implementing with
  larger-sized integer values, make sure to mask both CK_A and CK_B with 0xFF
  after both operations in the loop.

CK_A = 0, CK_B = 0
      For(I=0;I<N;I++)
      {
          CK_A = CK_A + Buffer[I]
          CK_B = CK_B + CK_A
      }

After the loop, the two U1 values contain the checksum, transmitted at the end of the packet.

An implementer would generate a correct checksum by following this to the letter. However, that does not mean that a CS calculation with larger integers, followed by masking, would generate an incorrect CS. It actually works, as you can see in the above tables.

The real problem is that the OP is trying to print too much while receiving from the GPS. This is a common problem, and I have documented the symptoms and solutions here. Go read it. Then upvote my answer.

With Irrelevant Civility,
/dev


1 The relevant excerpt from RFC 1145:

APPENDIX I: The 8-bit Fletcher Checksum Algorithm:

   The 8-bit Fletcher Checksum Algorithm is calculated over a sequence

of data octets (call them D[1] through D[N]) by maintaining 2
  unsigned 1's-complement 8-bit accumulators A and B whose contents are
  initially zero, and performing the following loop where i ranges from
  1 to N:

A := A + D[i]
          B := B + A

It can be shown that at the end of the loop A will contain the 8-bit
  1's complement sum of all octets in the datagram, and that B will
  contain (N)D[1] + (N-1)D[2] + ... + D[N].

The octets covered by this algorithm should be the same as those over
  which the standard TCP checksum calculation is performed, with the
  pseudoheader being D[1] through D[12] and the TCP header beginning at
  D[13].  Note that, for purposes of the checksum computation, the
  checksum field itself must be equal to zero.

At the end of the loop, the A goes in the first byte of the TCP
  checksum and B goes in the second byte.