Go Down

Topic: Print degree symbol ° on LCD (Read 114803 times) previous topic - next topic

adalgisio

Was wondering how I can correctly print the Celsius degree symbol ° with LiquidCrystalLCD

I tried with

lcd.print( "°C");

but I read a non-sense char.

Thanks in advance

mem

I think 223 (0xDF) is the code for the degree symbol, try:

lcd.print(223);
or
lcd.print((char)223);

adalgisio

The second instruction works fine.
Thanks again!

davidl

Interesting that the ASCII table in the reference section of arduino.cc only shows the first 128 characters. Would seem that HD44780-compatible LCD do more than this...

/david

halley

#4
Jan 30, 2009, 08:44 pm Last Edit: Jan 30, 2009, 08:44 pm by halley Reason: 1
ASCII is a 7 bit standard.

ASCII (the American Standard for Computer Information Interchange) only covers values between 32 and 127, and the meanings of control characters below 32.

Above that, if you're using a it's a no-mans-land where any device can come up with whatever they want:  smileys, graphics blocks, arrows, space invaders, copyright, degrees, fractions, whatever.  Your PC's idea of what to do with these characters is different from the old Commodore computers, and different from Tandy computers, etc.

To go beyond ASCII, you need to know what the encoding for a given device (and the device's mode) is.  These can be 8-bit encoding systems, or multiple bytes per character, depending on the language(s) required.  JIS is a coding standard that supports Japanese characters, for example.  In other cases, there are even variations on how multiple bytes are ordered must be part of the definition.  Unicode can be packed into equal widths (UTF-16) or variable widths (UTF-7, UTF-8).

The "default standard" for WWW pages is Unicode in UTF-8, but many pages get it wrong.  Web browsers usually have a menu to let you choose the encoding in case it wasn't specified on the page itself.  Tiny little embedded devices like this LCD panel don't have that luxury, so you have to send it the correct bytes to get the characters you expect.

anachrocomputer

Those LCDs have a bunch of "special" characters in positions above 128, such as 'mu' (as in microFarads) at 0xE4, Omega (Ohms) at 0xF4, and PI at 0xF7.  It's worth checking the data sheet for the chip, or writing a little test program that displays them, a few at a time.

hoopstar

Here's the HD44780's character set..




Hoops

halley

#7
Jan 31, 2009, 04:58 am Last Edit: Jan 31, 2009, 04:09 pm by halley Reason: 1
Heh, a full set of katakana.  Perfect for an Arduino Japanese RPG.

[size=14][ch12290][ch12300][ch12301][ch12289]?[ch12530][ch12449][ch12451][ch12455][ch12457][ch12515][ch12517][ch12519][ch12483]
[ch12540][ch12450][ch12452][ch12454][ch12456][ch12458][ch12459][ch12461][ch12463][ch12465][ch12467][ch12469][ch12471][ch12473][ch12475][ch12477]
[ch12479][ch12481][ch12484][ch12486][ch12488][ch12490][ch12491][ch12492][ch12493][ch12494][ch12495][ch12498][ch12501][ch12504][ch12507][ch12510]
[ch12511][ch12512][ch12513][ch12514][ch12516][ch12518][ch12520][ch12521][ch12522][ch12523][ch12524][ch12525][ch12527][ch12531]

[ch12450][ch12523][ch12485][ch12452][ch12494] (a ru du i no)[/size]

The "degrees symbol" and the `` double-quote there are serving a dual purpose, they're diacritical symbols used in Japanese also.

Three characters near the end are [ch21315] (1000) [ch19975] (10,000) and [ch20870] (yen).

anachrocomputer

Note that the first column in that table contains user-programmable characters.  I have a sketch here that programs one of them, and displays it.  If anyone's interested, I can tidy it up a bit and post it to the forum.

flyboy

I haven't used LCDs much and I didn't know how to do the custom characters.  I'd be interested in seeing how to do that.  Please post.

anachrocomputer

OK, will do!  I used the custom-character code at Dorkbot London the other day, so I have an example sketch.  It reads the analog input and displays a bar-graph across the LCD; to increase resolution, it defines a set of characters with columns of pixels lit.

flyboy


anachrocomputer

OK, this is the sketch that I used to try out user-defined characters on a four-row, 20 character LCD.  If you have a two-row LCD, you'll have to change the calls to "drawbar" in the main loop.  You'll need a potentiometer with the track connected to 0V and 5V, and the wiper connected to analog in 0.  Turn (or slide) the pot to see the bar extend across the LCD.  The crucial command to the LCD is 0x40, which is used to position the "cursor" in the CGRAM, which is where the user-defined characters are stored.  A call to "home" is required after defining the characters, to put the cursor back into the main display memory.  All this is documented in the HD44780 data sheet.

Code: [Select]
// lcd_test --- testing the 20x4 LCD for DorkSnow
// John Honniball

#include <LiquidCrystal.h>

LiquidCrystal lcd (8, 9, 10, 4, 5, 6, 7);

/* defChar --- set up a user-defined character in CGRAM */

void defChar (LiquidCrystal &thelcd, int asc, const unsigned char row[8])
{
 int i;
 
 if ((asc < 0) || (asc > 7))
   return;
   
 thelcd.command (0x40 | (asc << 3));
 
 for (i = 0; i < 8; i++)
   thelcd.write (row[i]);
   
 thelcd.home ();
}


/* setup --- Arduino initialisation */

void setup ()
{
 static unsigned char cheq[8] = {
   0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA
 };
 static unsigned char bar0[8] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 static unsigned char bar1[8] = {
   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
 };  
 static unsigned char bar2[8] = {
   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
 };
 static unsigned char bar3[8] = {
   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c
 };
 static unsigned char bar4[8] = {
   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e
 };
 static unsigned char bar5[8] = {
   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
 };
 
 lcd.clear ();
 defChar (lcd, 0x00, bar0);
 defChar (lcd, 0x01, bar1);
 defChar (lcd, 0x02, bar2);
 defChar (lcd, 0x03, bar3);
 defChar (lcd, 0x04, bar4);
 defChar (lcd, 0x05, bar5);
 defChar (lcd, 0x06, cheq);

 lcd.print ("Hello, DorkSnow");
}


/* loop -- Arduino main loop */

void loop ()
{
 int ana;
 
 // Read from potentiometer connected to analog pin 0
 ana = analogRead (0);
 
 lcd.setCursor (0, 1);

 // Display analog value in decimal
 lcd.print ("analogRead = ");
 lcd.print (ana, DEC);
 lcd.print ("   ");

 // Display two rows of "analog" bar-graph
 // For a two-row LCD, change these next two lines to: drawbar (0, ana);
 drawbar (2, ana);
 drawbar (3, ana);

 // Update rate is 50Hz (approx)
 delay (20);
}


/* drawbar -- draw a bar on one row of the LCD */

void drawbar (int row, int ana)
{
 int bar;
 int i;
 
 lcd.setCursor (0, row);
 
 // Bar is 120 pixels long; analog range is 0..1023
 bar = ((long int)ana * 120L) / 1023L;
 
 // Each character cell represents six pixels
 for (i = 0; i < bar / 6; i++)
   lcd.write (0x05);

 // Display last few pixels using user-defined characters (if not at extreme right)
 if ( i < 20) {
   lcd.write (bar % 6);
   i++;
 }
 
 // Clear remainder of row
 for ( ; i < 20; i++)
   lcd.write (0x00);
}
   

flyboy

Help me understand your code a little here.  It appears that at the beginning of Void Setup, you're defining the pixels that will be "on".

Code: [Select]
void setup ()
{
 static unsigned char cheq[8] = {
   0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA
 };
 static unsigned char bar0[8] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 static unsigned char bar1[8] = {
   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10
 };  
 static unsigned char bar2[8] = {
   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
 };
 static unsigned char bar3[8] = {
   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c
 };
 static unsigned char bar4[8] = {
   0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e
 };
 static unsigned char bar5[8] = {
   0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
 };


The second part in Void Setup is giving a variable name to each of the characters as well as telling it which memory location it will be stored in.  Am I understanding this correctly?

Code: [Select]
lcd.clear ();
 defChar (lcd, 0x00, bar0);
 defChar (lcd, 0x01, bar1);
 defChar (lcd, 0x02, bar2);
 defChar (lcd, 0x03, bar3);
 defChar (lcd, 0x04, bar4);
 defChar (lcd, 0x05, bar5);
 defChar (lcd, 0x06, cheq);

halley

Code: [Select]
defChar (lcd, 0x01, bar1);

"Define a custom character, on the lcd, to appear whenever printing character code 0x01, from bytes found in the array called bar1."

Go Up