Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Bouw een interactief LCD-spel met Arduino UNO

Onderdelen en benodigdheden

OnderdeelAantal
Arduino UNO1
Adafruit RGB Backlight LCD - 16x21
Breadboard (generic)1
Weerstand 220 ohm1
SparkFun Drukknopschakelaar 12mm1
Jumper draden (generic)1
USB-A naar B Kabel1

Apps en online diensten

  • Arduino IDE

Over dit project

Bouw een interactief LCD-spel met Arduino UNO

De benodigde onderdelen zijn in de afbeelding hierboven weergegeven. Begin met de Arduino zonder stroom. Steek de USB-kabel NOG NIET in. Dat gebeurt in een latere stap wanneer het tijd is om te programmeren en het spel uit te proberen.

Verbindingen

Gebruik een lange draad om het 5V-signaal op de Arduino te verbinden met het uiterst linkerpunt van de rode rij bovenaan het breadboard.

Gebruik een lange draad om het GND-signaal te verbinden met het uiterst linkerpunt van de zwarte (of blauwe op sommige breadboards) rij bovenaan het breadboard.

De LCD-module (Liquid Crystal Display) heeft een 16-pins mannelijke header aan de onderkant. Steek deze in het breadboard zoals in de afbeelding getoond. Alle elektronische signalen die de LCD voeden en besturen gaan door deze header.

Deze pennen zijn (van links naar rechts):

  • GND - stroom grond signaal
  • VCC - positief stroomsignaal
  • V0 - contrast aanpassen
  • RS - register selecteren
  • R/W - lezen/schrijven selecteren
  • E - bewerkingsinschakeling signaal
  • DB0 - databit 0 (hier niet gebruikt)
  • DB1 - databit 1 (hier niet gebruikt)
  • DB2 - databit 2 (hier niet gebruikt)
  • DB3 - databit 3 (hier niet gebruikt)
  • DB4 - databit 4
  • DB5 - databit 5
  • DB6 - databit 6
  • DB7 - databit 7
  • LED+ - achtergrondverlichting LED positief
  • LED- - achtergrondverlichting LED negatief

Met korte draden, verbind GND en LED- (pennen 1 en 16) met de zwarte rij bovenaan.

Op dezelfde manier, verbind VCC (pen 2) met de rode rij bovenaan met een korte draad.

Buig de draad van de 220 Ω weerstand (rode-rode-bruine kleurbanden) en verbind deze tussen LED+ en de rode rij bovenaan het breadboard.

Gebruik langere draden voor de overige verbindingen:

  • Verbind DB7 met Arduino pin 3
  • Verbind DB6 met Arduino pin 4
  • Verbind DB5 met Arduino pin 5
  • Verbind DB4 met Arduino pin 6
  • Verbind E met Arduino pin 9
  • Verbind R/W met Arduino pin 10 (of met zwarte rij bovenaan breadboard)
  • Verbind RS met Arduino pin 11
  • Verbind V0 met Arduino pin 12 (of met zwarte rij bovenaan breadboard)

Steek de drukknop ergens links van het LCD-scherm, de kanaal in het midden van het breadboard overspannend (zie afbeelding hierboven). Verbind een van de bovenste twee pennen van de knop met de zwarte rij bovenaan het breadboard met een korte draad. Verbind de andere pen bovenaan de knop met pin 2 van de Arduino.

Bouw een interactief LCD-spel met Arduino UNO
Bouw een interactief LCD-spel met Arduino UNO

Code

LCD_Game.ino

#include <LiquidCrystal.h> 
#define PIN_BUTTON 2 
#define PIN_AUTOPLAY 1 
#define PIN_READWRITE 10 
#define PIN_CONTRAST 12 
#define SPRITE_RUN1 1 
#define SPRITE_RUN2 2 
#define SPRITE_JUMP 3 
#define SPRITE_JUMP_UPPER '.' // Gebruik het '.' teken voor het hoofd 
#define SPRITE_JUMP_LOWER 4 
#define SPRITE_TERRAIN_EMPTY ' ' // Gebruik het ' ' teken 
#define SPRITE_TERRAIN_SOLID 5 
#define SPRITE_TERRAIN_SOLID_RIGHT 6 
#define SPRITE_TERRAIN_SOLID_LEFT 7 
#define HERO_HORIZONTAL_POSITION 1 // Horizontale positie van held op scherm 
#define TERRAIN_WIDTH 16 
#define TERRAIN_EMPTY 0 
#define TERRAIN_LOWER_BLOCK 1 
#define TERRAIN_UPPER_BLOCK 2 
#define HERO_POSITION_OFF 0 // Held is onzichtbaar 
#define HERO_POSITION_RUN_LOWER_1 1 // Held rent op onderste rij (pose 1) 
#define HERO_POSITION_RUN_LOWER_2 2 // (pose 2) 
#define HERO_POSITION_JUMP_1 3 // Start een sprong 
#define HERO_POSITION_JUMP_2 4 // Halfweg omhoog 
#define HERO_POSITION_JUMP_3 5 // Sprong is op bovenste rij 
#define HERO_POSITION_JUMP_4 6 // Sprong is op bovenste rij 
#define HERO_POSITION_JUMP_5 7 // Sprong is op bovenste rij 
#define HERO_POSITION_JUMP_6 8 // Sprong is op bovenste rij 
#define HERO_POSITION_JUMP_7 9 // Halfweg omlaag 
#define HERO_POSITION_JUMP_8 10 // bijna landen 
#define HERO_POSITION_RUN_UPPER_1 11 // Held rent op bovenste rij (pose 1) 
#define HERO_POSITION_RUN_UPPER_2 12 // (pose 2) 
LiquidCrystal lcd(11, 9, 6, 5, 4, 3); 
static char terrainUpper[TERRAIN_WIDTH + 1]; 
static char terrainLower[TERRAIN_WIDTH + 1]; 
static bool buttonPushed = false; 
void initializeGraphics(){ 
  static byte graphics[] = { 
    // Renpositie 1 
    B01100, B01100, B00000, B01110, B11100, B01100, B11010, B10011, 
    // Renpositie 2 
    B01100, B01100, B00000, B01100, B01100, B01100, B01100, B01110, 
    // Sprong 
    B01100, B01100, B00000, B11110, B01101, B11111, B10000, B00000, 
    // Sprong lager 
    B11110, B01101, B11111, B10000, B00000, B00000, B00000, B00000, 
    // Grond 
    B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111, 
    // Grond rechts 
    B00011, B00011, B00011, B00011, B00011, B00011, B00011, B00011, 
    // Grond links 
    B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000, 
  }; 
  int i; 
  // Karakter 0 overslaan, dit stelt lcd.print() in staat om snel meerdere tekens te tekenen 
  for (i = 0; i < 7; ++i) { 
    lcd.createChar(i + 1, &graphics[i * 8]); 
  } 
  for (i = 0; i < TERRAIN_WIDTH; ++i) { 
    terrainUpper[i] = SPRITE_TERRAIN_EMPTY; 
    terrainLower[i] = SPRITE_TERRAIN_EMPTY; 
  } 
} 
// Schuif het terrein naar links in half-teken stappen 
void advanceTerrain(char* terrain, byte newTerrain){ 
  for (int i = 0; i < TERRAIN_WIDTH; ++i) { 
    char current = terrain[i]; 
    char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1]; 
    switch (current){ 
      case SPRITE_TERRAIN_EMPTY: 
        terrain[i] = (next == SPRITE_TERRAIN_SOLID) ? SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY; 
        break; 
      case SPRITE_TERRAIN_SOLID: 
        terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_SOLID_LEFT : SPRITE_TERRAIN_SOLID; 
        break; 
      case SPRITE_TERRAIN_SOLID_RIGHT: 
        terrain[i] = SPRITE_TERRAIN_SOLID; 
        break; 
      case SPRITE_TERRAIN_SOLID_LEFT: 
        terrain[i] = SPRITE_TERRAIN_EMPTY; 
        break; 
    } 
  } 
} 
bool drawHero(byte position, char* terrainUpper, char* terrainLower, unsigned int score) { 
  bool collide = false; 
  char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION]; 
  char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION]; 
  byte upper, lower; 
  switch (position) { 
    case HERO_POSITION_OFF: 
      upper = lower = SPRITE_TERRAIN_EMPTY; 
      break; 
    case HERO_POSITION_RUN_LOWER_1: 
      upper = SPRITE_TERRAIN_EMPTY; lower = SPRITE_RUN1; 
      break; 
    case HERO_POSITION_RUN_LOWER_2: 
      upper = SPRITE_TERRAIN_EMPTY; lower = SPRITE_RUN2; 
      break; 
    case HERO_POSITION_JUMP_1: 
    case HERO_POSITION_JUMP_8: 
      upper = SPRITE_TERRAIN_EMPTY; lower = SPRITE_JUMP; 
      break; 
    case HERO_POSITION_JUMP_2: 
    case HERO_POSITION_JUMP_7: 
      upper = SPRITE_JUMP_UPPER; lower = SPRITE_JUMP_LOWER; 
      break; 
    case HERO_POSITION_JUMP_3: 
    case HERO_POSITION_JUMP_4: 
    case HERO_POSITION_JUMP_5: 
    case HERO_POSITION_JUMP_6: 
      upper = SPRITE_JUMP; lower = SPRITE_TERRAIN_EMPTY; 
      break; 
    case HERO_POSITION_RUN_UPPER_1: 
      upper = SPRITE_RUN1; lower = SPRITE_TERRAIN_EMPTY; 
      break; 
    case HERO_POSITION_RUN_UPPER_2: 
      upper = SPRITE_RUN2; lower = SPRITE_TERRAIN_EMPTY; 
      break; 
  } 
  if (upper != ' ') { 
    terrainUpper[HERO_HORIZONTAL_POSITION] = upper; 
    collide = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true; 
  } 
  if (lower != ' ') { 
    terrainLower[HERO_HORIZONTAL_POSITION] = lower; 
    collide |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true; 
  } 
  byte digits = (score > 9999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1; 
  // Teken de scene 
  terrainUpper[TERRAIN_WIDTH] = '\0'; 
  terrainLower[TERRAIN_WIDTH] = '\0'; 
  char temp = terrainUpper[16-digits]; 
  terrainUpper[16-digits] = '\0'; 
  lcd.setCursor(0,0); 
  lcd.print(terrainUpper); 
  terrainUpper[16-digits] = temp; 
  lcd.setCursor(0,1); 
  lcd.print(terrainLower); 
  lcd.setCursor(16 - digits,0); 
  lcd.print(score); 
  terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave; 
  terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave; 
  return collide; 
} 
// Afhandelen van knopindruk als interrupt 
void buttonPush() { 
  buttonPushed = true; 
} 
void setup(){ 
  pinMode(PIN_READWRITE, OUTPUT); 
  digitalWrite(PIN_READWRITE, LOW); 
  pinMode(PIN_CONTRAST, OUTPUT); 
  digitalWrite(PIN_CONTRAST, LOW); 
  pinMode(PIN_BUTTON, INPUT); 
  digitalWrite(PIN_BUTTON, HIGH); 
  pinMode(PIN_AUTOPLAY, OUTPUT); 
  digitalWrite(PIN_AUTOPLAY, HIGH); 
  // Digitale pin 2 wordt afgebroken op interrupt 0 
  attachInterrupt(0/*PIN_BUTTON*/, buttonPush, FALLING); 
  initializeGraphics(); 
  lcd.begin(16, 2); 
} 
void loop(){ 
  static byte heroPos = HERO_POSITION_RUN_LOWER_1; 
  static byte newTerrainType = TERRAIN_EMPTY; 
  static byte newTerrainDuration = 1; 
  static bool playing = false; 
  static bool blink = false; 
  static unsigned int distance = 0; 
  if (!playing) { 
    drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper, terrainLower, distance >> 3); 
    if (blink) { 
      lcd.setCursor(0,0); 
      lcd.print("Press Start"); 
    } 
    delay(250); 
    blink = !blink; 
    if (buttonPushed) { 
      initializeGraphics(); 
      heroPos = HERO_POSITION_RUN_LOWER_1; 
      playing = true; 
      buttonPushed = false; 
      distance = 0; 
    } 
    return; 
  } 
  // Schuif het terrein naar links 
  advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY); 
  advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY); 
  // Maak nieuw terrein dat rechts binnenkomt 
  if (--newTerrainDuration == 0) { 
    if (newTerrainType == TERRAIN_EMPTY) { 
      newTerrainType = (random(3) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK; 
      newTerrainDuration = 2 + random(10); 
    } else { 
      newTerrainType = TERRAIN_EMPTY; 
      newTerrainDuration = 10 + random(10); 
    } 
  } 
  if (buttonPushed) { 
    if (heroPos <= HERO_POSITION_RUN_LOWER_2) heroPos = HERO_POSITION_JUMP_1; 
    buttonPushed = false; 
  } 
  if (drawHero(heroPos, terrainUpper, terrainLower, distance >> 3)) { 
    playing = false; // De held botste tegen iets. Jammer. 
  } else { 
    if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos == HERO_POSITION_JUMP_8) { 
      heroPos = HERO_POSITION_RUN_LOWER_1; 
    } else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <= HERO_POSITION_JUMP_5) && terrainLower[HERO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) { 
      heroPos = HERO_POSITION_RUN_UPPER_1; 
    } else if (heroPos >= HERO_POSITION_RUN_UPPER_1 && terrainLower[HERO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) { 
      heroPos = HERO_POSITION_JUMP_5; 
    } else if (heroPos == HERO_POSITION_RUN_UPPER_2) { 
      heroPos = HERO_POSITION_RUN_UPPER_1; 
    } else { 
      ++heroPos; 
    } 
    ++distance; 
    digitalWrite(PIN_AUTOPLAY, terrainLower[HERO_HORIZONTAL_POSITION + 2] == SPRITE_TERRAIN_EMPTY ? HIGH : LOW); 
  } 
  delay(100); 
} 

Schema's

Geen document.

Productieproces

  1. TinyML Taaldetector met Edge Impulse op Arduino Nano 33 BLE Sense
  2. Bouw een real-time gyroscoop-spel met Arduino Nano & MPU-6050 sensor
  3. Arduino Digitale Dobbelsteen: Bouw Je Eigen LCD-willekeurige Getalgenerator
  4. Bouw Je Eigen 37-LED Roulette-spel met Arduino Nano
  5. DIY Arduino USB Gaming Controller – Bouw Je Eigen High-Performance Gamepad
  6. Interactieve Joystick Game met Arduino en LED Feedback
  7. Find Me: Slimme Item Locator met Arduino en Bluetooth
  8. Pixel Chaser: Interactieve één-tik LED-spel met Arduino Nano
  9. Zelfbouw Arduino Nano Oscilloscoop (10 Hz – 50 kHz) met 128×64 LCD
  10. Een audio-reactieve bureaulamp bouwen met Arduino Nano
  11. NeoPixel Matrix Pong op Arduino Nano: Bouw je eigen neon Pong-spel