Pages: [1]   Go Down
Author Topic: Forming a hex array to send on serial port  (Read 2566 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...

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!
Logged

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 129
Posts: 8598
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: October 09, 2012, 08:55:40 am by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 50300
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You want the sendMsg() function to accept an array as the 4th argument? Then, define it that way:
Code:
void sendMsg(byte source, byte destination, byte msgType, byte msgData[someMaxSizeHere]) {
or
Code:
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.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

You want the sendMsg() function to accept an array as the 4th argument? Then, define it that way:
Code:
void sendMsg(byte source, byte destination, byte msgType, byte msgData[someMaxSizeHere]) {
or
Code:
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!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 50300
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
byte msgDataArray[] = {0x04, 0x01, 0x99, 0xAA};
int msgDataSize = sizeof(msgDataArray);
sendMsg(0x44,0xBF,0x74, msgDataArray, msgDataSize);

The function itself:
Code:
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:
Code:
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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 637
Posts: 50300
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 55
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: