工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Arduino、Google Cardboard、Bluetoothで作るDIY VRスケートボード

必要なパーツと材料

パーツ数量備考
Arduino UNO1Leonardo推奨(Unoの場合は配線が異なる)
HC-06 Bluetoothモジュール1デフォルト名「HC-06」、パスワード「1234」
Androidデバイス1Google Cardboard対応必須
Google Cardboard VRヘッドセット1スマートフォン装着型
ジャンパーワイヤー1式
GY-521 MPU-6050 3軸ジャイロ+加速度センサー1ヘッダーピンのはんだ付け必要

必要なアプリとオンラインサービス

プロジェクト概要

古いスケートボードをVRスノーボードコントローラーに変える、約1時間で完成する楽しいプロジェクトです。スケートボードの底面にMPU-6050加速度/ジャイロセンサーとArduinoを搭載し、ボードの傾きをBluetoothでAndroidスマートフォンに送信します。Unityで作成したVRゲーム(Android用)と連携し、体重移動で左右に曲がり、フロントウィールを持ち上げるとジャンプします。

追加で必要なもの

Androidアプリ、Arduinoコード、パーツ購入リンクは こちら から入手可能です。

手順1:Arduinoデバイス(送信機)の組み立て

写真の通りに配線してください。MPU-6050にはヘッダーピンをはんだ付けする必要があります。はんだごての先が綺麗なら約11秒で完了しますが、酸化しているとかなり困難になります。

重要: 写真と全く同じ向きで部品を配置してください。コードの修正が不要になります。スケートボードへの取り付けも写真通りに行ってください(特にMPU-6050の向き)。バッテリーボックスはホットグルーで固定し、Arduino基板はネジ止めすると安定します。

Arduino Unoを使用する場合の配線違い:

Leonardoの場合はSDA/SCLピンを直接使用できます。

手順2:Arduinoコードのアップロード

重要: コードをアップロードする前に、BluetoothモジュールのRX/TXピンをArduinoから外してください。

提供されているコードは、MPU-6050のDMP(Digital Motion Processor)を使用してヨー・ピッチ・ロールを計算し、閾値に基づいて「前進」「後進」「左」「右」「停止」のコマンドをシリアル(Bluetooth)経由で送信します。

手順3:スマートフォンにアプリをインストール

  1. 提供リンクからAPKをダウンロード
  2. Androidの設定で「提供元不明のアプリ」インストールを許可
  3. Bluetooth設定でHC-06とペアリング(パスワード:1234)
  4. スケートボードを平らな場所に置き、Arduinoの電源をON
  5. アプリを起動すると自動的にBluetooth接続され、ゲームが開始

注意点:

回路図

Arduino、Google Cardboard、Bluetoothで作るDIY VRスケートボード

Arduinoコード

#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);   // Uno用
  Serial1.begin(9600);  // Leonardo用
  
  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  Serial.println(F("Testing device connections..."));
  Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
  
  Serial.println(F("Initializing DMP..."));
  devStatus = mpu.dmpInitialize();
  
  // キャリブレーション値(個体差により調整必要)
  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpu.setZAccelOffset(1788);
  
  if (devStatus == 0) {
    Serial.println(F("Enabling DMP..."));
    mpu.setDMPEnabled(true);
    Serial.println(F("Enabling interrupt detection..."));
    attachInterrupt(0, dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();
    Serial.println(F("DMP ready! Waiting for first interrupt..."));
    dmpReady = true;
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }
}

void sendData(int x, int y, int z) {
  if(z < -10){ // 前進
    Serial1.write("f"); Serial1.write(10);
    Serial.write("f"); Serial.write(10);
  } else if (z > 0){ // 後進
    Serial1.write("b"); Serial1.write(10);
    Serial.write("b"); Serial.write(10);
  } else if (y > 5){ // 右
    Serial1.write("r"); Serial1.write(10);
    Serial.write("r"); Serial.write(10);
  } else if (y < -5){ // 左
    Serial1.write("l"); Serial1.write(10);
    Serial.write("l"); Serial.write(10);
  } else { // 停止
    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;
}

製造プロセス

  1. 自作LUMAZOID:Arduino音楽ビジュアライザーDIYガイド
  2. Arduino Nanoで水滴を高速撮影 – DIYハイスピードフォトグラフィ
  3. Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
  4. JX Wave Generator – Arduino互換DDS発振器(OLEDディスプレイ搭載)
  5. 自作Arduino J.A.R.V.I.S. 音声アシスタント - アークリアクター風デザイン
  6. DIY ArduinoラジオニクスEMR治療デバイスの構築
  7. Arduino NanoとSG90サーボで作るDIY 2軸モーションレーシングシミュレータ
  8. Arduino UNOとNEO-6MモジュールでGPS目的地通知装置を作る
  9. ArduRadio:Arduino自作FMラジオ付き目覚まし時計
  10. Arduinoテニスゲーム:NeoPixelマトリクス・9DoFセンサー・Bluetoothで作るバーチャルラケット体験
  11. Arduinoで作るポータブルRFIDドアロック - ステップバイステップガイド