Need help with a piece of code

Hi all,

I am almost give up and this is my last resort!!

I am spending weeks now trying to calculate the checksum of a set of hex / characters data in Teensy code. I have all the info, even from manufacturer.

If any of you is willing to help me i would be very happy. I do guess i do not have the knowledge at this point to get to the result. Or i am totally looking it the wrong way but… i just run out of juice.

Hope some one good give a look and help this noob on his way :slight_smile:

Here is what i am trying to do:

Trimble send out true serial this kind of information:

I need this part:

Knipsel1

I have edit the pgn in aog like this:

  //AutoSteerData
        public class CPGN_FE
        {
            /// <summary>
            /// 8 bytes
            /// </summary>
            public byte[] pgn = new byte[] { 0x80, 0x81, 0x7f, 0xFE, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xCC };
            public int speedLo = 5;
            public int speedHi = 6;
            public int status = 7;
            public int steerAngleLo = 8;
            public int steerAngleHi = 9;
            public int lineDistance  = 10;
            public int sc1to8 = 11;
            public int sc9to16 = 12;
            public short SwathoffSetLow = 13;
            public int ROXTE = 14;

            public void Reset()
            {
            }
        }

In Teensy  autosteer code i use this:

typ of plak hier code



   //XTE // SwathOffset
    if (autoSteerUdpData[3] == 0xFE && Autosteer_running)  //XTE Data  // is off Pin A7 TX on pcb is output
    {
      static uint8_t hzCounter = 0;
      hzCounter++;
      if (hzCounter > 9)
      {
        XTE = (int16_t)(autoSteerUdpData[9] << 8) + autoSteerUdpData[8];
        ROSwathOffset = (int8_t)autoSteerUdpData[13];
        buildSwath();
        buildXTE();
        //buildROSwathOffset(ROSwathOffset);
        //Serial.write("ROSwathOffSet: " & ROSwathOffset);
        //Serial.print("ROSwathOffSet: ");
        //Serial.write(ROSwathOffset);


      }
    }

Then building the string i tried this:

void buildSwath()
{
  strcpy(SwathOffSet, "");
  strcat(SwathOffSet, "¿@ ROSwathOffset: ");

  dtostrf(ROSwathOffset, 0, 0, stringSwath);
  strcat(SwathOffSet, stringSwath);
  strcat(SwathOffSet, "");
  CalculateChecksum2();
  strcat(SwathOffSet, "");
  strcat(SwathOffSet, "\r\n");
  Serial.write(SwathOffSet);
}



And as checksum calculation i use this ( I have edit the  if (tmp == '') alot dont know wich one is good anymore)


void CalculateChecksum2() // XTE
{
  int16_t sum = 0;
  int16_t inx = 0;
  char tmp;

  // The checksum calc starts after '$' and ends before '*'
  for (inx = 3; inx < 200; inx++)
  {
    tmp = SwathOffSet[inx];

    // * Indicates end of data and start of checksum
    if (tmp == '')
    {
      break;
    }

    sum ^= tmp;    // Build checksum
  }

  byte chk = (sum >> 4);
  char hex[2] = { asciiHex[chk], 0 };
  strcat(SwathOffSet, hex);

  chk = (sum % 16);
  char hex2[2] = { asciiHex[chk], 0 };
  strcat(SwathOffSet, hex2);
}

So in example from Trimble Swath line -1 gives a checksum in serial with sign “/” wich in hex is “2F”

In hex the line = 10 BF 40 14 20 52 4F 53 77 61 74 68 4F 66
66 73 65 74 3A 20 2D 31 14 06 2F 10 03 10

So i tried calculating checksum between 40 and 06 and all possible ways. But never get to this / result.

I maybe sound a bit messy, but spending weeks trying to solve this makes me crazy :frowning:

I also have the original manufacturer code that checks the trimble checksum on this line of output.
But i can only send it private to be sure its not gonna go in public!! Sorry bout that!!

The thing i want to do is control this plough control and it only needs the ROXTE and the ROSWATHOFFSET.

images

According to this developer checksum should be calculated in whats marked yellow:

Hope its clear for you all.

I’m not sure about the message you want to send.

I guess the message start with
0x10 0xBF 0x40 XX YY Your text here ZZ C1 C2
with XX YY the lengh of your message,
ZZ ??? is it a magic number ? is it the lenght of the message used to compute the checksum ?
C1 C2 the checksum

If so something like this will give you the correct result :

char *SwathOffSet=new char[200];
char *stringSwath=new char[7];

  int ROSwathOffset=-1024;  //  The value from the example.

  strcpy(SwathOffSet+5, "");
  strcat(SwathOffSet+5, "ROSwathOffset: ");
  dtostrf(ROSwathOffset, 0, 0, stringSwath);
  strcat(SwathOffSet+5, stringSwath);
  int len=strlen(SwathOffSet+5);
  SwathOffSet[0]=0x10;
  SwathOffSet[1]=0xbf;
  SwathOffSet[2]=0x40;
  SwathOffSet[3]=len; // Assuming it will always be <255
  SwathOffSet[4]=0;
  SwathOffSet[len+5]=len+3; // is 0x17 a magic number ???  I set guess it is the len from the string + the 3 char acting as prefix:  0x40, len low, len high  

  int checksum=0;
  for (int i=2;i<len+6;i++){
    checksum+=SwathOffSet[i];
  }
  Serial.print("Final checksum: ");
  Serial.println(checksum, HEX );

  SwathOffSet[len+6]=checksum/256;
  SwathOffSet[len+7]=checksum%256;


  Serial.print("Message is: ");
  for (int i=0;i<len+8;i++){
    Serial.print(SwathOffSet[i], HEX );
    Serial.print(" ");
  }
   Serial.println(" ");

it gives:

Final checksum: 6C8
Message is: 10 BF 40 14 0 52 4F 53 77 61 74 68 4F 66 66 73 65 74 3A 20 2D 31 30 32 34 17 6 C8 

Is this what is called TUVR by trimble ?

Thank you i gonna try.

But the message i want to send over serial has to be exavtly the same as trimble sends for the geoplough x to work.

Header 10 BF 40 are always the same also the tail 10 03 10

But gonna try your code.

From our direct discussion I put the thing I understood here:

// the offset value as an integer (should be the input)
  int ROSwathOffset=-1;

  // This will contain the offset as string
  char *stringSwath=new char[10];

  // SwathOffSet will contain the full message you will have to send to your implement. 
  // BEWARE:  the message is not a readable message, it contains some charactere not displayable and even a 0x00 char which act as a stop when you try to print a string.
  char *SwathOffSet=new char[200];
  

  // The message is build like:
  // Start // len // message // magic byte // checksum // end
  // Start is static 0x10 0xbf 0x40
  // len is the message len 2 bytes,  first byte is the low byte,  2nd high byte. as the message is almost always <256 char long, the 2nd byte will be 0x00 
  // message: string like "ROSwathOffset: 5"  or "ROXTE: 0.0048881"
  // magic byte.  Not entirely sure about this one, but  "ROSwathOffset" seems to have a 0x17 value here   "ROXTE" message 0x13.  To know better, we would have to get more trace of a real trimble thing
  // Checksum:  it is the sum of the byte value from the 3nd byte (so the last start byte: which is 0x40 ) to the "magic" byte included.  value will be set in 2 byte:  high byte // low byte.  ( value 0x123 will be send  0x01 0x23 )
  // end: the end which is a static 0x10 0x03
  
  // here we set the message part at an empty string
  strcpy(SwathOffSet+5, "");
  // Copying the message type
  strcat(SwathOffSet+5, "ROSwathOffset: ");
  // Creating the string with the value for the message
  dtostrf(ROSwathOffset, 0, 0, stringSwath);
  // putting the value at the correct place
  strcat(SwathOffSet+5, stringSwath);
  // retrieving the message length
  int len=strlen(SwathOffSet+5);
  // Setting the start
  SwathOffSet[0]=0x10;
  SwathOffSet[1]=0xbf;
  SwathOffSet[2]=0x40;
  // Setting the len
  SwathOffSet[3]=len; // Assuming it will always be <256
  SwathOffSet[4]=0;
  // Now we set the magin byte after the message
  SwathOffSet[len+5]=0x17; // 0x17 seems a magic byte for ROSwathOffset,  0x13 for ROXTE  => need to validate that. Either from the doc or by capturing more data.

  // Compute the checksum (sum from byte 2 to end of magic byte)
  int checksum=0;
  for (int i=2;i<len+6;i++){
    checksum+=SwathOffSet[i];
  }
  /*
  Serial.print("Final checksum: ");
  Serial.println(checksum, HEX );
  */

  // Setting the checksum at the correct place 
  SwathOffSet[len+6]=checksum/256;
  SwathOffSet[len+7]=checksum%256;
  // Setting the end message static thing
  SwathOffSet[len+8]=0x10;
  SwathOffSet[len+9]=0x3;

  // Send the message to the wire ( here it is the teensy serial but in real life it should be something else)
  Serial.write(SwathOffSet, len+10);
3 Likes

Thank you @ed-grey for solving my frustration.

And reading you commands on every line learns me alot.

Thanks again and happy holiday’s

So with this code we can now simulate a trimble serial output for controlling the Geoplough.