AGHW-Arduino-Strings-Greek chars...

I am trying to read the chars from a String with Greek chars but I see them as 2 bytes probably because of Unicode...

  1. How can we handle Unicode strings in Arduino? I mean how can we tell if a string has Unicode chars? The length() is wrong... How can we read the chars?
  2. Is there support for Greek?

I am trying to show Greek chars in a LCD 16[ch967]2 but it does not support them.. I will use special chars (unfortunately only 8!) and load the Greek chars for displaying...

I am working in a function which gets the string to display in a LCD as a parameter, replace the Greek chars with Latin substitutes and for the rest it uses the special chars....

I write code in order to be able to write (easy) to the LCD text that might contain also Greek chars without bother for the technical details...

I transform all of them in capital (upper-case) Latin and for the the 10 Greek chars which do not exist in Latin alphabet I create them (createChar) and use them... Because the special chars are 8 (only) if happened to need more (9 or 10) in the same screen text, then only the first 8 (different) will be show...

This is my first code attempt in C and Arduino please be welcome to make any suggestions...

Waiting for your opinion...

PS: The Greek chars was designed by my 9year old son so be tolerant... this is his first attempt also...

/*
  LiquidCrystal Library - display() and noDisplay()
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD and uses the 
 display() and noDisplay() functions to turn on and off
 the display.
 
 The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe 
 modified 25 July 2009
 by David A. Mellis

 
 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//  pins: 4, 5, 6, 7,                  // could not change!
//        8 (RS), 9 (Enable), 11 (RW)  // could be changed!
// RS, RW, E, D4, D5, D6, D7
LiquidCrystal lcd(8, 11, 9, 4, 5, 6, 7);

const String ChrsTblTfrm = "ABgdEZHtIKlMNkOpPsTYfXcw";
const String ChrsTblGrChrs = "gdtlkpsfcw";
const String ChrsTblEngChrSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const String ChrsTblGrChrSet = "[ch945][ch946][ch947][ch948][ch949][ch950][ch951][ch952][ch953][ch954][ch955][ch956][ch957][ch958][ch959][ch960][ch961][ch963][ch964][ch965][ch966][ch967][ch968][ch969][ch913][ch914][ch915][ch916][ch917][ch918][ch919][ch920][ch921][ch922][ch923][ch924][ch925][ch926][ch927][ch928][ch929][ch931][ch932][ch933][ch934][ch935][ch936][ch937]1234567890";

byte GrChrGama[]  = {0x1f,0x10,0x10,0x10,0x10,0x10,0x0};     //[ch915] - 
byte GrChrDelta[] = {0x4,0xa,0x11,0x11,0x11,0x1f,0x0};       //[ch916] - 
byte GrChrThita[] = {0xe,0x11,0x11,0x1f,0x11,0x11,0xe};      //[ch920] - 
byte GrChrLamda[] = {0x4,0xa,0x11,0x11,0x11,0x11,0x0};       //[ch923] - 
byte GrChrXi[]    = {0x1f,0x0,0xe,0x0,0x0,0x1f,0x0};         //[ch926] - 
byte GrChrPi[]    = {0x1f,0x11,0x11,0x11,0x11,0x11,0x0};     //[ch928] - 
byte GrChrSigma[] = {0x1f,0x18,0x4,0x8,0x10,0x1f,0x0};       //[ch931] - 
byte GrChrFi[]    = {0x4,0xe,0x15,0xe,0x4,0x4,0x0};          //[ch934] - 
byte GrChrPsi[]   = {0x4,0x15,0xe,0x4,0x4,0x4,0x0};          //[ch936] - 
byte GrChrOmega[] = {0x0,0xe,0x11,0x11,0xa,0x1b,0x0};        //[ch937] - 

void setup() {
  String strText;

  Serial.begin(9600);

  lcd.begin(16, 2);

//  debugOutputGrChrSet();

  strText = "";
  for (int i=33; i <= 64; i++){
    strText += char(i);
  }
  
  displayTextOnLCD("[ch945][ch946][ch947][ch948][ch949][ch950][ch951][ch952][ch953][ch954][ch955][ch956][ch957][ch958][ch959][ch960][ch961][ch963][ch964][ch965][ch966][ch967][ch968][ch969]");
  displayTextOnLCD("[ch913][ch914][ch915][ch916][ch917][ch918][ch919][ch920][ch921][ch922][ch923][ch924][ch925][ch926][ch927][ch928][ch929][ch931][ch932][ch933][ch934][ch935][ch936][ch937]");
  displayTextOnLCD(strText);
  displayTextOnLCD("abcdefghijklmnopqrstuvwxyz");
  displayTextOnLCD("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

void loop() {
}

void displayTextOnLCD (String strText){
  int iPos = -1;
  int iChrsOnLCD = 0;
  int iSpecialChr = 0;
  int iSpecialChrPos = 0;
  String strLCDSpecialChars = "";
  char chrChar, chrLCDChar;
  boolean boolUnicode = false;
  byte SpecialCharToDisplay[] = {};
  boolean boolSetSpecialChar = false;

  lcd.clear();
  lcd.home();
  for (int i=0; i < strText.length(); i++){
    chrChar = strText.charAt(i);
    boolUnicode = ((int(chrChar) == -50) || (int(chrChar) == -49));
    if (boolUnicode) chrChar = strText.charAt(++i);     // unicode
    chrLCDChar = TransformChar(chrChar);
    Serial.println(chrLCDChar);
    iSpecialChr = -1;
    if (ChrsTblGrChrs.indexOf(chrLCDChar) > -1) {
        iSpecialChr = strLCDSpecialChars.indexOf(chrLCDChar);
        if (iSpecialChr == -1) {
          strLCDSpecialChars.setCharAt(iSpecialChrPos, chrLCDChar);
          if (iSpecialChrPos < 8) {
            boolSetSpecialChar = true;
            switch (chrLCDChar){
              case 'g':
                lcd.createChar(iSpecialChrPos, GrChrGama);
                break;
              case 'd':
                lcd.createChar(iSpecialChrPos, GrChrDelta);
                break;
              case 't':
                lcd.createChar(iSpecialChrPos, GrChrThita);
                break;
              case 'l':
                lcd.createChar(iSpecialChrPos, GrChrLamda);
                break;
              case 'k':
                lcd.createChar(iSpecialChrPos, GrChrXi);
                break;
              case 'p':
                lcd.createChar(iSpecialChrPos, GrChrPi);
                break;
              case 's':
                lcd.createChar(iSpecialChrPos, GrChrSigma);
                break;
              case 'f':
                lcd.createChar(iSpecialChrPos, GrChrFi);
                break;
              case 'c':
                lcd.createChar(iSpecialChrPos, GrChrPsi);
                break;
              case 'w':
                lcd.createChar(iSpecialChrPos, GrChrOmega);
                break;
              default:
                iSpecialChr = -1;
                boolSetSpecialChar = false;
            }
            if (boolSetSpecialChar) iSpecialChr = iSpecialChrPos++;
          }
        }
    }

    if (iSpecialChr > -1) {
      if (iChrsOnLCD <= 16) {
        lcd.setCursor(iChrsOnLCD,0); 
      }
      else {
       lcd.setCursor(iChrsOnLCD-16,1);
      }
      lcd.write(iSpecialChr);
    }
    else lcd.write(chrLCDChar);
    lcd.cursor();
//    if (++iChrsOnLCD > 16) lcd.scrollDisplayLeft(); 
    if (++iChrsOnLCD == 16) lcd.setCursor(0,1); 
    delay(500);
  }  

  lcd.blink();
  delay(5000);
  lcd.noBlink();
  for (int i=0; i < 16; i++){
    lcd.scrollDisplayLeft(); 
    delay(500);
  }
}

/* 
  -50, -79([ch945])..-65([ch959])
  -49, -128([ch960])..-127([ch961])
  -49, -125([ch963])..-119([ch969])
  -50, -111([ch913])..-95([ch929])
  -50, -93([ch931])..-87([ch937])
*/
char TransformChar(char chrC){
  int iAscii = int(chrC);
  char Result;
  if (iAscii >= -79 && iAscii <= -65) {     // -79: [ch945] .. -65: [ch959]
    Result = ChrsTblTfrm.charAt(iAscii+79);
  }
  else if (iAscii >= -128 && iAscii <= -127) {     // -128: [ch960], -127: [ch961]
    Result = ChrsTblTfrm.charAt(iAscii+128+(79-65+1));
  }
  else if (iAscii >= -125 && iAscii <= -119) {     // -125: [ch963], -119: [ch969]
    Result = ChrsTblTfrm.charAt(iAscii+125+(79-65+1)+2);
  }
  else if (iAscii >= -111 && iAscii <= -95) {     // -111: [ch913], -95: [ch929]
    Result = ChrsTblTfrm.charAt(iAscii+111);
  }
  else if (iAscii >= -93 && iAscii <= -87) {     // -93: [ch931], -87: [ch937]
    Result = ChrsTblTfrm.charAt(iAscii+93+(111-95+1));
  }
  else if (iAscii >= 32 && iAscii <= 90) {     // A..Z, 0..1, other chars
     Result = chrC;
  }
  else if (iAscii >= 97 && iAscii <= 122) {     // a..z
     Result = chrC-32;
  }
  return Result;
}

void debugOutputGrChrSet (){
  char chrChar;
  unsigned int uiAscii;

  for (int i=0; i < ChrsTblGrChrSet.length(); i++){
    chrChar = ChrsTblGrChrSet.charAt(i);
//    boolUnicode = ((int(chrChar) == -50) || (int(chrChar) == -49));
//    if (boolUnicode) chrChar = ChrsTblGrChrSet.charAt(++i);     // unicode
    uiAscii = chrChar;
    Serial.print(i);
    Serial.print(", ");
    Serial.print(int(chrChar));
    Serial.print(", ");
    Serial.print(uiAscii);
    Serial.print(", ");
    Serial.println(chrChar);
  }
  delay(250000);
}