Nextion + Arduino Multilanguage UI

Written by sinenko | Published 2022/12/20
Tech Story Tags: arduino | nextion | multilanguage | ui | guide | language-translation | user-experience | hardware

TLDRThe Nextion editor does not have full support for string arrays, so I had to think about how to implement language selection and store "language packs" in a convenient way. So that you can quickly read, change or create a new “language pack” in your project.via the TL;DR App

A couple of months ago, I had a need to make a lift table control. Initially, I wanted to use metal buttons with a backlight.

But then I think that 8 buttons would look very ugly.

And I got the idea to make control using the Nextion display. I had a 2.4” screen with a resolution of 320x240 (NX3224T024).

Its size was ideal for mounting in a table.

After reading about the possibilities of the screen, a lot of ideas for the user interface were born in my head.

Among these ideas was support for multilanguage. I planned to connect the screen to the Arduino Mega 2560. To work with their screens, Nextion made a library for Arduino, which is available on their official website and on GitHUB

Unfortunately, the Nextion editor does not have full support for string arrays, so I had to think about how to implement language selection and store "language packs" in a convenient way. So that you can quickly read, change or create a new “language pack” in your project.

As a result, I came up with the following option:

On the main page, I created a global variable cur_lang_id that has the value ID of the currently selected language.

Unfortunately, the NX3224T024 screens do not have an EEPROM, so we will store the selected language in the Arduino's EEPROM.

The NEXTION library for Arduino only allows you to access global variables that are on the current page, so when you turn on the Arduino, it will load the selected language ID from the EEPROM and pass it to the Nextion display.

Nextion display will use the value of this variable for its work.


Then I learned that pages in Nextion can be accessed as an arrayp[n], where n is the ordinal ID of the page.

I decided that the best solution would be to create a page with text elements for each language.

Each text object in Nextion has an “objname” attribute that can be used to access it and a “txt” attribute that will store the translation of the word.

After creating the language pages, we can access their values like this:

b4.txt=lang_en.Back.txt

or this:

b4.txt=p[3].Back.txt

and like this:

home.cur_lang_id.val = 3
b4.txt=p[home.cur_lang_id.val].Back.txt

Now, when changing the value in the global variable home.cur_lang_id.val, the text will change on all pages. The language page ID will change, and the language will change accordingly.

You can implement the process of changing the language using the code in Nextion. To do this, we set the value of the global variable home.cur_lang_id.val in the Touch Press Event.

It remains to write code for Arduino to save the selected language in EEPROM and load it after a power failure.

In order for the Nextion display to send information about pressing a button to the Arduino board, we need to check the “Send component ID” checkbox on the Touch Release Event of each button

The cur_lang_id global variable is on the home page (ID 0), and the choice of languages is on the lang_select page (ID 7), when you click on the language selection button, Arduino will not be able to immediately read the changed home.cur_lang_id.val value. To do this, you first need to open the home page.

This is very inconvenient for the user.

You can hang an event on each language selection button, and set ID language in each event. But in this case, if the language page ID changes in Nextion, then the Arduino code will also have to be rewritten. This is inconvenient for us.

Therefore, we will create another cur_lang_id variable on the lang_select page and write the language ID to it too, so that when the button is pressed, Arduino can read the selected language ID.

Then the Arduino code would look like this:

#include <Nextion.h>
#include <EEPROM.h>

byte currentLanguageId = 0;
 
NexPage homePage = NexPage(0, 0, "home");
NexButton english_b = NexButton(7, 2, "b0");	//Button Enlish language
NexButton deutsch_b = NexButton(7, 3, "b1");	//Button Deutsch language
NexButton kazakh_b = NexButton(7, 4, "b2");		//Button Kazakh language
NexButton russian_b = NexButton(7, 5, "b3");	//Button Russian language
NexVariable cur_lang_id = NexVariable(7, 22, "cur_lang_id");  //Global variable with Selected language ID

// Register objects to the touch event list
NexTouch *nex_listen_list[] = 
{
    &english_b,
    &deutsch_b,
    &kazakh_b,
    &russian_b,
    NULL
};

// Callback when user pop button with any language
void language_button_CallBack(void *ptr)
{
	cur_prof_id.getValue(&currentLanguageId); //Change language ID
	saveLanguageToEEPROM(); //Save new language ID to EEPROM
}

void setup(void)
{   
	loadLanguageFromEEPROM();

    nexInit();
	cur_lang_id.setValue(currentLanguageId);
	homePage.show();

    english_b.attachPop(language_button_CallBack, &english_b);
    deutsch_b.attachPop(language_button_CallBack, &deutsch_b);
    kazakh_b.attachPop(language_button_CallBack, &kazakh_b);
    russian_b.attachPop(language_button_CallBack, &russian_b);	
}

void loop(void)
{   
	nexLoop(nex_listen_list);
}

//*********  EEPROM  **********//
void loadLanguageFromEEPROM(){);
	currentLanguageId = EEPROM.read(1);
}

void saveLanguageToEEPROM(){
	EEPROM.write(1, currentLanguageId);
}

As a result, we got a user interface with the ability to change the language and save the settings to EEPROM memory.


Written by sinenko | CEO, WEB Software Engineer, Production of 3D printers
Published by HackerNoon on 2022/12/20