はじめに
NX開発推進部Android開発グループ所属の深沢と申します。今回は、Maker Faire Tokyoに参加し、出展物作成までの過程を振り返りたいと思います。Maker Faireとは何かについては公式サイトをご参照ください。
全4回投稿予定です。本記事は第3回になります。
- 【Maker Faire Tokyo 2023】 おしゃべりぱくちゃんず作成までの道のり(1)~企画・検証編~
- 【Maker Faire Tokyo 2023】おしゃべりぱくちゃんず作成までの道のり(2)~ボディ製造編~
前回の記事ではボディについて説明しましたが、今回は同時に作成していたぱくちゃんの内部機構の設計~完成までに試行錯誤したことなどを紹介したいと思います。
作成するもの
ぱくちゃんは口を上下運動させるようにしなくてはなりません。そこで、今回はモーターと機構を用いてモーターの回転運動を上下運動に変換するようにしようということになりました。
イメージ図
回転運動→上下運動
クランク作成
ぱくぱくと上下運動させるにはモーターの回転運動を上下運動に変える必要があります。まずは私が知っていたクランク機構を試してみることにしました。fusion360というモデリングができるソフトでスライダクランクを作成している動画を見つけたので、この動画を参考に作成してみました。
fusion360はblenderに比べて角度や長さなどを細かく設定することができ、パーツをモデリングするのに適しているとされています。感覚的な部分が少ない分、個人的にはblenderよりもfusion360のほうがモデリングを行いやすかったです。
fusion360で作成したスライダクランク
作成したクランクを見てみると、回転運動を上下運動に変換して動いていることを確認できました。しかし、クランクでぱくちゃんを持ち上げるにはある程度のサイズと強度が必要なことがわかり、これを担保できそうになかったため、この機構はボツとしました。
カム機構への転換
次に検討したのがカム機構でした。この機構はカムという楕円や多角形の板をモーターに取り付け、中心からの距離の差により上下運動を実現する方法を取ります。
カム機構イメージ図
これだと縦の収まりも良く、ぱくぱく動いてくれそうです。fusion360でパーツごとにモデリングを行い印刷しました。
しかし、実際に印刷して収納しようとしたところ、下画像の赤色のパーツが大きすぎて収納ができませんでした。そこで、反対に小さくしようとサイズを下げると、カムが小さくなってしまい全然上下に動きません。しかも、台の強度が弱くなり、安定しないという問題にぶつかってしまいました。
赤い部分のパーツが大きすぎてぱくちゃんに収まらなかった
どう修正しようかと悩んでいるときに別の形のカム機構を紹介しているサイトがありましたので、そちらのカム機構に切り替えてみようということになりました。
別のカム機構へ変更
新しいカム機構は台に上下させる棒(follower)とカムが沿う形になっており、収納面においてもかなり良さそうです。この新カム機構を作成してみることになりました。
その結果、新カム機構を元にした機構で上手くぱくちゃんを動かすことができました。
作成したパーツは以下のとおりです。
- 台座:下半球に入っている電池ボックスの上に載せるパーツ。これにカム機構のパーツを組み合わせていきます。スピーカーをのせるために手前にへこみを作り、スピーカーがカムを回しやすくするために奥の台の高さを調整しました。
-
follower:カムの回転に応じて動くパーツ。これが実際にぱくちゃんの上半球を押し上げて行きます。直方体ですと、followerが飛び出してしまうことがあったため先を横長にしてbaseに引っかかるようにしました。
-
base:これにfollowerとカムを組み合わせ、穴からモーターの先を出してカムと繋げます。そして台座の穴にbaseの下部分を差し込みます。差し込みやすいように先端だけ幅を狭くしました。
-
カム:穴にモーターの先を差し込みます。モーターと連動して回転することでfollowerを押し上げます。 多角形のカムだと力のかかり方が一定でなく、場所によって大きな力が必要になるため今回は丸形にしました。
動きの流れは以下のとおりです。
1. モーターが回ると連動して円形のカムが回る
2. カムが回るとカムの上に配置されているfollowerが上下する
3. followerがぱくちゃんの上部を押し上げる
組み合わせた新カム機構
これらパーツの調整は後述のモーター選定と並行して行いました。モーターが決まったあとに、どのようにパーツを作成すればもっとぱくぱくするのかということを考えながら調整していきました。
fusion360は触ったことがなかったのではじめは不安でしたが、使ってみると意外と簡単でどんどん思い通りのものを作れるようになりました。
モーター制御
回路の調整と改良
実装検証から得た結果をもとに、回路のブラッシュアップを行いました。主な変更点は以下の通りです。
- マイコンをM5StickC PlusからATOM Echoに変更
- ATOM Echoへの電池供給を追加
- 抵抗,トランジスタ,モーターの変更
実装検証ではM5StickC Plusでモーターを制御していましたが、M5StickC PlusにはスピーカーがないためATOM Echoに変更しました。そして、ぱくちゃんは電源コードなどをつけずに個体内で完結させたかったため、電源を電池に変更し、ATOM Echoにも電池ボックスを用いて電池をつなげるようにしました。
抵抗やトランジスタの値はモーターに合わせて変更していきました。モーター選定については次の章でお話します。
モーター選定
検証に使用していたモーターはサイズが大きく収納が難しいため、別途モーターの選定を行いました。ぱくちゃんの内部に収められるサイズのモーターを使いたかったので入手しやすいTAMIYAのトルクチューンモーターを試してみました。
トルクが高いのが特徴ということで、ぱくちゃんの上半球を持ち上げられるのではないかと思い試すことにしました。
以下がトルクチューンモーターを組み込んでぱくぱくさせている動画です。
ぱくぱくと動いているように見えます。しかし、実際はモーターの回転数が早すぎてしまいモーターが空回りしていました。GIFなのでこの記事からはわかりませんが、実際はモーターやカムが回転している音がとても大きく、後で実装するおしゃべり機能も聞こえなくなりそうな状態でした。
音や空回りを改善するには回転数を下げる必要があります。そこで、コード制御で回転数を下げたのですが、今度は力が足りずに持ち上がらないという問題にぶつかりました。
そのため、回転数は少なく力は大きいモーターを探す必要があるということがわかりました。
モーターについて色々調べている中でギアモーターというものを発見しました。これは、回転速度を力に変換してくれるモーターで、今私達が探しているモーターにピッタリのものでした。
変換率のようなものも色々な種類がありましたので、数種類のギアモーターを試した結果、1000RPMのものが一番条件に合いそうだという結論に至りました。
モーターが決まった結果、回路は以下のようになりました。
上図の回路図を基に回路は基盤にはんだ付けをして作成しました。
作成した回路。本番に向けて10個ほど作成しました。
モーター制御コード
ぱくちゃんに内蔵しているのATOM Echoからモーターを制御するコードです。
採用したモーターはDCモーターなので単純にPINの状態をHIGHにすると回転し、LOWにすると停止します。
const uint8_t OUT25 = 25; void setup() { // 省略 pinMode(OUT25, OUTPUT); // 省略 } void moveMotor() { digitalWrite(OUT25, HIGH); } void stopMotor() { digitalWrite(OUT25, LOW); } |
音声再生
おしゃべり実装
次におしゃべり機能について説明します。企画内容を詰めていく中でぱくちゃんはわかるようでわからない言葉を発したら良いのではないかという話になりましたので、この案を基に複数の音声ファイル(WAV)を作成しました。
ATOM Echoに音声ファイルを送るためには大きく2種類の方法がありました。
①音声ファイルをコード内に埋め込んでスケッチとして書き込む方法
②SPIFFSにファイルを書き込む
音声ファイル選定の過程での追加や削除を頻繁に行うことを考えると①の方法が楽だと感じたので、この方法を採用しました。
実際に音声ファイル「wav214493937780745.wav」をコードにすると下記のようになります。
#include <stdint.h> #ifndef WAV214493937780745_H #define WAV214493937780745_H const uint8_t wav214493937780745[66766] = { 0x52, 0x49, 0x46, 0x46, 0xc6, 0x04, 0x01, 0x00, 0x57, 0x41, 0x56, 0x45, // 中略 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; #endif |
このようにWAVファイルを変数として定義することで、簡単に音声を再生することができます。
// Wavファイルから作った変数で音声を再生する M5.Speaker.playWav(wav214493943017905, sizeof(wav214493943017905), 1, false); |
ぱくちゃんらしい音声を探っていくうちに多数のWAVファイルができたため、hファイルを生成する簡単なシェルを書いて試行錯誤しやすくなるよう工夫しました。
#!/bin/bash if [ "$#" -ne 1 ]; then echo "Usage: $0 " exit 1 fi input=$1 dirpath=$(dirname "$input") filename=$(basename "$input") # ファイル名を取得 (例: "file.txt") name="${filename%.*}" # 拡張子を取り除く (例: "file") output="${dirpath}/wav${name}.h" size=`wc -c "$input" | awk '{print $1}'` echo "#include " > "$output" echo "#ifndef WAV${name}_H" >> "$output" echo "#define WAV${name}_H" >> "$output" echo "" >> "$output" echo "const uint8_t wav$name[$size] = {" >> "$output" # xxdを使用してWAVデータを16進数でダンプし、適切なフォーマットで出力 xxd -i "$input" | sed '/^unsigned/d' | sed '/^,/d' >> "$output" echo "#endif" >> "$output" echo "Output written to $output" |
これでぱくちゃんがおしゃべりしてくれる様になりました。
おしゃべりしながら動く
モーター制御と音声再生ができたので、おしゃべりしながら動くようコードをまとめました。
struct WavData { const uint8_t* data; size_t size; }; WavData randomSelectSound() { // シード設定 std::srand(static_cast(std::time(nullptr))); // 0から9のランダムな値を取得 int choice = std::rand() % 10; Serial.print("choice: "); Serial.println(choice); switch(choice) { case 0: return {wav214493943017905, sizeof(wav214493943017905)}; case 1: return {wav214493943018019, sizeof(wav214493943018019)}; case 2: return {wav214493938940363, sizeof(wav214493938940363)}; case 3: return {wav214493938940581, sizeof(wav214493938940581)}; case 4: return {wav214493942968998, sizeof(wav214493942968998)}; case 5: return {wav214493942971711, sizeof(wav214493942971711)}; case 6: return {wav214493943017290, sizeof(wav214493943017290)}; case 7: return {wav214493943017329, sizeof(wav214493943017329)}; case 8: return {wav214493943017350, sizeof(wav214493943017350)}; case 9: return {wav214493943017492, sizeof(wav214493943017492)}; } return {nullptr, 0}; } void speakTask(void *arg) { // 喋る前に動かす moveMotor(); // ランダムな音声を再生 WavData wavData = randomSelectSound(); M5.Speaker.playWav(wavData.data, wavData.size, 1, false); // 動きを止める stopMotor(); vTaskDelete( NULL ); } |
想定通りに動いたが、、、
こうして回路とコードが完成し、いざ動かしてみたところ、音声を再生している間だけモーターを回すという想定通りの挙動をしてくれました。
しかし、よく観察してみるとおしゃべり音がモーターや周りの音に負けてしまいよく聞こえません。
ATOM Echoのスピーカーについて調べてみると0.7Wだということがわかりました。そこで外付けのスピーカー(3W)を購入して付け替えてみたところ、音量が大きく改善されました。
ATOM Echo内蔵スピーカー(左)と外付けスピーカー(右)
ぱくちゃんに取り付けた外付けスピーカー
こうしてぱくちゃんの機能はすべて実装完了しました。
ぱくちゃん中身収納について
機能としては問題なく動くようになったのですが、この時のぱくちゃんは中の回路などが飛び出してしまっており、とても人前には出せないような見栄えになっていました。
そこで、次はどうすればぱくちゃんのボディに中身をすべて収納できるかを考えました。
中身が飛び出しているぱくちゃん
まずは、かなり嵩張っていたATOM Echoをコンパクトにできないかと外装を剥がしてみることにしました。
剥がしてみるとかなり小さくなり、ぱくちゃんに収めやすくなりました。
ATOM Echo の外装(左)と中身(右)
また、収納のために配線を短くしてカムいたのですが、配線がカム機構に絡まってしまいカムが途中で止まってしまうということがありました。
そこで反対に配線を長くしてぱくちゃんの下半球の中をぐるっと回すようにしたところ、絡まらず収納することができました。
このように工夫したことで無事ボディに回路や機構を収めることができました!
以下がぱくちゃん中身の収納位置と実際の写真です。
さいごに
以上がぱくちゃん中身試行錯誤編でした。回路の作成やはんだづけなど色々やることがある中で、カム機構の作成が一番大変でした。自分が作成したパーツ同士を組み合わせていくので、途中で噛み合わなくなり、上手く動かないということが頻発しました。5パーツに分けて印刷したのですが、そのうち4パーツは30個くらいのモデリングと印刷を行いました。色々試していく中でなんとか形になりました。
今回の記事ではぱくちゃんの中身について紹介しました。
次の記事は【Maker Faire Tokyo】 おしゃべりぱくちゃんず作成までの道のり(4)~通信機・まとめ編~と題して、ぱくちゃんを動かす通信機や当日の様子について触れたいと思います。