はじめに
物理部部長のH崎です。
この記事では今年製作したオムニホイールについて紹介したいと思います。
※パンジャンドラムではありません
オムニホイールとは?
まずはこの写真を見てみて下さい。
んん? 車輪の上に車輪がついてる、、、
と思ったあなた、なかなか勘が鋭い!
このようにオムニホイールは車輪の外周に回転方向に対して垂直の方向で車輪がついています。
なぜ垂直?
この動画を見てもらうのが一番わかりやすいと思います。
普通の車輪の場合、横方向に対する動きは摩擦が大きく、滑らかに移動することができません。
しかし、オムニホイールの場合、横方向に対して新たに車輪がついてるため、摩擦なく全方向に移動することができます。
まあ、音展に来てもらうのが一番なんですけどねww
ということで、北館4F物理講義室でお待ちしています。
作り方(ハード編)
必要な主な材料は以下の通りです。
- オムニホイール × 4
- ステッピングモーター(NEMA17) × 4
- Arduino UNO × 1
- A4988 ×4
- BLE4.0モジュール × 1
- 12V電源アダプター × 1
- モーター固定用の金具 × 4
- MDF版など(土台)
↑自作モーターシールド(A4988とArduinoを接続)
↑A4988とBLEモジュールを接続したところ(旧バージョン)
実はオムニホイールを使った作品は去年も展示していました。
車輪を見るとわかるのですが、オムニホイールを買う資金がなかったので、自分で設計して3Dプリンタで印刷しました。印刷時間は合計二日にも及びます。そこそこの出来ではありましたが、純正品とは滑らかさの点で比べ物になりませんでした。
作り方(ソフト編)
去年のバージョンはパソコンの画面上でマウスを動かして操作するという、ユーザービリティのかけらもないような仕様でしたが、今年は違います。
スマホから操作できます!!
これは大きいのではないでしょうか。多分赤ちゃんでも操作できます(今時の子供はスマホリテラシーが高い)
具体的にはBlynkというアプリを用いて、BLE経由でコマンドをオムニホイール車に送信しています。
ソースコード
#include <TimerOne.h> | |
#include <BlynkSimpleSerialBLE.h> | |
#define BLYNK_USE_DIRECT_CONNECT | |
#define STEP1 12 | |
#define STEP2 10 | |
#define STEP3 7 | |
#define STEP4 5 | |
#define DIR1 11 | |
#define DIR2 9 | |
#define DIR3 6 | |
#define DIR4 4 | |
int counter, c, p0, p1, p2, p3; | |
char auth[] = "enter your passcode"; | |
BLYNK_WRITE(V0){ | |
p0 = param.asInt(); | |
} | |
BLYNK_WRITE(V1){ | |
p1 = param.asInt(); | |
} | |
BLYNK_WRITE(V2){ | |
p2 = param.asInt(); | |
} | |
BLYNK_WRITE(V3){ | |
p3 = param.asInt(); | |
} | |
void setup() { | |
pinMode(STEP1, OUTPUT); | |
pinMode(DIR1, OUTPUT); | |
pinMode(STEP2, OUTPUT); | |
pinMode(DIR2, OUTPUT); | |
pinMode(STEP3, OUTPUT); | |
pinMode(DIR3, OUTPUT); | |
pinMode(STEP4, OUTPUT); | |
pinMode(DIR4, OUTPUT); | |
digitalWrite(DIR1, LOW); | |
digitalWrite(DIR2, LOW); | |
digitalWrite(DIR3, LOW); | |
digitalWrite(DIR4, LOW); | |
Timer1.initialize(150); //マイクロ秒単位で設定 | |
Timer1.attachInterrupt(timer1); | |
Serial.begin(115200); | |
Blynk.begin(Serial, auth); | |
} | |
void loop() { | |
Blynk.run(); | |
if (p0 < 0) { | |
digitalWrite(DIR2, LOW); | |
digitalWrite(DIR3, HIGH); | |
} else { | |
digitalWrite(DIR2, HIGH); | |
digitalWrite(DIR3, LOW); | |
} | |
if (p1 < 0) { | |
digitalWrite(DIR1, HIGH); | |
digitalWrite(DIR4, LOW); | |
} else { | |
digitalWrite(DIR1, LOW); | |
digitalWrite(DIR4, HIGH); | |
} | |
if (p2 == 1) { | |
digitalWrite(DIR1, HIGH); | |
digitalWrite(DIR2, HIGH); | |
digitalWrite(DIR3, HIGH); | |
digitalWrite(DIR4, HIGH); | |
} else if (p3 == 1) { | |
digitalWrite(DIR1, LOW); | |
digitalWrite(DIR2, LOW); | |
digitalWrite(DIR3, LOW); | |
digitalWrite(DIR4, LOW); | |
} | |
} | |
void timer1() { | |
int s = abs(p0); | |
int j = abs(p1); | |
if (p0 != 0 && c < s) { | |
digitalWrite(STEP2, HIGH); | |
digitalWrite(STEP3, HIGH); | |
delayMicroseconds(15); | |
digitalWrite(STEP2, LOW); | |
digitalWrite(STEP3, LOW); | |
} | |
if (p1 != 0 && c < j) { | |
digitalWrite(STEP1, HIGH); | |
digitalWrite(STEP4, HIGH); | |
delayMicroseconds(15); | |
digitalWrite(STEP1, LOW); | |
digitalWrite(STEP4, LOW); | |
} | |
if (p2 == 1 || p3 == 1) { | |
digitalWrite(STEP1, HIGH); | |
digitalWrite(STEP2, HIGH); | |
digitalWrite(STEP3, HIGH); | |
digitalWrite(STEP4, HIGH); | |
delayMicroseconds(15); | |
digitalWrite(STEP1, LOW); | |
digitalWrite(STEP2, LOW); | |
digitalWrite(STEP3, LOW); | |
digitalWrite(STEP4, LOW); | |
} | |
c++; | |
if (c == 10) { | |
c = 0; | |
} | |
} |
完成!
どうでしょうか。真ん中の円をタッチして動かすだけで、その方向に移動するようになり、直感的な操作が可能になりました。
動かす大きさが大きいほど、早く移動するようになっています。また右回転や左回転にも対応しています。
ロボコンに出場する気はさらさらありませんので、これ以上の機能をつけるつもりはありません(風船割るとか)
オムニホイールの仕組みだけでも理解していただければ幸いです。