I have been trying to print the letter
µ on the Serial Monitor of Arduino IDE but I failed to do so. Is there any way to print
µ or any other
Non ASCII characters such as
þ, etc using
Most of what follows has already been covered in previous answers. I am posting this nevertheless because I feel no answer so far makes the whole story clear enough. Let me break down the question into two sub-questions.
1. How can I get non-ASCII characters correctly print on the serial monitor?
The answer is simply send them as UTF-8.
That's really all there is to it. The serial monitor expects you to send UTF-8, and it will print the characters correctly only if you use this encoding. But that brings the second question:
2. How can I get the characters as UTF-8 in my Arduino program?
Here you have several options:
Option 1: encode them yourself
For example, the Greek letter “μ” (U+03BC) in UTF-8 is (0xce 0xbc). You can send those bytes explicitly, like
or, more comfortably, like
The second syntax is more convenient because it allows the character to be embedded within a longer string.
Option 2: let the Arduino IDE encode them
If you can get the characters in the IDE's editor window, either with an appropriate keyboard layout or by copying and pasting from another application, then you can use them as is in the string:
The editor will save the source code as UTF-8, and those UTF-8 bytes will go undisturbed from the source file to the compiled program, to the Arduino memory, to the serial port, and finally to the serial monitor.
This option is the best for readability. However, it is somewhat fragile: if the source code ever gets re-encoded (e-mail clients and servers sometimes do that), then the resulting program will not work as expected.
Options 3: let the compiler encode them
You can ask the compiler to do the UTF-8 encoding for you with the syntax
Here, the escape sequence
\u03bc is a way to represent the Unicode
character U+03BC (i.e. “μ”), and the
u8 prefix means that you want the
string as a byte array encoded in UTF-8.
Note that, in practice, the
u8 prefix is not needed, as the gcc
compiler assumes UTF-8 by default. I would keep the prefix anyway
because it doesn't hurt to make the encoding explicit, and it may avoid
angering some language lawyer...
Note also that the syntax above only works for characters U+0000 through
U+FFFF, i.e. the basic multilingual plane. For other Unicode characters,
you have to use the syntax
\U + 8 hex digits. For example, the
character “😎” (U+1F60E: smiling face with sunglasses) can be printed
Clarification about UTF-16: A common misconception has it that with
\u you write the characters as UTF-16 code units, and with
write UTF-32 code units. But it is incorrect:
both syntaxes are used to describe a
single character (technically, a code point), irrespective of the
encoding. Since the UTF-16 encoding for “😎” is (0xd83d 0xde0e), one
could be tempted to write
// Write as UTF-16 code units in the source code. Serial.print("\ud83d\ude0e"); // WRONG
but then the compiler rightfully complains
error: \ud83d is not a valid universal character error: \ude0e is not a valid universal character
So forget about UTF-16. There is no UTF-16 involved anywhere, except in the internal representation used by a Java widget used to implement the serial monitor, which is a completely irrelevant implementation detail.
The Serial Monitor uses Unicode, so sending characters in that format is possible. The UTF-16 code for µ is 03BC, and you can send it by prepending
The actual stream of transformations is you provide Unicode (essentially UTF-16) in your string. C++ then converts that into a stream of 8-bit characters in UTF-8 format, which is then sent down the serial connection. Java then receives those and interprets them as UTF-8, recombining them back into the original UTF-16 characters for display in the JTextArea that comprises the Serial Monitor in the Arduino IDE.
This complex transformation is done because:
- UTF-8 is easier to stream over an 8-bit data link, but is very hard to work with in a program (because of variable-length byte sequences), and
- UTF-16 is hard to stream (and breaks ASCII compatibility) but is far easier to work with programmatically (since it is just fixed size 16-bit characters).
0x03BC gets transformed into
0xCE,0xBC which is the UTF-8 representation of the Unicode character
It depends on your operating system, the arduino version and perhaps even on the selected board.
You have selected a weird character, because there are two versions: the micro µ and the mu μ.
See: https://en.wikipedia.org/wiki/Mu_(letter) and https://en.wikipedia.org/wiki/Micro-. They are not the same.
In linux with the Arduino 1.8.5 and Arduino Uno board, everything supports UTF-8 (the Arduino ide, the serial monitor and the ino file).
To test it, I have written the micro character with AltGr+m in the sketch. It is stored in the ino file as C2 B5, which is UTF-8. It shows in the serial monitor as µ.
With gtkterm, it shows as a µ, and in hexadecimal and it shows C2 B5. That confirms that everything is UTF-8 in linux with Arduino version 1.8.5.
The Unicode "\u03BC" shows a µ in the serial monitor. It is stored in the ino file as 5C 75 30 33 42 43. That is not UTF-8 and not UTF-16, but ASCII for the characters "\u03BC". That is okay, since that is what is typed in the sketch. With gtkterm it shows a µ and CE BC in hexadecimal mode. The CE BC is UTF-8 for mu.
That means the Unicode is translated to UTF-8. Perhaps the compiler translates it to UTF-8?
These are the only tests that I did. It is just a very small part of all possibilities.
Try to type µ (mu or micro) in the Arduino ide editor.
Using AltGr+m will only work if you have selected a certain keyboard settings. Perhaps you can copy the character from the Wikipedia page.
Using Unicode "\u03BC" seems to be possible.
The internal format of text in Java was UTF-16, but only a fixed two byte format, not the four bytes. It was therefor only a subset of the Unicode characters. The newest Java version supports the real UTF-16 format for user strings, and thus supports all the Unicode characters.
The data that is stored to a ino file and the data that is transmitted to the serial monitor can be ASCII for normal characters with the addition of UTF-8. Most special characters that I use require two bytes in the UTF-8 format.
For Majenko: look at the binary data of a ino file and the binairy serial data. It is not a fixed two byte per character, but just one byte for normal characters.
I still don't know who translates the Unicode description of a character to UTF-8. It would be indeed weird if the compiler did that, so somewhere Java might automatically translate that.