One thing which which confused me when beginning Arduino, was Serial.print(78, HEX) BIN, OCT and so on. The data which goes via serial is bytes and it is programmers job to interprete those bytes. C is confusing enough itself.
Yes, the data is a series of bytes. However, many serial port implementations put special meaning on certain byte values, and may even do translations of some of those values (for example, a CR may become LF, or LF may become CR and LF.) Also, some control characters can be interpreted by the code on certain serial inputs, for example there may be line editing features where a backspace deletes a character, and control-X clears the input buffer.
If you have absolute control over the serial port drivers and know that absolutely no special meaning or translation is performed on any of the byte values, then you can go ahead and send the raw byte values over the link. But in many cases it can be not worth the risk.
The solution is to make sure that none of those special byte values are used in the communications stream, and the easiest way to do that is to convert the raw binary bytes into text representations. Using HEX is an efficient way to do so as it uses less characters to transfer data than decimal, octal, or binary, it divides easily into all of the commonly used data element sizes, and there are built in conversion mechanisms in most languages to format and parse hex values. Base64 is an even more compact way to encode binary data into safe printable values, but there aren’t the built-in mechanisms in place to generate or decode such data streams.
Yes, hexadecimal notation is a little strange to grasp at first. But it’s a valuable skill to learn. Depending on what you’re doing with the data, hexadecimal can actually make the math easier! For example, if you want to define a particular bit pattern, with experience it’s actually easier to figure out the value in hex than it is in decimal. For example, if you want to set the low bit of a byte, it’s 0x1. If you want to set the low bit of the second byte of a word, it’s 0x100. If you want to set the low bit of the high byte of a long word, it’s 0x1000000. The corresponding decimal values are 1, 256, and 16777216. (I had to get out a calculator to figure out that last value, while all of the hexadecimal values I could do without thinking about it.)
There is a reason for the different number bases (although the reasons for octal are far fewer these days, but it made a lot of sense for older 12 bit computers.) It’s worth taking the time to learn them, as they really can make your life easier in many situations - especially when dealing with low level hardware, which is so common in embedded electronics like Arduino projects.