Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Composants et fournitures

ComposantQuantité
Microcontrôleur ATtiny85 (Microchip Technology)1
Écran OLED graphique 128 x 641
Module USB microB SparkFun (breakout)1
Arduino Nano R3 (pour programmer l'ATtiny85)1

Outils et machines nécessaires

Applications et services en ligne

À propos de ce projet

Inspiration et projet antérieur

En décembre 2017, j'ai créé une console portable Arduino Pong avec un Arduino Nano, un écran OLED et deux boutons.

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Elle fonctionnait mais était trop encombrante. Récemment, j'ai voulu recréer certains de mes anciens projets, mais cette fois en très petit : une console miniature pour jouer à Snake.

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Les composants choisis

Pour la miniaturisation, impossible d'utiliser une carte de développement Arduino standard → choix de l'ATtiny85.

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Il offre assez d'entrées/sorties : deux pins ADC, un port I2C et un GPIO. J'ai opté pour un module joystick 2 axes avec bouton, facile à interfacer (3 pins de signal).

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Pour l'affichage, l'écran OLED 128 x 64 de DFRobot offre une bonne résolution dans un format réduit.

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Soudure du système

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED
ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED
  1. Soudez l'ATtiny85 sur un adaptateur SOP-8 vers DIP-8, puis sur un morceau de perfboard.
  2. Ajoutez deux connecteurs : un pour la programmation, un pour l'écran.
  3. Soudez les pins du joystick analogique et câblez-le.
  4. Câblez une carte breakout micro USB pour l'alimentation.

Conception de l'enceinte

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED
ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

L'enceinte a été conçue dans Fusion 360 : création des composants réels, puis boîtier autour. Objectif : évoquer une borne d'arcade des années 80 tout en restant minuscule.

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED
ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Programmation du jeu

Snake est simple à programmer. Longueur max du serpent fixée à 30 pour économiser la RAM : au-delà de 29 segments mangés, le joueur gagne. Pour suivre les segments, j'utilise un tableau 2D stockant les coordonnées (x,y) de chaque segment.

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

À chaque déplacement de la tête, les positions précédentes se décalent. À chaque pomme mangée, un nouveau segment apparaît aléatoirement. La détection de collision parcourt les coordonnées de chaque segment pour voir si la tête les chevauche. Toucher les bords fait aussi perdre.

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Jouer à Snake

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Allumez la console, attendez l'affichage de la première pomme et du premier segment. Pilotez le serpent avec le joystick. C'est amusant, un excellent tueur d'ennui dans un format minuscule.

Code

Code ATTiny85 C/C++

Installez d'abord la bibliothèque U8g2lib

//#include <TinyWireM.h>
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g(U8G2_R0, /* clock=*/ 2, /* data=*/ 0, /* reset=*/ U8X8_PIN_NONE);
#define MAX_LENGTH 30
#define X 0
#define Y 1
#define JOYSTICK_X 2
#define JOYSTICK_Y 3
#define DIR_THRESH 300
uint8_t segmentPositions[MAX_LENGTH][2];
uint8_t headPosition[2] = {63, 31};
uint8_t foodPosition[2];
uint8_t tempPosition0[2];
uint8_t tempPosition1[2];
int segmentLength = 1;
void gameUpdate();
enum DIRECTIONS { RIGHT, DOWN, LEFT, UP } currentDirection;

void setup() {
  u8g.begin();
  u8g.setPowerSave(0);
  pinMode(JOYSTICK_X, INPUT);
  pinMode(JOYSTICK_Y, INPUT);
  randomSeed(analogRead(0));
  beginGame();
}

void loop() {
  u8g.firstPage();
  do {
    gameUpdate();
    u8g.setColorIndex(1);
  } while(u8g.nextPage());
}

void beginGame(){
  currentDirection = RIGHT;
  spawnFood();
  delay(1000);
}

bool checkCollisions(){
  for(int i=1; i<segmentLength; i++){
    if(segmentPositions[i][X] == headPosition[X]){
      if(segmentPositions[i][Y] == headPosition[Y]) return 1;
    }
  }
  if(headPosition[X] <= 0 || headPosition[X] >= 128) return 1;
  else if(headPosition[Y] <= 0 || headPosition[Y] >= 64) return 1;
  return false;
}

void spawnFood(){
  int randomX = random(5, 123);
  int randomY = random(5, 60);
  foodPosition[X] = randomX;
  foodPosition[Y] = randomY;
}

void checkFoodEaten(){
  if(headPosition[X] == foodPosition[X] || headPosition[Y] == foodPosition[Y]){
    segmentLength += 1;
    spawnFood();
  }
}

void updateDirection(){
  int joy_x_val = analogRead(JOYSTICK_X);
  int joy_y_val = analogRead(JOYSTICK_Y);
  if(joy_x_val <= DIR_THRESH) currentDirection = LEFT;
  else if(joy_x_val >= 1023-DIR_THRESH) currentDirection = RIGHT;
  else if(joy_y_val <= DIR_THRESH) currentDirection = UP;
  else if(joy_y_val >= 1023-DIR_THRESH) currentDirection = DOWN;
}

void displaySegments(){
  for(int segment=0; segment < segmentLength; segment++){
    u8g.drawPixel(segmentPositions[segment][X], segmentPositions[segment][Y]);
  }
  u8g.drawPixel(foodPosition[X], foodPosition[Y]);
}

void gameUpdate(){
  updateDirection();
  tempPosition0[X] = headPosition[X];
  tempPosition0[Y] = headPosition[Y];
  switch(currentDirection){
    case UP: headPosition[Y] -= 1; break;
    case DOWN: headPosition[Y] += 1; break;
    case LEFT: headPosition[X] -= 1; break;
    case RIGHT: headPosition[X] += 1; break;
  }
  for(int segment=1; segment < segmentLength; segment+= 2){
    tempPosition1[X] = segmentPositions[segment][X];
    tempPosition1[Y] = segmentPositions[segment][Y];
    segmentPositions[segment][X] = tempPosition0[X];
    segmentPositions[segment][Y] = tempPosition0[Y];
    tempPosition0[X] = segmentPositions[segment+1][X];
    tempPosition0[Y] = segmentPositions[segment+1][Y];
    segmentPositions[segment+1][X] = tempPosition1[X];
    segmentPositions[segment+1][Y] = tempPosition1[Y];
  }
  displaySegments();
  checkFoodEaten();
  if(checkCollisions()) endGame();
  if(segmentLength >= MAX_LENGTH) endGame();
  delay(50);
}

void endGame(){
  segmentLength = 1;
  headPosition[0] = 63;
  headPosition[1] = 31;
  beginGame();
}

Pièces personnalisées et boîtiers

(Fichiers STL disponibles dans le dépôt du projet)

Schémas

ATtiny85 Mini Arcade : Snake – Construire une console de jeu portable OLED

Processus de fabrication

  1. Détecteur de langue TinyML avec Edge Impulse sur Arduino Nano 33 BLE Sense
  2. Construire un jeu gyroscopique temps réel avec Arduino Nano et capteur MPU-6050
  3. Dé numérique Arduino sur écran LCD 16x2 – Générateur aléatoire à bouton poussoir
  4. Créer votre propre jeu de roulette à 37 LED avec Arduino Nano
  5. Détecteur de distance portable – Kit DIY Arduino Nano avec HC-SR04, alimentation 18650 et boîtier imprimé 3D
  6. Construire une lampe de bureau réactive à l'audio avec Arduino Nano
  7. Projet de galvanoplastie au cuivre : Construisez un système intelligent avec Arduino UNO
  8. Jeu Pong sur Matrice NeoPixel avec Arduino Nano
  9. Créez des séquences lumineuses époustouflantes avec un registre à décalage Arduino