galoebn
Published © GPL3+

Wemos D1 - Minigame Console

In this project we will use a Wemos D1 Mini to create a tiny Minigame-console.

IntermediateShowcase (no instructions)7 hours936
Wemos D1 - Minigame Console

Things used in this project

Hardware components

Wemos D1 Mini
Espressif Wemos D1 Mini
×1
OLED 0.66 Shield
×1
Battery Shield
×1
Inertial Measurement Unit (IMU) (6 deg of freedom)
Inertial Measurement Unit (IMU) (6 deg of freedom)
×1

Story

Read more

Schematics

Schematics

The only thing to solder is the gyroscope. You have to make the connections as shown in the picture. You may also want to add a switch between the battery and the battery-module, because if you solder the battery to the module there would be no way to turn the device off. After you soldered the gyro to the battery-module the three modules (Wemos D1 mini, Battery Shield, OLED Display) can be stacked together with some header pins.

Code

Wemos Minigame

Arduino
Here is the code that you can upload to the Wemos D1 mini. You need to install the libraries "Adafruit_GFX" and "Adafruit_SSD1306".

I programmed four minigames and also added a function for charging (so that the screen is not on while charging). You can switch between the games by tilting the console far left/right. The brightness is also slightly adjustable by tilting the device forwards/backwards.
#include<Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);

const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;


void write_setup(int coordx, int coordy, int T_size){
  display.setTextSize(T_size);
  display.setCursor(coordx, coordy);
}


void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.println("Hello");

  display.display();
  delay(1000);
}


int jump(int t){
  return int(0.7*t*t - 11*t + 42);
}

void read_gyro(int16_t* AcX, int16_t* AcY, int16_t* AcZ){
    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
    *AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
    *AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    *AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
}


void title(char Str[]){
  display.clearDisplay();
  write_setup(0, 1, 2);
  display.println(Str);

  display.display();
  delay(1000);
  display.clearDisplay();
}


void jump(){
  while(true){
  title("Jump");
  display.fillRect(0,46,64,2,1);

  float adder = 1.9;
  bool b = true;
  int y = 42;
  int x = 15;  
  int t = 0;
  bool jumb = false;
  
 
  for(int j = 0; true; ++j){
    int b1x = 63;
    int b1y = random(28, 41);
    int b1_height = 46 - b1y;
    int b1_width = random(int(adder)*2, int(adder)*6);
    adder += 0.1;
 
    for(int i = 63 + b1_width + random(0, int(adder)*15); i > -b1_width;  i -= int(adder)){
      read_gyro(&AcX, &AcY, &AcZ);

      display.fillScreen(0);
      display.fillRect(i,b1y,b1_width,b1_height,1);
      display.fillRect(0,46,64,2,1);

      if(AcZ < -22800){jumb = true;}
      if(jumb && t<15){
        ++t;
        y = jump(t);
      }
      else{
        jumb = false;
        t = 0;
        y = 42;
      }
      
      display.drawCircle(x,y,3,1);
      write_setup(45,10,1);
      display.print(j);
      
      display.display();
      delay(1);

      if(i > 12 - b1_width && i < 19 && y + 4 > b1y){
        write_setup(1,11,1);
        display.print("Crash!");
        display.display();
        delay(1500);
        jump();
      }

      if(AcX > 12000){gravity();}
      else if(AcX < -8000){shoot();}
      if(AcY > 12000){display.dim(true);}
      else if(AcY < -12000){display.dim(false);}
    }
 
  }
  }
 
}


void gravity(){
  title("Catch");
  int x = 31;
  int y = 20;
  int Ay = 0;
  int Ax = 0;
  int t0 = millis();
  int t_rem = 10000;
  int count = 0;
  bool done = false;


  while(!done){
    int bx = random(8, 64);
    int by = random(8, 48);
    
    while(abs(x-bx) > 5 || abs(y-by) > 5){
      Ax = 0;
      Ay = 0;
      for(int i = 0; i < 5; i++){
        read_gyro(&AcX, &AcY, &AcZ);
        Ax += AcX;
        Ay += AcY;
        delay(3);
      }
      
      Ax /= 5;
      Ay /= 5;
      x = -3*int((Ax - 550)/400) + 30;
      y = -3*int((Ay + 265)/400) + 20;
      display.clearDisplay();
      if(x > 63){x = 63;}
      else if(x < 0){x = 0;}
      if(y > 47){y = 47;}
      else if(y < 0){y = 0;}

      write_setup(0,1,1);
      if((t_rem-(millis()-t0))/1000 > 12000){done = true; break;}
      display.print((t_rem-(millis()-t0))/1000);
      display.fillCircle(x, y, 3, 1);
      display.drawCircle(bx, by, 3, 1);
      display.display();
      delay(1);
  
      if(AcX < -12000){jump();}
      if(AcY > 12000){display.dim(true);}
      else if(AcY < -12000){display.dim(false);}
    }
    if(!done){count += 1;}
  }
  display.clearDisplay();
  write_setup(2,15,1);
  display.print("Score: ");
  display.print(count);
  display.display();
  delay(2000);
  gravity();
  
}


void shoot(){
  title("Shoot");
  int x = 0;
  int py = 42;
  int px = 0;
  bool shot = true;
  int f1x = random(0, 64);
  int f1y = -random(2, 50);
  int f2x = random(0,64);
  int f2y = -random(2, 15);
  int score = 0;
  int Ax = 0;

  while(true){
    
    while(true){
      for(int i = 0; i < 3; i++){
        read_gyro(&AcX, &AcY, &AcZ);
        Ax += AcX;
        delay(3);
      }

      Ax /= 3;
      display.clearDisplay();
      x = -3*int((Ax - 550)/400) + 30;
      Ax = 0;
      if(x > 59){x = 59;}
      else if(x < -5){x = -5;}
      display.fillRect(x, 45, 11, 3, 1);
      if(shot){px = x+5; shot = false;}
      display.fillRect(x+4, 42, 3, 3, 1);
      display.drawRect(px, py, 1, 3, 1);
      display.fillCircle(f1x, f1y, 2, 1);
      display.fillCircle(f2x, f2y, 2, 1);
      display.display();
      delay(1);

      if(py < -1){
        shot = true;
        py = 40;
      }

      if(abs(px-f1x) < 4 && py < f1y){
        shot = true;
        py = 42;
        f1x = random(0, 64);
        f1y = -random(5*(int(score/20)+1), 30*(int(score/12)+1));
        score += 1;
      }

      else if(abs(px-f2x) < 4 && py < f2y){
        shot = true;
        py = 42;
        f2x = random(0, 64);
        f2y = -random(4*(int(score/15)+1), 40*(int(score/12)+1));
        score += 1;
      }

      py -= 4*(int(score/15)+1);
      f1y += 1 + int(score/30);
      f2y += 1 + int(score/15);

      if(f1y > 46 || f2y > 46){
        delay(100);
        write_setup(3, 10, 1);
        display.print("Hit!");
        display.display();
        delay(1000);
        display.clearDisplay();
        write_setup(3, 10, 1);
        display.print("Score: ");
        display.print(score);
        display.display();
        delay(2000);
        shoot();
      }
      
      if(AcX < -12000){track();}
      else if(AcX > 12000){jump();}
      if(AcY > 12000){display.dim(true);}
      else if(AcY < -12000){display.dim(false);}
    }
  }
}


void track(){
  title("Track");
  int x;
  int Ax = 0;
  int coord[54];
  int p = 15;
  unsigned int dist = 0;
  for(int i = 0; i < 54; i+=2){
    coord[i] = random(0,65);
    coord[i+1] = random(0,49);
  }
  int line1[2] = {30, 48};
  int line2[2] = {37, 0};
  int line3[2] = {28, -48};
  
  while(true){
    for(int i = 0; i < 3; i++){
        read_gyro(&AcX, &AcY, &AcZ);
        Ax += AcX;
        delay(3);
      }

      Ax /= 3;
      display.clearDisplay();
      x = -3*int((Ax - 550)/400) + 30;
      Ax = 0;
      if(x > 59){x = 59;}
      else if(x < -5){x = -5;}

      for(int i = -3; i < 4; i++){
        display.drawLine(line1[0]+i, line1[1], line2[0]+i, line2[1], 1);
        display.drawLine(line2[0]+i, line2[1], line3[0]+i, line3[1], 1);
      }
      
      
      for(int i = 0; i < 54; i+=2){
        display.drawPixel(coord[i], coord[i+1], 1);
      }
      display.fillCircle(x, 42, 3, 0);
      display.drawCircle(x, 42, 4, 1);
      display.display();
      delay(1);

      float h = p*(line2[0]-line1[0])/64;
      if(abs(x - (line1[0] + h)) > 8 + abs(4*h/p) && p < 48){
        if(AcX < -12000){charging();}
        else if(AcX > 12000){shoot();}
        if(AcY > 12000){display.dim(true);}
        else if(AcY < -12000){display.dim(false);}
        display.fillCircle(x, 42, 4, 0);
        display.drawCircle(x, 42, 3, 1);
        display.display();
        delay(150);
        display.fillCircle(x, 42, 3, 0);
        display.drawCircle(x, 42, 2, 1);
        display.display();
        delay(150);
        display.fillCircle(x, 42, 2, 0);
        display.drawCircle(x, 42, 1, 1);
        display.display();
        delay(200);
        display.clearDisplay();
        write_setup(1,5,1);
        display.println("Distance: ");
        display.print(dist);
        display.display();
        delay(2000);
        track();
      }


      p += 2 + dist/500;
      line1[1] += 2 + dist/500;
      line2[1] += 2 + dist/500;
      line3[1] += 2 + dist/500;
      dist += 1;

      if(line2[1] > 48){
        line1[0] = line2[0]; line1[1] = line2[1];
        line2[0] = line3[0]; line2[1] = line3[1];
        line3[0] = random(3, 61); line3[1] = -48;
        p = 15;
      }


      if(AcX < -12000){charging();}
      else if(AcX > 12000){shoot();}
      if(AcY > 12000){display.dim(true);}
      else if(AcY < -12000){display.dim(false);}
  }
}


void charging(){
  display.clearDisplay();
  write_setup(0,1,1);
  display.println("Charge");
  display.display();
  delay(2000);
  display.clearDisplay();
  display.display();

  while(true){
    read_gyro(&AcX, &AcY, &AcZ);    
    if(AcX > 12000){track();}
    delay(10);
  }
}


void loop(){
  gravity();
}

Credits

galoebn

galoebn

9 projects • 3 followers

Comments