DIY VR-Skateboard mit Arduino, Google Cardboard und Bluetooth bauen
Komponenten und Materialien
| Arduino UNO | 1 |
| HC-06 Bluetooth Modul | 1 |
| Android-Gerät | 1 |
| Google Cardboard VR-Headset | 1 |
| Jumper-Wires (diverse) | 1 |
| GY-521 MPU-6050 3-Achsen Gyroskop + Beschleunigungssensor Modul | 1 |
Apps und Online-Dienste
- Google Cardboard VR SDKs
Über dieses Projekt
Dies ist ein wirklich spaßiges und einfaches Projekt, das in etwa einer Stunde fertiggestellt werden kann. An der Unterseite des Skateboards befindet sich ein Beschleunigungs- und Gyrosensor mit einem Arduino-Board, der die Winkelbewegungen des Boards per Bluetooth an ein kleines VR-Spiel sendet, das ich in Unity für Android-Handys entwickelt habe. Sobald du den Arduino einschaltest und die Bluetooth-Verbindung mit deinem Handy hergestellt ist, bewegst du dich vorwärts. Lehne dich nach links, gehst du nach links; lehne dich nach rechts, gehst du nach rechts. Hebst du die Vorderräder an, springt dein Charakter.
Dies funktioniert nur mit Android-Handys, die mit Google Cardboard kompatibel sind. Wenn du also ein altes Skateboard herumliegen hast, verwandle es in ein virtuelles Reality-Snowboard. Hier ist die Anleitung:
Du wirst benötigen:
- Ein Google Cardboard VR-Headset
- Ein Skateboard
- 4 Tennisbälle (damit du nicht wegrollst)
- Einen Arduino Leonardo (oder Uno)
- Jumper-Wires
- Ein Mini-Breadboard
- Ein HC-06 Bluetooth Modul
- Einen MPU-6050 Beschleunigungs-/Gyrosensor
- Einen 9V-Batteriehalter mit Ein-/Ausschalter und Hohlstecker (für die Arduino-Stromversorgung)
- Einen Lötkolben und eventuell eine Heißklebepistole
Die Android-App, der Arduino-Code und die Teileliste mit Links findest du hier: wirebeings.com/virtual-reality-skateboard.html
Schritt 1: Arduino-Gerät / Sender / Eingabemodul zusammenbauen
Baue dein Gerät wie in den Bildern oben gezeigt zusammen. Du musst die Header-Pins auf den MPU-6050 löten – mit einer sauberen Lötspitze geht das in etwa 11 Sekunden. Mit einer schmutzigen, alten Spitze wird es schnell zur schwierigsten Aufgabe ever (aus Erfahrung).
Achte darauf, dass die Ausrichtung aller Komponenten genau wie in den Bildern gezeigt ist, damit du den Code nicht anpassen musst. Befestige alles am Skateboard exakt wie abgebildet (wichtig: der MPU6050 muss in dieselbe Richtung zeigen wie auf dem Bild).
Ich habe den Batteriehalter mit Heißkleber befestigt und das Arduino-Board verschraubt. Ich nutzte ein Old-School-Board, da ein breiteres Board für dieses Erlebnis besser geeignet ist. Balancieren auf einem Board in VR ist nämlich ziemlich schwer.
Hinweis: Der Leonardo funktioniert deutlich besser dafür. Falls du einen Arduino Uno nutzt, sind alle Verbindungen identisch, außer:
- SDA geht an A4
- SCL geht an A5
Schritt 2: Arduino-Code hochladen
WICHTIG: Ziehe die RX- und TX-Pins vor dem Hochladen des Codes vom Board ab.
Schritt 3: App auf dein Handy laden
Folge diesem Link und lade die App auf dein Handy herunter: Google Cardboard Virtual Reality Skateboard/Snowboard App.
Du musst in deinen Sicherheitseinstellungen die Installation von Apps unbekannter Entwickler erlauben. Kopple das Bluetooth-Modul mit deinem Handy, ändere den Standardnamen (HC-06) nicht. Das Passwort ist 1234.
Hinweise:
- Das ist mein erstes Unity-Spiel – es ist also ziemlich basic.
- Falls genug Leute das nachbauen, kann ich versuchen, ein besseres Snowboard-Spiel oder ein echtes Skateboard-Spiel zu machen – je nach Wunsch.
- Beim Einschalten des Arduino-Geräts muss das Skateboard flach auf dem Boden liegen. Öffne dann die App. Sobald Bluetooth verbindet, startest du.
- Falls die Bluetooth-Verbindung abbricht, starte die App neu (sie verbindet nur beim Start, vorerst).
Code
Arduino Code
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 mpu;
bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint16_t fifoCount;
uint8_t fifoBuffer[64];
Quaternion q;
VectorInt16 aa;
VectorInt16 aaReal;
VectorInt16 aaWorld;
VectorFloat gravity;
float euler[3];
float ypr[3];
volatile bool mpuInterrupt = false;
void setup() {
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
TWBR = 24;
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
Serial.begin(9600); // Für Arduino Uno
Serial1.begin(9600); // Für Leonardo
Serial.println(F("Initialisiere I2C-Geräte..."));
mpu.initialize();
Serial.println(F("Teste Geräteverbindungen..."));
Serial.println(mpu.testConnection() ? F("MPU6050 Verbindung erfolgreich") : F("MPU6050 Verbindung fehlgeschlagen"));
Serial.println(F("Initialisiere DMP..."));
devStatus = mpu.dmpInitialize();
mpu.setXGyroOffset(220);
mpU.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788);
if (devStatus == 0) {
Serial.println(F("Aktiviere DMP..."));
mpu.setDMPEnabled(true);
Serial.println(F("Aktiviere Interrupt-Erkennung (Arduino externer Interrupt 0)..."));
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
Serial.println(F("DMP bereit! Warte auf ersten Interrupt..."));
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
Serial.print(F("DMP-Initialisierung fehlgeschlagen (Code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
}
void sendData(int x, int y, int z) {
if(z < -10){ // vorwärts
Serial1.write("f"); Serial1.write(10); // Leonardo
Serial.write("f"); Serial.write(10); // Uno
} else if (z > 0){ // rückwärts
Serial1.write("b"); Serial1.write(10);
Serial.write("b"); Serial.write(10);
} else if (y > 5){ // rechts (empfindlicher: 4 oder weniger)
Serial1.write("r"); Serial1.write(10);
Serial.write("r"); Serial.write(10);
} else if (y < -5){ // links (empfindlicher: -4 oder mehr)
Serial1.write("l"); Serial1.write(10);
Serial.write("l"); Serial.write(10);
} else { // stop
Serial1.write("s"); Serial1.write(10);
Serial.write("s"); Serial.write(10);
}
}
void loop() {
if (!dmpReady) return;
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
fifoCount = mpu.getFIFOCount();
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
mpu.resetFIFO();
Serial.println(F("FIFO Overflow"));
} else if (mpuIntStatus & 0x02) {
while (fifoCount < packetSize) {
fifoCount = mpu.getFIFOCount();
}
mpu.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
sendData(ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI);
}
}
void dmpDataReady() {
mpuInterrupt = true;
}
Schaltplan
Der Schaltplan ist als Bild verfügbar (siehe Originalprojekt).
Herstellungsprozess
- Eigenen LUMAZOID bauen: DIY Arduino Musik-Visualisierer
- Wassertropfen-Hochgeschwindigkeitsfotografie mit Arduino Nano – DIY Setup
- Intelligentes Voltmeter mit Arduino & Smartphone bauen – Einfaches DIY-Projekt
- JX Wave Generator – Arduino-kompatibler DDS-Oszillator mit OLED-Display
- DIY Arduino J.A.R.V.I.S. Sprachassistent mit Arc-Reactor-Design
- DIY Radionik EMR-Behandlungsgerät mit Arduino Nano – Kritische Betrachtung
- DIY 2D-Motion-Rennsimulator mit Arduino Nano & SG90 Servos
- GPS-Zielanzeiger mit Arduino UNO & NEO-6M Modul bauen
- ArduRadio: DIY Arduino-Wecker mit FM-Radio (TEA5767)
- Arduino-Tennisspiel – Virtueller Schläger mit NeoPixel, Sensoren & Bluetooth