Возможности Arduino порой просто поражают. Когда-то у меня был компьютер «Микроша», купленный за 500 советских рублей (а это несколько тогдашних зарплат!) и при этом он не имел ни цвета, ни графики. Работал он с ч/б теликом по антенному входу. А сегодня ардуинка, ценой в пару бутылок пива, уделывает того-же «Микрошу» по всем статьям! А сколько продается периферии для нее в виде разных датчиков, дисплеев, джойстиков и т.д. — глаза разбегаются! А количество готовых библиотек в интернете для этой периферии? Похоже, есть все! А ведь тогда для «Микроши» пришлось писать и свой текстовый редактор и Ассемблер и библиотеки…
Но время идет вместе с прогрессом и теперь Arduino у меня воткнут даже в выключатель света. Я уж не говорю о дачном автополиве и других применениях этой невероятно удобной штуки. На страничках муськи я уже раньше рассказывал как научить Arduino разговаривать и играть в Тетрис на ч/б экранчике. А сегодня на очереди уже цветная графика, посмотрим, как ардуина справится с ней…
На днях, роясь в своем загашнике, нашел когда-то заказанный цветной TFT дисплейчик на 1.8" с разрешением 128x160 пикселей и SD-картоприемником. О возможностях сего девайса в связке с Arduino и будет сегодня разговор. А чтобы не было скучно от сухих цифр даташитов, напишем для этого дисплея занятную игру «Columns», что в переводе означает «Столбики». Автор идеи этой игры мне неизвестен, но она еще из тех стародавних времен, когда компьютеры были слабыми, а игры интересными. Эта игрушка динамическая, относительно ресурсоемкая, т.к. основана на цветной графике, поэтому ардуине придется сегодня выложиться по-полной. В этой игре у нас будет все, как положено — и показ следующего столбика и подсчет очков и запись рекордов в энергонезависимую память ардуины. А тем, кого игрушка заинтересовала прямо сейчас, могут скачать ее версию для Андроида в PlayMarket.
Правила игры Columns
В «Стакан» падают столбики, состоящие из 3-х цветных квадратиков. Игрок может перемещать столбик вправо и влево, а также перемещать по кругу квадратики внутри столбика. Если игроку удается выстроить цепочку из квадратиков одного цвета длиной от 4-х и более, то вся эта цепочка уничтожается, а вышестоящие квадратики проваливаются на освободившееся место. В цепочку собираются квадратики, имеющие соседей одного цвета по горизонтали и вертикали. За уничтоженные цепочки игроку начисляются очки. Задача игрока — набрать как можно больше очков.
Вкратце пройдемся по железу, которое нам понадобится. Начнем с Arduino. Я собрал схему на Arduino Uno, просто потому, чтобы не использовать дополнительных макетных плат, но подойдет и Nano и Mini Pro на Atmega 328 (Atmega 168 со стандартным загрузчиком не пойдет из-за недостатка памяти). Для других моделей Arduino придется поменять аппаратные пины SPI на свои из даташитов.
Распиновка SPI на популярные модели Arduino
Uno: MOSI соответствует вывод 11 или ICSP-4, MISO – 12 или ICSP-1, SCK – 13 или ICSP-3, SS (slave) – 10.
Mega1280 или Mega2560: MOSI — 51 или ICSP-4, MISO – 50 или ICSP-1, SCK – 52 или ICSP-3, SS (slave) – 53.
Leonardo: MOSI — ICSP-4, MISO –ICSP-1, SCK –ICSP-3.
Due: MOSI — ICSP-4, MISO –ICSP-1, SCK –ICSP-3, SS (master) – 4, 10, 52.
Теперь о дисплее. Брал я его в прошлом году на ебее, где его и сегодня предлагает тот-же продавец за $4.23.
В этом дисплее установлен популярный контроллер ST7735, который работает по SPI интерфейсу, а, поскольку аппаратный SPI в Arduino есть, можно надеяться на приличную производительность видео. На другой стороне дисплея, кроме гребенки пинов, можно увидеть картоприемник для SD карт. Конечно, куда правильнее смотрелся бы картоприемник для микро SD, уж больно много места требует вставленная SD карта. Но, видимо, когда данный дисплей начали выпускать, микро SD не были еще так популярны. Работает картоприемник по тому-же SPI интерфейсу и наличие его на дисплее неслучайно. Дело в том, что для хранения картинок с 16 битовым цветом требуется очень много места, в частности для картинки 128x160 это около 40Кб, а EEPROM память у Atmega 328 всего 1 Кб, а у 168-й вообще 512 байт. Кстати, именно по причине больших объемов картинок, они не могут быть считаны одним разом в ОЗУ и посему загружаются с SD карты в память порциями, сильно замедляя процесс вывода изображения.
Из особенностей дисплея следует отметить, что контроллер ST7735R работает с напряжением 3.3V, включая логику, но в жизни у всех прекрасно работает и на 5V без дополнительных резисторов. У меня лично дисплей работал пару суток без выключения и не сгорел. Но если кто опасается, подключайте логику через резисторы 1-2 кОм. Отдельно подключается подсветка и тут даже продавец указывает — только 3.3V! Но я подключил ее к 5V через резистор 150 Ом и все работает замечательно.
Итак, дисплей может отображать 65536 цветов в палитре R5G6B5, т.е. 5 бит для красного цвета, 6 бит для зеленого и 5 бит для голубого. Для игры нам столько не нужно, достаточно будет восьми цветов.
Если вы уже ознакомились выше с правилами игры, то поняли, что игрок должен как-то управлять перемещениями столбиков влево/вправо и цветными квадратиками внутри столбиков. В прошлый раз, в игре Тетрис, управление было реализовано посредством ИК-приемника на ардуине и ИК пульта от бытовой техники. Здесь управление тоже можно было бы реализовать так-же, но это уже было, а потому не так интересно. А вот недавно я сделал реле времени для электросушилки, где в качестве элемента управления применил энкодер KY-040, который мне очень понравился по удобству работы.
И, поскольку еще один энкодер у меня остался, я подумал — а не попробовать ли мне его прикрутить к игрушке? Все, что нужно, на нем есть. Столбик влево/вправо — поворот вала, перемещать по кругу квадратики внутри столбика — короткое нажатие, а длинным нажатием можно быстро сбрасывать столбик вниз. Забегая вперед, скажу, что управление вышло даже в чем-то удобнее джойстика или кнопок, поскольку на энкодере я могу вращать вал с разной скоростью и, соответственно, с разной скоростью перемещая столбик. На кнопках или джое такое невозможно, там или долбить кнопку с бешеной скоростью или зажав кнопку, внимательно следить за быстрым перемещением столбика, чтобы он не проскочил нужную позицию. А тут я могу, крутанув вал, за мгновение переместить столбик от одной стенки до другой, а могу его двигать медленно, по одному шагу.
Вот такое получилось интересное решение, которое мне ранее нигде не встречалось.
Ну, вот, пожалуй железок нам и хватит. Я еще подключил пьезопищалку для озвучки проваливания одноцветных цепочек, но вполне можно обойтись и без нее. Переходим к сборке и оживлению железа.
Перед тем, как начать писать игру, мне стало интересно проверить вывод изображения с SD карты. Для этого я скачал библиотеку Adafruit-ST7735, присоединил дисплей к ардуине согласно нижеприведенной таблице:
Дисплей Arduino
GND = GND
VCC = +5В
RESET = 8
A0 = 9
SDA = 11
SCK = 13
CS = 10
SCK_SD = 13
MISO = 12
MOSI = 11
CS = 6
и открыл пример из этой библиотеки «spittbitmap». В заголовке примера поменял назначенные пины на свои
вот в этих строчках:
#define TFT_CS 10 // Chip select line for TFT display
#define TFT_RST 8 // Reset line for TFT (or see below...)
#define TFT_DC 9 // Data/command line for TFT
#define SD_CS 6 // Chip select line for SD card
...
bmpDraw("333.bmp", 0, 0);
и приготовил в корне SD карты файл «333.bmp» размерами 128x160.
Изображение вывелось прекрасно, жаль только, что фото с Redmi 3S не может правильно передать цвета с TFT дисплея. На фото какая-то синюшность, хотя на деле все выглядит отлично и неотличимо от картинки выше.
На вывод картинки уходит примерно 2-3 сек — медленно конечно, в динамических играх пользоваться растровой графикой с SD карты вряд-ли получится. А вот другой пример, «graphicstest», показал, что графические примитивы из библиотеки «Adafruit_GFX.h» выводятся с довольно приличной скоростью, а это, то, что нужно для нашей игрушки.
Вкратце об используемых библиотеках. Как было упомянуто выше, для работы с контроллером в качестве драйвера была использована библиотека "Adafruit-ST7735", а в качестве библиотеки для работы с графикой "Adafruit_GFX.h". Поскольку в качестве элемента управления решено использовать энкодер KY-040, то для комфортной работы с ним, без дребезга, была подключена библиотека "Encod_er.h" и, необходимая к ней, "TimerOne.h". Данное решение отлично зарекомендовало себя ранее. Для работы с EEPROM я использовал библиотеку "EEPROM2.h".
Соединяем дисплей, энкодер и пищалку с ардуиной согласно описанию из шапки программы и можно заливать скетч игры. Если у вас ардуина другой модели, то пины аппаратного SPI нужно заменить на свои. И, поскольку озвучка использует также аппаратную реализацию ШИМ, то и пин для нее также должен иметь такую поддержку.
Об особенностях игры сейчас расскажу.
При подаче питания на ардуину, в игре включается Демо-режим, в котором наглядно показывается как уничтожаются одноцветные цепочки и начисляются очки. Стакан наполняется случайным образом сгенерированными квадратиками и затем игра вычисляет одноцветные цепочки и уничтожает их. После провала квадратиков на первом цикле возникает новая картина, в которой также могут образоваться такие цепочки и все повторяется до тех пор, пока ни одной цепочки длиннее 3-х на экране не останется. Прикольно, но хочется смотреть и смотреть на этот процесс. Помимо того, что само созерцание этого зрелища завораживает, невольно пытаешься первым обнаружить эти цепочки, еще до их уничтожения.
Теперь о начислении очков. Если игроку удалось уничтожить цепочку длиной до 7 квадратиков, то за каждый квадратик ему начисляется 1 очко. Если удалось построить цепочку длиннее, то очки удваиваются. А вот если после первого цикла уничтожения сформировались новые цепочки, то к полученным очкам второго цикла прибавятся очки первого цикла. Это сделано для того, чтобы игрок стремился не сразу проваливать короткие цепочки, а строил комбинации, чтобы потом единственным перемещением столбика уничтожать длинные цепочки и организовывать провалы в несколько циклов. Задачка, я вам скажу, нетривиальная, но очень интересная. Таким образом, в этой игре будет побеждать тот, кто сможет быстрее в уме строить многоходовые комбинации. Впрочем, изменить систему начисления очков можно в функции MyScore().
Чтобы выйти из режима Демо достаточно нажать на вал энкодера или повернуть его. В этом случае автоматически начнется игра.
#define NumCol 6 // количество цветов квадратиков. Можно изменять это число от 1 до 6. Уменьшая количество цветов, можно существенно снизить сложность игры. #define MaxLevel 8 // макс. кол-во уровней. Можно изменять от 1 до 8. Каждому уровню соответствует своя скорость падения столбиков. К этой строке напрямую относится массив: word MasSpeed[MaxLevel]={500,450,400,350,300,250,200,100}; // задержки уровней Здесь можно задать задержку падения для каждого уровня в миллисекундах. По желанию, шкалу можно сделать хоть линейной, хоть логарифмической. #define NextLevel 80 // через сколько столбиков повышать уровень. Уровень повышается, когда игроку выпало столько столбиков от предыдущего уровня. Изменяя это число, мы можем варьировать порог его повышения. flfirst=1 Изменение значения этой переменной на любое другое число от 0 до 255 обнулит рекорд, записанный в EEPROM. #define DurationOfLongPush 350 // длительность длинного нажатия. Длительность длинного нажатия в миллисекундах. Длинное нажатие срабатывает при достижении этого значения и только один раз до отпускания кнопки. Короткое нажатие срабатывает только при отпускании кнопки, если время нажатия не превысило времени длинного нажатия.
В конце обзора я, как обычно, представляю видео процесса игры, на котором можно оценить скорость отрисовки графики и плавность перемещения столбиков под управлением энкодера.
Для чего делалось? Просто интересно осваивать новое, а осваивать всегда интереснее, когда в результате получается что-то полезное. Ну, или, по крайней мере, — прикольное, но работающее! У следующего исследуемого дисплея будет уже вдвое большее разрешение и, главное, — тачскрин, осталось дождаться посылки.
Всем хорошего настроения и новых рекордов!
P.S. Если у кого возникнут вопросы по описанным тут железкам и программе, постараюсь ответить.
У следующего исследуемого дисплея будет уже вдвое большее разрешение и, главное, — тачскрин, осталось дождаться посылки.
Уже более приятный экранчик. Пользуюсь только ими. Подобная мелочь… ну слишком мелкие. 1.8 считай не разглядеть. А уж разместить там что-то полезное.
Ну то что цветные классно, но то что не читаются… ну углы обзора ни о чем. И контрастности. Вот помогал тут товарищу… так после того как вспомнил по Oled… Вышло так что по читаемости 1.3'' Oled оказался в разы бодрее 2.4'' TFT. Есть еще кста 2.8'' экранчики.
У ардуино уж очень медленный SPI для работы с цветными экранами. Я подключал точно такой же экран к STM32F0, где SPI можно разогнать на 24 МГц, там обновление всего экрана занимает менее 30 мс, и простая анимация (в пределах возможностей STM32F0 с его 8КБ памяти) работает очень плавно. С экраном 320х240 на ILI9341 уже подтормаживает, но все равно кадров 10 в секунду можно добиться.
Логично что у меги SPI медленнее. У меги тактовая 16МГц, а у STM32F0 48МГц. Максимальная частота SPI у меги Fosс/2 = 8МГц. На меге для своих поделок использовал ЧБ дисплей от Nokia 1202 за 1$. На 4МГц SPI полная заливка у меня получалась 120Гц. И весь буфер в память влезает. Сейчас еще и олед есть.
Цветные для меги это, на мой взгляд, перебор.
Цветные дисплеи на али продаются еще и с 8бит и 16бит шиной. Можно взять 8бит и STM32F103. А кому нужна максимальная плавность берут 16 бит и STM32 с FSMC.
Если не пугает 8/16 бит шина и пайка шлейфа на плату, то можно посмотреть дисплеи от мобильников в локальных магазинах. Может выйти и дешевле, чем на али.
С параллельной шиной все-таки многовато возни. Ну и кейл бесплатный только для STM32F0.
Еще, кстати, на скорость влияет адафрутовская библиотека — если заливки, вертикальные и горизонтальные линии там оптимизированы, то шрифты рисуются попиксельно с установкой координат каждый раз (а это 12 байт и 4 смены A0). Это дает возможность рисовать текст поверх фона, но если нужно весь экран заполнить текстом, то блочное рисование раза в 3 быстрее.
Боюсь на таком дисплее слабенькая ардуина сдуется окончательно
Если постоянно перерисовать весь экран, то даже на дисплее из статьи резко падает плавность перемещения столбиков. Поэтому перерисовывается только то, что изменилось. Так, что многое зависит от самой задачи и правильной программной реализации.
О постоянном перерисовывании экрана даже речи идти не может, да это и не нужно для такой задачи. Только фрагментами. Но и в этом случае 2 байта на пиксель — тяжело для ATmega. Перерисовка квадратика всего 8х8 пикселей — 128 байт, как-никак…
Имею печальный опыт цепляния TFT дисплея с тачскрином. А именно — тачскрин выдавал неправильные координаты касания, как если бы был повернут на 45 градусов по часовой стрелке, то есть два касания на одной горизонтали выдавали координаты, как будто изменилась и Х и У координата. Думал математически можно обработать и вычислить правильную координату — нет, нельзя. Две точки расположенные физически, условно говоря в координатах (4,2) и (3,3) выдавали программно одну и ту же координату. Надеюсь, понятно описал проблему. Так что очень интересно, у кого вы заказали другой экран, что за экран и чем у вас дело кончится. Держите в курсе, и дайте ссылку, какой экран заказали еще.
Заказал тут. Вроде продавец нормальный. Звание «Лучший продавец», положительных отзывов 99.4%. Но спасибо за предупреждение. Теперь сначала все проверю перед подтверждением получения. Постараюсь не забыть отписаться.
Возможности Arduino порой просто поражают. Когда-то у меня был компьютер «Микроша», купленный за 500 советских рублей (а это несколько тогдашних зарплат!) и при этом он не имел ни цвета, ни графики. Работал он с ч/б теликом по антенному входу.
Интересное сравнение скажем мягко платы продающейся в настоящее время и компьютера 80-х годов прошлого столетия, фактически начала эры компьютеризации. Сравнили бы хотя с ZX Spectrum тех же времен.
Не в тему, но ZX Spectrum тоже компютер из начала 80х прошлого века и применявшиеся в упомянутых девайсах (Микроша и Spectrum) процессоры очень близки по архитектуре и производительности. (8080 и Z80)/ Впрочем, контроллерам ATMEGA, применяемым во всевозможных ардуинах тоже не один десяток лет уже и они далеко не верх совершенства по производительности.
ATmega как-раз верх совершенства. Они не для производительности, это микроконтроллеры, нереально универсальные. В приложении автора работают с графикой как аналог ZX Spectrum на полную мощь (их еще и разогнать можно). А у меня они работают от батарейки кнопочки и потребляют 1 мкА в режиме сна, ток сравним с саморазрядом батарейки. Кому-то нужна помехоусойчивость, чтобы работал в сантиметре от разрядника, кому-то работа в жидком азоте (и работают), кому-то при +100 градусах под капотом.
Новые ревизии кстати постоянно выходят, снижают потребление в основном.
Недавно сравнительно вышел ATtiny44, на борту множество инструментов для снижения потребления…
Интересное сравнение скажем мягко платы продающейся в настоящее время и компьютера 80-х годов прошлого столетия
Да, но я сравниваю старый, но полноценный компьютер, на котором я сделал диплом и, хоть и современный, но микроконтроллер.
p.s.
Сравнили бы хотя с ZX Spectrum тех же времен
ZX у меня не было, но глянул в Вики. Проц Z80 работал на частоте 3,5 МГц. Супротив 16 у Atmega 328? Так, что… А сравнивать тогдашние цены на Spectrum и нынешние на ардуину будем? )
Микроконтроллер = микропроцессор + периферия и (иногда) память на одном кристалле. В советские времена микроконтроллеры именовали «однокристалльными микро-ЭВМ. Суть не меняется. Микроконтроллер STM32 легко эмулирует ZX-Spectrгm полностью не напрягаясь ни разу. При этом будучи размером с рублевую монету, потребляя несколько десятков миллиампер и работая на порядок быстрее спектрума, если специально не замедлять. Вдобавок ко всему, кроме питания для этого ему не надо ничего сверху. И он не менее „полноценный компьютер“, чем тот, на котором Вы сделали свой диплом (я, кстати, тоже :) )
И он не менее „полноценный компьютер“, чем тот, на котором Вы сделали свой диплом (я, кстати, тоже :) )
Если подходить формально, то, согласно Вики, различие между контроллером и компьютером кардинальное: Персона́льный компью́тер, ПК (англ. personal computer, PC), ПЭВМ (персональная электронно-вычислительная машина) — настольная микро-ЭВМ, имеющая эксплуатационные характеристики бытового прибора и универсальные функциональные возможности. Микроконтро́ллер(англ. Micro Controller Unit, MCU) — микросхема, предназначенная для управления электронными устройствами
Но в жизни грани между ними уже весьма эфемеры. Так, что я с Вами соглашусь.
Тут нельзя впрямую сравнивать тактовую частоту этих совершенно разных микропроцессоров. ATMEGA — RISC-архитектура, Z80 — CISC. То, что Z80 делает одной командой, пускай и за десяток тактов, в атмеге придется выполнять за 20 однотактовых команд. Реальная производительность будет отличаться не в разы.
В Z80 по моему даже сопроцессора нет, убран для удешевления. По сути всё одно и тоже, только Z80 в разы медленней. Плюс ATmega не числодробилка, а очень экономичный микроконтроллер, хорошо работающий от батарейки и токами в микроамперы, быстродействие просто побочный эффект технологии современной.
ТС, на вашем дисплее есть пин регулировки подсветки? Работает ли он если есть?
Просто надоело уже перебирать эти дисплеи (( сколько не брал ни на одном не работает либо без ШИМ либо нет вообще хотя заявлен.
Отдельный пин зачем? Я подсветку через резистор 150 Ом подключил к +5V. Специально, для Вас, провел эксперимент. Теперь подсветку воткнул в пин 6 и написал в setup() строчку analogWrite(6,125); Яркость уменьшилась вдвое. Пин 6 в Atmega 328 поддерживает аппаратный ШИМ. оператором analogWrite(6,x) можно изменять x от 0 до 255. Или я Вас неверно понял?
Ну то что цветные классно, но то что не читаются… ну углы обзора ни о чем. И контрастности. Вот помогал тут товарищу… так после того как вспомнил по Oled… Вышло так что по читаемости 1.3'' Oled оказался в разы бодрее 2.4'' TFT. Есть еще кста 2.8'' экранчики.
как это сделал один чел с esp8266
Цветные для меги это, на мой взгляд, перебор.
Цветные дисплеи на али продаются еще и с 8бит и 16бит шиной. Можно взять 8бит и STM32F103. А кому нужна максимальная плавность берут 16 бит и STM32 с FSMC.
Еще, кстати, на скорость влияет адафрутовская библиотека — если заливки, вертикальные и горизонтальные линии там оптимизированы, то шрифты рисуются попиксельно с установкой координат каждый раз (а это 12 байт и 4 смены A0). Это дает возможность рисовать текст поверх фона, но если нужно весь экран заполнить текстом, то блочное рисование раза в 3 быстрее.
на профильных форумах совсем ничего не нашлось?
Новые ревизии кстати постоянно выходят, снижают потребление в основном.
Недавно сравнительно вышел ATtiny44, на борту множество инструментов для снижения потребления…
p.s.
ZX у меня не было, но глянул в Вики. Проц Z80 работал на частоте 3,5 МГц. Супротив 16 у Atmega 328? Так, что… А сравнивать тогдашние цены на Spectrum и нынешние на ардуину будем? )
Персона́льный компью́тер, ПК (англ. personal computer, PC), ПЭВМ (персональная электронно-вычислительная машина) — настольная микро-ЭВМ, имеющая эксплуатационные характеристики бытового прибора и универсальные функциональные возможности.
Микроконтро́ллер(англ. Micro Controller Unit, MCU) — микросхема, предназначенная для управления электронными устройствами
Но в жизни грани между ними уже весьма эфемеры. Так, что я с Вами соглашусь.
Просто надоело уже перебирать эти дисплеи (( сколько не брал ни на одном не работает либо без ШИМ либо нет вообще хотя заявлен.