中文   |    

How to Show Right-to-Left Text on LCD Screens?

Table of Contents

16x2 Monochrome Character LCD Module - 1602A
16x2 COB Character LCD Module - HUA XIAN JING

To show right-to-left (RTL) text on LCD screens like those with the AIP31066 controller, you set the “Entry Mode Set” command with the cursor direction bit (ID) to 0. This makes the cursor move left after each character.

You can use library functions like rightToLeft() to make this easier and control the cursor with setCursor() to place the text correctly. This sets up the display for RTL scripts or mixed-direction text.

The setup works with tricks like autoscroll() to handle longer text and keep it readable. These steps prepare the LCD for more advanced text features later.

How does the AIP31066 Entry Mode Set command control text directionality on a 16x2 LCD display?

1602 COB LCD Module Right to Left Display Arabic
1602 COB LCD Module Right to Left Display Arabic

The Entry Mode Set command uses the I/D bit to select text flow direction: I/D=1 : increment moves the cursor right (LTR), while I/D=0 : decrement moves it left (RTL). The optional S bit can also shift the entire display as you type.

When you enable I/D=1 : increment, new characters fill from left to right on an lcd 16×2 module, matching typical LTR orientation. Enabling I/D=0 : decrement reverses this flow, letting you create right‑to‑left text streams without extra verilog display logic.

Bit Definitions and Display Shift

  • I/D bit (bit 1):

    • 1 = increment cursor position (LTR orientation)
    • 0 = decrement cursor position (RTL orientation)
  • S bit (bit 0):

    • 1 = shift the entire display on each write
    • 0 = no shift; only cursor moves
  • Command byte: 0b000001(I/D)(S) – see lcd1602 datasheet for full opcode mapping

  • Cursor behavior: After writing, the hardware updates the DDRAM address based on I/D, so text directionality is enforced at the controller level.

How does the Entry Mode affect bidirectional text display?

The AIP31066 does not natively support bidirectional text or rtl override; it only shifts by single‑cell steps. You must reorder or mirror characters in your code before sending them to the display.

To show complex scripts (like Arabic), pre‑process each line in your firmware so that characters appear in correct visual order, since the controller cannot handle bidi text or LTR/RTL overrides on its own.

How do Arduino’s rightToLeft() and leftToRight() methods abstract text direction control for an LCD display?

Pack of 20 pieces of 1602 LCD modules, ideal for bulk prototyping

The rightToLeft() and leftToRight() methods wrap the AIP31066’s Entry Mode Set command to change text flow direction across the entire display in one call. Internally, they set the I/D bit of the driver to decrement or increment the cursor’s DDRAM address on each write.

These methods let you avoid low‑level bit‑banging. You simply call lcd.rightToLeft() to enable RTL flow or lcd.leftToRight() for LTR flow, and the library handles the correct command byte.

Method Behavior and Effects

  • Syntax and Library Call:

				
					#include <LiquidCrystal.h>  
LiquidCrystal lcd(rs, enable, d4, d5, d6, d7);  
lcd.begin(16, 2);  
lcd.rightToLeft();    // set text to flow right-to-left  
lcd.leftToRight();    // set text to flow left-to-right  
				
			
  • Underlying Command:

    • rightToLeft() sends 0b00000100 (I/D=0, S=0) to set RTL.
    • leftToRight() sends 0b00000110 (I/D=1, S=0) to set LTR.
  • Scope: Both methods affect all subsequent writes until changed again. They do not shift existing text .

Why must you call leftToRight() after writing in RTL mode?

Failing to revert to LTR causes all later writes to continue in RTL, leading to unintended text flow .

Reverting with leftToRight() restores normal increments of the DDRAM address so that further text displays in the usual left‑to‑right sequence.

Reversion Best Practices

  • Immediate Reversion: Always follow an RTL block with:

				
					lcd.leftToRight();
				
			
  • Avoid Mis‑flows: This prevents cursor decrements from colliding with prior text and maintains visual consistency.

Required Includes for Direction Control

To use these methods, include the LiquidCrystal library and instantiate an lcd object with correct pin assignments.

You must call lcd.begin(cols, rows) before invoking direction methods so the controller is initialized.

Setup Steps

  1. Include Header: #include <LiquidCrystal.h>

  2. Object Declaration:

    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    
  3. Initialization:

    lcd.begin(16, 2);  // for a 16x2 LCD
    

After this, lcd.rightToLeft() and lcd.leftToRight() become available.

How can you position the cursor at the start and use autoscroll on a 16×2 LCD display?

You call setCursor(maxCol, row) to place the far right cursor at the beginning of an RTL write, then use enable autoscroll so new characters push older ones left.

Using this approach in firmware lets you drive a 16×2 LCD module without extra display verilog logic. It ensures text flows correctly from right to left while you type.

Cursor & Autoscroll Commands

  • setCursor(col, row):

    • col = 15 for a 16‑column display ⇒ starts at far right cell
    • row = 0 or 1 selects top or bottom line
  • autoscroll():

    • Sends Entry Mode Set with I/D=0, S=1 ⇒ cursor decrements and display shifts
  • noAutoscroll():

    • Sends Entry Mode Set with I/D=0, S=0 ⇒ only cursor decrements, no shift
  • Behavior:

    • While autoscroll is on, each new write at DDRAM address 15 shifts all characters one cell left.
				
					// Position at far right, top line
lcd.setCursor(15, 0);

// Enable autoscroll (I/D=0, S=1)
lcd.autoscroll();

// After finishing, disable to stop shifts
lcd.noAutoscroll();
				
			

How do you stop autoscroll to avoid unintended text drift?

You must call noAutoscroll() immediately after completing your string so the cursor no longer moves display data on each write.

Leaving autoscroll active will keep shifting DDRAM on every subsequent character, causing all text to drift left across both lines.

How does Unicode bidirectional support work on an AIP31066 LCD?

Unicode characters carry inherent directional properties—Left‑to‑Right (LTR), Right‑to‑Left (RTL), or neutral—that your software must interpret and reorder before sending bytes to the LCD.

To display mixed‑direction text, you inject directional override codes like U+202A (LTR override) or U+202E (RTL override) into your character stream. These control marks force runs of text into the specified direction but must be stripped or handled by your MCU before byte‑level writes to the AIP31066.

				
					// Inject Unicode overrides
const char *mixed = "\xE2\x80\xAE" "Hello" "\xE2\x80\xAC";
lcd.print(mixed);
				
			

Directional Properties & Overrides

  • Directional Classes (Unicode):

    • L (Left‑to‑Right): Latin, Cyrillic, etc.
    • R (Right‑to‑Left): Hebrew, Arabic letters.
    • AN/EN (European Number): digits, often neutral but adopt context.
  • Override Codes:

    • U+202A (LEFT‑TO‑RIGHT OVERRIDE): forces subsequent text LTR until termination.
    • U+202E (RIGHT‑TO‑LEFT OVERRIDE): forces RTL flow until termination.
    • U+202C (POP DIRECTIONAL FORMATTING): ends the override.
  • Implementation Trade‑Offs:

    • Adding overrides increases string length by 2–3 bytes per run.
    • MCU code must parse and remove these before writing createChar or DDRAM writes to the LCD.

How can custom CG‑RAM fonts enable true RTL scripts on a character LCD?

You allocate up to eight 5×8 custom glyphs in CG‑RAM to represent context‑shaped Arabic or Hebrew letters, then map each Unicode codepoint to the corresponding CG‑RAM slot before writing to DDRAM .

				
					// Define a custom Arabic letter in CG‑RAM
byte arabicAlef[8] = {
  B00000,
  B00100,
  B00100,
  B00100,
  B00100,
  B00100,
  B01110,
  B00000
};
lcd.createChar(0, arabicAlef);
lcd.setCursor(15, 0);
lcd.write(byte(0));  // prints custom Alef
				
			

What advanced methods can improve RTL text handling on microcontroller‑driven LCDs?

40x4 Monochrome Character LCD Module - 4004A
40x4 COB Character LCD Module - HUA XIAN JING

You can implement a lightweight ICU subset on your MCU to apply the full Unicode Bidi‑Algorithm and use double‑buffering for smooth RTL scrolling. Migrating to graphic OLED/TFT modules with a UTF‑8 Bidi engine also unlocks richer script support.

Bringing a trimmed‑down ICU library onto a 32 bit MCU lets you shape and reorder Arabic glyphs in firmware before sending them to CG‑RAM. Double‑buffering on a 16×2 or larger display reduces flicker by preparing the next frame in RAM and swapping it on each refresh.

Key Next‑Step Techniques

  • Full Unicode Bidi‑Algorithm on MCUs
    • Use a pared‑down ICU core of ~20 KB to apply contextual shaping for Arabic.
    • Parse directional runs in O(n) time per string.
  • Dynamic RTL Scrolling & Buffering
    • Allocate two 16×2 or 40×4 frame buffers in RAM.
    • Swap buffers on each update to shift text left without visible tearing.
				
					// Pseudocode: double buffer swap
frame_t bufA, bufB;
drawRTL(bufA);
displaySwap(bufA, bufB);
				
			
  • Migrating to Graphic Displays
    • Switch to modules with built‑in UTF‑8 Bidi engine to offload shaping.
    • Use SPI‑driven OLED/TFT for fast pixel updates and smooth fonts.
  • Multi‑Language UI Frameworks
    • Design a menu system that toggles direction at runtime.
    • Integrate localization pipelines to load strings and scripts dynamically.

What MCU resources do embedded Bidi‑algorithms and buffering consume?

A lightweight Bidi library typically uses 20 KB of flash and 8 KB of RAM, while double‑buffering a 16×2 display needs 512 bytes per buffer.

Profiling shows that adding Bidi support raises firmware size by about 5% and RAM usage by 10%, which is acceptable on most 32 bit MCUs with >= 128 KB flash and >= 32 KB RAM.

FAQ

How do I handle mixed LTR and RTL text on the same LCD line?

To handle mixed text, use Unicode directional overrides like U+202A (LTR) and U+202E (RTL) to control specific sections. However, this requires software support beyond basic LCD controllers.

What if my LCD display doesn’t support custom fonts for RTL scripts?

If your display lacks CG-RAM support, switch to a module with native RTL capabilities or use a graphical LCD to draw text manually. This ensures RTL text displays correctly.

Can I use autoscroll for LTR text as well?

Yes, autoscroll works for LTR text to create a left-to-right scrolling effect, though it’s less necessary since LTR flows naturally. Enable it for dynamic displays if needed.

How does the Entry Mode Set command affect the display’s memory?

The Entry Mode Set command adjusts the memory address pointer’s movement, decrementing it for RTL to shift left. This determines where each character lands on the screen.

Are there any performance issues when using directional overrides in Unicode?

Yes, directional overrides add processing overhead, slowing rendering on limited systems. Use them sparingly to avoid performance drops.

Share:
Picture of Lyna

Lyna

Hi, I am Lyna, the author of this article. I have been in the LCD module industry for 13+ years and become to expert in small and medium-sized LCD modules.
I mainly provide wholesale services for LCD modules and professional business and technical support to factories and LCD dealers. I am happy to share my experience here with you, and you are welcome to discuss it with me.

Contact Us
Related Posts

Get A Quick Quote!

Hua Xian Jing Sales - Lyna Huang

GET FREE SAMPLE!

Over the years, rich experience in LCD module generation has led us to accumulate 10,000+ standard LCD modules in our standard library, download our catalog to select the LCD module that best suits your needs!