Библиотека
Закрашенные круги
В этом руководстве речь пойдёт о реализации этих полезных мелочей. Здесь же будут продемонстрированы возможности недорогого цветного дислея, состыкованного с Raspberry Pi Pico.
Дисплей и Raspberry Pi Pico
Для того чтобы воспроизвести то, о чём я расскажу, вам понадобятся следующие комплектующие и программы:
Изображение, выведенное на дисплее
У выбранного мной дисплея имеются разъёмы, соответствующие пинам Pi Pico. Для соединения двух устройств достаточно лёгкого нажатия. Правда, не стоит нажимать на экран, давление надо прикладывать только к плате дисплея. Нужно, кроме того, правильно его ориентировать — так, чтобы джойстик находился бы с той стороны, где у Pi Pico расположен USB-разъём. Джойстик и кнопки, которыми оснащён дисплей, будут использованы в наших проектах в роли простых устройств ввода информации.
Обычно, когда рекламируют подобные дисплеи, на них выводят цветные фотографии. Наш дисплей вполне на такое способен. Снимок экрана, приведённый в начале раздела, это подтверждает. Ниже я расскажу о том, как это делается. Правда, большая часть этого материала посвящена не тому, как выводить на дисплей готовые изображения, а тому, как создавать и выводить что-то своё.
Справка по плате дисплея
Дисплей
Документацию по дисплею можно найти здесь. На неё стоит взглянуть.
Компания Waveshare предлагает пользователям пример программы с включённым в её состав драйвером дисплея, а не отдельную библиотеку для работы с дисплеем. (Мне нравится такой подход, так как он избавляет от необходимости постоянной возни с библиотеками при смене периферийных устройств).
Вот — моя, немного дополненная, версия этого примера. Она выводит линии и текст, поддерживает работу джойстика и кнопок. Драйвер — это самая важная часть программы. Его код нужно включать в состав всех программ, которые работают с дисплеем.
Теорема Пифагора
Если нарисовать в круге радиус, а так же — вертикальные и горизонтальные линии, формирующие прямоугольные треугольники, можно воспользоваться теоремой Пифагора для того чтобы найди длину стороны
Если же нарисовать лишь конечные точки линий на границе круга — получится кольцо.
Разобьём треугольник на две части горизонтальной линией. Закрасим его, двигаясь от верхнего угла вниз и от нижнего угла вверх
Рисование границ треугольника — задача очень простая. Это — всего лишь три прямых линии.
А вот рисование закрашенного треугольника — это уже гораздо более сложная задача. Подробности об этом можно почитать здесь.
Предлагаемый метод похож на тот, который мы использовали для закрашивания кругов — для закрашивания треугольника рисуют прямые линии, касающиеся его границ.
Эту задачу легче решить в том случае, если речь идёт о треугольнике, имеющем вертикальную верхнюю или нижнюю сторону. Если такой стороны у треугольника нет, то исходный треугольник можно разделить на две части горизонтальной линией и закрасить получившиеся треугольники по отдельности. Всё это звучит довольно-таки просто, но для практической реализации этого механизма нужна серьёзная математика. Правда, что хорошо, для того, чтобы пользоваться математикой, понимать её не обязательно. А именно, я создал команду, обращение к которой вызывает выполнение довольно-таки сложных действий.
Полный код можно найти здесь, а результаты работы кода показаны в видеофрагменте, приведённом в следующем разделе. В коде программы содержится несколько команд
Замедленная видеосъёмка
Эксперименты с дисплеем
Обычно я, когда покупаю и исследую новый дисплей, а потом пишу об этом, включаю в статью раздел, в котором экспериментирую с этим дисплеем (эти эксперименты я называю «Workout-примерами»). Делаю я это для того, чтобы помочь разработчикам понять, подойдёт ли он для их проектов. Вот — такой раздел для дисплея, описываемого в этом материале. Он выполняет всё то, что выполняют другие исследованные мной дисплеи. Это позволяет сравнивать скорость вывода информации и качество формируемой картинки. Здесь я использую джойстик и кнопки, вывожу тригонометрические графики и нечто вроде столбчатых диаграмм, показываю текст разных размеров, градиенты, а теперь — и круги с треугольниками.
Надеюсь, вам понравилось то, что вы видели.
Программа, в которой всё это реализовано, получилась довольно длинной — 828 строк кода. Но её удалось уложить хотя бы в такой размер только благодаря тому, что этому миниатюрному экрану не нужен огромный фрейм-буфер. Это — реальный плюс экранов, состоящих из небольшого количества пикселей, если речь идёт о необходимости работы с большими объёмами графического кода.
Из кода этой программы, там, где выводятся круги и треугольники, убраны все задержки. Её скорость меня впечатлила, но в её распоряжении имеется очень небольшой буфер для копирования данных через SPI при каждой перерисовке экрана.
Фотография, выведенная на дисплее
На предыдущем рисунке показана фотография, которую я сделал в Катманду, в храмовом центре Сваямбунатх.
В исходном виде это был .RAW-файл, сформированный фотоаппаратом Canon. Для вывода фотографии на дисплее мне понадобилось выполнить следующие действия:
Как видите, немалая часть этой работы заключается в предварительной подготовке изображения. Если вы хотите сделать что-то подобное — всё необходимое можно найти здесь.
В этом проекте использовалось следующее:
Применяете ли вы Raspberry Pi Pico в своих проектах?
framebuf
— это то, что, при разработке на MicroPython, даёт нам возможности по работе с основными графическими элементами. Например — с текстовыми символами, с прямоугольниками, да и с отдельными пикселями. Это позволяет создать множество интересных изображений. Но весьма полезно оснастить MicroPython ещё и возможность рисования закрашенных треугольников, кругов и колец.Закрашенные круги
В этом руководстве речь пойдёт о реализации этих полезных мелочей. Здесь же будут продемонстрированы возможности недорогого цветного дислея, состыкованного с Raspberry Pi Pico.
Материалы
Дисплей и Raspberry Pi Pico
Для того чтобы воспроизвести то, о чём я расскажу, вам понадобятся следующие комплектующие и программы:
- Программируемый микроконтроллер Raspberry Pi Pico.
- Цветной LCD-дисплей Waveshare разрешением 160×80 пикселей с диагональю 0,96 дюйма, выполненный в форм-факторе модуля для Raspberry Pi Pico.
- USB-кабель.
- Редактор Thonny.
Шаг 1. Дисплей
Изображение, выведенное на дисплее
У выбранного мной дисплея имеются разъёмы, соответствующие пинам Pi Pico. Для соединения двух устройств достаточно лёгкого нажатия. Правда, не стоит нажимать на экран, давление надо прикладывать только к плате дисплея. Нужно, кроме того, правильно его ориентировать — так, чтобы джойстик находился бы с той стороны, где у Pi Pico расположен USB-разъём. Джойстик и кнопки, которыми оснащён дисплей, будут использованы в наших проектах в роли простых устройств ввода информации.
Обычно, когда рекламируют подобные дисплеи, на них выводят цветные фотографии. Наш дисплей вполне на такое способен. Снимок экрана, приведённый в начале раздела, это подтверждает. Ниже я расскажу о том, как это делается. Правда, большая часть этого материала посвящена не тому, как выводить на дисплей готовые изображения, а тому, как создавать и выводить что-то своё.
Шаг 2. Изучение документации
Справка по плате дисплея
Дисплей
Документацию по дисплею можно найти здесь. На неё стоит взглянуть.
Компания Waveshare предлагает пользователям пример программы с включённым в её состав драйвером дисплея, а не отдельную библиотеку для работы с дисплеем. (Мне нравится такой подход, так как он избавляет от необходимости постоянной возни с библиотеками при смене периферийных устройств).
Вот — моя, немного дополненная, версия этого примера. Она выводит линии и текст, поддерживает работу джойстика и кнопок. Драйвер — это самая важная часть программы. Его код нужно включать в состав всех программ, которые работают с дисплеем.
Шаг 3. Рисование кругов
Теорема Пифагора
Если нарисовать в круге радиус, а так же — вертикальные и горизонтальные линии, формирующие прямоугольные треугольники, можно воспользоваться теоремой Пифагора для того чтобы найди длину стороны
a
для любого значения i
. Если нарисовать горизонтальные линии длины a
в обоих направления от вертикального диаметра — они коснутся обеих сторон круга по его границе. Рисование последовательности таких линий, для каждой пиксельной строки, позволит закрасить круг.def circle(x,y,r,c):
lcd.hline(x-r,y,r*2,c)
for i in range(1,r):
a = int(math.sqrt(r*r-i*i)) # Теорема Пифагора!
lcd.hline(x-a,y+i,a*2,c) # Нижняя половина
lcd.hline(x-a,y-i,a*2,c) # Верхняя половина
lcd.display()
utime.sleep(0.1)
Если же нарисовать лишь конечные точки линий на границе круга — получится кольцо.
def ring(x,y,r,c):
lcd.pixel(x-r,y,c)
lcd.pixel(x+r,y,c)
lcd.pixel(x,y-r,c)
lcd.pixel(x,y+r,c)
lcd.display()
utime.sleep(0.1)
for i in range(1,r):
a = int(math.sqrt(r*r-i*i)) # Теорема Пифагора
lcd.pixel(x-a,y-i,c)
lcd.pixel(x+a,y-i,c)
lcd.pixel(x-a,y+i,c)
lcd.pixel(x+a,y+i,c)
lcd.pixel(x-i,y-a,c)
lcd.pixel(x+i,y-a,c)
lcd.pixel(x-i,y+a,c)
lcd.pixel(x+i,y+a,c)
lcd.display()
utime.sleep(0.1)
Шаг 4. Треугольники
Разобьём треугольник на две части горизонтальной линией. Закрасим его, двигаясь от верхнего угла вниз и от нижнего угла вверх
Рисование границ треугольника — задача очень простая. Это — всего лишь три прямых линии.
def triangle(x1,y1,x2,y2,x3,y3,c): # Рисуем границы треугольника
lcd.line(x1,y1,x2,y2,c)
lcd.line(x2,y2,x3,y3,c)
lcd.line(x3,y3,x1,y1,c)
А вот рисование закрашенного треугольника — это уже гораздо более сложная задача. Подробности об этом можно почитать здесь.
Предлагаемый метод похож на тот, который мы использовали для закрашивания кругов — для закрашивания треугольника рисуют прямые линии, касающиеся его границ.
Эту задачу легче решить в том случае, если речь идёт о треугольнике, имеющем вертикальную верхнюю или нижнюю сторону. Если такой стороны у треугольника нет, то исходный треугольник можно разделить на две части горизонтальной линией и закрасить получившиеся треугольники по отдельности. Всё это звучит довольно-таки просто, но для практической реализации этого механизма нужна серьёзная математика. Правда, что хорошо, для того, чтобы пользоваться математикой, понимать её не обязательно. А именно, я создал команду, обращение к которой вызывает выполнение довольно-таки сложных действий.
c = colour(0,255,0)
tri_filled(x1,y1,x2,y2,x3,y3,c)
lcd.display()
Полный код можно найти здесь, а результаты работы кода показаны в видеофрагменте, приведённом в следующем разделе. В коде программы содержится несколько команд
utime.sleep(0.1)
, предназначенных для того, чтобы замедлить работу кода до такого уровня, чтобы можно было бы наблюдать за происходящим.Шаг 5. Замедленная видеосъёмка процесса вывода треугольника, круга и кольца
Замедленная видеосъёмка
Шаг 6. Эксперименты с дисплеем
Эксперименты с дисплеем
Обычно я, когда покупаю и исследую новый дисплей, а потом пишу об этом, включаю в статью раздел, в котором экспериментирую с этим дисплеем (эти эксперименты я называю «Workout-примерами»). Делаю я это для того, чтобы помочь разработчикам понять, подойдёт ли он для их проектов. Вот — такой раздел для дисплея, описываемого в этом материале. Он выполняет всё то, что выполняют другие исследованные мной дисплеи. Это позволяет сравнивать скорость вывода информации и качество формируемой картинки. Здесь я использую джойстик и кнопки, вывожу тригонометрические графики и нечто вроде столбчатых диаграмм, показываю текст разных размеров, градиенты, а теперь — и круги с треугольниками.
Надеюсь, вам понравилось то, что вы видели.
Программа, в которой всё это реализовано, получилась довольно длинной — 828 строк кода. Но её удалось уложить хотя бы в такой размер только благодаря тому, что этому миниатюрному экрану не нужен огромный фрейм-буфер. Это — реальный плюс экранов, состоящих из небольшого количества пикселей, если речь идёт о необходимости работы с большими объёмами графического кода.
Из кода этой программы, там, где выводятся круги и треугольники, убраны все задержки. Её скорость меня впечатлила, но в её распоряжении имеется очень небольшой буфер для копирования данных через SPI при каждой перерисовке экрана.
Шаг 7. Вывод фотографий
Фотография, выведенная на дисплее
На предыдущем рисунке показана фотография, которую я сделал в Катманду, в храмовом центре Сваямбунатх.
В исходном виде это был .RAW-файл, сформированный фотоаппаратом Canon. Для вывода фотографии на дисплее мне понадобилось выполнить следующие действия:
- Я преобразовал файл в формат JPG, обрезал картинку, выдержав соотношение сторон, соответствующее разрешению в 160x80 пикселей, а после этого изменил размер изображения до 160x80 пикселей. Я это делал в Photoshop, но то же самое можно сделать и в бесплатном редакторе Gimp.
- Я преобразовал файл в новый RAW-формат, где, вместо 3-байтового цвета используется 2-байтовый цвет.
- Файл был скопирован на Pi Pico с Raspberry Pi 4 с использованием
rshell
. - Изображение было выведено на экран с использованием соответствующей программы и подходящего драйвера экрана.
Как видите, немалая часть этой работы заключается в предварительной подготовке изображения. Если вы хотите сделать что-то подобное — всё необходимое можно найти здесь.
Шаг 8. Компьютерная графика основана на математике
В этом проекте использовалось следующее:
- Базовая арифметика: счёт, вычисления, работа с процентными значениями, сравнение величин.
- Теория множеств: мэппинг и маскировка битов.
- Представление чисел в разных системах счисления при работе с битами и байтами: в двоичной, шестнадцатеричной и десятичной.
- Геометрия: круги, треугольники, прямоугольники, линии, точки.
- Координатная геометрия: рисование точек и отрезков.
- Теорема Пифагора.
- Тигонометрия: радианы, синус, косинус.
- Списки и суффиксы/указатели: байтовые массивы.
- Теория вероятностей: случайные числа.
Применяете ли вы Raspberry Pi Pico в своих проектах?