木製きかんしゃ◯ーマスの動力車を作ったよ


※この記事は11月28日のenebular developer meetup で発表した内容をベースに追記しています。

はじめに

UXデザイナーの どたてつや です。

僕はエンジニアではないのですが、
普段はUI設計やUX開発などの仕事の傍ら、こんなのこんなののプロトタイプなどを作ったりしています。
ココ数年はEテキスタイルを使った作品づくりが多いのですが、
今回は(子供の)趣味と実益を兼ねて、
3DプリントとArduino、enebularを使って既製品と組み合わせられるおもちゃを作ってみました。

木製きかんしゃ◯ーマス

子どもたちのアイドル、きかんしゃ◯ーマスの木製玩具です。

◯ーマスと言えばプラレールが主流かと思いますが、
このおもちゃは木製の車両とレールで手触り感がよく、
見た目も(比較的)落ち着いているので弊家ではこちらを採用しております。
最近レールの仕様が変更されてしまいましたが、仕様変更前の旧版であればBRIOとも併用可能です。

課題

しかしこの◯ーマス、自走するわけではなくあくまで手で押して遊ぶものです。
よってレールを組み立てて自走する様子を眺める、というような事ができません。
(前述したBRIOには自走できる車両も売っています)

解決方法

そこで◯ーマスと接続して走らせる自走車両を自分で作ってしまおうと目論みました。

なんとなくの制作方針の決定

3Dプリンタをほとんど使ったことがなく、
実際にきちんとレール上を走ってくれるかが不安なので、2ステップですすめることにしました。

1. サイズ感の検証をするための「アナログ版」を作る

2. 1.をベースに「マイコン版」を作る

ここから制作ログ

寸法計測

既存製品のパーツのサイズを計測していきます。
ここで得た値は次のパーツ選定時や、3Dデータを作成する際の基準にしました。

◯ーマスだけでなく、レールやトンネルの高さなども忘れず計測しています。

各種パーツ選定

計測したサイズに合わせて、
既製品が必要なスイッチや電池ボックス、ギヤボックスを選定します。

タミヤ 低速ギヤボックス

ぶっちゃけ今回の制作はこのモーターなしでは成り立ちません。
タミヤの楽しい工作シリーズで木製◯ーマスに適合するサイズのギヤボックスはこれだけでした。
このギアボックスはギア比を4種類選べるのですが、今回は一番回転速度が速いギヤ比74.1:1を使用しました。

電池ボックス

アナログ版用のスタンダードな電池ボックスです。
本体サイズに収めまるように、左右の仕切りは切り落としました。

6Pトグルスイッチ

どこのメーカーでもいいのですが、
タミヤのエレメカシリーズにいい感じのトグルスイッチがあったの採用しました。

ネオジム磁石

木製◯ーマスは磁石で連結されているので、その部分用のドーナツ型磁石を購入しました。
僕は秋葉原の千石電商で購入しましたが、amazonかaliexpressでも安く手に入ります。

プラレールゴムタイヤ

プラスチックのタイヤだと摩擦が少なく滑ってしまうので採用しました。
ゴムリングも試しまてみましたが、これが一番うまく走行してくれました。

ステンレス棒

前輪の車軸に必要です。

アナログ版の3Dプリントデータ作成

Fusion360を使用してデータを作ります。

・・・・・と一言で言ってしまいましたがココが一番時間かかってます。
Fusion360もほぼ初心者で、空いた時間でチマチマやっていたため、
この工程と次の工程(3Dプリント)の往復で3ヶ月以上かかりました。

屋根の下に電池ボックスがあるので、屋根の取り外ししやすいようにスナップフィット構造にしてみました。

アナログ版を3Dプリント

できあがった3Dデータをパーツごとにプリントしていきます。

ABSの反りについて

自前のフィラメントがそれしかなくABSでで印刷しましたが、
ABS特性の反りにてこずり、山のような失敗ボディが出来上がりました。
余談ですが最終的に一番効果的だったソリューションは
「ラフト印刷後に一旦止めてマスキングテープで固定する」
でした。

組みたて

パーツ単位で印刷されたボディを組み合わせアナログ版完成!

アナログ版が無事に走行できたことを確認して、マイコン版を実装します。

マイコン版の制作

上記のアナログ版でおおよそ動くようになったのでマイコン版を作ります。
モータードライバはDVR8830を使用しました
またマイコンはサイズ的にちょうどよくバッテリーも搭載しているM5StickCにしてます。

マイコン版のために3Dデータを修正

アナログ版の電池ボックスエリアにM5StickCが入るように修正します。
また、トグルスイッチもオミットしたので不要な仕切りも取り除きます。

Arduino

Wifi経由でFirebaseの値を読み取り、DB内の値が切り替わったときにモーターの処理を走らせるようにしています。

drv8830.ino
#include <IOXhop_FirebaseESP32.h>

#include <WiFi.h>
#include <M5StickC.h>

#define FIREBASE_DB_URL "XXXX.firebaseio.com"
#define FIREBASE_DB_AUTH "XXXXXXXXXXXXXXXXXXXXXXXXX"
#define FIREBASE_DB_DATA "/message"

#define WIFI_SSID "XXXXX"
#define WIFI_PASSWORD "XXXXX"


// ブリッジ制御
#define M_STANBY  B00   // スタンバイ   
#define M_REVERSE B01   // 逆転
#define M_NORMAL  B10   // 正転
#define M_BRAKE   B11   // ブレーキ

const bool ONLINE = true;//オンラインモード
const int DRV8830 = 0x60;


int changeFlag = true;//値変更時だけtrue
int dir = 0; //進行方向 0:停止 1:正転 2:逆転
byte vset = 0x21;
boolean atfst = true;

void writeResister(byte vset, byte data1) {
  int vdata = vset << 2 | data1;
  Wire.beginTransmission(DRV8830);
  Wire.write(0x00);
  //Wire.write(vset);
  Wire.write(vdata);
  Wire.endTransmission(true);
}

void setup() {
  M5.begin();
  // put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin(0, 26); //SDA, SCL
  Serial.println("Standby");
  writeResister(0x00, 0x00);
  delay(500);

  //WIFI セットアップ
  if (ONLINE) {
    WiFi.mode(WIFI_STA);
    WiFi.disconnect(true);
    delay(1000);
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    Serial.println("connecting");

    while (WiFi.status() != WL_CONNECTED) {
      Serial.print(".");
      delay(500);
      Serial.print(WiFi.status());
      Serial.print(",");
    }
    Serial.println();
    Serial.print("connected: ");
    Serial.println(WiFi.localIP());
    delay(500);
  }

  Firebase.begin(FIREBASE_DB_URL, FIREBASE_DB_AUTH);

  Firebase.stream(FIREBASE_DB_DATA, [](FirebaseStream stream) {
    String eventType = stream.getEvent();
    eventType.toLowerCase();
    Serial.print("event: ");
    Serial.println(eventType);
    if (atfst) {
      atfst = false;
    } else if (eventType == "put") {
      int data = stream.getDataInt();
      Serial.print("data: ");
      Serial.println(data);
      changeFlag = true;
      dir = data;
    }
  });
}


void loop() {
  // put your main code here, to run repeatedly:

  byte v;
  if (changeFlag) {
    writeResister(0x00, 0x00
    );
    delay(500);
    if (dir == 0) {
      v = 0x00;
    } else {
      v = vset;
    }
    writeResister(v, byte(dir));
    changeFlag = false;
  }
}

eneblar設定

flowはこれだけです

今回はウェブ上から操作できるようにnode-red-dashboardを使用しました。
上記フローではenebular上で操作できるボタンとウェブ上から操作できるUI両方ついています。

Firebase設定

こちらの記事を参考に設定しました。
enebular editorでローカル上でダッシュボードを試してみよう

完成!!!

できたーーー
ただM5StickCは無駄に高機能なので、
今後はESP32の他のボードを使ってバッテリー容量も増量したバージョンを作りたいです。

今回制作するにあたって大変だったこと

今回の制作にあたり、一番の課題はこれでした。

既製品と組み合わせる

既に寸法が決まっているので、サイズを合わせれば良いだけかと思っていたのですが、
内部にパーツを入れなくてはいけない都合上、同じ寸法にできない箇所が多々ありました。
これは設計後、実際に作ってみてから見えてくる部分も多かったです。

ちなみに3DプリントデータはThingiverseにアップしてます
https://www.thingiverse.com/thing:4053693
(マイコン版はアナログ盤との差分パーツだけアップしてます。)

エンジニアでないので、
ここが甘い!とかもっとこうしたほうがいい!とかあればぜひ教えて下さい! ではでは。