Fork me on GitHub

uGFX - библиотека GUI для микроконтроллеров

Когда говорят про графику для микроконтроллеров, то обычно подразумевают сравнительно небольшое количество графики низкого разрешения с минимум анимации — это обусловлено относительно высокими требованиями к быстродействию и объему ОЗУ. Если вся графика разрабатываемого устройства сводится к выводу числовой или текстовой информации, то оптимальным решением может быть использование либо сегментных, либо символьных дисплеев (например, на контроллере HD44780). Если же требуется вывод не только текстовой, но и графической информации (изображения, графики, диаграммы, анимация) и попутно обеспечить взаимодействие пользователя с устройством посредством полноценного графического интерфейса (GUI), то:

  • у микроконтроллера должно быть достаточно ресурсов — например 1Кбайт ОЗУ нужно только для кадрового буфера двухцветного дисплея 128x64, а для цветных дисплеев помножить ещё и на глубину цвета (битность изображения)

  • ввиду сложности программной части реализовывать с нуля сложный графический интерфейс далеко не оптимальное решение — куда проще и надёжней использовать проверенную графическую библиотеку, чем заново изобретать велосипед

uGFX — платформенно независимая, модульная графическая библиотека, написанная на Си и предназначенная для взаимодействия с различными типами дисплеев и сенсорными панелями во встраиваемых системах. Из коробки поддерживаются большинство современных графических контроллеров в виде готовых драйверов, а от программиста лишь требуется взять шаблон конкретного контроллера и реализовать парочку функции для обмена данными между микроконтроллером и дисплеем. У нас дисплей SSD1306, а в шаблоне board_SSD1306.h реализованы только две функции — запись данных и запись команд.

Ещё uGFX можно легко скомпилировать для настольных операционных систем (Linux, Windows, Mac OS), что весьма удобно для быстрого прототипирования графической части приложения прямо на персональном компьютере без перепрошивки микроконтроллера.

MSP430.js | исходники

screenshot

Библиотека uGFX разделена на несколько модулей, например модули GDISP, GINPUT отвечают за управление дисплеем и ввод данных из сенсорной панели / кнопок. Отключив неиспользуемые модули, можно добиться значительного снижения объема прошивки. Более того сами модули тоже можно гибко настраивать. Настройка осуществляется путем задания значений макроопределениям в конфигурационном файле gfxconf.h, который должен находиться в каждом проекте, использующем uGFX. Так, для подключения модуля GDISP конфигурационный файл должен содержать строку #define GFX_USE_GDISP TRUE. Ну а в качестве примера настроек самого модуля GDISP может быть макрос #define GDISP_NEED_STARTUP_LOGO TRUE, который отвечает за кратковременный вывод логотипа uGFX на дисплей сразу после старта программы.

Следующий пример демонстрирует работу с графическими примитивами, доступными для рисования в uGFX. Большинство API идут в паре — контур или закраска. В uGFX используется общепринятая в машинной графике декартова система координат с началом отсчета в верхнем левом углу:

main.c

#include "gfx.h"
#include <stdio.h>

static void show(delaytime_t ms) {
    gdispFlush();
    gfxSleepMilliseconds(ms);
    gdispClear(Black);
    gdispFlush();
}

int main(void) {
    // Initialize and clear the display
    gfxInit();

    const coord_t h = gdispGetHeight(), w = gdispGetWidth();

    // Рисование по пикселям
    for (coord_t x = 0; x < w; x += 3) {
        for (coord_t y = 0; y < h; y += 3) {
            gdispDrawPixel(x, y, White);
        }
    }
    show(4444);

    // кириллица
    const font_t f = gdispOpenFont("Archangelsk Regular 12");
    const char * const txt = "Все Буде Добре";
    gdispDrawString(w/2 - gdispGetStringWidth(txt, f)/2, h/4, txt, f, White);
    char str[10];
    sprintf (str, "%dx%d", w, h);
    gdispDrawString(w/2 - gdispGetStringWidth(str, f)/2, h/2, str, f, White);
    show(4444);

    while(TRUE) {
        // линии
        gdispDrawLine(3, 3, w - 3, h - 3, White);
        gdispDrawLine(w - 3, 3, 3, h - 3, White);
        gdispDrawLine(w/2, 3, w/2, h - 3, White);
        gdispDrawLine(3, h/2, w - 3, h/2, White);
        show(4444);

        // Прямоугольники
        gdispDrawBox(3, 3, 2*w/5, 2*h/5, White);
        gdispFillArea(w-2*w/5-3, h-2*h/5-3, 2*w/5, 2*h/5, White);
        gdispDrawRoundedBox(3, h-2*h/5-3, 2*w/5, 2*h/5, 10, White);
        gdispFillRoundedBox(w-2*w/5-3, 3, 2*w/5, 2*h/5, 10, White);
        show(4444);

        // Окружность, круг, эллипсы
        gdispDrawCircle(h/4, h/4, h/5, White);
        gdispDrawEllipse(w/2, h/4, w/5, h/5, White);
        gdispFillCircle(w-1-h/4, h-1-h/4, h/5, White);
        gdispFillEllipse(w-1-w/2, h-1-h/4, w/5, h/5, White);
        show(4444);

        // Дуга и сектор
        gdispFillArc(w/2, h/2, 2*h/5, 0, 90, White);
        gdispDrawArc(w/2, h/2, 2*h/5, 90, 180, White);
        gdispFillArc(w/2, h/2, 2*h/5, 180, 270, White);
        gdispDrawArc(w/2, h/2, 2*h/5, 270, 0, White);
        show(4444);

        // многоугольник (полигон)
        static const point shape[] = {
            {-GDISP_SCREEN_WIDTH/4, GDISP_SCREEN_HEIGHT/4},
            {0, 0},
            {GDISP_SCREEN_WIDTH/3, GDISP_SCREEN_HEIGHT/3},
        };
        gdispDrawPoly(w/3, 3, shape, sizeof(shape)/sizeof(shape[0]), White);
        gdispFillConvexPoly(2*w/3, h/2, shape, sizeof(shape)/sizeof(shape[0]), White);
        show(4444);
    }   
}

По выводу текста пожалуй стоит пройтись отдельно. Тут графическая библиотека uGFX предоставляет впечатляющие возможности, особенно учитывая изначальные высокие требования к производительности:

  • различные шрифты (в одной программе можно использовать несколько разных шрифтов)

  • имеется возможность добавить свой собственный шрифт

  • поддержка Unicode и стало быть кириллицы

  • сглаживание (anti-aliased)

  • кернинг (уплотнение текста за счет сдвига некоторых букв друг к другу)

  • выравнивание по левому, правому краю или посередине

  • API для расчёта длины строки с заданным шрифтом в пикселях перед выводом ее на экран

Следующий не менее интересный пример демонстрирует возможности uGFX для отображения картинок и даже анимации на базе нескольких их них на примере кота, который умеет спать, точить когти и всё такое.

MSP430.js | исходники

screenshot

В данных примерах RTOS не использовалась, однако в официальном архиве с исходниками uGFX есть достаточно различных примеров в том числе с FreeRTOS и даже Raspberry Pi с голым Linux на борту. В дополнение ко всему есть даже отдельная программка µGFX-Studio (Windows, Linux and Mac OS X) для дизайна и разработки сложных пользовательских интерфейсов для uGFX.

Comments !

links

social