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

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

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

Компонент Количество
ATtiny85 (Microchip) 1
Графический OLED-дисплей 128x64 (I2C) 1
Плата разъема micro USB (SparkFun microB USB Breakout) 1
Arduino Nano R3 (для программирования ATtiny85) 1

Инструменты

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

О проекте

История и вдохновение

В 2017 г. я делал портативную консоль Pong на Arduino Nano и OLED. Она была громоздкой. Теперь цель — крошечная консоль с игрой Snake на ATtiny85.

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

Выбор компонентов

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

Пайка схемы

ATtiny85 на переходнике SOP-8 → DIP-8 на макетной плате. Два разъема: для программирования и для экрана. Джойстик и micro USB breakout подпаяны к периферии.

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

Проектирование корпуса

Спроектирован в Fusion 360: компоненты размещены, вокруг построен корпус в стиле аркадного автомата 80-х. Файлы STL в разделе CAD.

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

Программирование Snake

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками
Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

Игровой процесс

Включаем, ждем загрузки еды и первого сегмента. Управляем джойстиком. Игра увлекательна и убивает скуку в миниатюрном формате.

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

Код (ATtiny85, C/C++)

Требуется библиотека U8g2lib (установите через Library Manager).

//#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], tempPosition1[2];
int segmentLength = 1;

void gameUpdate();
enum DIRECTIONS { RIGHT, DOWN, LEFT, UP } currentDirection;

void setup() {
  //TinyWireM.begin();
  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] && segmentPositions[i][Y] == headPosition[Y]) return 1;
  }
  if(headPosition[X] <= 0 || headPosition[X] >= 128) return 1;
  if(headPosition[Y] <= 0 || headPosition[Y] >= 64) return 1;
  return false;
}

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

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();
}

3D-модели

Файлы STL доступны в репозитории проекта.

Схемы

Мини-аркада на ATtiny85: Snake — ручная OLED-консоль своими руками

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

  1. TinyML-детектор языка на Arduino Nano 33 BLE Sense с Edge Impulse
  2. Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
  3. Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
  4. Создание рулетки на 37 светодиодов с Arduino Nano
  5. Портативный дальномер на Arduino Nano: HC-SR04, питание 18650, 3D-корпус
  6. Сборка аудиореактивной настольной лампы на Arduino Nano
  7. Медное гальваническое покрытие: умная система на Arduino UNO
  8. NeoPixel Matrix Pong на Arduino Nano: неоновая игра Pong на матрице 15×10
  9. Создание потрясающих световых последовательностей с Arduino и сдвиговым регистром
  10. Умная розетка 120В на Arduino с часами реального времени