Calculate word from two bytes

T

TBass

The controller I'm talking to sends back a string of bytes. The 8-bit
bytes are actually 16-bit word values sent out in HI-LO order.

So I get: <HI1><LO1><HI2><LO2>....
So register 1 = <H21>*256 + LO1 Register 2 = <HI2>*256+<HI2>
etc....

But I don't seem to be putting the values together correctly in my
code below:



/* THE INLINE FUNCTION getWord */
char
getWord( char HiByte, char LoByte){ return ((HiByte & 0xFF)<<8) |
(LoByte & 0xFF); }


/* The modPacket type */
class CModPacket
{
public:
CModPacket(void);
~CModPacket(void);

unsigned int File;
unsigned int Offset;
unsigned int Length;
unsigned int DataLength;
unsigned int UnitID;

std::vector<unsigned int> Data;

unsigned int TransRef;
};


#include ".\modpacket.h"

CModPacket::CModPacket(void) :
File(4),
Offset(1),
Length(1),
DataLength(0)
{
Data.reserve(255);
}

CModPacket::~CModPacket(void)
{
}


/***************************************************************
* parseReadMultiple
***************************************************************/
int
CModbusTCP_Compile::parseReadMultiple( char *pStream,
unsigned int Length,
CModPacket *pPacket )
{

unsigned int byte_length;
unsigned int x;
unsigned int y;
char *p_stream;
std::stringstream mystring;


/* GET NUMBER OF BYTES THAT FOLLOW */
byte_length = pStream[0];

if ( (unsigned int)(byte_length+1) > Length )
{
MessageBox( NULL, "Length no good", "parseReadMultiple", MB_OK );
return false;
}


/* COPY THE DATA TO THE STRUCTURE */
p_stream = &pStream[1];
char myhi;
char mylo;
for( x=0,y=0;x<byte_length;x+=2,++y )
{
myhi = ( p_stream[x] & 0xFF );
mylo = ( p_stream[x+1] &0xFF );

/* At this point, myhi = 0x1D and mylo = 0xE6 */
pPacket->Data[y] = getWord( myhi, mylo );

/* pPacket->Data[y] ends up with the value 4294967270 */
/* Expected value is 0x1D *256 + 0xE6 */
/* So expected value is: 7654 */

mystring.str("");
mystring << "[" << y << "]" << pPacket->Data[y] << " = " << myhi <<
" , " << mylo;
MessageBox( NULL, mystring.str().c_str(), "parseReadMultiple ",
MB_OK );
}

pPacket->DataLength = y;

return true;

} /* parseReadMultiple */



As you can see from the code below, I'm expecting the value 7654, but
end up with 4294967270.
Huh? That's not even a 16-bit number.

If I convert the character values to unsigned ints and put them in a
message box, like so:

mystring.str("");
mystring << "[" << y << "]" << pPacket->Data[y] << " = " <<
(unsigned int_myhi << " , " << (unsigned int)mylo;
MessageBox( NULL, mystring.str().c_str(), "parseReadMultiple ",
MB_OK );

The message returned is:

"4294967270 = 29, 4294967270"

So, the problem is in the low byte, mylo. But how can it equal
4294967270 when it is taken from an 8-byte char that I have AND'd with
0xFF. It should have a maximum value of 255.

I'm confused. Can anyone tell me what I'm doing wrong?

Thanks in advance,
T
 
T

TBass

Ouch. I see it. Stupid.

/* THE INLINE FUNCTION getWord */
char
getWord( char HiByte, char LoByte){ return ((HiByte & 0xFF)<<8) |
(LoByte & 0xFF); }

should be

unsigned int
getWord( char HiByte, char LoByte){ return ((HiByte & 0xFF)<<8) |
(LoByte & 0xFF); }
 
J

James Kanze

Ouch. I see it. Stupid.
/* THE INLINE FUNCTION getWord */
char
getWord( char HiByte, char LoByte){ return ((HiByte & 0xFF)<<8) |
(LoByte & 0xFF); }
should be
unsigned int
getWord( char HiByte, char LoByte){ return ((HiByte & 0xFF)<<8) |
(LoByte & 0xFF); }

You might also want to declare the parameters "unsigned char",
since that's how you use them. If they're unsigned char, on a
machine with 8 bit bytes, you don't need the "& 0xFF"s.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top