Дисплей Nextion HMI. Работа с китайской версией TJC

Как уже известно из предыдущих уроков, к Ардуино можно подключить множество разных дисплеев. Для самых простых проектов пригодится символьный ЖК дисплей 1602, который мы уже изучили на одном из уроков. Для вывода простейшей монохромной графики можно использовать дисплей от телефона Nokia 5110, либо более современный OLED дисплей. Ресурсов Ардуино хватает даже на цветные дисплеи с TFT матрицей.

Однако, чем сложнее дисплей, тем тяжелее приходится нашей Ардуино. Несмотря на самые изощренные и быстрые библиотеки, ресурсов микроконтроллера Atmega328 едва хватает для работы с цветной TFT матрицей. Для полезного кода остается менее половины флеш-памяти контроллера. Что делать в такой ситуации?

Технология HMI

Выход есть. Собственно, первое что приходит на ум — это наделить графический дисплей собственным микроконтроллером, который бы выделил весь свой вычислительный ресурс на обработку графики. Такой готовый модуль можно бы было подключать к Ардуино по одному из стандартных интерфейсов, и обмениваться с ним унифицированным командами.

Именно такой модуль мы и разберем на этом уроке. Называется этот графический модуль — Nextion HMI. Сокращение HMI означает Человеко-Машинный Интерфейс. Разработчики этого модуля предполагают, что именно такие устройства будут использоваться в элементах «умного дома», и разного рода гаджетах.

Существуют версии Nextion с различной диагональю, а также с версии с тачскрином. В нашем уроке мы используем самый простой дисплей с диагональю 2.2 дюйма и разрешением 320×240, без тачскрина.

Создание интерфейса

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

Для русификации редактора следует заменить файл cs.lang в папке с редактором. Переведенный файл можно взять тут:
http://git.robotclass.ru/download/NextionEditor

Наша задача будет состоять в том, чтобы сделать графический интерфейс для отображения показаний акселерометра. Соответственно, нам понадобится создать какой-то красивый фон, разместить на нем поля для вывода чисел. Также хотелось бы добавить и какие-нибудь компоненты для визуализации показаний, например шкальные индикаторы.

Итак, запускаем редактор. Перед нами появляется главная форма.

p1

1) Первое что мы сделаем — создадим новый проект. Жмем меню «Файл/Новый», выбираем папку где будет храниться файл проекта и его имя, например, test.hmi. Затем выбираем в появившемся окне подходящий формат и ориентацию дисплея.

p2

2) Теперь добавим фон нашего интерфейса. Жмем кнопку «Добав.» (Add) в разделе Изображения.

p3

В появившемся окне выбираем файл картинки с разрешением 320×240. Для урока мы нарисовали свой фон, в виде трех оранжевых прямоугольных областей.

3) Добавляем в интерфейс компонент «Изображение».

p4

По-умолчанию, компонент размещается в левом верхнем углу. Не будем его никуда двигать, и перейдем к настройкам компонента.

4) Ассоциируем компонент и ранее добавленную картинку. Для этого, в разделе настроек компонента жмем на параметр pic, и выбираем единственную в списке картинку.

p5

5) Аналогичным образом, добавляем компонент «Индикатор выполнения». Обычно этот блок служит для отображения статуса загрузки данных, но мы используем его для визуализации показаний с нашего датчика.

p6

Параметры bco и pco задают цвет фона элемента и цвет, которым заполняется индикатор. В нашем случае фон белый, и сам индикатор синий. Параметр val определяет степень наполнения индикатора, и варьируется от 0 до 100. Именно этот параметр мы и будем менять с помощью Arduino. Кстати, можно менять любой параметр, отмеченный зеленым цветом.

Остальные параметры отвечают за положение элемента на дисплее: x и y, а также за его размеры: w и h.

6) Добавляем на дисплей еще два таких же индикатора и настраиваем их. Затем добавляем компонент «стрелка» (gauge).

p8

Стрелка — это что-то вроде стрелки на спидометре автомобиля. Имеет диапазон значений от 0 до 360. Размещаем её в верхней правой части дисплея. Чтобы у стрелки был красивый круглый фон (можно и циферблат нарисовать), мы переключим параметр sta в режим crop image. Потребуется заполнить параметр picc; укажем там ту же картинку, что и для фона. Crop image означает, что фон компонента станет прозрачным, и через него будет просвечивать указанная в параметре picc картинка.

7) Перед тем, как добавить числовые поля, создадим шрифт. У дисплея нет такого же хранилища шрифтов, как в MS Windows, и он не умеет пользоваться стандартными файлами ttf. Чтобы добавить шрифт, нажмем кнопку «Добав.» (Add) в блоке «Шрифты», который находится в левой части редактора.

p9

Задаем высоту шрифта, жирность. Указываем имя шрифта. При изменении каждого параметра, в маленьком черном квадратике будет меняться написание буквы X. Не очень удобная настройка, но что поделать. Наконец, в поле «Имя шрифта» записываем подходящее название латинскими буквами и жмем «Создать шрифт». Генератор пробежится по всем буквам векторного шрифта, и создаст их растровые изображения, который мы потом загрузим в память дисплея вместе с графикой.

p10

8) Добавляем на форму три компонента «Число».

p11

В настройках компонента указываем номер шрифта font. У нас создан пока только один шрифт, так что его номер будет — 0. Параметр val отвечает за содержимое поля, его мы будем задавать через Arduino. В примере мы так же поменяли цвет и фон компонента.

9) Последний компонент, который мы разместим на нашем дисплее — «Текст». Мы не будем менять его содержимое, просто что-нибудь напишем в параметре text.

10) Наконец, скомпилируем все что мы сделали в файл, который затем отправится в память дисплея. Жмем кнопку «Компилировать» (Compile).

p13

Файл имеет расширение tft и хранится в папке, которую можно открыть через меню «Файл/Открыть папку с tft файлами».

С интерфейсом всё, переходим к самой ответственной части.

Nextion и TJC

Nextion HMI — марка дисплея для европейского рынка. В Китае существует версия для внутреннего рынка, которая носит название TJC (по названию чипа). С точки зрения электроники, они полностью идентичны. Как это обычно бывает, версия для Европы стоит значительно дороже. Подвох тут в том, что европейский редактор не позволяет загружать прошивку в китайский дисплей. Делать же интерфейс в китайском редакторе, немного неудобно.

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

Загрузка файла интерфейса

1) Скачиваем python-скрипт из репозитория на github: https://github.com/makeitlab/software_tools/tree/master/TJCUpload

2) Чтобы его запустить, потребуется установить интерпретатор Python 2.7.

3) После установки python, установим библиотеку для работы с последовательным портом —  pyserial.

4) Скрипт имеет несколько важных параметров, которые хранятся в отдельном файле config.py:

Последовательный порт, через который будет происходить загрузка. Меняем на актуальный:
PORT = ‘COM6’

Загрузка прошивки идет в два этапа, с разной скоростью. Обычно эти параметры менять не следует.
BAUDCOMM = 9600
BAUDUPLOAD = 115200

Идентификатор дисплея, который указан либо на самом дисплее, либо на коробке. В уроке мы использовали TJC3224T022.
CHECK_MODEL = ‘TJC3224T022’

Наконец, параметр определяющий временную задержку в протоколе обмена. Этот параметр нужно будет изменить только если процедура загрузки не удастся.
BAUDRATE_SWITCH_TIMEOUT = 0.5

5) Загружать прошивку будем через USB-UART мост, например такой:

DSC00981

Схема соединения моста и дисплея:

Nextion/TJCGNDVCCRXTX
USB-UARTGND+5VTX0RX1

6) Скопируем скомпилированный файл интерфейса tft в папку со скриптом, и запустим скрипт через командную строку:

c:\путь_к_python\python.exe upload.py test.tft

7) После запуска скрипта на дисплее запустится процедура загрузки с индикатором хода выполнения. Если всё пошло как надо, то дисплей напишет об успешном выполнении процедуры и перезагрузится. Python-скрипт тоже отчитается о проделанной работе:

p14

Если загрузка остановилась на 0%

Если загрузка зависла на 0%, значит следует изменить тот самый временной параметр в настройках. Рекомендую присвоить ему значение 0.05.

Также предстоит починить прошивку дисплея, иначе он не даст повторить процедуру. Для этого понадобится microSD карта. Загружаем на карту подходящую прошивку из папки со скриптом «TJCUpload/Basic Recovery». Эта прошивка минимальная, и служит лишь для ремонта. Вставляем флешку в дисплей, подаем питание. Ждем несколько секунд, пока прошивка не загрузится автоматически.

После этой процедуры можно повторить загрузку подготовленной ранее прошивки, не забыв изменить указанный параметр в файле настроек скрипта.

Программа

Приступим к написанию программы для управления HMI дисплеем. Каждый компонент имеет свой идентификатор. Индикаторы выполнения, размещенные на форме: j0, j1 и j2. Числовые поля: n0, n1 и n2. Компонент «стрелка» получил идентификатор z0.

Чтобы изменить параметр val у компонента, нам нужно передать в последовательный порт команду вида:

j0.val=44

Каждая команда должна завершаться тремя байтами 0xFF. Тестовая программа будет менять значение индикатора j0 в цикле.

void setValueJ(uint32_t number){
  char buf[10] = {0};
  String cmd;

  utoa(number, buf, 10);
  cmd += "j0.val=";
  cmd += buf;

  sendCommand(cmd.c_str());
}

void sendCommand( const char* cmd ){
  Serial.print(cmd);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}

void setup() {
  Serial.begin(9600);
  delay(2000);
  sendCommand( "" );
  sendCommand( "page 0" );
}

void loop() {
  for(int i=0; i<100; i++){
    setValueJ(i);
    delay(10);
  }
}

Загружаем программу на Ардуино, и подключаем дисплей по схеме:

Nextion/TJCGNDVCCRXTX
Ардуино УноGND+5V10

Подаем питание на Ардуино и наблюдаем движение самого верхнего индикатора.

Визуализация показаний акселерометра

Теперь добавим в скетч управление всеми остальными компонентами.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
float acc_lpf[3] = {0,0,0};

void setValueJ(uint8_t jn, uint32_t number){
  char buf1[3] = {0};
  char buf2[10] = {0};
  String cmd;

  utoa(jn, buf1, 3);
  utoa(number, buf2, 10);
  cmd += "j"; cmd += buf1; cmd += ".val="; cmd += buf2;
  sendCommand(cmd.c_str());
}

void setValueN(uint8_t nn, uint32_t number){
  char buf1[3] = {0};
  char buf2[10] = {0};
  String cmd;
  utoa(nn, buf1, 3);
  utoa(number, buf2, 10);
  cmd += "n"; cmd += buf1; cmd += ".val="; cmd += buf2;
  sendCommand(cmd.c_str());
}

void setValueZ(uint8_t zn, uint32_t number){
  char buf1[3] = {0};
  char buf2[10] = {0};
  String cmd;
  utoa(zn, buf1, 3);
  utoa(number, buf2, 10);
  cmd += "z"; cmd += buf1; cmd += ".val="; cmd += buf2;
  sendCommand(cmd.c_str());
}

void sendCommand( const char* cmd ){
  Serial.print(cmd);
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}

void setup() {
  Serial.begin(9600);
  accel.begin();
  accel.setRange(ADXL345_RANGE_8_G);
  delay(2000);
  sendCommand( "" );
  sendCommand( "page 0" );
}

void loop() {
  int r[3];
  acc_lpf[0] = acc_lpf[0]*0.7 + accel.getX()*0.3;
  acc_lpf[1] = acc_lpf[1]*0.7 + accel.getY()*0.3;
  acc_lpf[2] = acc_lpf[2]*0.7 + accel.getZ()*0.3;

  r[0] = int((acc_lpf[0]+500+61)/10);
  r[1] = int((acc_lpf[1]+500+26)/10);
  r[2] = int(((acc_lpf[2]-1500)+73+500)/10);

  setValueZ(0, r[0]*3);
  setValueJ(0, r[0]); setValueN(0, r[0]);
  setValueJ(1, r[1]); setValueN(1, r[1]);
  setValueJ(2, r[2]); setValueN(2, r[2]);
  delay(1);
}

Библиотеки для работы с акселерометром можно скачать отсюда:
https://github.com/adafruit/Adafruit_ADXL345
https://github.com/adafruit/Adafruit_Sensor

Загружаем скетч на дисплей, и крутим акселерометр вокруг осей.

nextion_gif

Ну и небольшое видео, если у вас не грузится анимированный gif:

Заключение

На этом уроке мы разобрали работу Nextion/TJC дисплея с разрешением 320×240 без тачскрина — это самый простой вариант из линейки. Разумеется, гораздо интереснее будет поработать с компонентами, отвечающими за реакцию тачскрина. На следующем уроке мы изучим именно такой продвинутый вариант дисплея, и попробуем поработать со слайдбарами и кнопками.  Также построим график с помощью специального компонента, разберемся с таймером и переменными. Успехов!


Изменено:

Дисплей Nextion HMI. Работа с китайской версией TJC: 20 комментариев

  1. Хотелось бы отметить, что tft файл, созданный при помощи программы Nextion Editor, корректно работает после загрузки в дисплей TJC только если версия программы меньше или равна v032. Загрузка tft файла, полученного при помощи более высоких версий, включая текущую, приводит к ошибке и потере работоспособности дисплея, восстановить его потом можно только загрузкой рабочего файла с SD карты.

  2. Олег добрый день!
    Материал отличный! Не сочтите за труд, поясните по руссификации -открыл папку программой Nextion Editor файл cs.lang установил, я так понимаю, что должна произойти замена аналогичного файла, замены не произошло, файл просто установился. Следовательно руссификация не установилась. Заходил в папку с правами администратора.
    Этот момент пожалуйста поясните по подробнее.
    С уважением

    • Эта статья актуальна только для старой версии программы. В последних версиях все немного изменилось и скорее всего python скрипт работать не будет.
      Файл с переводом тоже изменился. Сейчас он называется hmics.lang. Можете попробовать открыть его в редакторе и перевести самостоятельно.

  3. —————-Олег Евсегнеев пишет———————
    Разумеется, гораздо интереснее будет поработать с компонентами, отвечающими за реакцию тачскрина. На следующем уроке мы изучим именно такой продвинутый вариант дисплея, и попробуем поработать со слайдбарами и кнопками.
    ———————

    Привет!
    Олег, посмотрел список твоих уроков, но так и не нашел тот, где описывается работа с кнопками. А очень надо! 🙂 и именно для китайской версии экрана.
    Если такой урок был — можешь дать ссылку?
    Приобрел себе TJC4832T035.
    Пример из этого урока работает, но вот дополнительной инфо так и не смог найти. Или ее просто нет, или (что более вероятно) не там искал.

    • Урока действительно нет:) Скорее всего будем писать ближе к лету.
      Но на самом деле там ничего сложного. Рекомендую написать программу, которая будет выводить в COM-монитор всё, что приходит от дисплея. Затем надо создать для дисплея форму с кнопкой, загрузить её на дисплей, подключить к Arduino и смотреть что будет появляться в COM-мониторе при нажатии на кнопку.

      • Посмотрел несколько примеров, но правда для мониторов Nextion. Есть пара вопросов:
        1. Есть ли для мониторов отдельная библиотека (или можно пользовать библиотеку Nextion?)
        2. Не очень понятно как ловить нажатия клавиш — действие это краткое, всегда ли Ардуино через COM монитор сможет отловить? Почему то думал, что есть какая то возможность постоянно мониторить активность дисплея и как то учитывать не отработанные команды…

        Если не затруднит — можно ли ссылки на примеры работы с мониторчиками скинуть? Если не затруднит конечно. Думаю многим будет полезно.

  4. Очень полезная статья! Единственный дельный и рабочий пример в рунете с отправкой данных в численные переменные и числовые поля.

  5. Спасибо за статью
    К сожалению не работает
    после запуска скрипта пишет
    uploading test000.tft (176677 bytes)…
    Filesize: 176677
    Trying with 9600…
    Connected with 9600!
    Status: comok 1
    Model: TJC4832T035_011R
    Version: 61488
    Serial: D26610544359262F
    Flash size: 16777216
    waiting response

    и на этом виснет мертво может кто подскажет что сделать то

  6. Хорошая статья
    Повторюсь: не работает. После запуска скрипта пишет:

    uploading test.tft (176677 bytes)…
    Filesize: 176677
    Trying with 9600…
    Connected with 9600!
    Status: comok 1
    Model: TJC4832T035_011R
    Version: 61488
    Serial: D26610544359262F
    Flash size: 16777216
    waiting response

    и на этом виснет мертво. Есть варианты решения?

  7. Ссылка на редактор символов (см. выше) не работает, т.к. готовлю к выходу законченную версию.

    • Информация о файле
      Имя:Nextion_FG.exe
      Владелец:Сергей Трифонов
      Размер:371 КБ
      Изменён:29.06.2019 22:36
      Просмотры:32
      Скачан:7 раз
      Вирусов не обнаружено

  8. Все сделал по инструкции но что-то не работает. Пробовал одном Windows 10 и на двух компьютерах с Windows 7. Все х64. На Windows 10 при запуске выходит сообщени «невозможно запустить проиложение на вашем пк». На двух Windows 7 одинаково:
    uploading file.tft (2091028 bytes)…
    Filesize: 2091028
    Trying with 9600…
    No connection!
    Порт выставлен правильно, USART EDITOR экран видит и на него пишет. Подскажите пожалуйста где проблема.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.