Printing Hex into Serial Port
uart - Send HEX number over serial - Arduino Stack Exchange
Arduino: why does Serial.println(int, HEX) display 4 bytes? - Electrical Engineering Stack Exchange
How to use Serial.print returning full HEX value?
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.
I am attempting to send messages over serial usb via HEX (yes, I'm aware there are other posts similar to this one, but I feel I'm missing something).
Ultimately I will be sending messages back and forth from the pc to arduino mega. Right now when I send a message in hex I don't see the hex message appear in the serial monitor.
Right now I am sending 0x55 and 0xff, which comes out of the serial monitor as Uÿ. Shouldn't it show as a hex value, is there something else I need to add? The reason for using hex is to try to be somewhat efficient with sending/receiving the signal.
Here is the code that I am using:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
byte message[2]={0x55,0xff};
Serial.write(message,sizeof(message));
delay(5000);
}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);