Контроллер имеет виртуальный монохромный графический дисплей с разрешением 128x64 пикселей. Дисплей может использоваться как средство визуализации в пользовательских алгоритмах.

Модуль display предоставляет функции для управления дисплеем, рисования графических примитивов и вывода текстовой информации на дисплей.

Начало координат находится в нижнем левом углу дисплея: x растёт вправо, y — вверх. Видимые координаты: x от 0 до 127, y от 0 до 63. Передавайте целые координаты и разумные размеры в пределах экрана; отрисовка отдельных пикселей за границами экрана отсекается.

Все функции рисования возвращают None. Параметры передаются позиционно; исключение — именованный step у lines.

Функции

clear

Функция clear() очищает весь текущий графический буфер. Форма clear(x, y, w, h) очищает прямоугольную область. Допустимы только 0 или 4 позиционных аргумента. Область обрезается по границам экрана, в том числе при отрицательных x/y; используйте размеры w/h в пределах 0…255.

update

Функция update(doClear=True) копирует содержимое текущего графического буфера в результирующий. Если параметр doClear установлен в True (по умолчанию), текущий буфер очищается после копирования. Если передать False или 0 позиционно, буфер очищаться не будет: update(False). Именованный вызов update(doClear=False) не поддерживается.

  from display import clear, update

update()  # Копирует и очищает буфер
# равносильно
update(False)
clear()
  

Контроллер имеет два идентичных графических буфера:

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

Алгоритм рисования на виртуальном дисплее предполагает:

  1. Очистку графического буфера с помощью clear()
  2. Рисование графических элементов
  3. Обновление результирующего буфера с помощью update()
  from display import clear, rect, update

clear()
rect(0, 0, 40, 40)
update()
  

dot

Функция dot(x, y, mode=1) рисует один пиксель с координатами (x, y). Без третьего аргумента пиксель закрашивается. Фактические режимы:

  • 1 — установить пиксель;
  • 0 — очистить пиксель;
  • INVERT (2) — инвертировать.

Особенность текущих констант: экспортируется ON=0 и OFF=1, то есть имена не совпадают с фактическим действием. Для однозначного управления используйте dot(x, y, 1) и dot(x, y, 0) либо вызов без mode.

  # Рисуем кривую изменения значения с датчика температуры
from dev import count, Ai, conv
from display import dot, clear, update, WIDTH, HEIGHT
from time import sleep
from math import isfinite

count(Ai=1)
temp = Ai(0).conf(type='ntc', access='rr')
clear()
for x in range(WIDTH):
    temperature = temp.val()  # Уже градусы Цельсия, без деления на 10
    if isfinite(temperature):
        y = int(conv(temperature, 15.0, 35.0, 0, HEIGHT - 1))
        dot(x, y)
    update(False)
    sleep(0.5)
  
  # Рисуем "белый шум"
from display import dot, clear, update, WIDTH, HEIGHT, INVERT
from random import randint

clear()
while True:
    x = randint(0, WIDTH - 1)
    y = randint(0, HEIGHT - 1)
    dot(x, y, INVERT)
    update(False)
  
Виртуальный дисплей Виртуальный дисплей

line

Функция line(x, y, w, h, step=1) рисует линию от (x, y) до (x + w, y + h). w/h — приращения, они могут быть отрицательными. Необязательный пятый аргумент step передаётся позиционно и должен быть положительным, иначе возникает ValueError.

Особенность отрисовки с step > 1: точки между шагами сейчас инвертируются, а не пропускаются. Поэтому на пустом буфере линия может выглядеть сплошной. Для обычной линии используйте step=1.

  from display import line, clear, update, WIDTH, HEIGHT
from random import randint

clear()
for _ in range(50):
    x = randint(0, WIDTH - 1)
    y = randint(0, HEIGHT - 1)
    w = randint(-WIDTH, WIDTH)
    h = randint(-HEIGHT, HEIGHT)
    line(x, y, w, h)
    update(False)
  
Виртуальный дисплей Виртуальный дисплей

lines

Функция lines(start, *increments, step=1) рисует набор линий, в котором конец каждой линии соединен с началом следующей.

  • start — координаты начала первой линии (x, y).
  • *increments — последовательность приращений (w1, h1), (w2, h2), ..., определяющих направление и длину каждой линии относительно предыдущей точки.
  • step — необязательный именованный положительный шаг с тем же поведением, что у line.

Нужны начальная точка и хотя бы одно приращение. Каждая пара — список или кортеж ровно из двух целых чисел. Неверные значения вызывают исключение; ранее нарисованные сегменты при ошибке следующей пары не отменяются.

Пример использования:

  # Рисуем параллелепипед
from dev import run
from display import clear, lines, update

def parallelepiped(x, y, w, h, d):
    lines((x, y), (w, 0), (d, h), (-w, 0), (-d, -h))

clear()
parallelepiped(0, 0, 40, 40, 10)
update()
  
Виртуальный дисплей Виртуальный дисплей

circle

Функция circle(x, y, r, mode=1) рисует окружность с центром (x, y) и неотрицательным радиусом r. Необязательный четвёртый позиционный аргумент — режим пикселя: 1 для установки, 0 для очистки, INVERT для инверсии. Используйте радиусы, соизмеримые с экраном.

  # Анимация с окружностями
from dev import run
from display import clear, circle, update, WIDTH, HEIGHT

def step(c):
    for i in range(12):
        circle(WIDTH // 2, HEIGHT // 2, i * 6 + int(c % 6))
    update()

run(step, 0.25)
  
Виртуальный дисплей Виртуальный дисплей

image

Функция image(x, y, h, data) рисует битовое изображение (bitmap), где:

  • x, y — координаты изображения (нижний левый угол).
  • h — высота изображения 1…64 пикселя.
  • data — непустой bytes или array('B') (беззнаковые байты). array('b'), другие типы array, bytearray и memoryview не принимаются этой функцией.

Координаты x/y должны помещаться в signed int16 (−32768…32767). Число байт должно быть кратно (h + 7) // 8, а вычисленная ширина — от 1 до 255. Неверная геометрия/длина вызывает ValueError, тип данных — TypeError.

Битовое изображение представляет собой массив байт, в котором каждый байт определяет отображение столбца из 8 пикселей. Например, байт 0xff закрасит все 8 пикселей, 0x01 — только первый (нижний) пиксель в столбце.

Байты идут по столбцам: сначала все байты первого столбца снизу вверх, затем следующего. Внутри байта младший бит соответствует нижнему пикселю; лишние верхние биты последнего байта столбца игнорируются. Изображение заменяет пиксели прямоугольника, включая нулевые биты.

Ширина изображения определяется автоматически: w = len(data) // ((h + 7) // 8). Например, если высота изображения не превышает 8 пикселей, его ширина равна числу байт битового изображения; если 8 < h <= 16, то w = len(data) / 2.

  from display import clear, image, update

# Пример битового изображения: простой смайлик 8x8 пикселей
smiley_data = bytes([
    0x3C,  # 00111100
    0x42,  # 01000010
    0xA5,  # 10100101
    0x81,  # 10000001
    0xA5,  # 10100101
    0x99,  # 10011001
    0x42,  # 01000010
    0x3C   # 00111100
])

clear()
image(60, 28, 8, smiley_data)
update()
  
Виртуальный дисплей Виртуальный дисплей

icon

icon(x, y, num, type=0) выводит символ из встроенного набора. Все аргументы позиционные; num — числовой индекс символа, а не строка. Три аргумента выбирают системный шрифт.

Наборы (ширина × высота): 0 — системный шрифт 5×8; 1 — Arial 19×28; 2 — Arial 9×14; 3 — иконки 11×11; 4 — иконки 15×11; 5 — иконки 15×15; 6 — иконки 6×15. Другой type также выбирает системный шрифт. Наличие символа зависит от набора; универсального списка Unicode для этих индексов нет.

  import display

display.clear()
display.icon(0, 0, 65)  # Символ A системного шрифта.
display.update()
  

text

Функция text(x: int, y: int, s: str, align: int = LEFT) выводит строку текста на дисплей.

  • x, y — координаты начала текста при align == LEFT, середины при align == CENTER или конца при align == RIGHT.
  • s — строка текста.
  • align — выравнивание текста относительно координат (x, y). Возможные значения: LEFT (по умолчанию), CENTER, RIGHT.

Текст выводится с помощью системного шрифта, каждый символ которого имеет размер 5 пикселей в ширину и 8 пикселей в высоту. Шрифт поддерживает кириллицу. Входная строка UTF-8 переводится во внутренний однобайтный буфер на 128 байт, включая завершающий ноль: выводится не более 127 преобразованных символов. Ограничение относится к этому буферу, а не к числу байт исходного UTF-8. Символы вне поддерживаемого набора не отображаются корректно. Перевод строки \n переносит вывод вниз на 9 пикселей; суммарный лимит включает все строки.

  from display import clear, text, update, CENTER, WIDTH, HEIGHT

clear()
text(WIDTH // 2, HEIGHT // 2 - 4, "Привет, мир!", CENTER)
update()
  
Виртуальный дисплей Виртуальный дисплей

rect

Функция rect(x, y, w, h, step=1) рисует контур прямоугольника. Пятый позиционный аргумент step, если задан, должен быть положительным; особенности шага такие же, как у line. Используйте положительные размеры. Аргументы:

  • x, y — координаты начала прямоугольника.
  • w, h — ширина и высота прямоугольника.

rectfull

Функция rectfull(x, y, w, h) рисует закрашенный прямоугольник. Передавайте положительные ширину и высоту.

  from display import clear, rectfull, update

clear()
rectfull(10, 10, 50, 30)
update()
  
Виртуальный дисплей Виртуальный дисплей

invert

Функция invert() инвертирует весь текущий буфер. Форма invert(x, y, w, h) инвертирует прямоугольную область. Другие количества аргументов вызывают TypeError. Используйте положительные размеры в пределах 0…255. Аргументы области:

  • x, y — координаты начала области.
  • w, h — ширина и высота области.

При инвертировании закрашенные пиксели становятся незакрашенными и наоборот.

  from display import clear, invert, update

clear()
invert(10, 10, 30, 30)
invert(20, 20, 30, 30)
update()
  
Виртуальный дисплей Виртуальный дисплей

Константы

WIDTH

Ширина дисплея. WIDTH == 128

HEIGHT

Высота дисплея. HEIGHT == 64

LEFT

Выравнивание текста по левому краю. LEFT == 0

CENTER

Выравнивание текста по центру. CENTER == 2

Выравнивание текста по правому краю. RIGHT == 1

ON

Экспортируемое значение ON == 0. В текущей реализации передача этого значения в dot/circle очищает пиксель; для закрашивания используйте 1.

OFF

Экспортируемое значение OFF == 1. В текущей реализации передача этого значения в dot/circle устанавливает пиксель; для очистки используйте 0.

INVERT

Режим инвертирования пикселя. INVERT == 2

Проверено на контроллере

Проверены circle с четвёртым аргументом, icon с тремя/четырьмя аргументами, изображения высотой 1/7/8/9/63/64, проверки длины и типа bitmap, отказ при нулевом шаге и неверных координатах lines, а также очистка области с отрицательным y. Результат очистки сверялся по 1024 байтам LCD через HTTP. Это не визуальная проверка каждого символа и каждого графического примитива.