В статье Текстовый VGA-модуль для микроконтроллеров я рассказывал о доработанном варианте терминала 64х30 символов. 15 цветов. Всё хорошо, сделал плату, допилил софт под себя, но текст это текст. Только символы и только 8х16. Можно конечно рисовать псевдографикой. Таблички выходят на ура. Я даже написал колхозную функцию увеличения цифр. Работает достаточно шустро:
https://www.youtube.com/watch?v=69qP4clDQeo
И что-то можно изобразить похожее на интерфейс
(данное фото сделано на тапок)
Но, черт возьми, как рисовать диагональные линии ? В принципе, если хорошенько дунуть пораскинуть мозгами, то можно из этой таблицы символов
выкинуть всё не нужное и заменить на своё. Как собственно это сделано с логотипом Microchip. (Символы с кодами с 0x80 по 0x98, выстроенные в 5 рядов по 5 символов, образуют графическое изображение логотипа Microchip.) Ну то есть взять и выкинуть например английский алфавит. Или русский. Или всякие стрелочки и параграфы с тильдами и стрелочками. Получаем кучу символов, которые можно перерисовать и сделать части окружностей, дуг, диагональные линии и.т.д. Потом наколбасить библиотеку, которая будет рисовать кривые этой псевдографикой. Но что-то это сильно пахнет адским геморроем и я начал искать варианты с графикой.
Конечно, выводить на VGA-монитор информацию средствами микроконтроллера — это жесть. Те, кто знает что для этого нужно делать и с какой скоростью, меня поймут. А тем, кто не знает, 2 варианта: 1) читать принцип формирования vga-сигналов 2) поверить на слово, что борьба идет за каждый такт.
Поиск дал неутешительные результаты. Есть разработки 800*600, но опять только текстовый режим. Есть графический цветной, но 128*96 (Черт возьми, представил себе 19″ монитор с картинкой такого разрешения). Есть какой-то мутный проект на ATmega644P якобы 640*480 256 цветов, что при 20МГц атмеге просто не реально. К этому видео отключены комментарии. Есть проект 40*30 символов и 320*240 на dsPIC33E. Кроме как побаловаться и поизобретать Dendy лично я никаких перспектив не вижу. Есть на STM32F103 проект 256×192 с 64 цветами. Тоже сега мега драйв… и еще один на этом же камне 400*200 черно-зеленый. Есть проекты на микроконтроллере STM32F4. Выход: 800х600 60 Гц, разрешение 400х300. Очень жирное железо для такой задачи, и то не справляется. И туева хуча проектов аля «тестер монитора». Это можно соорудить и на pic12f629, тупо закрасив весь экран в один цвет. Толку от такой «видеокарты» мало. Почему-то все эти проекты делают упор на сохранение многоцветности и/или использование двойной буферизации. Отсюда и расход памяти, отсюда и низкое разрешение. Конечно быстрее протолкнуть 400*300 чем 800*600. Аж в 4 раза быстрее 🙂 Нет, есть проекты даже с буфером в SDRAM и какими-то (даже углубляться не стал) микрухами с аппаратным формированием сигналов vga, но сложность этих схем, громоздкость и стоимость перечеркивают всё на корню. Кому нахрен нужен модуль вывода графики c микроконтроллера на монитор через HDMI в FullHD и 16М цветов за 158$ ? Микроконтроллер же не успеет ничего формировать. Ну сколько у вас займет чтение с SD-карты фотографии 2-3Мб на 8-и битной ардуине и проталкивание этого добра в модуль? А именно такие объемы и захочется. Иначе зачем полноцветный 1080p?
https://www.youtube.com/watch?v=wCfP_d0cwZQ
В этом плане RaspberryPi Zero и дешевле и функциональнее. Как же так ? Неужели невозможно по-простому сделать выход 640*480 с разрешением 640*480 ? Просто сделать дисплей 12864 так, чтобы он был 640480 🙂 Для ч/б варианта это 38,4кБ памяти. (видимая область). Вообще ни о чем по нынешним меркам. То есть diy-мейкеры довольствуются дисплейчиками 1602, 2004, 12864 и всякими 0.96″ OLED. Нет, ну я тоже их использую, когда это необходимо. Но только когда это необходимо и достаточно.
https://www.youtube.com/watch?v=BIzaR5FjnVo
Но это всё «синяя изолента». О проекте контроллера для сауны напишу позднее.
Вот в нем планировалось использование этих дисплеев. А как же развитие ? А как же стремление вперед ? То есть крайности какие-то. Или быстро, дешево и убого 2″, или медленно и дорого, но в полном разрешении и цветности. 21-ый век на дворе, а с ардуины мы можем максимум куда вывести изображение — это на модуль 320*240, который 5″ LCD, задействуя кучу ног. О быстродействии не буду судить, ибо даже не пытался. Причем это как минимум должна быть arduino mega на Atmega2560. Для нее шилд и делался. Младшие довольствуются вышеупомянутыми сине-белыми штуками. Есть Nextion HMI, но опять же цена. Проще купить самый дешевый планшет и забыть про микроконтроллеры, погрузившись в программирование под Андройд.
Отвлекся я сильно. Вижу что утомил 🙂 Ну так вот… Тот же самый Игорь прислал мне «в подарок» на ДР схему графического терминала 640*480 одноцветный. И код к ней!. Как знал что я мучаюсь…
Уж не знаю, его это разработка или нет, не суть, все равно большое человеческое спасибо за идею. На тот момент для меня vga конечно был темный лес, но код-то на СИ! Ух я сейчас развернусь!… и развернулся. Как обычно, прога была не доделана, но, как известно, дареному коню в зубы не смотрят 🙂 Такое чувство, что в порыве стремления к прекрасному люди просто в какой-то момент перегорают идеей и бросают. Резко и навсегда. Тут надо помнить про Леонардо да Винчи, который 12 лет губы Моны Лизы рисовал. Потому-что часто отвлекали: то сделай им водокачку, то кран подъёмный, то летать хотим… 🙂 Это наверное про теорию «80/20». Когда 80% работы делается за 20% времени. Остальные 20% работы делается за 80% времени. Но уже лень столько времени тратить ради мизерного результата по сравнению с уже сделанным. За собой тоже такое замечал, но нашел по-моему гениальный выход из этого адского круга: всеми своими проектами я занимаюсь по спирали. Перегорел одним — пошел развивать другой. Потом вернулся. Ну, например, свежая мысль пришла.
Итак, опять схема без платы… Геморрой… (то же мне, любитель всего готовенького) Ну ничего 🙂 По-быстрому наваял рисунок, сделал плату, как обычно, в духе адского минимализма.
А заодно, раз уж управление VGA-модулем подразумевается через UART, развел на плате FT232RL чтобы можно было прямо из программы-терминала посылать команды в виртуальный COM-порт. Мозг уже рисовал в воображении, что можно ведь несколько таких модулей подключить по USB и выводить на несколько мониторов информацию из своей программы на том же C#. Благо команды однобайтные и никакого труда не составит воплотить клиента на любом языке программирования.
Как-то вот так оно и подключалось: с одной стороны USB, с другой, блин… Монитор! 🙂
Сам удивляюсь как смог всё разместить на плате таких размеров. И тут понеслось… Во-первых код написан как псевдомногозадачная система. Отдельная задача на UART, отдельная задача на изменение буфера, и.т.д. А сам вывод в монитор через DMA. 2 таймера для синхронизаций и весь массив буфера строк непрерывно валится в SPI. Любое фоновое изменение массива моментально отображается на экране. Это гениально. Но мог бы и сам догадаться… наверное… сильно позже. Во-вторых в какой-то момент произошел взрыв срыв. Я удалил всё что было в коде, оставив только инициализацию переменных и DMA. А всё остальное написал заново. Ну не могу я в чужом коде копаться, особенно когда он не дописан. Точнее заточен именно на вывод текста а не графики. Текст меня как-то мало интересовал уже.
// отображение пикселя
case WORK_PUT_PIXEL:
break;
Ну как так-то ? 🙂 Это же самое главное 🙂 А если учесть что 640 это больше чем 1 байт, то для передачи координат одного пикселя нужно использовать 2 байта на X и 2 байта на Y… И писал я долго и упорно…
В итоге функция рисования линии по двум точкам стала одной функцией а не тремя. (Хотя я понимаю, это было для быстродействия). Мой код в этом нисколько не проиграл. Функцию рисования окружностей сделал по алгоритму Брезенхэма. У Этого дядьки окружности более округлые. Переписал все команды по-своему, а их там 31. Сделал рисование не только белым, но и черным. Задаваемую толщину линий. Закраску прямоугольников и окружностей. Встроил второй громадный шрифт. Запилил пропорциональное увеличение шрифта 8*16 на заданную величину множителя. Убил весь обратный вывод в UART. Не нужно ничего отвечать на команды. Просто рисуй быстрее. Одно подтверждение обработки команды тормозит вывод графики в десятки раз. Естественно добавил кольцевой буфер на 1024 байта. Конечно UART в этом смысле достаточно убогий по скорости интерфейс, но зато более универсальный. Во-первых, в микроконтроллере их может быть несколько, а во-вторых, можно и в ПК воткнуть. I2C интерфейс убил по-этой же причине. Да и в скорости он не сильно выигрывает, особенно софтварный.
Далее пошли первые тесты. (фотографировал на тапок)
Округлые окружности
Прямоугольнички
А дальше пошел писать библиотеку для ардуино. В этом плане всё проще. Берем стандартный класс SoftwareSerial и наследуемся от него, добавляя свои функции.
#include "VgaSoftwareSerial.h"
VgaSoftwareSerial::VgaSoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false): SoftwareSerial(receivePin, transmitPin, inverse_logic = false) {}
Можно конечно юзать и HardwareSerial, но их в ардуине гораздо меньше чем SoftwareSerial 🙂 Cофтовый UART спокойно работает на 115200 и в arduino nano (Atmega328) и в arduino pro micro (Atmega32u).
class VgaSoftwareSerial : public SoftwareSerial {
public:
VgaSoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
void cls(void);
void pixel(int x1, int y1, uint8_t color);
void setcolor(uint8_t color);
void setcursor(uint8_t x1, uint8_t y1);
void line(int x1, int y1, int x2, int y2, uint8_t color);
void rectangle(int x1, int y1, int x2, int y2, uint8_t color, uint8_t filling);
void circle(int x1, int y1, uint8_t color, uint8_t radius, uint8_t filling);
int version(void);
private:
};
Собственно всё рисование сводится к последовательной подаче байт в UART.
Пиксель:
void VgaSoftwareSerial::pixel(int x1, int y1, uint8_t color)
{
uint8_t buf[] = {0x11, // команда установки X1 Lo
x1, // значение X1 Lo
0x10, // команда установки X1 Hi
x1 >> 8, // значение X1 Hi
0x13, // команда установки Y1 Lo
y1, // значение Y1 Lo
0x12, // команда установки Y1 Hi
y1 >> 8, // значение Y1 Hi
0x03, // команда установки цвета пикселя
color, // значение цвета пикселя
0x0A // команда рисования пикселя
};
VgaSoftwareSerial::write(buf, 11);
}
А так рисуется линия:
void VgaSoftwareSerial::line(int x1, int y1, int x2, int y2, uint8_t color)
{
uint8_t buf[] = {0x11, x1, 0x10, x1 >> 8, 0x13, y1, 0x12, y1 >> 8, 0x15, x2, 0x14, x2 >> 8, 0x17, y2, 0x16, y2 >> 8, 0x03, color, 0x0B};
VgaSoftwareSerial::write(buf, 19);
}
В самом скетче всё еще проще:
#include "VgaSoftwareSerial.h"
VgaSoftwareSerial MonitorOne(8, 9);
VgaSoftwareSerial MonitorTwo(10, 11);
MonitorOne.pixel(320, 240, 1);
MonitorTwo.pixel(320, 240, 1);
И на обоих мониторах рисуется точка по центру.
Обкатанные платы были заново отрисованы в DipTrace и отправлены на завод.
https://www.youtube.com/watch?v=1Zhp9OwLn7M
Изменилась схема питания. Применен прекраснейший DC-DC преобразователь LM3671MF. Платы стали еще меньше.
И это, на минуточку, PIC32. Расту над собой 🙂
Такими же нехитрыми командами был наколбашен тест всего что есть в модуле.
https://www.youtube.com/watch?v=0ttAb0A4_i0
В дальнейшем использовал сей девайс для отрисовки приборной панели для второй версии автомобильчика.
https://www.youtube.com/watch?v=6UwqeKBoYpA
Ну и 3D до кучи:
Данный VGA-модуль доступен в 4х вариантах исполнения и вы можете его приобрести в соответствующем разделе.
Буду рад вопросам и комментариям. Еще больше буду рад рационализаторским предложениям.
Добрый день,
отличное решение, но цена слишком велика для железа подобного типа.
т.е. я не имю ввиду, что Вы задорого продаете, а скорее, что подобный шилдик должен стоить 500-600 руб. и это самый максимум.
Честно говоря, когда пошел посмотреть цену так и думал руб. 600, но за 1700… я подожду распродаж 😜, или дед мороза.
Готов продать дешевле. Если найдете аналогичный товар дешевле.
Исходные данные для поиска: графический, одноцветный, 640х480
Вы мне ссылку — я вам цену ниже того, что вы найдете.
Согласен с предыдущим человеком, очень дорого. Рублей 500-600 адекватная цена, прибыль количеством возьмете.
bubastic правильно говорит. Нельзя быть таким жадиной))
Лично я черно белую графику и за 500 не купил бы)
Для вывода какой никакой цветной информации на VGA дисплей подойдет проект из двух ардуино nano за 300 рублей на все про все.
https://habr.com/ru/post/348380/
https://www.instructables.com/id/Arduino-Basic-PC-With-VGA-Output/
А если более серьезно подойти к вашей теме то самый разумный вариант купить
ESP32 за те же 300 рублей
и получить разрешение пусть и 640×350 но зато 8 цветов!
Только посмотрите какая красота всего за 300 рублей!
https://www.youtube.com/watch?v=TRQcIiWQCJw
И все это даром позволяет библиотека FabGL посмотрите сколько всего интересного и не нужно никакие 1400-1700 рублей.
http://www.fabglib.org/index.html
И Глеб правильно говорит, лучше брать количеством, это лучше чем ничего или мало 🙂
Повторюсь, если вам нужен vga-адаптер 20х10 символов — делайте его на ардуино.
Если вам нужен 640*200 и 8 цветов — берите ESP32 и делайте на ней.
Как только у вас будет коммерческий проект а не просто поиграться и забыть —
берите stm32 или pic32 и делаете самостоятельно 640*480. Это будет качественнее
чем тормозные 320*240 глубенькие дисплеи.
Простите, не готов продавать за 500р железку, в которой только МК стоит 400.
Если кто-то готов за 100р работать — позвоните мне. Я вам дам работу.
Здравствуйте.Очень понравилась Ваша отктовенность.100% с Вами согласен.
Обидно когда критикуют своими фонтазиями а не реальной разработанной рабочей конструкцией.Очень возмутили коментарии.
Я простой пенсионер,немного на асм-е програмирую pic16F,только для себя
Я не занимаюсь комерцией.
Извините ,отнял Ваше время на пустое отступление.
Главное У меня появилась идея куда применить устаревшие мониторы благодаря Вашей разрабтке.т.е. добавить затраты 3,5 евро и уверен девайс пойдет на ура.
У меня рабочий образец на фото и видео ,если Вас заинтересует все покажу
Надеюсь на ответ и сотрудничество
С уважением Михаил
Мне всегда всё интересно из тем, в которых вращаюсь 🙂
Здравствуйте.
По некоторым обстоятельствам не видел Ваш ответ.Спасибо.Очень хотелось бы продолжить общение но не в комент-ах.Как Вам переслать видео или фото?
С уважением Михаил
Добрый день.
В почту, в месссенджеры.
Попытался все это добро запустить на esp-wroom-32 и не очень то это получилось!
Хорошо конечно хоть что то отражает на экране, значит платка работает, но
библиотека SoftwareSerial тут (под ESP32) видимо не такая т.к. последний параметр пришлось выпилить, а без него видимо на экран получаем чушь.
Под капот пока сильно не лез, но видимо придется, хочется задействовать данный девайс!