Printing Hex into Serial Port
How get a HEX number from the Serial Monitor
uart - Send HEX number over serial - Arduino Stack Exchange
Arduino: why does Serial.println(int, HEX) display 4 bytes? - Electrical Engineering Stack Exchange
Simple brute force method, is to write a routine as:
void p(char X) {
if (X < 16) {Serial.print("0");}
Serial.println(X, HEX);
}
And in the main code:
p(byte1); // etc.
The lowest footprint in Memory, Code and runtime would be classic bit playing
byte b;
Serial.print(b>>4, HEX);
Serial.print(b&0x0F,HEX);
Which is working fine on any 8bit type. For any other mask also the first line to
Serial.print((b>>4)&0x0F, HEX);
As noticed by jsotola in a comment, your device doesn't seem to be
expecting HEX at all, but rather plain binary. Serial.print() is not
appropriate, as it is designed for sending ASCII text. For binary data,
you should prefer Serial.write(). More specifically, for sending
arbitrary binary data, the proper method is
size_t Print::write(const uint8_t *buffer, size_t size)
Applying this to your example gives:
const size_t packet_length = 6;
uint8_t packet[packet_length] = {0xaa, 0xbb, 0x03, 0x01, 0x03, 0xee};
Serial.write(packet, packet_length);
if device expects actual numbers, then it does not receive them in hex format or decimal, but in binary. in which case you would need an array of numbers and then go with them using for loop (or purpouse made function.
byte sequence[]={0xAA, 0xBB, 0x03, 0x01, 0x01, 0xEE};
for(byte i=0; i<sizeof(sequence);i++) Serial.write(sequence[i]);
if you have to send it as a HEX, then its most likely a case of hex representation and you can use printf for that
Serial.printf("0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", 0xAA, 0xBB, 0x03, 0x01, 0x01, 0xEE);
Another think is that you should be careful using println when communicating with other devices.
println ads extra character (number) for new line, after the data you wish to send. if you only want to send data you wish to send, then use print instead
Edit: Thanks for the note from Edgar Bonet, I was warned that printf is still not a standard instruction outside of the ESP core. Its well worth adding it up by yourself. Look for a guide on arduino playground.
The Arduino print / println function casts the int to a long, which is 4 bytes long for Arduinos. See here: https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/Print.cpp
To have more control over printing check out the C++ sprintf function. For example,
int x = 0x9876;
char buf[9];
sprintf(buf, "%04x", x);
Serial.println(buf);
Will print it out correctly.
sprintf - http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/
format string reference - http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Some implementations of the Print class, include printf (Like Adafruit's, see here). In that case, you just do Serial.printf("%04X", x).
This is because the data-type 'int' in 'C' language, as per ANSI C standards, is a 32-bit numeric type, and thus you see 4 bytes.
If your variable 'x' can only take 2 byte values, then declare it as a 'short' variable, instead of 'int'. This is because 'short' type as per the language standards is a 16-bit numeric type.
First of all, I will challenge your assumption that you have to send the
three bytes in the same call to Serial.write(). There is no real
advantage in doing so. Serial output is handled through a memory buffer
that is consumed by the serial port within an interrupt service routine.
Serial.write() only writes to that memory buffer. Thus, you can
simply:
Serial.write("@M");
Serial.write(1);
and the receiver will not see the difference. There will be no gap
between the 'M' and the 1. There is no notion of “messages” or
“frames” on a serial link, unless an upper layer protocol adds its own
framing, which is not the case here.
Next, if you really want to issue a single call (futile as this is), you could
Serial.write("@M\1");
This, however, will not work if the last byte is zero. The method shown by the busybee is more general ans is able to send a zero-valued byte.
You can use a byte array for this:
// at the appropriate place in your code:
byte message[] = { '@', 'M', 0x01 };
Serial.write(message, sizeof message);
If you need, you can prepare the array and just assign the value:
byte message[] = { '@', 'M', 0 };
// ...
byte value = 0x01; // or any other assignment
// at the appropriate place in your code:
message[2] = value;
Serial.write(message, sizeof message);