RSS блога
Подписка
Бюджетная графика для Ардуино. Пишем Тетрис для дисплея Nokia 5110.
- Цена: $1.89
- Перейти в магазин
Собирая устройства на Ардуино, мы часто сталкиваемся с необходимостью автономного вывода информации. И, как всегда, хочется чтобы решение было недорогим. И вот тут оказывается, что из недорогих устройств выбор не очень-то и богат.
Если выводимой инфы немного, удобно использовать семисегментные индикаторы. Они очень яркие и контрастные. Такие линейки из 4-х разрядов высотой в 0.36 дюйма на TM1637 продаются по 70 центов и управляются всего по 2-м пинам. Как нетрудно догадаться, заточены они, в основном, под отображение времени, хотя без труда могут отображать и, к примеру, температуру, давление и другие параметры, для которых достаточно 4-х разрядов.
Но если выводимой информации много, они не подойдут. В таких случаях чаще всего используются «народные» LCD 1602 дисплейчики, имеющие возможность вывода 2-х строк по 16 символов ценой в полтора бакса. На такой уже можно вывести информации в разы больше.
Его более продвинутый 4-х строчный собрат выведет инфы еще больше, но стоит уже заметно дороже, около 5 долларов, да и размер у него уже немаленький.
У всех этих устройств имеются свои плюсы и минусы. Из главных минусов можно отметить отсутствие поддержки русского языка, поскольку кодовая таблица зашита наглухо в микросхему, и невозможность вывода графики. Строго говоря, прошивка кириллицы в подобных устройствах бывает, но такие продаются в основном в России и по неразумным ценам.
Если эти минусы являются для применения в создаваемом устройстве решающими и разрешение в 84x48 точек в черно-белой графике вас устроит, то стоит обратить внимание на дисплейчик Nokia 5110. Когда-то обзор на него был, но очень неполный, и местами устаревший. В частности там утверждалось о невозможности отображения кириллицы. На сегодня такой проблемы нет.
Герой нашего обзора, ценой менее пары баксов, ко мне пришел в прочной картонной коробке с защитной пленкой на экране, за что большое спасибо продавцу. Девайс имеет размеры печатной платы 45x45 мм красного текстолита и экран ЖК с разрешением 84x48 точек и размером 40x25 мм. Вес устройства 15 г. У него есть подсветка голубого цвета, которую можно отключить. У Ардуино этот дисплей откусит 5 цифровых пинов, не считая питания. На плате есть 2 ряда выводов, которые запараллелены между собой, поэтому можно использовать всего один ряд. Из них 5 – это управление, 2 питание и один на включение подсветки. Для включения подсветки нужно пин LIGHT замкнуть на землю (встречается другой вариант этого дисплея, как пишут — на плате синего цвета, где этот пин соединяется с питанием). Плата приходит нераспаянной, две гребенки прилагаются в комплекте.
Итак, подсоединяем выводы SCLK, DIN, DC, CE и RTS к пинам Ардуино, например, 3, 4, 5, 6, 7. Пин VCC к 3.3V (Именно 3.3, а не 5!), подсоединяем землю и качаем библиотеку Adafruit GFX Library.
Функции из этой библиотеки позволяют выводить графические примитивы (линия, круг, прямоугольник и т.д.), растровые картинки и текст. В составе библиотеки есть пример, показывающий ее возможности, советую посмотреть. А вот, чтобы текст выводился на русском, придется подшаманить фонт. Но, к счастью, добрые люди все уже сделали за нас и файл для подмены можно скачать с этой странички.
Пример скетча я дам далее, а результат вывода текста на русском видим выше. Нетрудно подсчитать, что на самом маленьком размере шрифта (№ 1), можно вывести 84 символа (по 14 в 6 строк), чего вполне хватит для вывода, например, емких диагностических сообщений. Шрифт №2 вдвое крупнее.
Разрешение экрана позволяет выводить довольно неплохие растровые двухцветные картинки, которые в программе можно использовать в качестве иконок.
Создавать такие иконки очень просто. Под спойлером я покажу, как это делается.
Теперь отключим подсветку и посмотрим, как изображения будут выглядеть без нее.
Как видим, и текст и значки читаются хорошо. Причем, чем ярче свет, тем лучше читабельность (эх, вспоминаю как было приятно пользоваться Nokia 1100 солнечным днем, в то время, как народ прятал свои трубки с цветными матрицами в тень, чтобы набрать номер). В общем, в таком режиме можно использовать дисплей, если освещения хватает или подсветка мешает или для экономии автономного питания. Если у кого изображение на экранчике будет плохо видно, поиграйтесь с контрастностью в скетче. Лучшая контрастность при подсветке и без нее получается при разных значениях, это надо учитывать.
Ну, и, поскольку Ардуино (Процессор+Озу+Загрузчик-BIOS)+накопитель (EEPROM) + система ввода-вывода (Пульт IRDA и Nokia 5110)- это, по сути, полноценный компьютер, то почему бы не написать для него полноценной игры? Конечно, игру типа ГТА наш ардуино-комп не потянет, но простую казуальную игрушку — запросто! Напишем игру всех времен и народов — Тетрис.
Для любого программиста — это как утренняя зарядка, легкое упражение для мозга, поэтому — вперед! Да и на муське вроде такого раньше еще не было. А в игре как раз раскроется потенциал сабжа.
В качестве системы ввода я решил использовать IRDA пульт от ЛЮБОГО устройства. При таком решении нам понадобится всего лишь один IR приемник, ценой 4 руб за штуку. А IR пульт найдется в любой квартире. Для озвучки мы еще применим пьезопищалку от старой материнки — это будет наш бюджетный аналог мультимедиа )). Ко мне едет сейчас более крутой вариант, но это уже удорожание нашего суперкомпа на целый доллар! Пока обойдемся. С ним будет уже другая история.
На макетке коммутируем устройства вывода, ввода и нашу «мультмедиа». Получилось так:
Я использовал Arduino Uno, поскольку там нужные нам 3.3V уже есть, но если использовать Mini, то придется для экрана добыть из 5 вольт нужные 3.3. Самый несложный способ из инета — поставить последовательно два кремниевых диода (подобрать).
Чтобы не рисовать электрическую схему, просто укажу задействованные мной пины Ардуино.
Подсоединение дисплея Nokia 5110:
pin 3 — Serial clock out (SCLK)
pin 4 — Serial data out (DIN)
pin 5 — Data/Command select (D/C)
pin 6 — LCD chip select (CS)
pin 7 — LCD reset (RST)
Для подсветки пин LIGHT дисплея кидаем на GND Ардуино. (Только для платы красного цвета!). Плюс питания на 3.3V. Земля на GND.
Подсоединение IR приемника:
pin 8 — IR (управляющий). Питание на +5V и GND соответственно.
Подсоединение пьезопищалки:
pin 9 — speaker, Земля на GND.
После монтажа, заливаем скетч
И можно ирать. Игра поддерживает привязку к любому пульту. Для этого достаточно в начале игры, на вопрос «Нажмите ОК» нажать на пульте кнопку, которая будет отвечать за вращение фигуры. Если пульт игре уже знакомый, то игра сразу запустится. Если пульт новый, то код кнопки ОК не совпадет с запомненным и игра потребует последовательно нажать кнопки «Влево», «Вправо» и «Вниз». Эти кнопки будут записаны в энергонезависимую память Ардуино и впоследствии именно этот пульт будет узнаваться сразу по нажатию кнопки «ОК».
При «проваливании» на собранную строку будет воспроизводиться писк. Он реализован на особенности нескольких пинов Ардуино (в нашем случае 9) выдавать ШИМ с заданной частотой.
Игра поддерживает все атрибуты нормальной игры. Ту и подсказка следующей фигуры и текущий счет. Игра ведет учет рекордов. Это значение хранится в энергонезависимой памяти Ардуино. Чтобы сбросить рекорд, достаточно изменить в скетче значение flfirst=1234 на любое другое. В игре также идет автоувеличение скорости падения через каждые 30 списанных строчек, так что, бесконечно долго поиграть не получится ). Скетч не оптимизировался и тщательно не прогонялся, а был написан на досуге в свое удовольствие. Если кто обнаружит ошибку — пишите. О ©. Скетч разрешается править для себя как угодно. Только при публикации где-либо своих вариантов ссылку на первоисточник-муську указывайте ).
Для чего делал — длинные выходные + «из любви к искусству». Была бы дочка маленькой, сделал бы ей, наверное, мини игровой автомат для кукольной комнатки на 8 марта, как раз успел бы. Добавил бы несколько игр типа Змейки и Арканоида, а корпус вырезал бы из текстолита, наверное. Только дочка в этом году уже докторскую защищает, так, что мимо, но может кому еще эта идея пригодится ).
Подведем итог для дисплея Nokia 5110:
Плюсы
+Возможность вывода графики;
+Отсутствие проблем с кириллицей;
+Небольшой вес;
+Отличное соотношение габариты/кол-во выводимой информации;
+Плюсы примененной технологии ЖК — малое энергопотребление и хорошая читабельность на ярком свете;
+Отключаемая подсветка;
+Цена.
Минусы
-Подсветка неравномерная;
-Изображение черно-белое (оттенков нет);
-Необходимость позаботиться о 3.3V, не на каждой Ардуино такое напряжение есть.
Вердикт: За свои деньги по совокупности характеристик уверено занимает свою нишу, недаром и является таким долгожителем среди устройств отображения для Ардуино.
Upd: добавлена озвучка Тетриса на mp3 модуле
Если выводимой инфы немного, удобно использовать семисегментные индикаторы. Они очень яркие и контрастные. Такие линейки из 4-х разрядов высотой в 0.36 дюйма на TM1637 продаются по 70 центов и управляются всего по 2-м пинам. Как нетрудно догадаться, заточены они, в основном, под отображение времени, хотя без труда могут отображать и, к примеру, температуру, давление и другие параметры, для которых достаточно 4-х разрядов.
Но если выводимой информации много, они не подойдут. В таких случаях чаще всего используются «народные» LCD 1602 дисплейчики, имеющие возможность вывода 2-х строк по 16 символов ценой в полтора бакса. На такой уже можно вывести информации в разы больше.
Его более продвинутый 4-х строчный собрат выведет инфы еще больше, но стоит уже заметно дороже, около 5 долларов, да и размер у него уже немаленький.
У всех этих устройств имеются свои плюсы и минусы. Из главных минусов можно отметить отсутствие поддержки русского языка, поскольку кодовая таблица зашита наглухо в микросхему, и невозможность вывода графики. Строго говоря, прошивка кириллицы в подобных устройствах бывает, но такие продаются в основном в России и по неразумным ценам.
Если эти минусы являются для применения в создаваемом устройстве решающими и разрешение в 84x48 точек в черно-белой графике вас устроит, то стоит обратить внимание на дисплейчик Nokia 5110. Когда-то обзор на него был, но очень неполный, и местами устаревший. В частности там утверждалось о невозможности отображения кириллицы. На сегодня такой проблемы нет.
Герой нашего обзора, ценой менее пары баксов, ко мне пришел в прочной картонной коробке с защитной пленкой на экране, за что большое спасибо продавцу. Девайс имеет размеры печатной платы 45x45 мм красного текстолита и экран ЖК с разрешением 84x48 точек и размером 40x25 мм. Вес устройства 15 г. У него есть подсветка голубого цвета, которую можно отключить. У Ардуино этот дисплей откусит 5 цифровых пинов, не считая питания. На плате есть 2 ряда выводов, которые запараллелены между собой, поэтому можно использовать всего один ряд. Из них 5 – это управление, 2 питание и один на включение подсветки. Для включения подсветки нужно пин LIGHT замкнуть на землю (встречается другой вариант этого дисплея, как пишут — на плате синего цвета, где этот пин соединяется с питанием). Плата приходит нераспаянной, две гребенки прилагаются в комплекте.
Итак, подсоединяем выводы SCLK, DIN, DC, CE и RTS к пинам Ардуино, например, 3, 4, 5, 6, 7. Пин VCC к 3.3V (Именно 3.3, а не 5!), подсоединяем землю и качаем библиотеку Adafruit GFX Library.
Функции из этой библиотеки позволяют выводить графические примитивы (линия, круг, прямоугольник и т.д.), растровые картинки и текст. В составе библиотеки есть пример, показывающий ее возможности, советую посмотреть. А вот, чтобы текст выводился на русском, придется подшаманить фонт. Но, к счастью, добрые люди все уже сделали за нас и файл для подмены можно скачать с этой странички.
Пример скетча я дам далее, а результат вывода текста на русском видим выше. Нетрудно подсчитать, что на самом маленьком размере шрифта (№ 1), можно вывести 84 символа (по 14 в 6 строк), чего вполне хватит для вывода, например, емких диагностических сообщений. Шрифт №2 вдвое крупнее.
Разрешение экрана позволяет выводить довольно неплохие растровые двухцветные картинки, которые в программе можно использовать в качестве иконок.
Создавать такие иконки очень просто. Под спойлером я покажу, как это делается.
Как быстро создать растровую картинку на примере логотипа сайта MYSKU
Для начала сделаем скрин экрана с логотипом (клавиша Print Screen).
Запустим Paint из стандартных программ и жмем Ctrl+V. Весь экран с логотипом в нашем распоряжении.
Выделяем нужный фрагмент и жмем кнопку ОБРЕЗАТЬ. Получим наш фрагмент.
Теперь нам нужно превратить этот фрагмент в двухцветный. С эти справится сам Paint. Жмем «Сохранить как» и выбираем тип «Монохромный риcунок (*.bmp)». Не обращаем внимания на предупреждение редактора и жмем Ок и видим такую картинку:
Теперь нужно превратить этот набор пикселей в массив кодов для Ардуино. Я нашел онлайн редактор, который справляется с такой задачей.
Ему на вход нужно подать bmp файл, но обязательно 256 цветный! Поэтому мы снова жмем «Сохранить как» и выберем тип «256-цветный рисунок bmp». Теперь запомним размеры сторон получившегося файла, их будет нужно указать в скетче (смотрим или в Paint внизу в строке состояния или открыв Свойства файла — > вкладка Подробно) и перейдем в онлайн конвертер.
Выберем наш файл, поставим галочку на шестнадцатеричных числах и нажмем КОНВЕРТИРОВАТЬ.
Получим нужный нам массив:
Копируем этот массив в скетч, компилируем и смотрим, что получилось.
Запустим Paint из стандартных программ и жмем Ctrl+V. Весь экран с логотипом в нашем распоряжении.
Выделяем нужный фрагмент и жмем кнопку ОБРЕЗАТЬ. Получим наш фрагмент.
Теперь нам нужно превратить этот фрагмент в двухцветный. С эти справится сам Paint. Жмем «Сохранить как» и выбираем тип «Монохромный риcунок (*.bmp)». Не обращаем внимания на предупреждение редактора и жмем Ок и видим такую картинку:
Теперь нужно превратить этот набор пикселей в массив кодов для Ардуино. Я нашел онлайн редактор, который справляется с такой задачей.
Ему на вход нужно подать bmp файл, но обязательно 256 цветный! Поэтому мы снова жмем «Сохранить как» и выберем тип «256-цветный рисунок bmp». Теперь запомним размеры сторон получившегося файла, их будет нужно указать в скетче (смотрим или в Paint внизу в строке состояния или открыв Свойства файла — > вкладка Подробно) и перейдем в онлайн конвертер.
Выберем наш файл, поставим галочку на шестнадцатеричных числах и нажмем КОНВЕРТИРОВАТЬ.
Получим нужный нам массив:
Копируем этот массив в скетч, компилируем и смотрим, что получилось.
Теперь отключим подсветку и посмотрим, как изображения будут выглядеть без нее.
Как видим, и текст и значки читаются хорошо. Причем, чем ярче свет, тем лучше читабельность (эх, вспоминаю как было приятно пользоваться Nokia 1100 солнечным днем, в то время, как народ прятал свои трубки с цветными матрицами в тень, чтобы набрать номер). В общем, в таком режиме можно использовать дисплей, если освещения хватает или подсветка мешает или для экономии автономного питания. Если у кого изображение на экранчике будет плохо видно, поиграйтесь с контрастностью в скетче. Лучшая контрастность при подсветке и без нее получается при разных значениях, это надо учитывать.
Пример скетча для вывода текста и картинки
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// pin 3 - Serial clock out (SCLK)
// pin 4 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 6 - LCD chip select (CS)
// pin 7 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);
const static unsigned char PROGMEM ku59x39[] =
{
0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xc0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
0xe0, 0x1f, 0xff, 0xff, 0xe0, 0x0, 0x3, 0xf0,
0xfc, 0xf, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0,
0xff, 0x87, 0xff, 0xc0, 0x0, 0x0, 0x7f, 0xc0,
0xff, 0xe3, 0xff, 0x0, 0x0, 0x7f, 0xff, 0x90,
0xff, 0xf1, 0xfc, 0x0, 0x7, 0xff, 0xff, 0x30,
0xff, 0xf8, 0xf0, 0x0, 0x7f, 0xff, 0xfe, 0x30,
0xff, 0xfc, 0x40, 0x3, 0xff, 0xff, 0xfc, 0x70,
0xff, 0xfe, 0x0, 0xf, 0xff, 0xff, 0xf8, 0xf0,
0xff, 0xff, 0x0, 0x7f, 0xff, 0xff, 0xf0, 0xf0,
0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xe1, 0xf0,
0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xe3, 0xf0,
0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xc3, 0xf0,
0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0x83, 0xf0,
0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0x87, 0xf0,
0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0x87, 0xf0,
0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0x87, 0xf0,
0xff, 0xff, 0xf8, 0x7f, 0xff, 0x1f, 0x87, 0xf0,
0xff, 0xff, 0xf8, 0x7f, 0x0, 0x0, 0x7, 0xf0,
0xff, 0xff, 0xfc, 0x38, 0x0, 0x0, 0x1, 0xf0,
0xff, 0xff, 0xfc, 0x20, 0x0, 0x0, 0xbf, 0xf0,
0xff, 0xff, 0xfe, 0x0, 0x3, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xfe, 0x0, 0x3f, 0xe1, 0xff, 0xf0,
0xff, 0xff, 0xfe, 0x3, 0xf0, 0x0, 0x1, 0xf0,
0xff, 0xff, 0xfe, 0xf, 0x80, 0x0, 0x0, 0xf0,
0xff, 0xff, 0xff, 0xe, 0x0, 0x3f, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xc, 0x3, 0xff, 0xe1, 0xf0,
0xff, 0xff, 0xff, 0x0, 0x1f, 0xff, 0xc0, 0xf0,
0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0x88, 0xf0,
0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0x9c, 0xf0,
0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0x38, 0xf0,
0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0x19, 0xf0,
0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0x3, 0xf0,
0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0x87, 0xf0,
0xff, 0xff, 0xff, 0xce, 0x7f, 0xff, 0xdf, 0xf0,
0xff, 0xff, 0xff, 0xce, 0x7f, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0x9e, 0x7f, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0x8c, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xf0,
0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xf0
};
void setup() {
display.begin();
display.setContrast(50);
display.setTextSize(1);
display.setTextColor(BLACK); // установка цвета текста
}
void loop() {
display.clearDisplay();
display.drawBitmap(10, 5, ku59x39, 59, 39, BLACK);
display.display();
delay(2000);
display.clearDisplay();
display.setCursor(0,0);
display.print("ЗРС способна поражать не только баллистические, но и аэродинамические цели - самолеты");
display.display();
delay(2000);
}
Ну, и, поскольку Ардуино (Процессор+Озу+Загрузчик-BIOS)+накопитель (EEPROM) + система ввода-вывода (Пульт IRDA и Nokia 5110)- это, по сути, полноценный компьютер, то почему бы не написать для него полноценной игры? Конечно, игру типа ГТА наш ардуино-комп не потянет, но простую казуальную игрушку — запросто! Напишем игру всех времен и народов — Тетрис.
Для любого программиста — это как утренняя зарядка, легкое упражение для мозга, поэтому — вперед! Да и на муське вроде такого раньше еще не было. А в игре как раз раскроется потенциал сабжа.
В качестве системы ввода я решил использовать IRDA пульт от ЛЮБОГО устройства. При таком решении нам понадобится всего лишь один IR приемник, ценой 4 руб за штуку. А IR пульт найдется в любой квартире. Для озвучки мы еще применим пьезопищалку от старой материнки — это будет наш бюджетный аналог мультимедиа )). Ко мне едет сейчас более крутой вариант, но это уже удорожание нашего суперкомпа на целый доллар! Пока обойдемся. С ним будет уже другая история.
На макетке коммутируем устройства вывода, ввода и нашу «мультмедиа». Получилось так:
Я использовал Arduino Uno, поскольку там нужные нам 3.3V уже есть, но если использовать Mini, то придется для экрана добыть из 5 вольт нужные 3.3. Самый несложный способ из инета — поставить последовательно два кремниевых диода (подобрать).
Чтобы не рисовать электрическую схему, просто укажу задействованные мной пины Ардуино.
Подсоединение дисплея Nokia 5110:
pin 3 — Serial clock out (SCLK)
pin 4 — Serial data out (DIN)
pin 5 — Data/Command select (D/C)
pin 6 — LCD chip select (CS)
pin 7 — LCD reset (RST)
Для подсветки пин LIGHT дисплея кидаем на GND Ардуино. (Только для платы красного цвета!). Плюс питания на 3.3V. Земля на GND.
Подсоединение IR приемника:
pin 8 — IR (управляющий). Питание на +5V и GND соответственно.
Подсоединение пьезопищалки:
pin 9 — speaker, Земля на GND.
После монтажа, заливаем скетч
Скетч игры Тетрис
//// © Klop 2017
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <IRremote.h>
#include <EEPROM2.h>
#define rk 4 // ширина квадратика
#define rz 5 // ширина места
#define smeX 1
#define smeY 1
#define MaxX 10 // стакан кол-во мест по гориз
#define speaker 9
#define RECV_PIN 8 // нога на IRDA приемник
// pin 3 - Serial clock out (SCLK)
// pin 4 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 6 - LCD chip select (CS)
// pin 7 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);
IRrecv irrecv(RECV_PIN);
decode_results results;
byte mstacan[MaxX][30];
byte Lst,SmeH, center, NumNext;
byte MaxY; // стакан кол-во мест по вертик
int dxx, dyy, FigX, FigY, Victory, myspeed,tempspeed;
unsigned long ok, levo, pravo, vniz, myrecord;
unsigned long flfirst=1234; // метка первого запуска
byte fig[][4][4]=
{
{{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}},
{{0,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,1,0,0}},
{{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}},
{{0,1,0,0},
{0,1,1,0},
{0,0,1,0},
{0,0,0,0}},
{{0,1,0,0},
{0,1,0,0},
{0,1,1,0},
{0,0,0,0}},
{{0,1,0,0},
{0,1,1,0},
{0,1,0,0},
{0,0,0,0}},
{{0,0,1,0},
{0,1,1,0},
{0,1,0,0},
{0,0,0,0}},
{{0,0,1,0},
{0,0,1,0},
{0,1,1,0},
{0,0,0,0}},
{{0,0,0,0}, //8
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}}
};
//==============================================
void mybeep() // звук
{analogWrite(speaker, 100);
delay(100);
analogWrite(speaker, 0);
}
//==============================================
void figmove(byte a, byte b)
{
for (byte i=0;i<4;i++)
for (byte j=0;j<4;j++)
fig[a][i][j]=fig[b][i][j];
}
//==============================================
void figinit(byte a)
{
for (byte i=0;i<4;i++)
for (byte j=0;j<4;j++)
{
fig[0][i][j]=fig[NumNext][i][j];
if (fig[a][j][i]==1) // покажем след фигуру
display.fillRect(i*rz+60, 20+(j)*rz, rk , rk, BLACK);
else display.fillRect(i*rz+60, 20+(j)*rz, rk , rk, WHITE);
}
display.display();
NumNext=a;
tempspeed=myspeed-(Victory/30)*50; // через каждые 30 линий увеличим скорость падения;
dxx=0;
for (byte i=0;i<MaxX;i++)
if (mstacan[i][3]==2) newgame();
}
//==============================================
void viewstacan()
{
display.drawLine(0,0,0,display.height()-1, BLACK);
display.drawLine(0,display.height()-1,Lst, display.height()-1, BLACK);
display.drawLine(Lst,display.height()-1,Lst,0, BLACK);
for (byte j=4;j<MaxY;j++)
for (byte i=0;i<MaxX;i++)
if (mstacan[i][j]>0)
display.fillRect(i*rz+1, SmeH+(j-4)*rz, rk , rk, BLACK);
else display.fillRect(i*rz+1, SmeH+(j-4)*rz, rk , rk, WHITE);
ds(Victory,1);
display.display();
}
//================================================
void ds(int aa, int b)
{
display.fillRect(55, 10, 29, 10, WHITE);
display.setCursor(55,b*10);
display.println(aa);
}
//================================================
bool iffig(int dx, int dy)
{int i,j;
bool flag=true; bool pov=false;
for (i=0;i<MaxX;i++)
for (j=0;j<MaxY;j++)
if (mstacan[i][j]==1)
mstacan[i][j]=0; // убрали временно фигуру
if (dx==2) // поворот
{ dx=0; pov=true;
figmove(8,0);
for (i=0;i<4;i++)
for (j=0;j<4;j++)
{ fig[0][i][j]=fig[8][3-j][i];
if (fig[0][j][i]==1)
{ if (i+FigX+dx<0) dx=1; // пробуем отодвинуть от стенки слева на 1
if (i+FigX+dx>MaxX-1) dx=-1;// пробуем отодвинуть от стенки справа на 1
}
}
}
for (i=0;i<4;i++)
for (j=0;j<4;j++)
if (fig[0][j][i]==1)
if (i+FigX+dx<0 || i+FigX+dx>MaxX-1 || FigY+j+dy>MaxY-1 || mstacan[i+FigX+dx][FigY+j+dy]>0)
{flag=false; break;} // проверили на новые координаты
if (flag)
{FigX=FigX+dx; FigY=FigY+dy;byte k=0;
for (i=0;i<4;i++)
for (j=0;j<4;j++)
if (fig[0][j][i]==1)
{mstacan[i+FigX][j+FigY]=1;
dxx=0;
}
} // переместили фигуру на новые координаты
else
{ if (pov) figmove(0,8);
for (i=0;i<4;i++) // восстановили фигуру
for (j=0;j<4;j++)
if (fig[0][j][i]==1)
mstacan[i+FigX][j+FigY]=1;
}
return(flag);
}
//================================================
void clearstacan()
{
for (byte i=0;i<MaxX;i++)
for (byte j=0;j<MaxY;j++)
mstacan[i][j]=0;
}
//================================================
unsigned long getbutton(char s[])
{unsigned long tt;
display.fillRect(5, 30, 40, 10, WHITE);
display.setCursor(5,30);
display.print(s);
display.display();
while (true)
if (irrecv.decode(&results)) // ловим код кнопки пульта
{ tt=results.value;
delay(400);
irrecv.resume();
break;
}
return(tt);
}
//================================================
void newgame()
{ unsigned long tb;
dxx=0; dyy=1;
display.setCursor(0,0);
clearstacan();
NumNext=random(7)+1;
figinit(random(7)+1);
center=MaxX/2-2;
FigX=center;FigY=0;
display.setCursor(52,0);
display.println("Линий");
viewstacan();
if (Victory>myrecord)
{ myrecord=Victory;
EEPROM_write(16, myrecord);
}
display.setCursor(5,0);
display.print("Рекорд");
display.setCursor(5,10);
display.print(myrecord);
display.display();
display.setCursor(5,20);
delay(2000);irrecv.resume();
display.println("Нажмите");
tb=getbutton(" OK");
if (tb!=ok)
{ ok=tb;
levo=getbutton("Влево");
pravo=getbutton("Вправо");
vniz=getbutton("Вниз");
EEPROM_write(0, ok);
EEPROM_write(4, levo);
EEPROM_write(8, pravo);
EEPROM_write(12, vniz);
}
display.fillRect(5, 0, (MaxX-1)*rz, 40, WHITE);
myspeed=800; tempspeed=myspeed;
Victory=0;
}
//================================================
void setup()
{ unsigned long tr; word gg=0;
randomSeed(analogRead(0));
irrecv.enableIRIn(); // Старт ресивера IRDA
display.begin();
display.setContrast(50);
display.setTextSize(1);
display.setTextColor(BLACK); // установка цвета текста
display.clearDisplay();
Lst=rz*MaxX; // ширина стакана в пикселях
MaxY=display.height()/rz+4; // Высота стакана в кубиках
SmeH=display.height()%rz; // смещение сверху в пикселях для отображения
random(7);
EEPROM_read(0, ok);
EEPROM_read(4, levo);
EEPROM_read(8, pravo);
EEPROM_read(12, vniz);
EEPROM_read(20, tr);
if (tr==flfirst) EEPROM_read(16, myrecord);
else { myrecord=0;
EEPROM_write(16, myrecord);
EEPROM_write(20, flfirst);
}
newgame();
}
//================================================
void dvoiki()
{
for (byte i=0;i<MaxX;i++)
for (byte j=0;j<MaxY;j++)
if (mstacan[i][j]==1)
mstacan[i][j]=2;
}
//================================================
void mydelay(int md)
{
unsigned long starttime=millis();
while (millis()-starttime<md)
{
if (irrecv.decode(&results)) // ловим код кнопки пульта
{
if (results.value==levo) dxx=-1; else
if (results.value==pravo) dxx=1; else
if (results.value==ok) dxx=2; else
if (results.value==vniz) {tempspeed=100; md=0;}
if (dxx!=0) {iffig(dxx,0); viewstacan(); }
delay(40); // убираем дребезг
irrecv.resume();
}
}
}
//================================================
bool iffs() // есть ли полные строки?
{bool res=false;
for (byte j=0;j<MaxY;j++)
{ bool fl=true;
for (byte i=0;i<MaxX;i++)
if (mstacan[i][MaxY-1-j]==0) fl=false;
if (fl)
{Victory++;
if (myspeed<0) myspeed=0;
res=true; mybeep();
for (byte k=0;k<MaxX;k++)
for (byte n=j;n<MaxY-2;n++)
mstacan[k][MaxY-n-1]=mstacan[k][MaxY-n-2];
viewstacan();
}
}
return(res);
}
//================================================
void loop()
{ if (!iffig(dxx,dyy))
if (!iffig(0,dyy))
{ dvoiki();
while (iffs()) ;
figinit(random(7)+1);
FigX=center;FigY=0;
}
viewstacan();
mydelay(tempspeed);
}
И можно ирать. Игра поддерживает привязку к любому пульту. Для этого достаточно в начале игры, на вопрос «Нажмите ОК» нажать на пульте кнопку, которая будет отвечать за вращение фигуры. Если пульт игре уже знакомый, то игра сразу запустится. Если пульт новый, то код кнопки ОК не совпадет с запомненным и игра потребует последовательно нажать кнопки «Влево», «Вправо» и «Вниз». Эти кнопки будут записаны в энергонезависимую память Ардуино и впоследствии именно этот пульт будет узнаваться сразу по нажатию кнопки «ОК».
При «проваливании» на собранную строку будет воспроизводиться писк. Он реализован на особенности нескольких пинов Ардуино (в нашем случае 9) выдавать ШИМ с заданной частотой.
Игра поддерживает все атрибуты нормальной игры. Ту и подсказка следующей фигуры и текущий счет. Игра ведет учет рекордов. Это значение хранится в энергонезависимой памяти Ардуино. Чтобы сбросить рекорд, достаточно изменить в скетче значение flfirst=1234 на любое другое. В игре также идет автоувеличение скорости падения через каждые 30 списанных строчек, так что, бесконечно долго поиграть не получится ). Скетч не оптимизировался и тщательно не прогонялся, а был написан на досуге в свое удовольствие. Если кто обнаружит ошибку — пишите. О ©. Скетч разрешается править для себя как угодно. Только при публикации где-либо своих вариантов ссылку на первоисточник-муську указывайте ).
Для чего делал — длинные выходные + «из любви к искусству». Была бы дочка маленькой, сделал бы ей, наверное, мини игровой автомат для кукольной комнатки на 8 марта, как раз успел бы. Добавил бы несколько игр типа Змейки и Арканоида, а корпус вырезал бы из текстолита, наверное. Только дочка в этом году уже докторскую защищает, так, что мимо, но может кому еще эта идея пригодится ).
Подведем итог для дисплея Nokia 5110:
Плюсы
+Возможность вывода графики;
+Отсутствие проблем с кириллицей;
+Небольшой вес;
+Отличное соотношение габариты/кол-во выводимой информации;
+Плюсы примененной технологии ЖК — малое энергопотребление и хорошая читабельность на ярком свете;
+Отключаемая подсветка;
+Цена.
Минусы
-Подсветка неравномерная;
-Изображение черно-белое (оттенков нет);
-Необходимость позаботиться о 3.3V, не на каждой Ардуино такое напряжение есть.
Вердикт: За свои деньги по совокупности характеристик уверено занимает свою нишу, недаром и является таким долгожителем среди устройств отображения для Ардуино.
Upd: добавлена озвучка Тетриса на mp3 модуле
Самые обсуждаемые обзоры
+20 |
2444
149
|
+80 |
4423
111
|
Только в Митино можно было купить всё. М/сх корпуса, клавиатуру и др.
Специально летал В Москву за этим.
Закупал несколько комплектов. Даже с учётом дороги и питания, было выгодно.
В тумбочке до сих пор лежит готовый набор: ВМ80 (в керамике), ВВ55, ВВ51 и т.д. :)
надо все-таки завершить этот гештальт, начать можно с хабра
Супер машинка!
от на таком))
только после игр в теннис кнопки часто вылетали. Физически. Слабое крепление у них, да и годы…
«В 1970 году был разработан PDP-11.
PDP-11 имел невероятный успех, в СССР был «полностью срисован» процессор КМ1801ВМ2 (аналог DEC LSI-11/03) и на его базе построены практически полные клоны PDP-11 — ДВК и серия микрокомпьютеров, таких как БК-0010, УКНЦ и МК-90 „… Вариации на тему PDP-11 привились в СССР под двумя названиями: СМ-ЭВМ и «Электроника»“
А то, что наши сделали копии этой ветки — это нормально. Замечательно даже. Я вырос на этих ЭВМ. И благодарен этим железкам, потому как, до сих пор железками и занимаюсь в свое удовольствие. Спасибо нашим PDP-11!
На БК был еще подключаемый блок с Паскалем, но это для продвинутых :)
Да еще и Эпловский софт. в то время… Не советский человек однако
И, наконец, третья игрушка — 4-х катушечный диктофон с педалью, который также был отдан отцом в мое распоряжение.
И только потом, в конце 80-х, уже были «Крот», «Волна-К», «Р250», ламповый UW3DI и далее по возрастающей :)
+!
Как реализовано здесь у автора — я думаю он сам скажет :)
А по делу просто отлично быть самому себе программистом, без этого очеень сильно ограничиваются возможности и пропадает желание что либо мастырить))
п.с. можно к Вам изредка обратиться с утреца для разминки мозга в написании программулины на ардуино?))
или правки какого нибудь уже кривого кода)
— А что, уже был?
— Нет, уже хотел
https://aliexpress.com/item/item/J34-A96-Free-Shipping-1-8-Serial-128X160-SPI-TFT-LCD-Module-Display-PCB-Adapter-Power/32599685873.html
https://aliexpress.com/item/item/1-44-Serial-LCD-Display-128-128-SPI-TFT-Color-Screen-With-Adapter-5110-PCB/32599757275.html
2.8', ILI9341, зачем-то еще гнездо для SD карты прикрутили.
С ардуино проблем нет, с Orange Pi сложнее, написал свою библиотеку для простого рисования: github.com/wyfinger/OrangePi_ILI9341, может пригодится кому.
На этом модуле и тач-скрин предполагается, но он не распаян.
На сенсорный экран не планируете обзор делать?
Скрин пришел с надколотым уголком, но в целом рабочий. А вот с тач-скрином беда — много левых показаний при нажатиях. Без программной фильтрации вообще не применимы.
Типа этого.
Orange Pi набор китайских глюков, самое то для изучения Linux, а Raspberry Pi 3 намного дороже. И нет у них реального времени, всем управляет медленная ОС…
Но STM32 можно купить отдельно чип, они массовые, и платы есть копеечные, а вот AT91SAM по отдельности не продаются, с Arduino Due никуда не перейти, тупиковая ветка какая-то. Зато встроенная поддержка среды Arduino (но нужны свои библиотеки обычно). Иногда удобно, иногда нет…
Берите stm32f103c8t6 и никого не слушайте. Программировать их проще чем avr-ки, 32 бит, внутрисхемный отладчик, для вашей задачи есть два 12bit ADC. А стоит эта красота 1.5-2.0$, запарывайте с удовольствием.
Контроллер: https://aliexpress.com/item/item/STM32F103C8T6-ARM-STM32-Minimum-System-Development-Board-Module-ForArduin/32282374854.html
Программатор: https://aliexpress.com/item/item/Hot-Sale-1PCS-ST-LINK-Stlink-ST-Link-V2-Mini-STM8-STM32-Simulator-Download-Programmer-Programming/1956977845.html
Если 12бит встроенного АЦП не хватит, посмотрите на это:
https://aliexpress.com/item/item/I2C-ADS1115-16-Bit-ADC-4-channel-Module-with-Programmable-Gain-Amplifier-2-0V-to-5/32673245125.html
16bit ADC с 4 входами, которые могут использоваться как два дифференциальных входа для измерения разности напряжения между входами, либо как 4 отдельных несимметричных входа.
Скорее всего на 1000 герц считывать три канала без разного рода хаков не получится.
ШИМ тоже не быстрый, без изменения коэффициентов делителя частоты полуторакиловаттный мотор писчал. А при увеличении частоты появляются другие проблемы.
banggood.com/STM32F407ZET6-Development-Board-M4-STM32F4-Core-Board-Arm-Development-Board-Cortex-M4-p-1103688.html
Может чуть цену поднять и взять что-то помощнее? Ну и если там на C программировать и библиотеки нормальные есть, было бы отлично
Другой вопрос будут ли обновляться показания с этой скоростью или он просто будет считыквать одно и тоже, а реальный замер будет меняться с меньшей скоростью. Нужно внимательно читать доки, а еще лучше — проверить.
А Вам что мерить нужно? может лучше взять специализированный ПИМ, который уже сам считает действующее значение напряжения, тока, частоту, гармоники и еще много чего, первый попавшийся пример — energoma.ru/et-mnogofunkcionalnyj-izmeritelnyj-preobrazovatel/
Может уже тысячу раз делали, но что-то я не могу нагуглить (кстати и сайт www.st.com из России недоступен).
А сайт их вполне доступен.
Вообще у меня главное — сделать максимально быстро и с быстрым входом в тему. Т.е. возможно чуть дороже заплатить, но хотелось бы сразу нормальные библиотеки получить и писать на С
Ну и всё, что там делать то…
Можно на C++ даже писать что может оказаться полезным для UI дисплея если нужен очень красивый.
Если сильно крутая графика не нужна то STM32F2. Не берите F1 серию и тем более F0 и вот почему:
F1 — старый, то есть новые библиотеки и код инициализации дислея и приличного ADC не подойдёт.
F0 — глючный хлам, кроме моргания светодиодом ни на что не годится. ADC там оооочень глючный и медленный (не смотря на заверения ST) и DMA путает каналы.
Ну в общем да, F4 должно быть в самый раз чтобы на большом экране UI не бесил пользователя )
Arduino Due же взял и сразу работаешь с ним.
geektimes.ru/post/258166/
arduino.ru/forum/apparatnye-voprosy/arduino-due-lcd-32-podklyuchenie
Я считаю что если сделать надо быстро, и для себя то ардуино (они же разные есть, но DUE это одна из самых быстрых с АЦП и ЦАП, да и не такая дорогая) так как я не программист а больше «железячник» и осваивать программирование хоть и хочется, но это не на первом месте.
И да, если много математики, то может быть полезен fpu
SETTEMP 0x04
SETBIAS 0x10
SETVOP 0x80
Кстати у TM1637 есть фича — к нему можно подключить кнопки и читать по теме же двум проводам.
Еще плюс дисплея на TM1637 — он работает на холоде. А вот дисплей Nokia 5110 уже при +5 начинает тупить
Полностью поддерживаю, потому пользуюсь телефоном с цветным экраном, который тоже не надо прятать от солнца :)
Для незнающих объясню, IRDA это протокол передачи данных (причем двухсторонний), и в ИК пультах этого нет, так как там команды подчинены другому протоколу.
Кто хочет знать больше, может почитать, IRDA, любой ИК пульт.
IRDA использовали как приемник ИК пульта, но дальность действия была очень маленькой, около 1 метра.
Поэтому, если написано про пульт IRDA, это и значит, что он работает по ИК. Еще есть радиопульты, к примеру.
Это абсолютно неверно. Это как решить, что если что-то передаёт данные по проводам, то это ethernet. IRDA — это вполне конкретный подкласс спецификации для устройств, использующих ИК для передачи данных. Относить всё, использующее ИК к IRDA — неверно.
Слово протоколы написано во множественном числе, отсюда понятно, что они бывают разные, а сама аббревиатура IRDA имеет собирательный смысл и никакого конкретного подкласса устройств я там не увидел.
Любопытно, минус за коммент есть, а RC5 в списке IRDA протоколов показать слабо :)
Но Вы же не будете говорить, WiFi, Bluetooth и просто радиоканал это одно и то же?
Так можно сказать что аналоговое и цифровое ТВ это одно и то же.
У ИК пультов большой радиус действия, малое количество заранее определенных команд, у IRDA все наоборот. И это не говоря о протоколах.
Меня заинтересовала фраза из Вашего обзора-
Можно ссылку на Пульт IRDA? Возможно я что-то просто упускаю, но весьма любопытно, потому я и спросил.
Чтобы не переливать из пустого в порожнее, останемся каждый при своем, а те читатели, кому это интересно, смогут почитать об этом из Вики по Вашей ссылке. Ок?
В оригинале указано —
Никаких IR Remote control здесь нет.
Также как и тут
Так что в данном случае ошибка в русской версии вики.
Были попытки приколхозить IRDA порт для управления компом при помощи обычного ИК пульта (LIRC), но малый радиус действия и отсутствие некоторых особенностей ИК приемников свело на нет все эти попытки.
Примерно из той же оперы СОМ порт. Можно работать по протоколу UART, а можно просто «дергать ножками» (как в понипроге), только это будет уже не совсем UART.
Кстати, кроме меня Вам уже как минимум два человека написали то же самое.
Да, и дома и в гараже я компом управляю так-же с пульта. Но, тему лучше не поднимать, а то… )
Купил под проект у разных продавцов, в итоге все выкинул ибо взбесили.
A+A+A+ Store или A+A+A+?
Оба продают электронные модули. Или это один продавец держит два магазина?
Вроде, никчемный экранчик, а и из такого можно сделать интересное. :)
Юмор, с изрядной долей сарказма, оценил! :))
Сапог не туда же поставил. Потом будет труднее собрать полосу.
А вот с аппаратной частью — проблема: этому дисплею не только питание надо 3.3 вольта, но и управляющие сигналы надо той же величины. В противном случае, срок его жизни становится не очень выигрышной лотереей.
Нужно просто брать с индексом CT или CP в конце.
https://aliexpress.com/item/item/Smart-Electronics-LCD-Module-Display-Monitor-White-backlight-adapter-PCB-84-48-84x84-Nokia-5110-Screen/32314362902.html
Не хватает кнопок «Mute» и «Pause».
на УНО тоже неполучатся почемуто