Пишем для Arduino на C++ игру в стиле Google Dino (https://trex-runner.com/). Из электронных компонентов нам понадобится плата Arduino NANO или UNO, дисплей MT16S2H или LCD 1602 подключённый к плате Arduino с помощью сдвигового регистра 74HC595B1 и кнопка. В программе используется библиотека LiquidCrystal_74HC595.
Легенда игры: Мы пошли пешком в пустыню и должны перепрыгнуть все встречающиеся на пути препятствия.
Задание на проектирование игры-тренажёра «Поход в пустыню»:
Символьный дисплей MT16S2H или LCD 1602 имеет две строки по 16 символов каждый символ на дисплее состоит из 8-ми строк по 5 пикселей. Расстояние между символами 1 пиксель. На этот дисплей нам необходимо вывести анимированного человечка, который должен уметь ходить и прыгать. Так же мы должны вывести на дисплей пустынный ландшафт, который преодолевает человечек. На экране дисплея действие будет происходить относительно воображаемой камеры, которая перемещается по пустыне вместе с человечком и снимает его. В результате, на экране дисплея человечек будет идти на месте, а пустыня будет двигаться на него. Все встречающиеся на пути препятствия человек преодолевает в прыжке.
Mov 1. Идущий человек.
Mov 2. Подпрыгивающий человек и раскадровка.
Управление человечком будет происходить с помощью одной кнопки, подключённой одним контактом к шине GND, а другим - к выводу D6 платы Arduino.
Для упрощения интерфейса связи дисплея MT16S2H или LCD 1602 с микроконтроллером, мы соединили интерфейсные выводы этого дисплея с микросхемой CN74HC595B1. Микросхема CN74HC595B1 это сдвиговый регистр с защёлкой. Эта микросхема очень часто используется для преобразования последовательного интерфейса в параллельный.
Управление дисплеем MT16S2H осуществляется с помощью 8- битной (DB0...DB7) или 4-битной (DB4...DB7) шины данных и двух линий управления (RS, E). см. рис. 1.
Микросхема CN74HC595B1 преобразует синхронный поток последовательных данных на входе SER в параллельные данные на своих выходах Q0...Q7. Для синхронной передачи данных по входу SER в микросхему CN74HC595B1 должны быть задействованы входы синхронизации SRCLK (вход тактовых импульсов) и RCLK (строб передачи байта данных).
В связке, дисплея MT16S2H и микросхемы CN74HC595B1 получился двух-строчный, по 16 символов в каждой строке, дисплей с последовательным интерфейсом передачи данных.
Рис. 1. Схема подключения буквенно-цифрового индикатора МТ-16S2H к плате Arduino с помощью сдвигового регистра 74HC595B1.
Рис. 2. Макет игры «Красный или синий».
#include <LiquidCrystal_74HC595.h>
LiquidCrystal_74HC595 lcd(4, 3, 2, 1, 2, 3, 4, 5, 6);
#define imgs 3
byte man[imgs][8] = {
{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
},
{
0b01110,
0b01110,
0b00100,
0b01111,
0b10100,
0b00110,
0b01011,
0b11000
},
{
0b01110,
0b01110,
0b00100,
0b11110,
0b00101,
0b01100,
0b11010,
0b00011
}
};
void setup() {
lcd.begin(16, 2);
for (int i = 0; i < imgs; i++) {
lcd.createChar(i, man[i]);
}
lcd.setCursor(0, 0);
lcd.write(byte(0)); // when calling lcd.write() '0' must be cast as a byte
lcd.write(1);
lcd.write(2);
}
void loop() {
lcd.setCursor(6, 1);
lcd.write(1);
delay(500);
lcd.setCursor(6, 1);
lcd.write(2);
delay(500);
}
Программа 1. Для mov 1.
- В программе 1 в первой строке мы подключаем библиотеку, а далее с помощью конструктора класса из этой библиотеки создаём объект lcd. Конструктору класса, в качестве параметров требуются три номера выводов (портов) на плате Arduino к которым подключена микросхема 595 и номера пяти ножек микросхемы 595 к которым подключён LCD дисплей. Перечислим параметры конструктора класса по порядку: SER, SRCLK, RCLK, RS
#include <LiquidCrystal_74HC595.h>
LiquidCrystal_74HC595 lcd(4, 3, 2, 1, 2, 3, 4, 5, 6);
#define imgs 5
byte man[imgs][8] = {
{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
},
{
0b01110,
0b01110,
0b00100,
0b01110,
0b10101,
0b00100,
0b01010,
0b11011
},
{
0b00000,
0b01110,
0b01110,
0b10101,
0b01110,
0b00100,
0b01010,
0b11011
},
{
0b01110,
0b01110,
0b00100,
0b01111,
0b10100,
0b00110,
0b01011,
0b11000
},
{
0b01110,
0b01110,
0b00100,
0b11110,
0b00101,
0b01100,
0b11010,
0b00011
}
};
void setup() {
lcd.begin(16, 2);
for (int i = 0; i < imgs; i++) {
lcd.createChar(i, man[i]);
}
lcd.setCursor(0, 0);
lcd.write(byte(0)); // when calling lcd.write() '0' must be cast as a byte
lcd.write(1);
lcd.write(2);
lcd.write(3);
lcd.write(4);
}
void loop() {
lcd.setCursor(8, 1);
lcd.write(1);
lcd.setCursor(6, 1);
lcd.write(3);
delay(500);
lcd.setCursor(8, 1);
lcd.write(2);
lcd.setCursor(6, 1);
lcd.write(4);
delay(500);
lcd.setCursor(8, 1);
lcd.write(3);
lcd.setCursor(6, 1);
lcd.write(3);
delay(500);
lcd.setCursor(8, 1);
lcd.print(' ');
lcd.setCursor(8, 0);
lcd.write(2);
lcd.setCursor(6, 1);
lcd.write(4);
delay(500);
lcd.setCursor(8, 0);
lcd.write(2);
lcd.setCursor(6, 1);
lcd.write(3);
delay(500);
lcd.setCursor(8, 0);
lcd.write(1);
lcd.setCursor(6, 1);
lcd.write(1);
delay(500);
lcd.setCursor(8, 0);
lcd.print(' ');
}
Программа 2.