Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
hassankamran107
Published © GPL3+

Control games using arduino, mpu6050 and python

I am controlling my asphalt 8 game using my old upgraded bicycle. So let's see how it works

AdvancedFull instructions provided4,286
Control games using arduino, mpu6050 and python

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
6 DOF Sensor - MPU6050
DFRobot 6 DOF Sensor - MPU6050
×1
Pushbutton Switch, Pushbutton
Pushbutton Switch, Pushbutton
×2
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE
python

Story

Read more

Schematics

Circuit Diagram

diagram is very easy and simple so connect wire, upload the program and enjoy

Code

directkey.py

Python
this is additional program required for port2.py so place them in same folder while running port2.py but don't run this, Only run port2.py that will automatically import the requirement from this program file
import ctypes
import time

SendInput = ctypes.windll.user32.SendInput


W = 0x11
A = 0x1E
S = 0x1F
D = 0x20

NP_2 = 0x50
NP_4 = 0x4B
NP_6 = 0x4D
NP_8 = 0x48

# C struct redefinitions 
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time",ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]

# Actuals Functions

def PressKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

if __name__ == '__main__':
    PressKey(0x11)
    time.sleep(1)
    ReleaseKey(0x11)
    time.sleep(1)

Arduino_game_code.ino

Arduino
Upload this code to your arduino uno
#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);

void setup() {
  Serial.begin(9600);   //start the serial communication
  Wire.begin();         // start I2C communication for comunicating with MPU6050
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
  pinMode(A1,INPUT);            // throttle button signal pin
  pinMode(A0,INPUT);            // brake button signal pin
}

void loop() {
  mpu6050.update();
  if(mpu6050.getAngleZ()>25 && digitalRead(A0))   // check if forward(throttle) and left
   Serial.println('q');                           // print 'q' on the serial port
  else if(mpu6050.getAngleZ()<-25 && digitalRead(A0))   // check if forward(throttle) and right
   Serial.println('e');                                 // print 'e' on the Serial Port
  else if(mpu6050.getAngleZ()>25 && digitalRead(A1))    // check if backward(brake) and left 
   Serial.println('z');                                 // print 'z' on the Serial Port
  else if(mpu6050.getAngleZ()<-25 && digitalRead(A1))   // check if backward(brake) and right 
   Serial.println('c');                                 // print 'c' on the Serial Port 
  else if(digitalRead(A0))                              // check if forward(throttle)
   Serial.println('w');                                 // print 'w' on the serial port
  else if(digitalRead(A1))                              // check if backward(brake)
   Serial.println('s');                                 // print 's' on the Serial 
  else if(mpu6050.getAngleZ()>25)                       // check if left 
  Serial.println('a');                                  // print 'a' on the Serial Port
  else if(mpu6050.getAngleZ()<-25)                      // check if right
  Serial.println('d');                                  // print 'd' on the Serial Port
}

port1.py

Python
before trying this install pyautogui by the command "pip install pyautogui", try this first if doesn't then try port2.py
# this is port1.py, first python program if this doesn't work on your game then use port2.py

import time
import pyautogui as pg
import serial

print("i wil give input after 5s so")
for i in range(5):
    print(i, end = "\n")
    time.sleep(1)
ser = serial.Serial('COM3', baudrate=9600, timeout=1)   # change COM3 to your port in which arduino is connected
while True:
    portdata = ser.readline().decode('ascii')           # read the data comming from arduino
    if len(portdata) == 0:
        print("no data comming........", end = "\n")    # port is connected but no data is avaliable on serial port
        ser.flushInput()
    if len(portdata) != 0:                              # if data is avaliable on the serial port
        if portdata[0] == 'q':                          # check the data
            pg.keyDown('w')                             #simulate key input
            pg.keyDown('a')
            time.sleep(0.2)
            pg.keyUp('w')
            pg.keyUp('a')
            ser.flushInput()                            # clear the queues of data on Serial port that stored while simulating key input
        elif portdata[0] == 'e':
            pg.keyDown('w')
            pg.keyDown('d')
            time.sleep(0.2)
            pg.keyUp('w')
            pg.keyUp('d')
            ser.flushInput()
        elif portdata[0] == 'z':
            pg.keyDown('s')
            pg.keyDown('a')
            time.sleep(0.2)
            pg.keyUp('s')
            pg.keyUp('a')
            ser.flushInput()
        elif portdata[0] == 'c':
            pg.keyDown('s')
            pg.keyDown('d')
            time.sleep(0.2)
            pg.keyUp('s')
            pg.keyUp('d')
            ser.flushInput()
        elif portdata[0] == 'w':
            pg.keyDown('w')
            time.sleep(0.1)
            pg.keyUp('w')
            ser.flushInput()
        elif portdata[0] == 's':
            pg.keyDown('s')
            time.sleep(0.1)
            pg.keyUp('s')
            ser.flushInput()
        elif portdata[0] == 'a':
            pg.keyDown('a')
            time.sleep(0.1)
            pg.keyUp('a')
            ser.flushInput()
        elif portdata[0] == 'd':
            pg.keyDown('d')
            time.sleep(0.2)
            pg.keyUp('d')
            ser.flushInput()

port2.py

Python
this is port2.py, second python program use this if first one doesn't work, and this also need a additional program file so also place that on the same folder am also giving that additional program
# check this program if work then Enjoy , this will probably work on all high end games(Direct X games)

import serial
import time
from directkey import PressKey, ReleaseKey, W, A, S, D

ser = serial.Serial('COM3', baudrate=9600, timeout=1)   # change COM3 to your port in which arduino is connected
while True:
    portdata = ser.readline().decode('ascii')           # read the data comming from arduino
    if len(portdata) == 0:
        print("no data comming........", end = "\n")    # port is connected but no data is avaliable on serial port
        ser.flushInput()
    if len(portdata) != 0:                              # if data is avaliable on the serial port
        if portdata[0] == 'q':                          # check the data
            PressKey(W)                                 #simulate key input
            PressKey(A)
            time.sleep(0.2)
            ReleaseKey(W)
            ReleaseKey(A)
            ser.flushInput()                            # clear the queues of data on Serial port that stored while simulating key input
        elif portdata[0] == 'e':
            PressKey(W)
            PressKey(D)
            time.sleep(0.2)
            ReleaseKey(W)
            ReleaseKey(D)
            ser.flushInput()
        elif portdata[0] == 'z':
            PressKey(S)
            PressKey(A)
            time.sleep(0.2)
            ReleaseKey(S)
            ReleaseKey(A)
            ser.flushInput()
        elif portdata[0] == 'c':
            PressKey(S)
            PressKey(D)
            time.sleep(0.2)
            ReleaseKey(S)
            ReleaseKey(D)
            ser.flushInput()
        elif portdata[0] == 'w':
            PressKey(W)
            time.sleep(0.2)
            ReleaseKey(W)
            ser.flushInput()
        elif portdata[0] == 's':
            PressKey(S)
            time.sleep(0.2)
            ReleaseKey(S)
            ser.flushInput()
        elif portdata[0] == 'a':
            PressKey(A)
            time.sleep(0.2)
            ReleaseKey(A)
            ser.flushInput()
        elif portdata[0] == 'd':
            PressKey(D)
            time.sleep(0.2)
            ReleaseKey(D)
            ser.flushInput()

Credits

hassankamran107
1 project • 4 followers
Contact

Comments

Please log in or sign up to comment.