Forming a hex array to send on serial port

Im trying to form a hex array with a variable number of data bits. I have a function which accepts the src, dest, message type and message data all in bytes and with single bytes everything works. I cant work out how to get it to accept an array of bytes for the message data as this can be anything from 1 to 20 bytes long. I will effectively end up with [SRC][LEN][DST][MSGTYPE][MSGDATA0]...[MSGDATA99][CRC]

So, how do i get it to accept this array within an array?!

Heres the code...

void sendMsg(byte source, byte destination, byte msgType, byte msgData) {

	byte len = sizeof(msgData) + 3;
	
	/* DEBUG
	Serial.println("");
	Serial.print("Src: ");
	Serial.println(source, HEX);
	Serial.print("Len: ");
	Serial.println(len, HEX);	
	Serial.print("Dst: ");
	Serial.println(destination, HEX);
	Serial.print("Msg:");
	Serial.println(msgType, HEX);
	Serial.print("MsgData: ");
	Serial.println(msgData, HEX);
	*/

	byte GetData[] = {source, len, destination, msgType, msgData, 0x00};
	byte chkSum = getCheckSum(GetData);
	int chkSumLocation = sizeof(GetData) -1;
	
	/* DEBUG
	Serial.print("chkLoc: ");
	Serial.println(chkSumLocation);
	*/

	GetData[chkSumLocation] = chkSum;

	for (int i = 0; i < sizeof(GetData); i++)  {
		Serial.print(GetData[i], HEX);
	}
	//Serial.println("");
}

int getCheckSum(byte *string) {
int i;
int checksum;
int length;
checksum = 0;
length = string[1]+1;
//Serial.print("length: ");
//Serial.println(length);
for (i = 0; i < length; i++) {
	checksum ^= string[i];
}
return checksum;
}

Also, while printing the packet out i am only getting one digit if the number printed is less than 10, for example instead of getting 04050610 i get 45610. any ideas?

Many thanks!

What is a "HEX array"?

You've got a function called sendMsg() that has an array called GetData and there is no obvious getting of anything and anyway the array has no room for data.

I'm confused.

What are
source, len, destination, msgType, msgData
Variables, constants?
Doh, read the code Rob.

How about posting all the code.


Rob

You want the sendMsg() function to accept an array as the 4th argument? Then, define it that way:

void sendMsg(byte source, byte destination, byte msgType, byte msgData[someMaxSizeHere]) {

or

void sendMsg(byte source, byte destination, byte msgType, byte *msgData) {

Statically sizing GetData will be required. You'll need to define the array large enough to hold the largest message you plan to support. Copying the data from msgData to GetData is easy, using a for loop.

Graynomad:
What is a "HEX array"?

Apologies, thought it was more obvious than it is. Its an array of hex bytes. It is formed in the way i showed in the OP, but where the message data bytes sit needs to be expandable and fed from another array of bytes.

PaulS:
You want the sendMsg() function to accept an array as the 4th argument? Then, define it that way:

void sendMsg(byte source, byte destination, byte msgType, byte msgData[someMaxSizeHere]) {

or

void sendMsg(byte source, byte destination, byte msgType, byte *msgData) {

Statically sizing GetData will be required. You'll need to define the array large enough to hold the largest message you plan to support. Copying the data from msgData to GetData is easy, using a for loop.

I was trying this but because i did not know the exact length it wouldnt accept the array being initialised as byte msgData[] which threw me. i have got the code to fill the array from a for loop, that came to me shortly after posting. Can you explain the concept of *msgData?

I'll try these solutions now and let you know. Thanks!

Can you explain the concept of *msgData?

The * means that the variable is a pointer. It points to one or more byte variables in a row, which is what an array is.

The biggest difference is that with the pointer, the called function doesn't need to know, in advance, how big the array is, providing that there is some other way to know when to stop traversing the array.

For strings, a NULL terminator defines when to stop. If there is some value that you can place in the array that means "stop here" like the NULL does, then you can process the "array" using the pointer until you see the element that contains the "stop here" marker.

Usually, with byte arrays, there is no "stop here" byte possible, since all possible values have other meanings. In that case, you will need to pass the length of the array pointed to to the function.

That makes sense now. Also explains why i've seen *char every now and again.

Heres the solution i've got that seems to work now, although if anyone can tell me how to get away with not passing the length of the msgData array then feel free!

This calls the function:

byte msgDataArray[] = {0x04, 0x01, 0x99, 0xAA};
int msgDataSize = sizeof(msgDataArray);
sendMsg(0x44,0xBF,0x74, msgDataArray, msgDataSize);

The function itself:

void sendMsg(byte source, byte destination, byte msgType, byte *msgData, int msgLen) {
	
	//	1		2		3		4			5	6		7
	// [src]	[len]	[dest]	[msgtype]	[d0]...[dn]	[crc]
	
	//get length of msg data for len field
	byte len = msgLen + 3;
	//Set known data
	byte GetData[255] = {source, len, destination, msgType};
	for (int i = 0; i < msgLen; i++) {
		int index = i+4;
		GetData[index] = msgData[i];
	}
	//Location of ChkSum
	int crcLoc = msgLen + 4;
	//Set ChkSum
	GetData[crcLoc] = getCheckSum(GetData);

	//Print data to serial
	for (int i = 0; i < len+2 ; i++)  {
		Serial.print(GetData[i], HEX);
	}
}

and the CRC function:

int getCheckSum(byte *string) {
int i;
int checksum;
int length;
checksum = 0;
length = string[1]+1;
//Serial.print("length: ");
//Serial.println(length);
for (i = 0; i < length; i++) {
	checksum ^= string[i];
}
return checksum;
}

Many thanks to those that helped.

although if anyone can tell me how to get away with not passing the length of the msgData array then feel free!

You can't. What you are passing to the function is similar to one end of a piece of string, telling the function to follow the string. Only the caller knows how long the piece of string is. The called function can not tell.

that sucks, but never mind. i can work round it! Cheers for the help.