Bart
Bart

Reputation: 767

converting unsigned char > 255 to int

I'm programming with a PLC and I'm reading values out of it.

It gives me the data in unsigned char. That's fine, but the values in my PLC can be over 255. And since unsigned chars can't give a value over 255 I get the wrong information.

The structure I get from the library:

struct PlcVarValue
{
    unsigned long   ulTimeStamp         ALIGNATTRIB;
    unsigned char   bQuality            ALIGNATTRIB;
    unsigned char   byData[1]           ALIGNATTRIB;
};

Anyways I'm trying this now: (where ppValues is an object of PlcVarValue)

    unsigned char* variableValue =  ppValues[0]->byData;            
    int iVariableValue = *variableValue;

This works fine... untill ppValues[0]->byData is > 255;

When I try the following when the number is for example 257:

unsigned char testValue = ppValues[0]->byData[0];
unsigned char testValue2 = ppValues[0]->byData[1];

the output is testvalue = 1 and testvalue2 = 1

that doesn't make sense to me.

So my question is, how can I get this solved so it gives me the correct number?

Upvotes: 1

Views: 1179

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409356

That actually looks like a variable-sized structure, where having an array of size 1 at the end being a common way to have it. See e.g. this tutorial about it.

In this case, both bytes being 1 for the value 257 is the correct values. Think of the two bytes as a 16-bit value, and combine the bits. One byte will become the hight byte, where 1 corresponds to 256, and then add the low bytes which is 1 and you have 256 + 1 which of course is equal to 257. Simple binary arithmetic.

Which byte is the high, and which is the low we can't say, but it's easy to check if you can force a message that contains the value 258 instead, as then one byte will still be 1 but the other will be 2.

How to combine it into a single unsigned 16-bit value is also easy if you know the bitwise shift and or operators:

uint8_t high_byte = ...
uint8_t low_byte = ...
uint16_t word = high_byte << 8 | low_byte;

Upvotes: 3

Related Questions