2

I am writing a computer program which utilizes input from some equipment which I seldom have availible in my office. In order to develop and test this program I am trying to use an Arduino board to simulate the communication from the actual equipment. To this effect I create datapackets on the Arduino and send them to my computeer over the serial port. The packets are formated as a header and a hexidecimal integer, representing some sensor data.

The header is supposed to contain a checksum (2's complement 256-modulo). I am however not sure how to calculate it. In the datasheet of the equipment (which communication I try to simulate), it is stated that I should first compute the sum all bytes in the packet, and then take the 256-modulo of the sum and perform a 8-bit two's complement on the result.

However, as I am a newbie to bits, bytes and serial communication, I do not understand the following:

1) Lets say that I want to send the value 5500 as two bytes (high byte and low byte). Then the high-byte is '15' and the low-byte is '7c' in hexidecimal encoding, which corresponds to 21 and 124 in decimal values. Do I then add the contributions 21 and 124 to the checksum before taking the 256-modulo, or do I have to do some bit-magic beforehand?

2) How do I perform a two's compliment?

Here is a code which should illustrate how I think. The idea is to send a packet with a header containing a byte which states the length of the packet, a byte which states the type of the packet, and a byte for the checksum. Then a two-byte integer value representing some sensor value is devided into a high-byte and a low-byte, and transmitted low-byte first.

int intVal;
byte Len = 5;
byte checksum;
byte Type = 2;
byte intValHi;
byte intValLo;

void setup(){
    Serial.begin(9600);
}

void loop(){
    intVal = 5500; //assume that this is a sensor value
    intValHi = highByte(intVal);
    intValLo = lowByte(intVal);

    //how to calculate the checksum? I unsuccessfully tried the following
    checksum = 0;
    checksum = (Len+checksum+Type+intValHi+intValLo) % 256;   

    //send header
    Serial.write(Len);
    Serial.write(checksum);
    Serial.write(Type);
    //send sensor data
    Serial.write(intValLo);
    Serial.write(intValHi)
}

Thanks!

user3774617
  • 35
  • 1
  • 1
  • 5

1 Answers1

5

The first thing you should understand is that mod 256 is the same thing as looking at the bottom log(256) => 8 bits.

To understand this you have to first realize what the 'mod' operation does and how digits are represented in hardware.

Mod is the remainder after an old-school division (ie only with whole numbers). eg 5%2 = 1

Digits in hardware are stored in 'bits' which can be interpreted as base 2 mathematics.

Thus if you want to take the mod operation of a power of 2 you don't actually have to do any math.

This is just like if you want to have the remainder of the power of 10, you just take the lower digits.

ie. 157 % 100 = 57.

This can be sped up by using the fact that bytes should overflow by themselves. This means that all you have to do to take %256 of a bunch of numbers is to add them to a single byte and the arduino will take care of the rest.

For twos compliment see this question:

What is “2's Complement”?

Community
  • 1
  • 1
Treesrule14
  • 711
  • 7
  • 14