In this project you will be building a steering wheel game controller, that communicates to python using the serial port. Then, python will communicate with Unity through sockets, allowing you to translate data from the gyro to actions in the game.
WiringHere is the wiring schematic for this project. I used a Mega 2560 and a MPU-6050 gyro. For Arduino types other than Mega 2560, you may need to plug in SCL and SDA into A4 and A5. Check online for more resources regarding wiring for other boards.
Upload this code onto your arduino!
#include<Wire.h>
#include <Streaming.h>
const int MPU_addr=0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
int pitch, roll;
void setup(){
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(9600);
}
void loop(){
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr,14,true);
AcX=Wire.read()<<8|Wire.read();
AcY=Wire.read()<<8|Wire.read();
AcZ=Wire.read()<<8|Wire.read();
Tmp=Wire.read()<<8|Wire.read();
GyX=Wire.read()<<8|Wire.read();
GyY=Wire.read()<<8|Wire.read();
GyZ=Wire.read()<<8|Wire.read();
roll = atan2(AcY , AcZ) * 180.0 / PI;
pitch = atan2(-AcX , sqrt(AcY * AcY + AcZ * AcZ)) * 180.0 / PI;
Serial << roll << endl;
delay(55);
}
Python CodeRun the following code on an IDE. I recommend setting up a virtual environment with PyCharm to run this script.
import serial
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
HOST = "127.0.0.1" # Standard loopback interface address (localhost)
PORT = 5052 # Port to listen on (non-privileged ports are > 1023)
def checkLeft(data):
return data and int(data) < 150 and int(data) >= 0
def checkRight(data):
return data and int(data) < 150 and int(data) >= 0
def readserial(comport, baudrate):
ser = serial.Serial(comport, baudrate, timeout=0.1) # 1/timeout is the frequency at which the port is read
num = 0
while True:
data = ser.readline().decode().strip()
if data and int(data) < 150 and int(data) >= 0:
print("right")
sock.sendto(str.encode("right"), (HOST, PORT))
elif data and int(data) > -150 and int(data) <= 0:
print("left")
sock.sendto(str.encode("left"), (HOST, PORT))
elif data and abs(int(data)) > 150:
print("center")
sock.sendto(str.encode("center"), (HOST, PORT))
# print(data)
while True:
readserial('COM4', 9600)
Unity EnvironmentThe scripts used in the Unity project are attached.
1. Create a new Unity project
2. Create a simple track with a plane and a couple of cubes as obstacles.
3. Create an empty game object and attach the Main Camera to it.
4. Create a rectangular prism for the car (or a 3D model if you have one)
5. Give the car rigid body and box collider components.
5. Attach the Car Drive and UDP Recieve scripts to the car object.
6. Under the Manager field in the Car Drive script, drag and drop the UDP Receive script.
7. The speed, turn speed, and gravity multiplier fields in Car Drive should be 3, 1.25, and 5 respectively.
7. Set the UDP Receive port to 5052
10. Drag the camera script onto the empty game object that the main camera is attached to.
11. Smoothing and Rot Smoothing on the camera script should be 0.3 and 0.1 respectively.
12. Finally, drag and drop the car game object onto the Player field in the camera script.
3D Printing (Optional)If you want, you can 3D-print a mount to hold all the electronics. A 3D-Model is attached to this post - however, you should double-check the dimensions of your components and make sure each slot is oriented properly in the 3D model. You will likely have to make changes to the model before printing it.
Putting It All TogetherAfter wiring the circuit, upload the Arduino code onto your Arduino board. Then, close the Arduino IDE and run the python script while the Arduino is still connected to the computer. The Arduino will broadcast gyro data to the serial port, which is read by the python script. The python script then checks the angle given by the data and determines whether the gyro is tilted left, right, or not at all. You should hold the gyro so that the longer edge of the module, the side with no pins, faces towards the ground. The circuitry on the module should face away from you and the pins should point at you. Avoid tilting the module too far forwards and backwards - only tilt it left and right. Once the Arduino is plugged in and the python script is running, you can start the game in Unity. The UDP receive script will read the data that python is spitting out via socket. It will then translate this data into motion of the in-game car!
Comments