[SOLVED] How to print the degree symbol ? (extended ASCII)

Serial Monitor now uses UTF-8...

float TbmpC = 24.1;

void setup() {
  Serial.begin(250000);
  Serial.print("Temperature: ");
  Serial.print(TbmpC, 1);
  
  Serial.write(0xC2);
  Serial.write(0xB0);
  //Serial.print(char(176));

  Serial.println("C");
}
void loop() {}

The correct byte sequence is easy to locate through Google...

https://www.google.com/search?q=utf8+degree+symbol

1 Like

That does not work on my 1.8.1 / Win7-64 / Mega

Btw 0xB0 == 176 (11 * 16)

float TbmpC = 24.1;

void setup() {
  Serial.begin(250000);
  Serial.print("Temperature: ");
  Serial.print(TbmpC, 1);
  Serial.write(176);
  Serial.println("C");
  Serial.print("Temperature: ");
  Serial.print(TbmpC, 1);
  Serial.write(0xC2);
  Serial.write(0xB0);
  Serial.println("C");
}
void loop() {}
Temperature: 24.1°C
Temperature: 24.1°C

[quote author=Coding Badly date=1499329066 link=msg=3328563]
Serial Monitor now uses UTF-8...[/quote]

thanks, that solves it.

Did that come in after IDE 1.8.1 ?

FWIW all these work correctly:

Serial.print("\xC2"); 
Serial.print("\xB0");
Serial.print("\xC2\xB0");
Serial.print(char(194)); 
Serial.print(char(176));
1 Like

I would still prefer

Serial.write(0xC2);
Serial.write(0xB0);
Serial.write(194);
Serial.write(176);

I actually prefer the Streaming library by Arduinana for simplified outputting of Serial string commands. I've used it for years with no big issues:

#include <Streaming.h>

void loop {
.
.
Serial << "Temperature: " << TbmpC  << "\xC2\xB0" << "C\n"; // 0xC2B0 is degree symbol in UTF-8 charset
.
.

Small function to write extended ASCII

void writeAscii2Utf8(Print &out, byte in){
  if(in < 0x80){
    out.write(in);
  }
  else{
    out.write(0xC0 | (in >> 6));
    out.write(in & 0x3F | 0x80);
  }
}

ninja2:
Did that come in after IDE 1.8.1 ?

Given @Whandall's experience the answer is clearly "yes".

It looks like charting was added between x.1 and x.3. But, as far as I can tell, text handling was not changed.

I suspect a bug existed in x.1 that was silently fixed by x.3. Given the code for Serial Monitor the bug was either in the Java runtime itself or in the way the Java text components were initialized.

for anyone who may run into this:

Serial.print("\xC2\xB0");

is the ONLY snippet I could get to work on my system:

Linux Mint 18.1, Cinnamon 3.2.7
Arduino IDE 1.8.3
Mega2560 R3

1 Like

Im on 1.8.4. And they are all not working for me now. And I just want to get a nice little "°"...
It used to be "\260" but nope. Giving me mirrored "?" or even more weird symbols:

      Serial.println("\xC2\xB0 C");
      Serial.write(0xC2);
      Serial.println();
      Serial.write(0xB0);
      Serial.println();
      Serial.write(194);
      Serial.println();
      Serial.write(176);
      Serial.println("\xC2");
      Serial.println("\xB0");

I moved to 1.8.4 recently and \xC2\xB0 is still working as before for me ...

I realize this topic has been closed for a while - presumably solved. However, I just upgraded to 1.8.6, and my degree symbols are no longer printing.

In fact, none of the extended ASCII characters are printing - they are all appearing as backwards " ? ".

I am on Windows10, HP TouchSmart laptop. I cannot think of anything changed except for a number of libraries which were updated, and a few new ones added.

None of the suggested solutions in this thread is working. I even tried setting preproc.substitute_unicode and change it's value from true to false, as was suggested in a 2014 forum entry.

Any suggestions?

Thanks.

seitmand:
In fact, none of the extended ASCII characters are printing

On your circa 1985 Epson dot matrix printer?

I'm sorry if I confused you. I'm "printing" to my monitor. I added the code below near the beginning of my program, and the output on the screen is a bunch of backwards question marks.

Serial.print(char(176));
Serial.write(0xC2);
Serial.println("\xC2");
byte  n=0;
for (byte i=160; i<255; i++) {
  Serial.print ((char)i); Serial.print (" ");
  n=n+1;
  if  (n==10){
    n=0;
    Serial.println(); Serial.print(i); Serial.print ("  ");
  }
}

Prior to my recent library and IDE updates, I had no problems printing out the degree symbol on the screen. I should also add that this code is on an Arduino Nano with the old bootloader. However, I have a similar program on an Arduino Uno which "prints" to both an LCD and to the serial monitor. Instead of the degree symbol, I get the backwards question mark on the monitor. (I print a special character on the LCD, and this is still printing correctly).

I hope this gives a bit more info.

Oh, yes, I used to own a dot matrix printer. But it was a Panasonic (despite poor reviews, it performed better imho than the Epson, although the Epson was a better power horse) and it was in the 1970s.

In the IDE, try Tools->Fix Encoding and reload

Also, you could try editing preferences.txt (if you go to File->Preferences, the bottom three lines of the preferences panel show you where preferences.txt is, and what to do)

Look for the line: editor.font

try setting it to : editor.font=Monospaced,plain,12

None of the suggested solutions in this thread is working.

Based on your posted example code, I don't think you are not correctly executing the two byte codes for the UTF8 characters which pick up extended Ascii. See post #25.

The two bytes of the unicode characters need to be written together without new lines or anything in between them.

void setup() {
  Serial.begin(9600);
  Serial.print(char(176));//extended ascii not valid gives backward question mark
  Serial.println();
  Serial.write(0xC2);//utf-8 OK 2 byte sequence for extended ascii degree symbol
  Serial.write(0xB0);
  Serial.println();
  Serial.print("\xC2");//utf-8 ok
  Serial.print("\xB0");
  Serial.println();
  for (byte i = 160; i < 255; i++)
  {
    Serial.print(i);
    Serial.print("  ");
    //first byte 0xC2 or 0xC3 depending on value of i
    Serial.write(0xC0 |(i >> 6));
    Serial.write(i & 0x3F | 0x80);
    Serial.println();
  }
 
}
void loop() {}

@darob - good thought, but my preferences.txt already lists the Monospace font.

@cattledog - Thank you. Using the double character print works perfectly.

This still behooves the question as to why my code worked a few weeks ago, but stopped working after I updated my IDE and a few other libraries. However, I am sure I can "fix" my software to print this out the way it is needed so that I should no longer have any issues with the extended ASCII characters.

seitmand:
I updated my IDE

Because that's not a small thing... IDE switched between extended ascii to UTF-8 for the Serial Monitor somewhere down the line. Yeah, I don't like it either that a big-ish change like that doesn't give a warning...

That would be my guess also, and I need to try reverting to my older IDE to confirm. I did not see any mention that this was one of the changes.

For LCD, this is the only one that work for me:
IDE version 1.8.8
lcd.print(char(0xDF));

Those do not work for me:
// lcd.print(char(176));
// lcd.print(char("°"));
// lcd.print((char)176);

But thanks to this thread, I did solve my problem making my
MLX 90614 IR Thermometer.

My code so far, if someone is interested:

#include <Wire.h>
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
#include <LiquidCrystal.h>

// LCD module connections (RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {
lcd.begin(16, 2);
lcd.clear();
Serial.begin(9600);
mlx.begin();
Serial.println("Adafruit MLX90614 test.");
Serial.println("");

lcd.setCursor(0, 0);
// Next line (0, 1)
lcd.print(" MLX 90614 Test ");
lcd.setCursor(0, 1);
lcd.print(" IR Thermometer ");
delay(2000);

}
void loop() {
Serial.print("Ambient = ");
lcd.setCursor(0, 0);
lcd.print("Ambient ");
lcd.setCursor(8, 0);
Serial.print(mlx.readAmbientTempC());
lcd.print(mlx.readAmbientTempC());
lcd.setCursor(13, 0);

// lcd.print(char(176));
// lcd.print(char("°"));
// lcd.print((char)176);
lcd.print(char(0xDF));

lcd.print(" C");
Serial.print("° C\tObject = ");
Serial.print(mlx.readObjectTempC());
lcd.setCursor(0, 1);
lcd.print("Object ");
lcd.setCursor(8, 1);
lcd.print(mlx.readObjectTempC());
lcd.setCursor(13, 1);
lcd.print(char(0xDF));
lcd.print(" C");

Serial.println("° C");
Serial.print("Ambient = ");
Serial.print(mlx.readAmbientTempF());
Serial.print("° F\tObject = ");
Serial.print(mlx.readObjectTempF());
Serial.println("° F");

Serial.println();
delay(500);
}

Try this belated reply..

Serial.print(byte(223)); //serial monitor for degree symbol or similar
Serial.print((byte)223);

lcd.write(byte(223)); // on lcd or
lcd.write((byte)223);