Go Down

Topic: send data packet to serial (Read 884 times) previous topic - next topic

bl4d3

Hi, I have to send this command to a serial device

0x02
0x00
0x02
0x30
0x30
0x03
BCC

i made in this way
Code: [Select]


void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(1000);
  Serial.print(et_prepareMessage());
}

char* et_prepareMessage() {
  char buffer[7];
  buffer[0] = '0x02';
  buffer[1] = '0x00';
  buffer[2] = '0x02';
  buffer[3] = '0x30';
  buffer[4] = '0x30';
  buffer[5] = '0x03';
  buffer[6] =   getCheckSum(buffer);

  return buffer;
}

uint8_t getCheckSum(char *string)
{
  int XOR = 0;
  for (int i = 0; i < strlen(string); i++)
  {
    XOR = XOR ^ string[i];
  }
  return XOR;
}

is it correct?
I'm wondering this because by printing Serial.print(et_prepareMessage()); the result I can not see the hex string but some strange character.
Thank you

billroy

Returning the address of a local variable declared on the stack is bound to cause problems, because the memory it occupied on the stack is quickly reused.

Move the declaration of buffer[] out of the function to make it global and it should help.

-br

spatula

Serial.print() is good for printable characters, which is not your case. The second byte would be treated as a string terminating character so you would only send one byte. You should use Serial.write().

In your particular use case you may also do without a buffer, just call repeatedly Serial.write() with the different bytes. If you think you really need a buffer, either declare it globally or declare it within loop, then pass it as an argument to et_prepareMessage(). This way the buffer will not go out of scope when et_prepareMessage returns.


bl4d3

Hi, I made in this way
Code: [Select]

char buffer[7];

void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(1000);
  et_prepareMessage();
  delay(200);
  Serial.write(buffer);
}

void et_prepareMessage() {

  buffer[0] = '0x02';
  buffer[1] = '0x00';
  buffer[2] = '0x02';
  buffer[3] = '0x30';
  buffer[4] = '0x30';
  buffer[5] = '0x03';
  buffer[6] =   getCheckSum(buffer);
}

uint8_t getCheckSum(char *string)
{
  int XOR = 0;
  for (int i = 0; i < strlen(string); i++)
  {
    XOR = XOR ^ string[i];
  }
  return XOR;
}

I declared the buffer globally, but the output on the serial is pretty strange, take a look at this screenshot

is it right?
Thank you

spatula


is it right?


Not yet. In getCheckSum() you use strlen, which is based on the presence of a string terminating char (0). But your second byte is 0 so strlen will return 1 and the checksum will be wrong. You can hardcode the length directly in the for() loop, but if you want to make getCheckSum() reusable you can add a second argument for the length of the buffer, i.e. declare getCheckSum(byte* buf, int len).
The general rule is that for an array of bytes without a terminating char you need to supply its length. So, when you call Serial.write() you should pass the buffer length, i.e. Serial.write(buf, len).

PaulS

Code: [Select]
  buffer[0] = '0x02';
I seriously doubt that the receiver expects a multibyte character. I really think that you need to lose the quotes.

Go Up