Solved. LCD Arabic letters

I have a project where i have to use a fingerprint scanner to register workers attendance i need to display the worker name on a screen for the worker to read and be sure that his fingerprint wase read right I need a library to print Arabic Names on the (16*2) LCd or Nokia 5110 display i understand the idea of mapping arabic letters to pixels and preparing the values to be sent to the display , but if a library exists then it is better than making all that work over again. thank you for help

Most 16x2 LCDs come with a limited Font in ROM. It is very unlikely that any exist with an Arabic Font. Since you have only 8 User Defined letters it is not possible to create "your own Font"

I suggest that you use your Nokia 5110 display with the U8g2lib library (PCD8544 contructor) It supports many fonts. And it even has Arabic Fonts.

You should be able to write programs with UTF8 text. i.e. easy for you to read read and maintain Arabic messages.

No, I don't know Arabic. I have never used Arabic Fonts. But there are plenty of readers from Egypt, Syria, Iran, ... who can help you.

David.

david_prentice: I suggest that you use your Nokia 5110 display with the U8g2lib library (PCD8544 contructor) It supports many fonts. And it even has Arabic Fonts.

David.

thank you David Can you provide more informatio about how i can do that Thank you Fidamon.

You seem to have perfect English. I suggest that you install U8g2lib and run all the examples.

Especially the UFT8 examples. e.g. Chinese, Greek, ...

Then experiment with Arabic Fonts with UFT8 messages in Arabic.

David.

david_prentice: You seem to have perfect English.

I take this for a joke Thank you David i shall try your Advice. Thanks

Ah-ha. It was harder than I thought.

UTF8 strings are drawn right to left. But library UTF8 parsers work left to right. So I had to read the UTF8 string, glyph by glyph. And draw each glyph from right to left.

I have it running on TFT displays. e.g. 160x128 can display الإنكليزية مثالية The Nokia 5110 is tiny. Please can you post some sample UTF8 strings.

Then I will post a sketch for you.

Oliver has three Arabic Fonts. You will have to choose which one looks best.

David.

Thank you David but there is another problem , I am basically a visual basic 6 programmer i just right the words and "Msgbox" displays it on screen i tried to understand how to make a UTF8 string buti couldn't all i want is to print "مرحبا " and a worker's name on the screen. thank you.

Here are two examples. U8g2 can control many different LCDs, OLEDs, …
Adafruit GFX style have a different hardware library for each display e.g. Adafruit_PCD8544 or Adafruit_SSD1306

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

//U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_PCD8544_84X48_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);       // Nokia 5110 Display
//U8G2_PCD8544_84X48_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);    // Nokia 5110 Display

void UTF8_rt_lft(int x, int y, const char *u8str)
{
    char buf[5], c, n;
    while (c = *u8str) {
        switch (c & 0xF0) {   //escape sequences
            case 0xC0: n = 2; break;
            case 0xD0: n = 2; break;
            case 0xE0: n = 3; break;
            case 0xF0: n = 4; break;
            default: n = 1; break;
        }
        memcpy(buf, u8str, n); //copy one glyph at a time
        buf[n] = 0;   //terminate with NUL
        u8str += n;
        uint8_t len = u8g2.getUTF8Width(buf);
        x -= len;     //calc new posn for glyph
        u8g2.drawUTF8(x, y, buf);
    }

}

void setup(void)
{
    u8g2.begin();
    u8g2.enableUTF8Print();       // enable UTF8 support for the Arduino print() function
    u8g2.setFontDirection(0);
}

void loop(void)
{
    u8g2.firstPage();
    u8g2.setFont(u8g2_font_unifont_t_arabic);
    //u8g2.setFont(u8g2_font_cu12_t_arabic);
    //u8g2.setFont(u8g2_font_10x20_t_arabic);
    do {
        u8g2.drawUTF8(0, 12, "Hi Omar");
        UTF8_rt_lft(u8g2.getWidth(), 40, "مرحبا عمر");
    } while ( u8g2.nextPage() );
    delay(5000);
}

and using Adafruit-style libraries:

#include <Adafruit_PCD8544.h>
Adafruit_PCD8544 lcd(9, 10, 8);   //HW SPI constructor
//Adafruit_PCD8544 lcd(13, 11, 9, 10, 8);   //SW SPI constructor
#include <U8g2_for_Adafruit_GFX.h>
U8G2_FOR_ADAFRUIT_GFX u8g2_for_adafruit_gfx;

void setup()
{
    lcd.begin();
    u8g2_for_adafruit_gfx.begin(lcd);                 // connect u8g2 procedures to Adafruit GFX
    u8g2_for_adafruit_gfx.setFontDirection(0);       // left to right
    if (lcd.width() < lcd.height()) lcd.setRotation(1);
    u8g2_for_adafruit_gfx.setFontMode(0);                 // use u8g2 transparent mode (this is default)
    u8g2_for_adafruit_gfx.setForegroundColor(WHITE);  // apply Adafruit GFX color
    u8g2_for_adafruit_gfx.setBackgroundColor(BLACK);  // apply Adafruit GFX color
}

void UTF8_rt_lft(int x, int y, const char *u8str)
{
    char buf[5], c, n;
    while (c = *u8str) {
        switch (c & 0xF0) {   //escape sequences
            case 0xC0: n = 2; break;
            case 0xD0: n = 2; break;
            case 0xE0: n = 3; break;
            case 0xF0: n = 4; break;
            default: n = 1; break;
        }
        memcpy(buf, u8str, n); //copy one glyph at a time
        buf[n] = 0;   //terminate with NUL
        u8str += n;
        uint8_t len = u8g2_for_adafruit_gfx.getUTF8Width(buf);
        x -= len;     //calc new posn for glyph
        u8g2_for_adafruit_gfx.drawUTF8(x, y, buf);
    }

}

void loop()
{
    int x = lcd.width();                                // write from right
    lcd.fillScreen(BLACK);
    u8g2_for_adafruit_gfx.setFont(u8g2_font_unifont_t_arabic);
    //u8g2.setFont(u8g2_font_cu12_t_arabic);
    //u8g2.setFont(u8g2_font_10x20_t_arabic);
    u8g2_for_adafruit_gfx.drawUTF8(0, 12, "Hi Amir");
    UTF8_rt_lft(x, 40, "مرحبا امير");
    lcd.display();                                       // make everything visible
    delay(2000);
}

Edit. Existing constructors are for HW SPI i.e. SCLK=13, DIN=11 on a Uno. Added Software SPI constructors to both examples.

Thank you very much that is very generous of you thank you David

Does it work?

Which is the best Font?

The fonts look a bit different to the UFT8 text that I see in a Browser.

Remember to use getUFT8Width() when you calculate the next print position.

David.

The second sketch worked after i changed this line
Adafruit_PCD8544 lcd(9, 10, 8);
to this

// pin 6 - Serial clock out (SCLK)
// pin 7 - Serial data out (DIN)
// pin 8 - Data/Command select (D/C)
// pin 9 - LCD chip select (CS)
// pin 10 - LCD reset (RST)

Adafruit_PCD8544 lcd(6,7,8, 9, 10);
but it still printed it as if separate letters
i can’t understand how in your two examples it was supposed to be declared with 3 pin numbers
i changed the second to 5 pin numbers it worked
the first did not compile with 5 pin numbers and did not work with 3 pin numbers
Thank you very much
Fidamon

I use HW SPI pins on th Uno i.e LCD_DIN = 11, LCD_SCLK = 13, LCD_CS = 10, LCD_DC = 9, LCD_RST = 8

David.

Edit. Added example SW SPI constructors to code in #7

Ah-ha. I have only just seen your JPG from #10

I have tested SW and HW constructors in both my examples.

Your JPG shows the Adafruit version (Amir) but you have changed the BLACK / WHITE i.e. to give BLACK text. And your Font looks better than mine !!

David.

david_prentice: And your Font looks better than mine !!

David.

it is the third font from your first example I used HW SPI pins on th Uno i.e LCD_DIN = 11, LCD_SCLK = 13 with the first example and it worked but still separate letters Fidamon

Oliver is the expert with Fonts.

Your photo shows a gap surrounding the glyph below 'A'. The other glyphs seem to join up quite well. I presume that the gap under 'ir" is correct.

You will never get a "perfect" font on a 84x48 display.

I presume that your "writing rules" will alter with which letters are next to each other. Exactly like cursive Latin hand-writing. With formal letter-type we just accept separate letters. The only exception is "ae" which sometimes appears as a single joined-up letter.

David.

An alternative way is using Custom Character Generator

IoT_hobbyist: An alternative way is using Custom Character Generator

I challenge you to produce the image on the JPG in #10 with a 16x2 LCD.

David.

david_prentice: I presume that your "writing rules" will alter with which letters are next to each other.

Arabic Writing rules are complicated , the morphology of a letter totally differs if it is in the middle of a word than if in the end , you can notice that in the third letter from right "ح" versus "مرحبا" it looses the bowed tail to connect with the succeeding letter "ا" edit : sorry the succeeding letter is "ب" Fidamon

Problem solved by printing the words on a picturebox in vb6 then sending it to arduino byte by byte through. Comm port