Многоязычный пользовательский интерфейс 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(¤tLanguageId); //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.
Оригинал