RSS блога
Подписка
То, что вы не очень хотели знать о дисплеях Nextion
- Цена: $27,4 + доставка
- Перейти в магазин
Долго ли, коротко ли, а так давно, что уже почти не помню, товарищи из ITEAD предложили познакомиться с их продукцией — на мой вкус. Про Wi-Fi выключатель Sonoff я рассказал довольно быстро, а вот знакомство с дисплеем Nextion затянулось.
Причина банальна: ITEAD разослали на обзоры многие множества этих дисплеев, а мне не хотелось быть совсем банальным. Поэтому я сначала придумал, как бы разнообразить текст, а потом начались муки творчества, бессонные ночи, позорные отступления и проч., и проч.
В итоге я, конечно, получил бесценный опыт общения с Nextion, но, положа руку на сердце, предпочел бы обойтись без него. А так как страдать одному невыносимо, приглашаю всех желающих разделить мои мучения.
В первую очередь прошу прощения, что не буду повторять дословно все то, что уже многократно рассказывали до меня. Тем более, что размеры, список функций и даже примеры их использования очень неплохо документированы соотечественниками (чего не скажешь о разработчиках).
Перечислю:
И чтобы вы понимали, сколько их раздали на MySKU:
Поэтому конспективно. Изначально задумка ITEAD превосходна: дисплей с собственным простым API и сенсорной панелью. Просто чудо, чтобы изготавливать блоки управления с графическими меню без особых хлопот.
Для этой цели у Nextion есть простая система команд для вывода изображений (и их частей), текстовых элементов, полей ввода, графиков. Плюс к тому — некое подобие скриптового языка для выполнения действий, скажем, по нажатию на экранные кнопки или по таймеру. И заодно порт для получения внешних команд от микроконтроллеров или им подобных и возврата данных о прикосновениях к экрану, чтобы знать, до какой кнопки добрались шаловливые руки владельца, и в каком состоянии эта кнопка (нажата, отпущена) в текущий момент.
Грубо говоря, здесь не нужно мучиться и собирать массивы точек или подключать тучу всяких библиотек. Одна строчка — и на экране поменялся фон. Нажали — открылось меню. Подключили Arduino — строим графики по данным, которые поступают через последовательный порт.
Для обзора я выбрал экран NX4832TO35 из серии Basic с диагональю 3.5 дюйма и разрешением 320х480 точек. Выбор был связан с тем, что я до конца не был уверен в том, что буду писать текст, поэтому подбирал агрегат, за который мог бы потом без особого сожаления рассчитаться с товарищами из ITEAD.
Кроме этих экранов в линейке Nextion есть так называемые модели Enhanced, улучшение которых, если я правильно понял, сводится к операциям энергонезависимой памятью (EEPROM) и портам ввода/вывода (GPIO).
Но вернемся к моему экземпляру, где необходимо добавить некоторые размеры к уже имеющемуся эскизу от ITEAD:
Добавляю: дисплей выступает над платой примерно на 3,5 мм, толщина текстолита — 1,5 мм, интерфейсный разъем имеет толщину 6,5 мм, и это самый толстый элемент обратной стороны экрана. С вставленной ответной частью разъема есть шансы уложиться в 107 мм по длине всей конструкции.
Геометрия, как видите, не сложная, но и не совсем элементарная:
Качество экрана не идеально, что объяснимо — это не IPS. Но матрица имеет неплохие углы обзора и яркость. Разумеется, просто обязан пожаловаться на некоторую белесость черного оттенка и характерную, хотя и не фатальную инверсию.
Вместе с тем, у лично меня претензий особых нет: фото и видео смотреть не намерен, а что нужно отлично читается практически с двух метров, не говоря о меньших дистанциях.
Что касается сенсорного управления, то здесь оно такое же архаичное, как и матрица — резистивное. И удивительно адекватное — продавливать экран не нужно, а сами нажатия ну буквально что-то среднее между прикосновением, характерным для емкостных экранов, и легким нажатием.
Вот что немного раздражает, так это хорошо видимые дорожки сенсорной панели, которая во всей красе уложена поверх экрана. Причина моего негодования проста: при таком раскладе невозможно сделать аккуратный корпус, где экран был бы вровень с поверхностью. То есть, можно, конечно, но тогда или будет видна служебная часть, или же нужно будет изуродовать поверхность какой-нибудь компактной, но выступающей заглушкой.
Если смириться, то будет как-то так:
И сразу хочу сказать, что в попытках сделать корпус вровень с экраном, я все-таки что-то повредил у Nextion, и сенсорная панель хотя и работает, но только если посильнее сжать экран в месте крепления шлейфа сенсорной панели (отсюда и странное видео).
К чести дисплея, сломал я его не с первой попытки, а после десятка с лишним примерок под разные корпуса. И решающую роль, полагаю, сыграло то, что вырез под экран я старался сделать максимально плотным — чтобы, по возможности, не было зазоров между экраном и корпусом. По этой причине я, конечно, был готов, что в конечном итоге переломлю шлейф, который прямо располагает к этому.
Но все равно огорчился.
Впрочем, для тех, кто не столь придирчив и допускает корпус, где дисплей утоплен, Nextion сразу предлагает макет рамки к 3D-печати. Это для 3.5 дюймов, но рамки имеются на весь ассортимент на страничке Nextion HMI Solution.
Вот такая рамка (картинка от ITEAD, я не печатал):
В целом, понимаете, все выглядит почти прекрасно (мелочи не в счет), пока не начинаешь задумываться о чем-то более-менее симпатичном.
Я, к примеру, задумался о метеостанции и даже мечтал, что сейчас быстренько все соберу, подключу и напишу текст, изобилующий восторженными эпитетами в отношении просветленного китайского гения. По идее, у меня буквально сразу же должно было бы получиться что-то вроде такого (простите за музыку, но я помню, что мое сопение вам нравится еще меньше):
Но вышло не совсем так и далеко не сразу. А чтобы понять, почему, следует вкратце ознакомиться с ТЗ на проектируемый прибор.
Именно:
1) Температура в помещении и на улице
2) Влажность в помещении и на улице
3) Атмосферное давление
4) Концентрация углекислого газа в помещении
5) Концентрация механических примесей типа PM2.5 в помещении
6) Тенденции изменения всех показателей за последние несколько часов
7) График изменения показателей за сутки (или около того)
Из этого понятно, что нужно:
1) Симпатичную фоновую картинку
2) Шрифты
3) Графики
Как хорошо, думал я, что Nextion сам это все может и умеет. Только загружу в него картинку и шрифты, скормлю данные от Arduino и буду самым крутым самодельщиком. И тут начинается самое интересное.
Начиная со среды разработки Nextion Editor, которая является ключевым элементом всей экосистемы. Здесь можно не только собрать весь интерфейс будущего устройства, но и полностью протестировать, не отходя от кассы — встроен полный эмулятор Nextion, включая даже взаимодействие с внешним микроконтроллером.
И все бы хорошо, если бы не некоторые весьма огорчительные вещи. Во-первых, если говорить о картинках, недопустимы прозрачные изображения. То есть, использовать их можно, но прозрачная область таковой не будет.
Поэтому вот такой исходник в GIMP:
Превращается в такую штуку в Nextion:
Во-вторых, все добавляемые элементы нумеруются. Это, разумеется, правильно, потому что именно по этим номерам они впоследствии адресуются скриптами и микроконтроллером. Проблема в том, что нумерация автоматическая и поменять ее крайне сложно. К чести ITEAD можно упомянуть, что они предусмотрели некий способ перемещения элементов вверх-вниз, но это обычно не помогает.
А помогает только полностью удалить все элементы с экрана, затем составить на бумажке план нумерации и добавлять все в соответствии с этим самым планом.
Конечно, найдутся энтузиасты, которые скажут, что какая разница, как все нумеруется — главное, что есть уникальный номер, по которому можно обратиться к элементу интерфейса. Но так как у меня энтузиазма больше, отвечу, что в некоторых довольно типичных случаях это даже не вариант.
К слову, так выглядит макет главного экрана для спейсбоев:
Например, один из элементов метеостанции — страница с графиками показателей. Причем страница не одна, а вовсе даже четыре. Чтобы можно было на одном экране увидеть, что происходило с отдельными климатическими составляющими.
На этом же экране, конечно, следует иметь и кнопки — для возврата на главную страницу и для перехода к просмотру отдельного показателя, если это возможно.
Для наглядности пара макетов — первого и третьего экрана с графиками:
Здесь на переднем плане мы наблюдаем невидимые в рабочем режиме кнопки типа Hotspot (по версии Nextion), а на заднем — клетку элементов Waveform, предназначенных для вывода графиков.
При этом кнопки слева служат для возврата на шаг назад, а справа — к более детальному представлению данных. А так как на первом экране все и так детальнее некуда, то кнопка детализации ведет (сюрприз-сюрприз) на главный экран.
Так вот, представьте себе, что кнопки и графики добавляем хаотично. В итоге получается, что для каждого элемента в коде для управляющего контроллера придется жестко задавать соответствие функции кнопки и ее уникального номера.
Грубо говоря, кнопка «Назад» на первой странице имеет номер 5, на второй — 3, а третьей — 6. И если бы я хотел их адресовать из Arduino (а я хотел), то мне пришлось бы делать таблицу соответствий для каждой страницы. Наоборот, если сделать правильно, то кнопка «Назад» на любой странице будет иметь один и тот же номер, к примеру, 2. А это, между прочим, существенно упрощает код.
Когда я в первый раз так жестоко ошибся (т.е. понакидал элементов, как попало), то надолго ушел в депрессию. Поскольку уже нарисовал весь интерфейс, как я себе его представлял. Но потом взял себя в руки и все перерисовал, как следует. Потому что альтернатива (фиксированный код) меня пугала еще больше.
Однако есть и светлая сторона. Когда интерфейс готов, элементы можно двигать произвольным образом. То есть, если захотелось одно сделать больше, другое — меньше, а третье вообще переместить — на здоровье. В части адресации элементов программный код внешнего контроллера менять не придется.
Третья особенность — отображение текста. Изначально тоже выглядит фантастически, поскольку предполагает использование любого шрифта. Достаточно лишь прогнать его через встроенный конвертер и загрузить полученный результат в дисплей.
Конвертер очень простой, нельзя даже выбрать разновидность шрифта, если их несколько:
Однако конвертер ужасен. Да что там! У любого уважающего себя хипстера-ламберсека борода бы разом выпала, когда бы он увидел, во что превратились изящные очертания того, что я нагуглил по словосочетанию «хипстерские шрифты».
Смотрите сами:
На мой взгляд, здесь вполне очевидно, что — конвертированный шрифт, а что — чистая графика.
Решение, как и в случае с автонумерацией, не слишком простое. Опять же, нужно взять себя в руки и сделать табличку потребных символов в любом приличном графредакторе (тот же GIMP подойдет).
. Вот так выглядит табличка символов:
А затем вместо того, чтобы непринужденно хохоча, посылать в Nextion прямой текст, следует составлять надписи из подготовленной таблички символов. Здесь, кстати, здорово выручает функция вырезки фрагмента изображения, предусмотренная в Nextion.
Выручает прежде всего потому, что с ней можно все элементы надписей хранить в одной картинке, а не россыпью. Но, конечно, даже этот светлый момент не меняет довольно нудного процесса подготовки таблицы символов, для которой еще надо записать координаты отдельных элементов — иначе не получится их показывать на экране.
В моем случае координатный массив выглядит таким образом:
Если точнее, это массив с шириной каждого символа — этого вполне достаточно, чтобы вычислить координаты любого символа в табличке простым сложением ширин. И, да, я знаю, что мог бы сэкономить память, если бы не стал повторять одинаковые значения четыре раза. Но на тот момент так мне было проще, а я уже был в таком состоянии, что ничего сложнее позволить себе не имел возможности.
Но к индикации. Например, чтобы отобразить символ 0 в позиции x = 10, y = 20 следует отправить в Nextion команду:
Здесь 60 — известная заранее высота символа (известная потому, что именно такой высоты символы в моей табличке), «0,0» — координаты верхнего левого угла области обрезки, а следующая за ними единица — уникальный номер изображения, загруженного в Nextion:
Самое печальное, что другого способа сделать красивый текст без ущерба хипстерам я не придумал. Если вы знаете больше моего — пишите.
Наконец, графики. Опять же, с одной стороны все прекрасно: дисплею можно скармливать координаты точек, и он, по идее, будет складывать из них тот самый график. Но и здесь все не просто так.
Дело в том, что элемент Waveform, который логичнее всего использовать для графиков, рассчитан на непрерывный поток входных данных. Иными словами, при попытке показать десяток значений, все они будут скромно жаться в левом (или в зависимости от ориентации графика) уголке.
Поэтому для построения адекватного графика по числу значений меньшему, чем число точек дисплея по горизонтали, промежуточные точки необходимо достраивать самостоятельно.
Кроме того, существует печальное ограничение на формат входных данных: строго положительные значения от 0 до 255. Перевожу на русский: если хочется строить график по произвольному набору данных, все значения нужно привести к указанному диапазону (сдвинуть, нормализовать, масштабировать).
Например, если на входе ряд вида
То мой алгоритм выглядит так:
1) Поиск минимального и максимального значения
2) Расчет коэффициента масштаба (по моей версии y=255/|(max-min)|)
3) Получение расчетной точки по формуле z = (x + |min|)*y, где x — исходное значение, а y — коэффициент масштабирования
Тогда, скажем, значение -280 трансформируется следующим образом:
При этом выплывает еще одна особенность. Помните, я говорил про одновременное отображение нескольких графиков. Например, влажности, температуры и давления?
Так вот, у элемента графика Nextion есть четыре канала. Здорово, подумал я, мне как раз столько и нужно, потому что больше на дисплее с 320 точками по вертикали — издевательство. А вот по 80 точек на график — еще куда ни шло.
И можете считать меня идиотом, но я сильно удивился, когда понял, что в этом случае все четыре канала рисуются в единой системе координат. Поэтому понять, пусть даже и с цветовой дифференциациейштанов кривых, какая из них что — непросто.
Если не верите — попробуйте понять сами:
В результате я остановился на использовании нескольких элементов типа «график» на одной странице. Это тоже связано со своими неудобствами, но иначе моя задача просто не решается. Наиболее очевидное неудобство связано с тем, что субъективно при уменьшении высоты элемента Waveform, уменьшается и его рабочий диапазон.
Т.е. это уже не от 0 до 255, а гораздо меньше. Как так — уму непостижимо, но судя по всему, именно так, поскольку график, который нормально смотрится на Waveform в весь экран, внезапно обрезается при переходе на Waveform меньшей высоты.
В конечном итоге я решил, что дисплей отображает 255 логических точек в текущую физическую высоту элемента типа Waveform. И по этому поводу выдумал еще один масштабирующий коэффициент, равный соотношению физической и логической высот Waveform. То есть, если высота Waveform, скажем, 100 точек, то дополнительный коэффициент масштабирования получается 100/255.
В общем, сам сдвинешься, пока график нарисуешь. Мне, между прочим, так это до конца и не удалось (хотя графики стали выглядеть лучше), но я утешаю себя тем, что у меня все же не прецизионный прибор, а так, демонстрация.
Чтобы понимать, что вышло, вот сравнение графиков, отрисованных на Nextion и построенных примерно по тем же данным сервисом Народный Мониторинг:
Еще одна не совсем очевидная вещь — переключение скорости порта Nextion. По умолчанию это 9600 бит/с, что довольно мало для отрисовки графиков. Точнее, достаточно для тех, кто любит медленно и печально, но когда я наблюдал вывод четырех кривых, в голову настойчиво просился анекдот про хочешь я расскажу тебе сказочку?
Поэтому я решил увеличить скорость, благо контроллер и дисплей позволяют. Не буду утомлять деталями, но сходу не вышло, а беглое гугление показало, что недостаточно просто дать команду Nextion и поменять затем скорость порта контроллера.
Нужно так:
1) Дать команду на переключение скорости Nextion
2) Закрыть порт, поменять скорость внешнего контроллера
3) Открыть порт на новой скорости
4) Дать команду на переключение скорости Nextion
В моем коде это выглядит следующим образом:
Если вы думаете, что это все проблемы, спешу заверить: не все. Просто потому, что я не ставил целью использовать все команды Nextion и еще не рассказал об особенностях сборки образа интерфейса для загрузки в дисплей.
А особенность в том, что при наличии скриптовых (встроенных в Nextion Editor) действий, они обрабатываются компилятором, который суров, как чугунный лом. Сообщения об ошибках в нем настолько же точны, насколько бесполезны.
Особенно, если учесть некоторую несуразность системы команд. Поясню. Например, для перехода на нулевую страницу дисплею нужно сказать:
А чтобы обновить выбранный элемент, хоть ту же страницу —
Все заметили, что в первом случае пробел между page и 0 есть, а во втором — нет? То-то. С точки зрения программиста концепция, конечно, довольно прозрачна: сначала команда, а затем — аргумент.
Однако с точки зрения логики было бы неплохо формализовать формат наименования страниц (и, вероятно, других элементов) в подобных ситуациях.
На данном примере это могло бы выглядеть так:
Плюс к тому я сталкивался, что даже лишний пробел может стать причиной того, что код не компилируется или команда исполняется не так, как следует.
Например, вот эта работает:
А вот эта — нет:
И это нужно помнить тем, кто избалован приличными компиляторами, которые и за ручку возьмут, и проведут, и сами исправят, что могут. Я уже молчу о том, что описание системы команд содержит очевидные ошибки вроде вот такого:
Т.е. в примере команда xpic волшебным образом превращается в picq. Скажете, что не смертельно, и будете правы. Но крайне неприятно.
Вероятно, по причине вот таких не смертельных, но мелких неприятностей, я решил, что не буду пользоваться стандартной библиотекой Nextion, а как-нибудь обойдусь простым общением через последовательный порт.
Не знаю, ошибочное это было решение, или правильное, но могу точно сказать, что при таком раскладе все прекрасно работает и отлаживаться было не слишком сложно.
Что касается текущей реализации, то при моему подходе к написанию кода закономерно вышло, что я подобрался вплотную к пределам Arduino Pro Mini, а точнее — ATmega328p. По счастью, компиляция прошла без проблем, и при исполнении программа не имеет тенденции к зависанию.
Данные дисплей получает от самодельного «мультисенсора», в котором установлен комплект из четырех датчиков:
Данные передаются моим излюбленным способом — с помощью элементарного передатчика с амплитудной модуляцией на частоте 433,92 МГц посредством библиотеки RC-Switch. Это для совместимости с уже имеющейся немудреной домашней автоматикой.
Я прекрасно понимаю, что с таким комплектом о точности речь не идет, однако данные базовых датчиков (температура, влажность, давление) хорошо соотносятся с показаниями простой бытовой метеостанции.
Что касается более затейливых датчиков, то показания MQ135 хорошо отражают состояние атмосферы в комнате: чем выше показания, тем более душно. Датчик Sharp измеряет более тонкие материи, поэтому я пока не готов рассуждать о достоверности его данных.
Поэтому показания этих датчиков я считаю не абсолютными величинами, а относительными и стараюсь интерпретировать их на основании собственных ощущений.
Для желающих повторить сей беспримерный подвиг, но на другой платформе, сразу показываю, где в коде происходит получение данных:
Здесь смысловое значение имеют конструкции вида
Теоретически, если я нигде не ошибся, то вместо моего мультисенсора можно легко и непринужденно (ну хорошо, почти легко и непринужденно) подключить любые другие локальные и беспроводные датчики, подставляя свои данные.
Код не для слабонервных. Это, в принципе, рабочая версия, которая вписывается в ограничения по памяти ATmega328p. Но не до конца почищенная и, вероятно, не финальная, потому что с графиками надо что-то делать.
Для экрана еще потребуется интерфейс:
1) Версия для редактирования
2) Вариант для загрузки в дисплей
Несколько комментариев. Для экономии памяти (может быть, субъективной) я остановился на размере архива в 48 значений по каждому параметру. С учетом того, что значения отправляются в архив каждые полчаса, график охватывает период примерно в сутки.
Примерно — потому что по причине не слишком стабильного качества радиоканала могут быть пропуски и сдвиги.
Тенденция к изменению параметров строится по шести точкам из архива (по этому методу), что вместе с тем же получасовым интервалом дает период в 3 часа. Т.е. тенденция отражает изменение конкретного параметра за последнюю восьмую суток.
Время «жизни» датчиков — полчаса. Т.е. если в течение получаса датчик не передавал показания (или они не были приняты), он считается отключенным и не отображается на дисплее.
Общее количество разрядов в параметрах — не более четырех. При этом для температуры и PM2.5 это включает и десятичный разряд.
Проверок, обработок ошибок и защит от всяких бед вроде переполнения, неверных форматов и прочего практически нет. Это мой сознательный выбор, как человека ленивого.
Кроме того, чтобы все было приемлемо и с эстетической точки зрения, я нарисовал очень простой корпус для 3.5-дюймового Nextion. Экран здесь вровень с поверхностью, много прямых углов, заглушки на контактах сенсорной панели нет — то, что надо для ценителей сурового промдизайна. Но у меня подозрение, что это не финальный вариант.
С предыдущей итерацией, которая мне больше симпатична за счет тонких рамок:
В окрасе:
Мультисенсор из обычной коробчонки переместил в дизайнерскую лампу за авторством тов. Markellov. Штука, считаю, идеальная: хорошо маскирует бардак внутри и одновременно прекрасно продувается всеми ветрами, что актуально для всех датчиков (ну разве что кроме давления).
Если подсадить кота, получится как на картинке «Настало время удивительных историй»:
Размеры артобъекта, разумеется, менял под свои потребности. И впоследствии покрасил его невероятной «каменной» краской Rust-Oleum American Accents Stone.
Итог в двух словах: дисплеи Nextion — превосходная по своей концепции задумка (как, по-моему, вообще все идеи ITEAD), по поводу реализации которой лично у меня ощущения двоякие.
С одной стороны, понятно, что конструирование интерфейсов процесс по-любому не простой. И если есть способ его облегчить — я только за. Поэтому действия ITEAD в этом направлении всецело поддерживаю.
И пусть я придираюсь, но все же хотелось бы иметь более внятное описание команд дисплея, более адекватный компилятор (который бы очевидно указывал на ошибки) и более адекватное поведение элементов интерфейса.
Но несмотря на то, что мне не все понравилось, а некоторые вещи совсем не понравились, не могу сказать, что это гадость или еще что-то в таком роде.
Что касается оправданности цены экрана, то вряд ли смогу сказать что-то толковое. По сравнению с любимыми текстовыми дисплеями типа 1602 или экранами Nokia, которые работают с Arduino, конечно, дорого.
Однако если хочется укомплектовать терпимым (не идеальным) сенсорным дисплеем свою самоделку, сэкономив некоторое время на проектировании и макетировании интерфейса — уже неплохо.
Далее спорить об экономической целесообразности возможностей не имею, но с удовольствием послушаю мнения старших товарищей на эту (и не только) животрепещущую тему. Точно так же я уверен, что увидев мое несовершенство, вы наверняка сможете сделать лучше на таком же (или другом) железе.
Небольшая сессия вопросов-ответов.
Q: У Nextion куча команд и возможностей, а ты рассказал про полторы функции и решил, что все плохо. Как так?
A: Ну, каждый кулик свое болото хвалит. У меня не было задачи перемалывать каждую букву руководства. Поэтому я рассказал, на какие грабли наступил при решении типовой задачи.
Q: А ты смешной, использовать датчики за 2 бакса, чтобы оценивать качество атмосферы. И что они у тебя показывают, погоду на Луне?
A: Про датчики мне уже все рассказали еще в обзоре MQ135, но меня все устраивает.
Q: А не проще было взять старый смартфон, закачать апп и поставить все на видном месте?
A: Наверное, проще, но цель была другая.
Q: Прямо просятся часы, игры другие фичи. Почему не сделал?
A: Если честно, еще много чего просится. Смена фона прямо из интерфейса, к примеру. Но мне эта конструкция уже и так всю душу вынула. Сил больше никаких нет.
Q: Да за такие деньги можно целый планшет купить!
A: Я не призываю покупать Nextion.
Q: Ты вообще в курсе, что в Nextion процессор круче, чем в Arduino, которую к нему прикрутил?
A: Да, в курсе. Нет, разбираться со встроенным не собираюсь.
Причина банальна: ITEAD разослали на обзоры многие множества этих дисплеев, а мне не хотелось быть совсем банальным. Поэтому я сначала придумал, как бы разнообразить текст, а потом начались муки творчества, бессонные ночи, позорные отступления и проч., и проч.
В итоге я, конечно, получил бесценный опыт общения с Nextion, но, положа руку на сердце, предпочел бы обойтись без него. А так как страдать одному невыносимо, приглашаю всех желающих разделить мои мучения.
В первую очередь прошу прощения, что не буду повторять дословно все то, что уже многократно рассказывали до меня. Тем более, что размеры, список функций и даже примеры их использования очень неплохо документированы соотечественниками (чего не скажешь о разработчиках).
Перечислю:
И чтобы вы понимали, сколько их раздали на MySKU:
- Nextion Enhanced NX4827K043 — 4.3'' дисплей + тачскрин + контроллер для взаимодействия с пользователем
- Дисплей от компании Nextion 3.5" для Arduino и не только
- Два дисплея Nextion 3.2" и 3.5" HMI TFT LCD с тач-скрином
- Nextion NX4827T043 — 4.3” HMI-панель с последовательным портом
- Nextion NX4827T043 — 4.3” TFT LCD
- Nextion Enhanced 3.5'' — обновленная версия всем известной HMI панели, теперь с RTC, GPIO и EEPROM на борту
- Nextion + Arduino. Мысли, идеи. Часть 1
- Nextion + Arduino. Мысли, идеи. Часть 2
Поэтому конспективно. Изначально задумка ITEAD превосходна: дисплей с собственным простым API и сенсорной панелью. Просто чудо, чтобы изготавливать блоки управления с графическими меню без особых хлопот.
Для этой цели у Nextion есть простая система команд для вывода изображений (и их частей), текстовых элементов, полей ввода, графиков. Плюс к тому — некое подобие скриптового языка для выполнения действий, скажем, по нажатию на экранные кнопки или по таймеру. И заодно порт для получения внешних команд от микроконтроллеров или им подобных и возврата данных о прикосновениях к экрану, чтобы знать, до какой кнопки добрались шаловливые руки владельца, и в каком состоянии эта кнопка (нажата, отпущена) в текущий момент.
Грубо говоря, здесь не нужно мучиться и собирать массивы точек или подключать тучу всяких библиотек. Одна строчка — и на экране поменялся фон. Нажали — открылось меню. Подключили Arduino — строим графики по данным, которые поступают через последовательный порт.
Для обзора я выбрал экран NX4832TO35 из серии Basic с диагональю 3.5 дюйма и разрешением 320х480 точек. Выбор был связан с тем, что я до конца не был уверен в том, что буду писать текст, поэтому подбирал агрегат, за который мог бы потом без особого сожаления рассчитаться с товарищами из ITEAD.
Кроме этих экранов в линейке Nextion есть так называемые модели Enhanced, улучшение которых, если я правильно понял, сводится к операциям энергонезависимой памятью (EEPROM) и портам ввода/вывода (GPIO).
Но вернемся к моему экземпляру, где необходимо добавить некоторые размеры к уже имеющемуся эскизу от ITEAD:
Добавляю: дисплей выступает над платой примерно на 3,5 мм, толщина текстолита — 1,5 мм, интерфейсный разъем имеет толщину 6,5 мм, и это самый толстый элемент обратной стороны экрана. С вставленной ответной частью разъема есть шансы уложиться в 107 мм по длине всей конструкции.
Геометрия, как видите, не сложная, но и не совсем элементарная:
Качество экрана не идеально, что объяснимо — это не IPS. Но матрица имеет неплохие углы обзора и яркость. Разумеется, просто обязан пожаловаться на некоторую белесость черного оттенка и характерную, хотя и не фатальную инверсию.
Вместе с тем, у лично меня претензий особых нет: фото и видео смотреть не намерен, а что нужно отлично читается практически с двух метров, не говоря о меньших дистанциях.
Что касается сенсорного управления, то здесь оно такое же архаичное, как и матрица — резистивное. И удивительно адекватное — продавливать экран не нужно, а сами нажатия ну буквально что-то среднее между прикосновением, характерным для емкостных экранов, и легким нажатием.
Вот что немного раздражает, так это хорошо видимые дорожки сенсорной панели, которая во всей красе уложена поверх экрана. Причина моего негодования проста: при таком раскладе невозможно сделать аккуратный корпус, где экран был бы вровень с поверхностью. То есть, можно, конечно, но тогда или будет видна служебная часть, или же нужно будет изуродовать поверхность какой-нибудь компактной, но выступающей заглушкой.
Если смириться, то будет как-то так:
И сразу хочу сказать, что в попытках сделать корпус вровень с экраном, я все-таки что-то повредил у Nextion, и сенсорная панель хотя и работает, но только если посильнее сжать экран в месте крепления шлейфа сенсорной панели (отсюда и странное видео).
К чести дисплея, сломал я его не с первой попытки, а после десятка с лишним примерок под разные корпуса. И решающую роль, полагаю, сыграло то, что вырез под экран я старался сделать максимально плотным — чтобы, по возможности, не было зазоров между экраном и корпусом. По этой причине я, конечно, был готов, что в конечном итоге переломлю шлейф, который прямо располагает к этому.
Но все равно огорчился.
Впрочем, для тех, кто не столь придирчив и допускает корпус, где дисплей утоплен, Nextion сразу предлагает макет рамки к 3D-печати. Это для 3.5 дюймов, но рамки имеются на весь ассортимент на страничке Nextion HMI Solution.
Вот такая рамка (картинка от ITEAD, я не печатал):
В целом, понимаете, все выглядит почти прекрасно (мелочи не в счет), пока не начинаешь задумываться о чем-то более-менее симпатичном.
Я, к примеру, задумался о метеостанции и даже мечтал, что сейчас быстренько все соберу, подключу и напишу текст, изобилующий восторженными эпитетами в отношении просветленного китайского гения. По идее, у меня буквально сразу же должно было бы получиться что-то вроде такого (простите за музыку, но я помню, что мое сопение вам нравится еще меньше):
Но вышло не совсем так и далеко не сразу. А чтобы понять, почему, следует вкратце ознакомиться с ТЗ на проектируемый прибор.
Именно:
1) Температура в помещении и на улице
2) Влажность в помещении и на улице
3) Атмосферное давление
4) Концентрация углекислого газа в помещении
5) Концентрация механических примесей типа PM2.5 в помещении
6) Тенденции изменения всех показателей за последние несколько часов
7) График изменения показателей за сутки (или около того)
Из этого понятно, что нужно:
1) Симпатичную фоновую картинку
2) Шрифты
3) Графики
Как хорошо, думал я, что Nextion сам это все может и умеет. Только загружу в него картинку и шрифты, скормлю данные от Arduino и буду самым крутым самодельщиком. И тут начинается самое интересное.
Начиная со среды разработки Nextion Editor, которая является ключевым элементом всей экосистемы. Здесь можно не только собрать весь интерфейс будущего устройства, но и полностью протестировать, не отходя от кассы — встроен полный эмулятор Nextion, включая даже взаимодействие с внешним микроконтроллером.
И все бы хорошо, если бы не некоторые весьма огорчительные вещи. Во-первых, если говорить о картинках, недопустимы прозрачные изображения. То есть, использовать их можно, но прозрачная область таковой не будет.
Поэтому вот такой исходник в GIMP:
Превращается в такую штуку в Nextion:
Во-вторых, все добавляемые элементы нумеруются. Это, разумеется, правильно, потому что именно по этим номерам они впоследствии адресуются скриптами и микроконтроллером. Проблема в том, что нумерация автоматическая и поменять ее крайне сложно. К чести ITEAD можно упомянуть, что они предусмотрели некий способ перемещения элементов вверх-вниз, но это обычно не помогает.
А помогает только полностью удалить все элементы с экрана, затем составить на бумажке план нумерации и добавлять все в соответствии с этим самым планом.
Конечно, найдутся энтузиасты, которые скажут, что какая разница, как все нумеруется — главное, что есть уникальный номер, по которому можно обратиться к элементу интерфейса. Но так как у меня энтузиазма больше, отвечу, что в некоторых довольно типичных случаях это даже не вариант.
К слову, так выглядит макет главного экрана для спейсбоев:
Другие варианты экранов
Для хоббитов:
Для колонистов:
Для романтиков:
Для кофеманов:
Для колонистов:
Для романтиков:
Для кофеманов:
Например, один из элементов метеостанции — страница с графиками показателей. Причем страница не одна, а вовсе даже четыре. Чтобы можно было на одном экране увидеть, что происходило с отдельными климатическими составляющими.
На этом же экране, конечно, следует иметь и кнопки — для возврата на главную страницу и для перехода к просмотру отдельного показателя, если это возможно.
Для наглядности пара макетов — первого и третьего экрана с графиками:
Здесь на переднем плане мы наблюдаем невидимые в рабочем режиме кнопки типа Hotspot (по версии Nextion), а на заднем — клетку элементов Waveform, предназначенных для вывода графиков.
При этом кнопки слева служат для возврата на шаг назад, а справа — к более детальному представлению данных. А так как на первом экране все и так детальнее некуда, то кнопка детализации ведет (сюрприз-сюрприз) на главный экран.
Так вот, представьте себе, что кнопки и графики добавляем хаотично. В итоге получается, что для каждого элемента в коде для управляющего контроллера придется жестко задавать соответствие функции кнопки и ее уникального номера.
Грубо говоря, кнопка «Назад» на первой странице имеет номер 5, на второй — 3, а третьей — 6. И если бы я хотел их адресовать из Arduino (а я хотел), то мне пришлось бы делать таблицу соответствий для каждой страницы. Наоборот, если сделать правильно, то кнопка «Назад» на любой странице будет иметь один и тот же номер, к примеру, 2. А это, между прочим, существенно упрощает код.
Когда я в первый раз так жестоко ошибся (т.е. понакидал элементов, как попало), то надолго ушел в депрессию. Поскольку уже нарисовал весь интерфейс, как я себе его представлял. Но потом взял себя в руки и все перерисовал, как следует. Потому что альтернатива (фиксированный код) меня пугала еще больше.
Однако есть и светлая сторона. Когда интерфейс готов, элементы можно двигать произвольным образом. То есть, если захотелось одно сделать больше, другое — меньше, а третье вообще переместить — на здоровье. В части адресации элементов программный код внешнего контроллера менять не придется.
Третья особенность — отображение текста. Изначально тоже выглядит фантастически, поскольку предполагает использование любого шрифта. Достаточно лишь прогнать его через встроенный конвертер и загрузить полученный результат в дисплей.
Конвертер очень простой, нельзя даже выбрать разновидность шрифта, если их несколько:
Однако конвертер ужасен. Да что там! У любого уважающего себя хипстера-ламберсека борода бы разом выпала, когда бы он увидел, во что превратились изящные очертания того, что я нагуглил по словосочетанию «хипстерские шрифты».
Смотрите сами:
На мой взгляд, здесь вполне очевидно, что — конвертированный шрифт, а что — чистая графика.
Решение, как и в случае с автонумерацией, не слишком простое. Опять же, нужно взять себя в руки и сделать табличку потребных символов в любом приличном графредакторе (тот же GIMP подойдет).
. Вот так выглядит табличка символов:
А затем вместо того, чтобы непринужденно хохоча, посылать в Nextion прямой текст, следует составлять надписи из подготовленной таблички символов. Здесь, кстати, здорово выручает функция вырезки фрагмента изображения, предусмотренная в Nextion.
Выручает прежде всего потому, что с ней можно все элементы надписей хранить в одной картинке, а не россыпью. Но, конечно, даже этот светлый момент не меняет довольно нудного процесса подготовки таблицы символов, для которой еще надо записать координаты отдельных элементов — иначе не получится их показывать на экране.
В моем случае координатный массив выглядит таким образом:
// ширина символов 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
byte symbolW[5][11] = {{25, 15, 30, 25, 30, 30, 25, 30, 25, 30, 5},
{11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3},
{11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3},
{11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3},
{11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3}};
Если точнее, это массив с шириной каждого символа — этого вполне достаточно, чтобы вычислить координаты любого символа в табличке простым сложением ширин. И, да, я знаю, что мог бы сэкономить память, если бы не стал повторять одинаковые значения четыре раза. Но на тот момент так мне было проще, а я уже был в таком состоянии, что ничего сложнее позволить себе не имел возможности.
Но к индикации. Например, чтобы отобразить символ 0 в позиции x = 10, y = 20 следует отправить в Nextion команду:
xpic 10, 20, 25, 60, 0, 0, 1
Здесь 60 — известная заранее высота символа (известная потому, что именно такой высоты символы в моей табличке), «0,0» — координаты верхнего левого угла области обрезки, а следующая за ними единица — уникальный номер изображения, загруженного в Nextion:
Самое печальное, что другого способа сделать красивый текст без ущерба хипстерам я не придумал. Если вы знаете больше моего — пишите.
Наконец, графики. Опять же, с одной стороны все прекрасно: дисплею можно скармливать координаты точек, и он, по идее, будет складывать из них тот самый график. Но и здесь все не просто так.
Дело в том, что элемент Waveform, который логичнее всего использовать для графиков, рассчитан на непрерывный поток входных данных. Иными словами, при попытке показать десяток значений, все они будут скромно жаться в левом (или в зависимости от ориентации графика) уголке.
Поэтому для построения адекватного графика по числу значений меньшему, чем число точек дисплея по горизонтали, промежуточные точки необходимо достраивать самостоятельно.
Кроме того, существует печальное ограничение на формат входных данных: строго положительные значения от 0 до 255. Перевожу на русский: если хочется строить график по произвольному набору данных, все значения нужно привести к указанному диапазону (сдвинуть, нормализовать, масштабировать).
Например, если на входе ряд вида
-1586, -300, -280, -100, 0, 20, 185, 550, 2567
То мой алгоритм выглядит так:
1) Поиск минимального и максимального значения
2) Расчет коэффициента масштаба (по моей версии y=255/|(max-min)|)
3) Получение расчетной точки по формуле z = (x + |min|)*y, где x — исходное значение, а y — коэффициент масштабирования
Тогда, скажем, значение -280 трансформируется следующим образом:
1) min = -1586, max = 2567
2) y = 255/|(2567-(-1586)| = 0,06
3) z = (-280+|-1586|)*0,06 = 78,36
При этом выплывает еще одна особенность. Помните, я говорил про одновременное отображение нескольких графиков. Например, влажности, температуры и давления?
Так вот, у элемента графика Nextion есть четыре канала. Здорово, подумал я, мне как раз столько и нужно, потому что больше на дисплее с 320 точками по вертикали — издевательство. А вот по 80 точек на график — еще куда ни шло.
И можете считать меня идиотом, но я сильно удивился, когда понял, что в этом случае все четыре канала рисуются в единой системе координат. Поэтому понять, пусть даже и с цветовой дифференциацией
Если не верите — попробуйте понять сами:
В результате я остановился на использовании нескольких элементов типа «график» на одной странице. Это тоже связано со своими неудобствами, но иначе моя задача просто не решается. Наиболее очевидное неудобство связано с тем, что субъективно при уменьшении высоты элемента Waveform, уменьшается и его рабочий диапазон.
Т.е. это уже не от 0 до 255, а гораздо меньше. Как так — уму непостижимо, но судя по всему, именно так, поскольку график, который нормально смотрится на Waveform в весь экран, внезапно обрезается при переходе на Waveform меньшей высоты.
В конечном итоге я решил, что дисплей отображает 255 логических точек в текущую физическую высоту элемента типа Waveform. И по этому поводу выдумал еще один масштабирующий коэффициент, равный соотношению физической и логической высот Waveform. То есть, если высота Waveform, скажем, 100 точек, то дополнительный коэффициент масштабирования получается 100/255.
В общем, сам сдвинешься, пока график нарисуешь. Мне, между прочим, так это до конца и не удалось (хотя графики стали выглядеть лучше), но я утешаю себя тем, что у меня все же не прецизионный прибор, а так, демонстрация.
Чтобы понимать, что вышло, вот сравнение графиков, отрисованных на Nextion и построенных примерно по тем же данным сервисом Народный Мониторинг:
Еще несколько менее успешных визуализаций
Еще одна не совсем очевидная вещь — переключение скорости порта Nextion. По умолчанию это 9600 бит/с, что довольно мало для отрисовки графиков. Точнее, достаточно для тех, кто любит медленно и печально, но когда я наблюдал вывод четырех кривых, в голову настойчиво просился анекдот про хочешь я расскажу тебе сказочку?
Поэтому я решил увеличить скорость, благо контроллер и дисплей позволяют. Не буду утомлять деталями, но сходу не вышло, а беглое гугление показало, что недостаточно просто дать команду Nextion и поменять затем скорость порта контроллера.
Нужно так:
1) Дать команду на переключение скорости Nextion
2) Закрыть порт, поменять скорость внешнего контроллера
3) Открыть порт на новой скорости
4) Дать команду на переключение скорости Nextion
В моем коде это выглядит следующим образом:
Serial1.begin(9600); // открытие порта дисплея на стандартной скорости
Serial1.print("baud=57600"); // команда на изменение скорости
sendToNextion();
Serial1.end(); // закрытие порта
Serial1.begin(57600); // открытие порта на новой скорости
Serial1.print("baud=57600"); // команда на изменение скорости
sendToNextion();
Если вы думаете, что это все проблемы, спешу заверить: не все. Просто потому, что я не ставил целью использовать все команды Nextion и еще не рассказал об особенностях сборки образа интерфейса для загрузки в дисплей.
А особенность в том, что при наличии скриптовых (встроенных в Nextion Editor) действий, они обрабатываются компилятором, который суров, как чугунный лом. Сообщения об ошибках в нем настолько же точны, насколько бесполезны.
Особенно, если учесть некоторую несуразность системы команд. Поясню. Например, для перехода на нулевую страницу дисплею нужно сказать:
page 0
А чтобы обновить выбранный элемент, хоть ту же страницу —
ref page0
Все заметили, что в первом случае пробел между page и 0 есть, а во втором — нет? То-то. С точки зрения программиста концепция, конечно, довольно прозрачна: сначала команда, а затем — аргумент.
Однако с точки зрения логики было бы неплохо формализовать формат наименования страниц (и, вероятно, других элементов) в подобных ситуациях.
На данном примере это могло бы выглядеть так:
page page0 // переход на страницу 0
ref page0 // обновление страницы 0
Плюс к тому я сталкивался, что даже лишний пробел может стать причиной того, что код не компилируется или команда исполняется не так, как следует.
Например, вот эта работает:
add 1,0,227
А вот эта — нет:
add 1, 0, 227
И это нужно помнить тем, кто избалован приличными компиляторами, которые и за ручку возьмут, и проведут, и сами исправят, что могут. Я уже молчу о том, что описание системы команд содержит очевидные ошибки вроде вот такого:
xpic: Advanced crop picture
xpic x, y, w, h, x0, y0, picid
[удалено]
Example:
picq 20, 50, 30, 20, 15, 15, 0
Т.е. в примере команда xpic волшебным образом превращается в picq. Скажете, что не смертельно, и будете правы. Но крайне неприятно.
Вероятно, по причине вот таких не смертельных, но мелких неприятностей, я решил, что не буду пользоваться стандартной библиотекой Nextion, а как-нибудь обойдусь простым общением через последовательный порт.
Не знаю, ошибочное это было решение, или правильное, но могу точно сказать, что при таком раскладе все прекрасно работает и отлаживаться было не слишком сложно.
Что касается текущей реализации, то при моему подходе к написанию кода закономерно вышло, что я подобрался вплотную к пределам Arduino Pro Mini, а точнее — ATmega328p. По счастью, компиляция прошла без проблем, и при исполнении программа не имеет тенденции к зависанию.
Данные дисплей получает от самодельного «мультисенсора», в котором установлен комплект из четырех датчиков:
- BMP085 измеряет давление и температуру
- DHT22 измеряет влажность
- MQ135 измеряет содержание газов (условно — CO2)
- Sharp GP2Y1010AU0F измеряет содержание твердых частиц (условно — PM2.5)
Данные передаются моим излюбленным способом — с помощью элементарного передатчика с амплитудной модуляцией на частоте 433,92 МГц посредством библиотеки RC-Switch. Это для совместимости с уже имеющейся немудреной домашней автоматикой.
Я прекрасно понимаю, что с таким комплектом о точности речь не идет, однако данные базовых датчиков (температура, влажность, давление) хорошо соотносятся с показаниями простой бытовой метеостанции.
Что касается более затейливых датчиков, то показания MQ135 хорошо отражают состояние атмосферы в комнате: чем выше показания, тем более душно. Датчик Sharp измеряет более тонкие материи, поэтому я пока не готов рассуждать о достоверности его данных.
Поэтому показания этих датчиков я считаю не абсолютными величинами, а относительными и стараюсь интерпретировать их на основании собственных ощущений.
Для желающих повторить сей беспримерный подвиг, но на другой платформе, сразу показываю, где в коде происходит получение данных:
Дополнительная информация
// ПОЛУЧЕНИЕ ДАННЫХ ОТ РАДИОДАТЧИКОВ
if (mySwitch.available()) { // проверяем датчики
int value = mySwitch.getReceivedValue();
if (value != 0) {
// ВЛАЖНОСТЬ И ТЕМПЕРАТУРА СНАРУЖИ
if (mySwitch.getReceivedValue() / 100000 == 161) {
weatherData = mySwitch.getReceivedValue() - 16100000;
if (weatherData > 10000) { // пришла влажность
parameterS[3] = (weatherData - 10000)/10;
statusS[3] = statusS[3]+1;
statusBoolean[3] = true;
}
else { // пришла температура
if (weatherData > 1000) { // минусовая температура
parameterS[1] = -(weatherData - 1000);
minusOut = true;
}
else { // плюсовая температура
parameterS[1] = weatherData;
minusOut = false;
}
}
statusS[1] = statusS[1]+1;
statusBoolean[1] = true;
}
// ДАВЛЕНИЕ И ТЕМПЕРАТУРА ВНУТРИ
if (mySwitch.getReceivedValue() / 10000 == 1210) {
parameterS[4] = (mySwitch.getReceivedValue() - 12100000) / 1.33; // пришло давление
statusS[4] = statusS[4]+1;
statusBoolean[4] = true;
}
if (mySwitch.getReceivedValue() / 100000 == 131) {
weatherData = mySwitch.getReceivedValue() - 13100000;
if (weatherData > 1000) { // минусовая температура
parameterS[0] = -(weatherData - 1000);
minusIn = true;
}
else { // плюсовая температура
parameterS[0] = weatherData;
minusIn = false;
}
statusS[0] = statusS[0]+1;
statusBoolean[0] = true;
}
// ВЛАЖНОСТЬ ВНУТРИ
if (mySwitch.getReceivedValue() / 10000 == 1212) {
parameterS[2] = (mySwitch.getReceivedValue() - 12120000)/10; // влажность
statusS[2] = statusS[2]+1;
statusBoolean[2] = true;
}
// CO2 PPM
if (mySwitch.getReceivedValue() / 10000 == 1213) {
parameterS[5] = (mySwitch.getReceivedValue() - 12130000); // CO2
statusS[5] = statusS[5]+1;
statusBoolean[5] = true;
}
// PM2.5
if (mySwitch.getReceivedValue() / 10000 == 1214) {
parameterS[6] = (mySwitch.getReceivedValue() - 12140000); // PM2.5
statusS[6] = statusS[6]+1;
statusBoolean[6] = true;
}
}
mySwitch.resetAvailable();
// mySwitch.enableReceive(0); // включение RC Switch
}
Здесь смысловое значение имеют конструкции вида
parameterS[индекс параметра] = значение параметра];
statusS[индекс параметра] = statusS[индекс параметра]+1;
statusBoolean[индекс параметра] = true;
Теоретически, если я нигде не ошибся, то вместо моего мультисенсора можно легко и непринужденно (ну хорошо, почти легко и непринужденно) подключить любые другие локальные и беспроводные датчики, подставляя свои данные.
Код не для слабонервных. Это, в принципе, рабочая версия, которая вписывается в ограничения по памяти ATmega328p. Но не до конца почищенная и, вероятно, не финальная, потому что с графиками надо что-то делать.
Для экрана еще потребуется интерфейс:
1) Версия для редактирования
2) Вариант для загрузки в дисплей
Несколько комментариев. Для экономии памяти (может быть, субъективной) я остановился на размере архива в 48 значений по каждому параметру. С учетом того, что значения отправляются в архив каждые полчаса, график охватывает период примерно в сутки.
Примерно — потому что по причине не слишком стабильного качества радиоканала могут быть пропуски и сдвиги.
Тенденция к изменению параметров строится по шести точкам из архива (по этому методу), что вместе с тем же получасовым интервалом дает период в 3 часа. Т.е. тенденция отражает изменение конкретного параметра за последнюю восьмую суток.
Время «жизни» датчиков — полчаса. Т.е. если в течение получаса датчик не передавал показания (или они не были приняты), он считается отключенным и не отображается на дисплее.
Общее количество разрядов в параметрах — не более четырех. При этом для температуры и PM2.5 это включает и десятичный разряд.
Проверок, обработок ошибок и защит от всяких бед вроде переполнения, неверных форматов и прочего практически нет. Это мой сознательный выбор, как человека ленивого.
Кроме того, чтобы все было приемлемо и с эстетической точки зрения, я нарисовал очень простой корпус для 3.5-дюймового Nextion. Экран здесь вровень с поверхностью, много прямых углов, заглушки на контактах сенсорной панели нет — то, что надо для ценителей сурового промдизайна. Но у меня подозрение, что это не финальный вариант.
Больше корпуса
Сборка
С предыдущей итерацией, которая мне больше симпатична за счет тонких рамок:
В окрасе:
Мультисенсор из обычной коробчонки переместил в дизайнерскую лампу за авторством тов. Markellov. Штука, считаю, идеальная: хорошо маскирует бардак внутри и одновременно прекрасно продувается всеми ветрами, что актуально для всех датчиков (ну разве что кроме давления).
Если подсадить кота, получится как на картинке «Настало время удивительных историй»:
Размеры артобъекта, разумеется, менял под свои потребности. И впоследствии покрасил его невероятной «каменной» краской Rust-Oleum American Accents Stone.
Итог в двух словах: дисплеи Nextion — превосходная по своей концепции задумка (как, по-моему, вообще все идеи ITEAD), по поводу реализации которой лично у меня ощущения двоякие.
С одной стороны, понятно, что конструирование интерфейсов процесс по-любому не простой. И если есть способ его облегчить — я только за. Поэтому действия ITEAD в этом направлении всецело поддерживаю.
И пусть я придираюсь, но все же хотелось бы иметь более внятное описание команд дисплея, более адекватный компилятор (который бы очевидно указывал на ошибки) и более адекватное поведение элементов интерфейса.
Но несмотря на то, что мне не все понравилось, а некоторые вещи совсем не понравились, не могу сказать, что это гадость или еще что-то в таком роде.
Что касается оправданности цены экрана, то вряд ли смогу сказать что-то толковое. По сравнению с любимыми текстовыми дисплеями типа 1602 или экранами Nokia, которые работают с Arduino, конечно, дорого.
Однако если хочется укомплектовать терпимым (не идеальным) сенсорным дисплеем свою самоделку, сэкономив некоторое время на проектировании и макетировании интерфейса — уже неплохо.
Далее спорить об экономической целесообразности возможностей не имею, но с удовольствием послушаю мнения старших товарищей на эту (и не только) животрепещущую тему. Точно так же я уверен, что увидев мое несовершенство, вы наверняка сможете сделать лучше на таком же (или другом) железе.
Небольшая сессия вопросов-ответов.
Q: У Nextion куча команд и возможностей, а ты рассказал про полторы функции и решил, что все плохо. Как так?
A: Ну, каждый кулик свое болото хвалит. У меня не было задачи перемалывать каждую букву руководства. Поэтому я рассказал, на какие грабли наступил при решении типовой задачи.
Q: А ты смешной, использовать датчики за 2 бакса, чтобы оценивать качество атмосферы. И что они у тебя показывают, погоду на Луне?
A: Про датчики мне уже все рассказали еще в обзоре MQ135, но меня все устраивает.
Q: А не проще было взять старый смартфон, закачать апп и поставить все на видном месте?
A: Наверное, проще, но цель была другая.
Q: Прямо просятся часы, игры другие фичи. Почему не сделал?
A: Если честно, еще много чего просится. Смена фона прямо из интерфейса, к примеру. Но мне эта конструкция уже и так всю душу вынула. Сил больше никаких нет.
Q: Да за такие деньги можно целый планшет купить!
A: Я не призываю покупать Nextion.
Q: Ты вообще в курсе, что в Nextion процессор круче, чем в Arduino, которую к нему прикрутил?
A: Да, в курсе. Нет, разбираться со встроенным не собираюсь.
Самые обсуждаемые обзоры
+79 |
4269
150
|
+61 |
4440
74
|
Я понимаю, что пункт 18 надо как-то отрабатывать, но стоит ли овчинка выделки?
Мороки с этим дисплеем просто жесть.
И да, как Вы и указали, расположение шлейфа крайне неудачное.
Для красоты еще нужно колхозить тонкую накладку.
Опять же, к чести ITEAD хочу сказать, что они меня вообще не терзали — за что им большое и человеческое спасибо. Но тем не менее, необходимость сделать обзор все-таки была занозой где-то там в уголке головы.
Подводя итог — возможно, впечатления были бы более светлыми, если бы я купил экран за свои и не был бы никому ничем обязан.
Стоит ли покупать экран при всей его сырости !?
Скажем так, имеет ли место целесообразность использования данного продукта в проектах при том, что есть и альтернативные решения, хоть и менее красивые.
Здесь привлекает сам подход: вот экран, вот среда разработки. Особенно, если учесть, что интерфейс все же лучше делать в какой-то визуальной среде и еще лучше — с возможность обкатки прямо в ней, без железа. У Nextion это есть.
Если это есть у других, более доступных и грамотных решений, то, конечно, стоит выбирать их.
Интерфейс там все таки проще городить еще и к интернету можно нормально подключиться и что-то оттуда тянуть.
Может подойти для мелкосерийного производства, где цена комплектующих особого значения не имеет, но нужно продемонстрировать, что все сделано самостоятельно, а не набрано из блоков Ардуины.
А из этой приблуды уже третий год вымучивают одни метеостанции.
Обзор шикарен.
Одни из программистов, за прогу переключения 13-ти реле запросили 10т.р. В итоге сам разобрался ща пару вечеров, написал прогу, да еще и визуализировал. Мало того, разобравшись — получил возможность дополнять и улучшать систему в целом. Для технических целей идеален.
А на счет двух ардуино — у меня та же фигня. Одна обрабатывает данные с датчиков и отправляет на дисплей, другая принимает команды на переключение. Плюсы: не тормозит, не требует подборки сложных алгоритмов с циклами…
это потом уже взрослые дядьки потом переходят на всякие STM, а перед этим они гордо разводят свои платы. Но лично мне вполне хватает и навесного монтажа и той же дуни. Я бы тоже юзал этот экран, но его цена… а интерфейс, ну лично как по мне что отрисовать где-то BMP и заюзать массив кнопок с атрибутом видимости и поверх отрисовать текст… ну не стоит это дело 20 бачей. В смысле мне проще это сделать, тем более 1 раз создал макет отработок кнопок и макет отрисовки сцены и больше не варишься. Все ни как не соберусь причесать код да увести в либу подключаемую. И на выходе за 30 баксов я имею 3 экрана при чем с ардуино нано или мини в купе по одной на экран )
не так там все просто, как кажется
а такие картинки ты можеш нарисовать на андроиде в скаде
flprog.ru/forum/18-992-1
Плюс возможно, что дело не (или не только) в шлейфе. Специфика этих шлейфов такова (как мне видится), что если он где-то переломился, то надежный контакт не восстанавливается (да и ненадежный — тоже не особо). А в моем случае, если надавить — контакт надежный.
Поэтому я думаю, что привытягивании платы, вероятно, отошел контакт под самим дисплеем. Я бы проверил, но пока не имею понятия, как он разбирается. Наверное, следует начать с отжатия металлической рамки, но сначала попробую поговорить с ITEAD. Вдруг расскажут, что там можно сделать.
Однако несмотря на последнее, мне не очень симпатична идея показывать вообще все внутренности. Собственно, я вообще хотел отлить все в
гранитебетоне, но оказалось, что это тоже не очень простая задача. Один прототип корпуса сделал, ужаснулся и решил не повторять.Автору стоило купить готовое или хотя бы переделать официальный пример метеостанции.
P.S. (to admin): А спойлеры в комментариях нормально не работают? Жаль.
Кстати, спасибо за ссылку на вышеупомянутый метод — очень простое и наглядное объяснение способов выравнивания данных.
Все что есть на сайте это:
add objid, ch, val
objid: Waveform component ID
ch: Waveform component channel number
val: value (maximum 255, minimum 0)
А вот что с этим делать и как ему дать показания температуры?
p.s. Показания всегда положительные.
ch — это номер канала, в который добавляются точки. Всего на одном элементе графика может быть до 4 каналов (с номерами от 1 до 4). Т.е. грубо говоря, на одном поле рисуются до четырех кривых. Соответственно, если у вас график один, то и ch всегда 1.
А дальше отправляете показания командой вида:
add 1,1,8
Здесь первая единичка — ID элемента графика, вторая — номер кривой, а 8 — значение, которое надо отобразить.
Отправить команду в виде:
myNextion.sendCommand( add 1, 1, sensor1); и все, одна строка?
myNextion.sendCommand(add 1,1,sensor1);
А так, да — одна строка на одну точку. Соответственно, если передача показаний крутится в цикле (loop) или еще каком, то при каждом проходе через эту строку будет дорисовываться очередная точка со сдвигом всей конструкции вправо. Т.е. при таком раскладе справа будут самые старые показания, слева — самые новые. По-моему, я ничего не путаю.
int x = ds.getTempC(sensor1); //присваиваем переменной х значение температуры с сенсора 1.
myNextion.sendCommand(«add 1,1,x»);
то ничего нет, только полоса в 0-м значении… т.е. как то нужно сделать х понятным для nextion…
Так вот, судя по всему, sendCommand просто отправляет строку на экран. Строка по сути своей константа и должна быть подготовлена до отправки. Поэтому переменные в ней недопустимы, поскольку тот самый x так и остается символом x и не принимает значение переменной x.
А для графика в библиотеке Nextion существует специальная функция NexWaveform.
Опять же, если я правильно понял, то работает она следующим образом.
Сначала в секции переменных объявляем объект графика:
NexWaveform s0 = NexWaveform(0, 1, «s0»);
Зесь s0 — имя для использования в коде, «s0» уникальное имя объекта, которое можно посмотреть в свойствах графика в Nextion Editor в строке objname.
А потом в нужном месте кода можно добавлять точки следующим образом:
s0.addValue(0, x);
Здесь 0 — номер канала на графике, ну а x — значение которое нужно добавить.
Хз где найти ее, гугл не помог…
Например:
stringToNextion = String(«add 1,1,»);
stringToNextion = stringToNextion + String(x);
myNextion.sendCommand(stringToNextion);
Тоже балуюсь со всяким ардуинством и умение показывать тенденцию очень нужно…
yadi.sk/d/180zTaahWtHvtw
Редактор шрифтов для экранов Nextion (Nextion Editor)
Яндекс.диск: yadi.sk/d/gQ34YZXAjgfo3g
Например, для перехода на нулевую страницу дисплею нужно сказать:
page 0
А чтобы обновить выбранный элемент, хоть ту же страницу —
ref page0
Всё тут верно. Просто в первом случае page — это оператор, которому говорим перейди на страницу с индексом 0, можно и так page page0, если имя страницы page0
Во втором случае говорим обнови страницу с именем page0
page page0
page 0
обе рабочие)!