Reputation: 767
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;
};
ulTimeStamp
gives the timebQuality
gives true/false (be able to read it or not)byData[1]
gives the data.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
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