Многоязычный пользовательский интерфейс Nextion + Arduino

Многоязычный пользовательский интерфейс Nextion + Arduino

20 декабря 2022 г.

Пару месяцев назад у меня возникла потребность сделать управление подъемным столом. Изначально я хотел использовать металлические кнопки с подсветкой.

Но тогда я думаю, что 8 кнопок будут выглядеть очень некрасиво.

И пришла идея сделать управление с помощью дисплея Nextion. У меня был экран 2,4" с разрешением 320x240 (NX3224T024).

Его размер идеально подходил для установки на столе.

После прочтения о возможностях экрана в моей голове родилось множество идей для пользовательского интерфейса.

Среди этих идей была поддержка многоязычности. Планировал подключить экран к Arduino Mega 2560. Для работы со своими экранами компания Nextion сделала библиотеку для Arduino, которая доступна на их официальном сайте и на GitHUB

К сожалению, в редакторе Nextion нет полноценной поддержки строковых массивов, поэтому пришлось думать, как реализовать выбор языка и хранить «языковые пакеты» в удобном виде. Чтобы вы могли быстро прочитать, изменить или создать новый «языковой пакет» в своем проекте.

В итоге пришел к следующему варианту:

На главной странице я создал глобальную переменную cur_lang_id, которая имеет идентификатор значения текущего выбранного языка.

К сожалению, экраны NX3224T024 не имеют EEPROM, поэтому мы сохраним выбранный язык в EEPROM Arduino.

Библиотека NEXTION для Arduino позволяет вам обращаться только к глобальным переменным, которые находятся на текущей странице, поэтому при включении Arduino она загрузит идентификатор выбранного языка из EEPROM и передаст его на дисплей Nextion.

Next display будет использовать значение этой переменной для своей работы.

n Затем я узнал, что доступ к страницам в Nextion можно получить в виде массива p[n], где n — порядковый идентификатор страницы.

Я решил, что лучшим решением будет создание страницы с текстовыми элементами для каждого языка.

Каждый текстовый объект в Nextion имеет атрибут «objname», который можно использовать для доступа к нему, и атрибут «txt», в котором будет храниться перевод слова.

После создания языковых страниц мы можем получить доступ к их значениям следующим образом:

b4.txt=lang_en.Back.txt

или это:

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

и вот так:

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

Теперь при изменении значения глобальной переменной home.cur_lang_id.val текст будет меняться на всех страницах. Идентификатор языковой страницы изменится, и язык соответственно изменится.

Вы можете реализовать процесс смены языка с помощью кода в Nextion. Для этого мы устанавливаем значение глобальной переменной home.cur_lang_id.val в Touch Press Event.

Осталось написать код для Arduino, чтобы сохранить выбранный язык в EEPROM и загрузить его после сбоя питания.

Чтобы дисплей Nextion отправлял информацию о нажатии кнопки на плату Arduino, нам нужно установить флажок «Отправить идентификатор компонента» в событии Touch Release каждой кнопки

Глобальная переменная cur_lang_id находится на домашней странице (ID 0), а выбор языков находится на странице lang_select (ID 7), когда вы нажимаете на выбор языка кнопку, Arduino не сможет сразу прочитать измененное значение home.cur_lang_id.val. Для этого сначала нужно открыть домашнюю страницу.

Это очень неудобно для пользователя.

Вы можете повесить событие на каждую кнопку выбора языка и установить язык идентификатора для каждого события. Но в этом случае, если в Nextion изменится ID языковой страницы, то и код Arduino придется переписывать. Нам это неудобно.

Поэтому мы создадим еще одну переменную cur_lang_id на странице lang_select и в нее тоже запишем идентификатор языка, чтобы при нажатии кнопки Arduino могла считать идентификатор выбранного языка.

Тогда код Arduino будет выглядеть так:

#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);
}

В результате мы получили пользовательский интерфейс с возможностью смены языка и сохранения настроек в память EEPROM.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE