Введение в векторные дисплеи

в 11:18, , рубрики: avr, векторная графика, переводы, метки:

Данная статья является переводом этой статьи.
Надеюсь мой перевод окажется не слишком топорным, а материал интересным.

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

Большинство двойных осциллографов имеют режим XY, в которых сигнал, используемый для развертки изображения по времени, заменяется входным сигналом, тем самым позволяя управлять положением луча в двух плоскостях. Использование ШИМ-а с фильтром низких частот может быть эффективно для управления яркостью светодиода, но для того, что бы рисовать сложные фигуры необходим более быстрый способ. Наиболее простым способом является использование ЦАП (цифро-аналогового преобразователя) по схеме R-2R.

Если вам интересно узнать больше о создании векторного дисплея или о том как рисовать на экране осциллографа- добро пожаловать под кат.

Параллельный ЦАП по схеме R-2R

image
Восьмибитный ЦАП прост в изотовлении, для него требуется всего 16 резисторов на канал. Желательно использовать резисторы с однопроцентным допуском, но 5%-ные тоже сгодятся. Вам нужны 7 резисторов сопротивлением R и 9 сопротивлением 2*R.
В данном случае используются резисторы на 0.5 и 1 кОм.
Принципиальная схема преобразователя:

image

Так как мы управляем двумя каналами осциллографа, то нам нужно два ЦАП-а.

Если вы не хотите паять столько деталей, то можно использовать резисторные сборки в SIP корпусах либо использовать что-то вроде MC1408/1508 (умножающий ЦАП) в 16 пиновом DIP корпусе.

В данном проекте используется плата, основанная на микроконтроллере ATMEGA32U4, вы можете использовать практически любой другой другой микроконтроллер, главное что бы в нем было свободно два 8 пиновых порта, что бы можно было изменять состояние пинов одновременно.

Я использую порты PORTD и PORTB.

Настройка осциллографа

После спайки схемы подключите ее к осциллографу и переведите его в режим X-Y.
В недорогих Rigol-ах для этого необходимо войти в меню Horizontal Menu — Time Base и выбрать режим X-Y.
К сожалению недорогие цифровые осциллографы с LCD экранами уступают аналоговым в контексте рисования, хотя некоторые и имеют режим «Цифрового фосфора», симулирующий инертность экрана.

Горизонтальные и вертикальные линии

image

Подключив ЦАП-ы непосредственно к портам микроконтроллера аналоговое напряжение может меняется путем записи значений в порт. Например, для генерации сигнала напряжением 2 Вольта значение должно быть 256 * 2.0V / 5.0V == 102.


DDRB = 0xFF;
PORTB = 102; //Значение, необходимое для генерации напряжения, равном 2 Вольта

В принципе нас не итересует конкретное значение напряжение, важно то что выходное напряжение линейно изменяется от 0 Вольт при 0x00 до 5 Вольт при 0xFF.

Осциллограф следует настроить на диапазон 0-5 Вольт и выровнять по каждой из осей.
Первое что следует попробовать это нарисовать горизонтальные и вертикальные линии, это можно сделать с помощью циклов, оставляя одну переменную неизменной. Например, при рисовании горизонтальной линии значение Y неизменно и наоборот.

void
line_vert(
uint8_t x0,
uint8_t y0,
uint8_t w
)
{
PORTB = x0;
PORTD = y0;

for (uint8_t i = 0 ; i < w ; i++)
PORTD++;
}

void
line_horiz(
uint8_t x0,
uint8_t y0,
uint8_t h
)
{
PORTB = x0;
PORTD = y0;

for (uint8_t i = 0 ; i < h ; i++)
PORTB++;
}

Код для рисования квадрата, наподобие того что на предыдущем рисунке.

line_vert(64, 64, 128);
line_vert(196, 64, 128);
line_horiz(64, 64, 128);
line_horiz(64, 196, 128);

Наклонные линии

image

Это изображение показывает распространенный артефакт векторных дисплеев: яркие точки в начале и конце линии. Этот эффект возникает потому, что интенсивность свечения точки зависит о времени, проведенного лучом в этой точке, а так как программе необходимо некоторое время для загрузки новой линии, то луч немного дольше задерживается на одном месте. Для решения этой проблемы можно использовать 16-битную арифметику или добавлять NOP-ы, что бы переключение всегда проходило за одно и тоже время.

Тут нужно сказать о выгорании экрана.

Если значения не меняются длительное время, то фосфор в этом месте может выгорать и становится другого цвета. Экраны также могут повреждается, если постоянно выводить одно и тоже изображение. Во время прошивки микроконтроллера порты обычно переключаются в Z-режим, что означает что на вход осциллографа подаются нули, что выражается в появлении яркого пятна в углу экрана.

Во время перепрошивки лучше всего снижать яркость.

Рисование наклонных линий намного сложнее чем рисование вертикальных или горизонтальных линий.
Идеальным вариантом является использование аналоговых схем для плавного изменения сигнала, как, например, это сделано в SC200.

В прочем, вместо этого мы можем использовать алгоритм Брезенхема, для разбиения линии на точки. Применение данного алгоритма вызывает появление ступенек на изображении, но это компенсируется простотой реализации.

void
line(
uint8_t x0,
uint8_t y0,
uint8_t x1,
uint8_t y1
)
{
int dx, dy, sx, sy;

if (x0 < x1)
{
dx = x1 - x0;
sx = 1;
} else {
dx = x0 - x1;
sx = -1;
}

if (y0 < y1)
{
dy = y1 - y0;
sy = 1;
} else {
dy = y0 - y1;
sy = -1;
}

int err = dx - dy;

while (1)
{
PORTB = x0;
PORTD = y0;

if (x0 == x1 && y0 == y1)
break;

int e2 = 2 * err;
if (e2 > -dy)
{
err = err - dy;
x0 += sx;
}
if (e2 < dx)
{
err = err + dx;
y0 += sy;
}
}
}

Шрифты

image

После того как мы научились рисовать линии ничто не мешает так же рисовать символы.
В качестве шрифта удобно использовать библиотеку Hershey Fonts.
В ней каждый символ состоит из менее чем 32 точек. Все координаты точек расположены относительно нижнего левого угла символа и соединены до тех пор, пока не встретится значение (-1, 1), которое означает, что нужно перепрыгнуть к следующей точке. Контур заканчивается в точке с значением(0, 0).
Пример для числа 1.

typedef struct {<h4></h4>
int8_t x, y;
} path_t;

static const PROGMEM path_t digits[][32] = {
[1] = {
{ 6,17},
{ 8,18},
{11,21},
{11, 0},

Иногда на изображении вы можете увидеть линии между двумя точками, которые не соединяются, это объясняется тем, что напряжение на ЦАП-е изменяется не мгновенно. Этот эффект можно исправить если использовать канал яркости осциллографа, к сожалению мой осциллограф не имеет такой функции.

Растровые изображения

image
С помощью осциллографа также можно отображать растровые изображения.
Изображения получаются путем преобразования картинки в формат X Bitmap посредством ImageMagick. X Bitmap это текстовый формат для представления изображений, может использоваться напрямую в исходниках.
convert -resize 256x256 input.jpg image/image.xbm
В результате появляется монохроматическое изображение, занимающее 8 килобайт памяти программы.

Видео

http://www.flickr.com/photos/osr/7925036218/
Если видеоролик не отображается, его можно найти по ссылке www.flickr.com/photos/osr/7925036218/in/set-72157631344809602/

Планы на будущее

image
В будущем я планирую восстановить замечательный ЭЛТ осцилограф и портировать Spacewar с PDP-1.

Автор: Levsha128

Источник



https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js