Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Создание анимации и игр на LCD 16×2 с Arduino UNO

Компоненты и материалы

КомпонентКоличество
Arduino UNO1
Символьный LCD 16×2 (HD44780-совместимый)1
Потенциометр 10 кОм (для контраста)1
Резистор 220 Ом (подсветка)1
Макетная плата и перемычки1 комплект

Приложения и сервисы

О проекте

Проект посвящен основам анимации на символьном LCD 16×2 с Arduino. Принципы применимы к дисплеям других размеров.

Подключение LCD

Схема подключения (4-битный режим):

Вывод LCDНазначениеПодключение
1 (VSS)ЗемляОтрицательная шина макетной платы (GND Arduino)
2 (VDD)Питание +5VПоложительная шина (5V Arduino)
3 (VO)КонтрастСредний вывод потенциометра (крайние — на +5V и GND)
4 (RS)Выбор регистраArduino pin 12
5 (R/W)Чтение/записьЗемля (режим записи)
6 (E)СтробArduino pin 11
11 (D4)Данные 4Arduino pin 4
12 (D5)Данные 5Arduino pin 5
13 (D6)Данные 6Arduino pin 6
14 (D7)Данные 7Arduino pin 7
15 (A)Анод подсветки+5V через резистор 220 Ом
16 (K)Катод подсветкиЗемля

Тест: включите питание. Если нижняя строка загорелась — LCD работает. Если нет — проверьте пайку, проводку, замените дисплей.

После успешного теста подключите линии данных D4–D7 (пины 4–7 Arduino) и загрузите тестовый скетч:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 4, 5, 6, 7); // rs, e, d4, d5, d6, d7
void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(0, 1);
  lcd.print("Working");
}
void loop() {}

Если выводится «Working» — подключение верное. Если мусор или пусто — проверьте контраст (поверните потенциометр), пайку данных (нет ли коротких замыканий), соответствие пинов в коде схеме.

Разбор тестового кода

Бегущая строка

Вывод текста, прокручивающегося справа налево:

void setup() {
  lcd.begin(16,2);
}
void loop() {
  int n = 15;
  char message[] = "scrolling text!";
  char* ptr = message;
  while(n != -14) {
    lcd.clear();
    lcd.setCursor(n, 1);
    if(n < 0) ptr++;
    lcd.print(ptr);
    n--;
    delay(250);
  }
}

Указатель ptr сдвигается при выходе за левый край, чтобы текст продолжал прокручиваться. delay(250) задает скорость — меняйте под нужды.

Пользовательские символы

Библиотека LiquidCrystal позволяет создавать до 8 своих символов (5×8 пикселей). Каждый символ — массив из 8 байт, где 1 = пиксель включен, 0 = выключен.

byte dino[] = {
  B01110,
  B01110,
  B01100,
  B01111,
  B11101,
  B01010,
  B01010,
  B01010
};

Создание и вывод:

void setup() {
  lcd.createChar(0, dino); // символ 0 = dino
  lcd.begin(16,2);
  lcd.setCursor(0,1);
  lcd.write(byte(0)); // вывод по адресу 0
}

Создавать символы удобно в онлайн-редакторе: LCD Character Creator.

Анимация «Летающая стрела»

Используем три пользовательских символа: наконечник, тело, хвост.

byte arrowhead[] = { B00001, B00011, B00111, B01111, B00111, B00011, B00001, B00000 };
byte arrowbody[] = { B00000, B00000, B00000, B11111, B11111, B00000, B00000, B00000 };
byte arrowtail[] = { B00011, B00111, B01111, B11111, B11111, B00111, B00011, B00000 };

void setup() {
  lcd.createChar(0, arrowhead);
  lcd.createChar(1, arrowbody);
  lcd.createChar(2, arrowtail);
  lcd.begin(16,2);
}
void loop() {
  int n = 15;
  while(n != -1) {
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.write(byte(0));
    lcd.write(byte(1));
    lcd.write(byte(2));
    n--;
    delay(50);
  }
}

Можно заметить «хвост» от предыдущего кадра — это артефакт медленного обновления жидких кристаллов, не ошибка.

Игра «Уворачивайся от стрел»

Суть: герой (человечек) стоит на нижней строке (строка 1). Стрелы летят справа налево по той же строке. Нажатие кнопки (pin 2, прерывание) перемещает героя на верхнюю строку (строка 0). Попадание — конец игры. Очки считаются каждый цикл.

Ключевые элементы кода:

Полный код игры приведен в разделе Code. Это база для более сложных игр — добавляйте кнопки, уровни, врагов!

Код

Код анимации (стрела)

#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

byte arrowhead[] = { B00001, B00011, B00111, B01111, B00111, B00011, B00001, B00000 };
byte arrowbody[] = { B00000, B00000, B00000, B11111, B11111, B00000, B00000, B00000 };
byte arrowtail[] = { B00011, B00111, B01111, B11111, B11111, B00111, B00011, B00000 };
byte man[] = { B01110, B01110, B00100, B01110, B10101, B00100, B01010, B10001 };

void setup() {
  lcd.createChar(0, arrowhead);
  lcd.createChar(1, arrowbody);
  lcd.createChar(2, arrowtail);
  lcd.createChar(3, man);
  lcd.begin(16, 2);
}

void loop() {
  int n = 15;
  while(n != -1) {
    lcd.clear();
    delay(10);
    lcd.setCursor(0,0);
    lcd.print("by Debanshu Das");
    delay(65);
    n--;
  }
}

Код игры

#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

int level = 1;
int score = 0;
byte arrowhead[] = { B00001, B00011, B00111, B01111, B00111, B00011, B00001, B00000 };
byte arrowbody[] = { B00000, B00000, B00000, B11111, B11111, B00000, B00000, B00000 };
byte arrowtail[] = { B00011, B00111, B01111, B11111, B11111, B00111, B00011, B00000 };
byte man[] = { B01110, B01110, B00100, B01110, B10101, B00100, B01010, B10001 };

void setup() {
  lcd.createChar(0, arrowhead);
  lcd.createChar(1, arrowbody);
  lcd.createChar(2, arrowtail);
  lcd.createChar(3, man);
  lcd.begin(16, 2);
  attachInterrupt(0, buttonin, CHANGE);
  randomSeed(analogRead(A0));
}

int n;
void loop() {
  n = 15;
  int rnd = random(15, 25);
  while(n != -1) {
    lcd.clear();
    delay(10);
    drawman();
    lcd.setCursor(n, 1);
    if(n == 1) {
      if(level == 1) { stopgame(); continue; }
    }
    lcd.write(byte(0));
    lcd.write(byte(1));
    lcd.write(byte(2));
    lcd.setCursor(10, 0);
    lcd.print(score);
    delay(100 - rnd);
    n--;
    score++;
    if(level == 0) score--;
  }
}

void drawman() {
  lcd.setCursor(1, level);
  lcd.write(byte(3));
}

void buttonin() {
  if(digitalRead(2) == LOW) level = 0;
  else level = 1;
}

void stopgame() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Game over");
  lcd.setCursor(10, 0);
  lcd.print(score);
  level = 1;
  score = 0;
  n = 15;
  delay(3000);
}

Схема

Создание анимации и игр на LCD 16×2 с Arduino UNO

Производственный процесс

  1. Arduino-датчики: типы, применения и реальные проекты
  2. Сборка портативной игровой консоли-клона Arduboy на Arduino Micro с проектированием PCB
  3. Умный вольтметр на Arduino и смартфоне — простое DIY-проект
  4. Логгер температуры и влажности на Arduino с DHT11 и Ethernet Shield
  5. Управление Arduino Uno из Python 3: команды через последовательный порт и демонстрация с LED
  6. Клеточный автомат «Жизнь» Конвея на Arduino Nano с OLED 128x64
  7. Сборка компактного FM-радио на Arduino Nano и RDA5807M
  8. Надежная погодная станция на Arduino с датчиками DHT
  9. Создание классической аркадной игры на Arduino с LCD, зуммером и джойстиком
  10. MKR1000 + DHT22: мониторинг температуры и влажности в Azure в реальном времени