Int16_t and int32_t

Hello,

For a school project im making a telemetry system.
Im reciving data in 2 parts for instance FF and BC.
To reconstruct them im using the following line: Reconstruct = (BC << 8) + FF
Then I have the following value BCFF.
Next I can type Serial.Println(Reconstruct1); and I get the value (-68) (this is correct), (reconstruct is in int16_t format).
Now I have the following problem.
Ive reconstucted the following value: 104A This makes the value 4170. This is not the correct value it should be closer to 68.
I think its a int32_t (because when I use the online calculator: http://www.scadacore.com/field-tools/programming-calculators/online-hex-converter/ and put 104A in the same value comes out).
When I change the datatype it is still not the value it is seposed to be.
Ive tryed changing the bitshift from 8 to 16 this did not work.
Does anyone know a way to convert this value to the right number (it should be around 68)?

Greetings, Robert

(PS. When the firstpart or second part is under 10 im multiplying it by 16. this prevents a miscalculation. When the first part is 9 and the second part is BC. Then it would be 9BC (whitout the * 16) while it is seposed to be 90BC)

maybe you should be using unsigned data types...

Hello,

thanks for you fast reply. Ive dint mention that im ''hacking'' a CAN Bus system. So the data format in what it gets send I cant choose. (I think that is what you mean). Ive tryed diffrent formats whitout result (unsigned, unsigned long, unsigned long long, int).

Greetings,

Robert

R_Bouw: Hello,

thanks for you fast reply. Ive dint mention that im ''hacking'' a CAN Bus system. So the data format in what it gets send I cant choose. (I think that is what you mean). Ive tryed diffrent formats whitout result (unsigned, unsigned long, unsigned long long, int).

Greetings,

Robert

your actual code may provide a clue as to what's happening.

Hello,
This is not the whole code but the part where I am talking about.

 if (!digitalRead(2)) {
    CAN0.readMsgBuf(&len, rxBuf);              // Read data: len = data length, buf = data byte(s)
    rxId = CAN0.getCanId();                    // Get message ID
    if (rxId == 0x302) {
      for (int i = 0; i < len; i++) {          // Print each byte of the data
        CanBusData = rxBuf[i];
        //Serial.println(CanBusData);

if (ID == CurrentID && DataCounter == 4 && CurrentFirstPartRead == 1 && CurrentHasBeenCalculated == 0) {
          if (CanBusData < 10) {
            CanBusData = CanBusData * 16;
          }
          //Serial.println("Second");
          //Serial.println(CanBusData, HEX);
          Current = (CanBusData << 8) + CurrentFirstPart;
          CurrentFirstPartRead = 0;
          CurrentHasBeenCalculated = 1;
          if (Current < 0) {
            Current = Current * -1;
            CurrentIsNegative = 1;
            Serial.print("Current (Negative): ");
          }
          else {
            Serial.print("Current: ");
          }
          Serial.println(Current);
          //Serial.println(Current, HEX);
        }

        if (ID == CurrentID && DataCounter == 4 && CurrentFirstPartRead == 0 && CurrentHasBeenCalculated == 0) {
          if (CanBusData < 10) {
            CanBusData = CanBusData * 16;
          }
          //Serial.println(CanBusData, HEX);
          CurrentFirstPart = CanBusData;
          CurrentFirstPartRead = 1;
        }
     CurrentDischargeHasBeenCalculated = 0;
      CurrentChargeHasBeenCalculated = 0;
      DataCounter = 0;
      Serial.println();
    }
if (ID == CurrentDischargeID && DataCounter == 4 && CurrentDischargeFirstPartRead == 1 && CurrentDischargeHasBeenCalculated == 0) {
          if (CanBusData < 10) {
            CanBusData = CanBusData * 32;
          }
          //Serial.println("Second");
          //Serial.println(CanBusData, HEX);
          CurrentDischarge = (CanBusData << 16) + CurrentDischargeFirstPart;
          CurrentDischargeFirstPartRead = 0;
          CurrentDischargeHasBeenCalculated = 1;
          Serial.print("Current Discharge: ");
          Serial.println(CurrentDischarge);
          //Serial.println(CurrentDischarge, HEX);
        }

        if (ID == CurrentDischargeID && DataCounter == 4 && CurrentDischargeFirstPartRead == 0 && CurrentDischargeHasBeenCalculated == 0) {
          if (CanBusData < 10) {
            CanBusData = CanBusData * 32;
          }

         // Serial.println(CanBusData, HEX);
          CurrentDischargeFirstPart = CanBusData;
          CurrentDischargeFirstPartRead = 1;
        }
  }

}

R_Bouw: Hello,

thanks for you fast reply. Ive dint mention that im ''hacking'' a CAN Bus system. So the data format in what it gets send I cant choose. (I think that is what you mean). Ive tryed diffrent formats whitout result (unsigned, unsigned long, unsigned long long, int).

Greetings,

Robert

The CAN bus sends bits, 1's and 0's. What datatype you assemble those into on the processor once you read them is entirely up to you.

That is true. But Ive hit a roadblock whit reasembleing CurrentDischarge. In the beginning the value is what it is suposed to be. But when it reaches above 300 orso it will suddenly send way to high values (Like 4795). Do you know the reason?

R_Bouw: That is true. But Ive hit a roadblock whit reasembleing CurrentDischarge. In the beginning the value is what it is suposed to be. But when it reaches above 300 orso it will suddenly send way to high values (Like 4795). Do you know the reason?

Certainly not without seeing the code you used to put them together.

Hello,

I havent wrtiten the ''sending'' part and I dont have acces to it. How I know that the value is wrong is because the data gets recived bij a Display (What I also cant program). On the display it says it is: 0.3A. The value of 300 is 0.001A (300 * 0.001) = 0.3A If you put in 4795 it is 4.795 that does not match the display at all. Do you have any sugestion in what direction I sould be looking for? If you want I can send you raw bus data and maby that you spot somting i missed.

Greetings,

Robert

R_Bouw: Hello,

I havent wrtiten the ''sending'' part and I dont have acces to it. How I know that the value is wrong is because the data gets recived bij a Display (What I also cant program). On the display it says it is: 0.3A. The value of 300 is 0.001A (300 * 0.001) = 0.3A If you put in 4795 it is 4.795 that does not match the display at all. Do you have any sugestion in what direction I sould be looking for?

Greetings,

Robert

Without seeing the code or some sort of specification that tells me what it is supposed to be doing there's nothing I can do for you. There's a bug in the code somewhere. That's about all I can tell.

Like bulldog said. You should be using unsigned ints.
If you are constructing a 16 bit value from two 8 bit values
simply use uint8_t for the two 8 bit values and uint16_t for the constructed 16 bit value

Then you simply create the 16 bit value from the two 8 bit bytes:

val16bit = (val8bitHigh << 8) | val8bitLow;

You really don’t want to use addition to construct the 16 bit value especially if your values are signed integers.

— bill

Hello bperrybap,

Thanks. Ill give it a try.
Ill post the results when ive tryed (Tomorrow or monday or so).

Greetings,

Robert

Hello,

I solved the puzzel.
It turns out that I cant use the line: if(CanBusData < 10){ CanBusData = CanBusData * 16);}
This will make the value way bigger (where I was talking about). Whit BitShift this is not needed.

Thanks for you help!

Greeting,

Robert