hi,
I tried
sprintf(txt,"%d °C", temp);
Serial.print(txt);
to print a temperature.
But I get
15°
In the forum here I saw tips how to print "°" with Serial.print(), but I need it within sprintf.
What to do?
hi,
I tried
sprintf(txt,"%d °C", temp);
Serial.print(txt);
to print a temperature.
But I get
15°
In the forum here I saw tips how to print "°" with Serial.print(), but I need it within sprintf.
What to do?
I suspect txt is too small.
sorry, I missed one letter.
The output is e.g.
15°C
The problem is the letter  after 15.
The problem is not how to print it, the problem is how you read it ![]()
The "degree sign" character ° is not a normal readable character.
For ASCII it is the extended ASCII character 248.
For UTF-8 is it U+00B0, which is 0xC2, 0xB0.
When the 0xC2, 0xB0 are displayed as ASCII you get weird characters.
Even when everyone would use UTF-8, there are still problems. In Windows a text file with UTF-8 has often a 'BOM' identifier as the first bytes to indicate that it is a UTF-8 text file. But other operating system don't support that.
That's not all, there is also ANSI and Unicode.
The Arduino IDE used UTF-8, but that is not completely supported and is different for Windows or linux. The serial monitor in Windows might not use UTF-8 yet.
Why do you need the "degree sign" in the serial monitor ? Is it that important ? If you fix it, it might not work when the serial monitor is in an other mode or with another serial terminal program.
For a webpage, it is well defined. The "degree sign" in HTML is °
For a LCD display it is also reliable. Create your own ° sign, for example as code 1. Print text to the lcd display with: "25 \1C
Principally I have a solution, but...
The new code is
sprintf(txt,"%d%cC", temp, (char)248);
Serial.print(txt);
According to my ASCII table 248 should be °, but I get
15øC
The Arduino IDE seems to use a different ASCII table.
Does anybody know the wright code, instead of 248 what?
well, on the SerialMonitor it looks somewhat curiously.
But what matters.
We prefer that you give a test sketch.
In linux I see UTF-8 characters in the serial monitor. If you give a test sketch, I could try it in Windows if you want.
Perhaps you should give a screendump of what you see, since the character could be different after copying to this forum.
hi,
the complete sketch is quite long and would need some special hardware. But the part where the problem comes up is here:
char wdat[24];
char wstr[8];
... // here is code to read temperature data from an external sensor
... // and some Serial.print() the printout of which can be seen on the screen shot too
... // vf is a float value for temperature and rh an integer for relative humidity
dtostrf(vf, 4, 1,wstr);
sprintf(wdat," -> %s°C %d%%",wstr, rh);
Serial.print(wdat);
A screenshot is attached as a png file. The relevant part is marked.

For our convenience:

(Embedding images described here.)
To avoid any UTF-8 monkey business with the editor and/or IDE, I think you should try this,:
sprintf(wdat," -> %s\xF8C %d%%",wstr, rh);
That uses the "\x" hexadecimal escaping in a double-quoted string. Described here, for example. That should work on your LCD, if (char)248 is indeed the degree sign. In the Serial Monitor window, (char)248 will look like you described above: ø. It's just the difference between the Serial Monitor and your LCD.
Cheers,
/dev
sprintf(wdat," -> %s \xB0 C %d%%",wstr, rh);
Hello,
There was this workaround, unfortunately not working anymore since recents IDE updates...
If you use older IDE like 1.0.X it should work.
And yes, "\xB0" will work too.
In your Reply #7, when I copy that part of the sketch into the Arduino IDE, and save the file, and open it in a binary editor, it says : C2 B0. That is the same as I wrote before.
This webpage has the tag :
That means the code C2 B0 in your Reply #7 reads as a ° when it is viewed in a browser, as you are doing this very moment.
The screenshot is from a program we don't know. But that obvious does not use UTF-8. It might use ASCII, but I don't know if it supports extended ASCII.
I thougth it was code 248 in extended ascii, be Coding Badly says it is 0xB0 which is 176. I was wrong, it is indeed 176.
If you want me to try that in Windows, please give a short test sketch.
My conclusion: we can not answer your question. It depends on the character encoding that the program uses which is used to view that data.
As I wrote before, it is well defined for a webpage, and no problem with a LCD display. But the degrees sign in a text file, that gets messy, and that is what you have encountered.
I suppose the extended ascii 176, 0xB0, 'xB0' will work. But what if the program to view that data is updated and no longer supports extended ascii ? Or another program is used to view that data which uses UTF-8 ?
Koepel:
I thougth it was code 248 in extended ascii, be Coding Badly says it is 0xB0 which is 176. I was wrong, it is indeed 176.
"Extended ASCII" is such an ambiguous term...
248 is degree in CP437 (Wikipedia) and other IBM PC / MS-DOS code pages.
Thank you oqibidipo ![]()
SupArdu, we could go on with this forever. Do you understand that one problem is how to write the data, and another problem is how it is printed/viewed ? Let us know what you have deciced.
thank you for so many tips ![]()
" -> %s\xB0 C " works. The printout is: 18.4° C
But " -> %s\xB0C " does not work. The printout then is: 18.4
The blank between \xB0 and C is necessary! And this is acceptable.
Nevertheless I will ask the supplier of the display. It is a MI0283Qt9.
You can solve it like this:
"-> %s\xB0""C"
(tl;dr? Skip to the bottom of this post.)
sprintf, at the end of the day, produces a series of bytes. Numbers from 0-255. So why do we see letters on our serial monitor? Because the serial monitor displays those nubers as characters. How does it decide which numbers correspond to which characters?
Well, it's complicated.
For numbers from 32-126, it uses ASCII: the American Standard Code for Information Interchange. This was originally meant for teletype machines, and these days it is pretty ubiquitous. It has mostly replaced other standards such as EBCDIC.
But you'll notice that ASCII doesn't define anything above 128. Instead, they used bit 7 as a parity bit. But inside devices where noise in the transmission lines isn't such a problem, different platforms used these numbers in different ways. IBM PCs had a set of useful accented characters, and other things like characters with which you could draw boxes.
This evolved, in MS-DOS and the earlier versions of Windows, to sets of "code pages" for different languages. You would specify a code page on whatever device you are outputting to (a printer, a textbox) and the 128-256 character range would have a map of suitable characters for that language.
After many years of shenanigans, the computing world bit the bullet and developed a big set of all characters ever called Unicode. The price of Unicode is that all characters ever are described by a 16-bit number. (But we still have code pages for Chinese, in particular).
To cope with this new world, one needs to grok that a byte is not a character, and a character is not a byte. Rather, a stream or sequence of characters is encoded into a series of bytes.
The 'char = a machine byte' in the C programming language is a hangover of simpler times, and is not really the case anymore when we are talking about text. The Unicode standard never talks about bytes or chars, it is defined explicitly in terms of 'octets' - packets of exactly 8 bits. But for us (and most people), that's a byte, or a C char.
We have encodings like ASCII, which explicitly only has the original 127; we have various ISO encodings, which basically are the old MS-DOS code pages rebranded; we have UTF-16, where we just print out the full two-byte value for each character; and we have things like JS-16 and UTF-8, which handle the whole unicode character set efficiently and preserve the ASCII set of encodings at the price of characters being represented by variable length sequences of bytes.
So. To get a degree sign onto whatever output device you are using, you have to send a series of bytes which that particular output device recognises as being an encoded degree sign.
So there's your first problem: what encoding is your output device? If you are using an LCD, you'll need to look at that LCD's data sheet. If you just want to see it in the arduino serial monitor, well - the serial monitor is implemented in java. It might be using the default encoding on whatever platform it is running on (eg: Windows-1252), or it might be using UTF-8.
Let's assume UTF-8. A unicode degree sign is character 0xB0. Assuming that our serial monitor talks UTF-8, you need to output a UTF-8 encoded U+00B0 to the serial port. Googling 'UTF-8 calculator' sends me to a page that tells me that the UTF-8 encoding for a unicode 00B0 is C2 B0.
Your next problem is explaining to sprintf that that's what you want to send. Embedding the codes in the string is awkward because 'C' is a hexadecimal digit, so you are probably better off just doing it as characters:
sprintf(txt,"%d %c%cC", temp, 0xC2, 0xB0);
My sketch is
void setup() {
// put your setup code here, to run once:
Serial.begin(57600);
while(!Serial);
}
void loop() {
static int temp = 0;
char txt[256];
sprintf(txt,"%d %c%cC\n", temp++, 0xC2, 0xB0);
Serial.write(txt);
delay(500);
}
And the output on the IDE serial monitor on my Mac is
0 °C
1 °C
2 °C
3 °C
4 °C
5 °C
6 °C
7 °C
8 °C
9 °C
10 °C
11 °C
YMMV, particularly if you want this to got to an LCD or other output device, or if you are running on a widows box an the serial monitor uses the windows default encoding. There ought to be a way to specify the encoding in the IDE, but I can't find it.
EDIT: added this in the suggestions subforum.
I recently dealt with this myself. On any keyboard with a number pad, you can type these >128 characters by holding down the ALT key and pressing the numbers. ALT-167 is the degree symbol.
Type it in, upload the program and it will work. Unfortunately when you save the program, the IDE uses UTF-8 so it stores the character with two bytes. When you open that saved program, it looks the same but there are now two bytes in that string, representing that one printable character.
I haven't tested fully, but it seems like the serial monitor doesn't use UTF-8 so it will display the incorrect characters.
Serial.write(167); //write degree char