Arduinoメカナムホイールロボット自作ガイド:全方向移動を実現
このチュートリアルでは、あらゆる方向に移動できるArduinoメカナムホイールロボットの作り方を学びます。このユニークな移動性は、メカナムホイールと呼ばれる特殊なホイールによって実現されます。 以下の動画を見るか、書面チュートリアルをお読みください。 メカナムホイールは購入すると高価なので、自分で設計・3Dプリントしました。よく動作し、このロボット台車の操作は非常に楽しいです。NRF24L01無線トランシーバーモジュールで無線制御できます(私の場合、以前の動画で作ったDIY RC送信機を使用)。 スマートフォン経由のBluetooth制御も可能です。カスタムAndroidアプリであらゆる方向への移動と、スライダーでの速度制御ができます。 このロボット台車の頭脳はArduino Megaボードで、各ホイールを個別に制御します。各ホイールはNEMA 17ステッピングモーターに取り付けられ、ステッピングモーターは精密制御可能なため、アプリに自動動作プログラミング機能を追加しました。Saveボタンで各位置/ステップを保存し、自動でそれらを繰り返し実行できます。同じボタンで一時停止、リセット/全ステップ削除も可能です。 このメカナムホイールロボットを3Dモデリングソフトで設計しました。ベースプラットフォームはシンプルな箱型で、8mm厚MDFボードで作ります。 4つのステッピングモーターをプラットフォームに取り付け、モーターシャフトにメカナムホイールを装着。 Thangsで3Dモデルを探索・ダウンロードできます。 アセンブリ3Dモデルのダウンロード(Thangs) STLファイル(3Dプリント用): メカナムホイールは、円周にローラーが取り付けられたホイールです。これらのローラーはホイールの回転軸に対して斜め(45度)に配置されています。このため、ホイールが前後進すると斜め方向に力を発生させます。 ホイールを特定のパターンで回転させることで、これらの斜めの力を利用し、ロボットをあらゆる方向に動かせます。 左ねじれ(左手系)と右ねじれ(右手系)の2種類のメカナムホイールが必要です。違いはローラーの向きで、ロボット上の特定位置に正しく取り付ける必要があります。各ホイールのトップローラーの回転軸がロボットの中心を向くように配置します。 ホイール回転方向によるロボットの動きを簡単にデモします。 4輪すべて前進 → ロボット前進。すべて後退 → 後退。右移動:右ホイールを内側(ロボット中心方向)、左ホイールを外側に回転。斜め配置ローラーの合力で右に移動。左移動はその逆。対角線移動は2輪のみ回転させることで実現。 では実際の製作過程を見ていきましょう。ベースプラットフォームには8mm厚MDFボードを使用。テーブルソーで3Dモデルの寸法通りにカット。 3mmドリルと25mmフォルスタービットで側面パネルにステッピングモーター取り付け用の開口部を加工。木工用接着剤とネジで組み立て。最重要ポイントはモーター取り付け穴を精密に加工し、すべてのホイールが地面と均等に接触するようにすることです。 ベースプラットフォームは3Dプリントでも作れます(Web記事に3Dファイルを掲載)。最後にベースとカバーを白でスプレー塗装。 メカナムホイールの製作。購入すると高いため自作しました。ホイールは外側・内側の2パーツで、M4ボルト・ナットで固定。各10個のローラーと、NEMA 17ステッピングモーター専用のシャフトカプラーを備えます。 Creality CR-10 3Dプリンターで全パーツをプリント。 ローラー用シャフトを作ります。3mm径のスチールワイヤーを使用し、長さ約40mmにロータリーツールでカット。 ホイールの組み立て:2つの側面パーツとシャフトカプラーをM4ボルト・ナット4本で固定(ボルト長45mm)。 ローラー取り付け:内側パーツの円周上の穴にシャフトを少し通し、M3ワッシャー、ローラーを入れ、シャフトを外側パーツのスロットまで押し込みます。反対側にワッシャーを入れるスペースがなかったため1枚のみ使用。 10個すべてのローラーで同じ作業を繰り返し。簡単で楽しい作業です。ローラーが自由に回ることが重要です。 最後に内側の穴に瞬間接着剤を数滴垂らし、シャフトが緩まないようにします。 ホイールが完成したらロボット全体を組み立てます。まずステッピングモーターをベースプラットフォームに取り付け(M3ボルト12mm)。 ホイールをモーターシャフトに取り付け。シャフトカプラーにM3ナット用スロットがあり、M3ボルトでホイールをシャフトに固定できます。 トップカバー固定用に、ベースの2隅にネジロッドを立て、カバーにも同じ位置に穴を開けてカバーを着脱可能にしました。 ベース背面に電源スイッチ用20mm穴、LED用5mm穴を開けました。 電子部品の接続に移ります。完全な回路図はこちら。 4つのNEMA 17ステッピングモーターを4つのDRV8825ステッピングドライバー(A4988も可)で制御。ステッピングモーターとロボット全体の電源は12V(3S Li-Poバッテリーで約12V)。無線通信用にNRF24L01モジュール、Bluetooth通信用にHC-05モジュール。バッテリー電圧監視用の簡易分圧回路と、電圧が11V未満になったら点灯するLEDも搭載。 将来的にArduinoロボットアームプロジェクトと統合する予定で、サーボ駆動用5V(約3A)を供給する専用電圧レギュレーターも搭載しています(オプション)。 必要なコンポーネント: 電子部品を整理し配線をすっきりさせるため、EasyEDAでカスタムPCBを設計。このPCBはArduino MEGAシールドとして機能し、Arduino Megaボードの上に直接装着できます。表裏両層で配線。未使用のArduinoピンもピンヘッダーで引き出し、将来の拡張に対応。12V、5V、GND接続ピン、ドライバーのステップ分解能選択用ピンも搭載。 PCBプロジェクトファイルへのリンク。設計完了後、製造用ガーバーファイルを生成。 ガーバーファイル: スポンサーのJLCPCBに発注。 ガーバーファイルをドラッグ&ドロップでアップロード、ガーバービューアーで確認。問題なければ仕様を選択。今回はArduinoボードの色に合わせてPCB色を青に指定。初回注文なら最大10枚まで2ドルで注文可能。 数日後にPCB到着。品質は素晴らしく、設計通りの仕上がり。 PCBを組み立てます。小さな部品から:抵抗とコンデンサーをはんだ付け。Arduino接続用オスピンヘッダーを挿入・はんだ付け。 メスピンヘッダーを配置・はんだ付け。ステッピングモーター接続用とステップ分解能選択用にはオスピンヘッダーを使用(モーター直結、ジャンパーで分解能選択可能)。ターミナルブロック、トリマー、電圧レギュレーターをはんだ付け。 PCB完成。ドライバーを装着し、モーターを接続。まずステップ分解能選択用ジャンパーを装着。MS3ピンを5Vに接続して16分割ステップを選択。 その上にDRV8825ドライバーを装着、NRF24L01モジュールとHC-05 Bluetoothモジュールを接続。PCBをArduinoボードに装着。 バッテリーを適切なターミナルブロックに接続し、ベースプラットフォーム内に収納。 電源スイッチを取り付け、もう一方のターミナルブロックに接続。スイッチのすぐ上にバッテリー残量表示LEDも取り付け。 モーターをPCBに接続。重要:対向するモーターを接続する際、コネクターも対向させて接続します。これはプログラミング時に、例えば「前進」コマンドで両モーターが同じ方向に回るようにするためです(物理的には反対向きに取り付けられているため、一方は時計回り、他方は反時計回りになります)。 最後にカバーを被せて、メカナムホイールロボットプロジェクト完成です。 Arduinoコードを見てみましょう。実は2つの別々のコードがあります。1つはNRF24L01モジュールで制御するコード、もう1つはスマートフォンで制御するコードです。 NRF24L01モジュールでロボットを制御するArduinoコード: 解説: RF24ライブラリで無線通信、AccelStepperライブラリでステッピングモーター制御を行います。ピン定義、必要な変数宣言、setup()でステッピングモーターの最大速度設定と無線通信開始。 loop()ではRC送信機からのデータを読み取ります。RC送信機のコードと通信の詳細は専用チュートリアルをご覧ください。 受信データに応じて動作を決定。例えば左ジョイスティックを前方に倒すと値が160を超え、moveForward()を呼び出します。この関数は全モーター速度を正の値に設定するだけ。後退は負の値。他の方向も冒頭で説明した通りホイール回転を適切に設定します。 これらの命令を実行するため、loop()で全ステッピングモーターのrunSpeed()を呼び出します。また分圧回路からのアナログ入力でバッテリー電圧を読み取り、11V未満なら表示LEDを点灯させます。 スマートフォンでロボットを制御するArduinoコード: 解説: スマートフォン/Bluetooth制御用のコードも基本的に同じ仕組みです。無線モジュールの代わりにBluetoothモジュールを定義し、setup()で通信を初期化。スマートフォン/Androidアプリからの着信データを読み取り、それに応じてロボットの移動方向を指示します。 Androidアプリを見ると、ボタン押下時に0〜15の数字をBluetoothで送信しているだけです。 アプリはMIT App Inventorで作成。詳細は専用チュートリアルをご覧ください。 アプリと編集可能なプロジェクトファイルはこちらからダウンロードできます: このアプリで自動動作をプログラミングするには、「SAVE」ボタンでステッピングモーターの現在位置を配列に保存。「RUN」ボタンでrunSteps()カスタム関数を呼び出し、for/whileループで記録済みステップを実行します。 このチュートリアルがお役に立てば幸いです。質問はコメント欄でどうぞ。Arduinoプロジェクトコレクションもご覧ください。概要


メカナムホイールロボットの3Dモデル


メカナムホイールの仕組み


メカナムホイールロボットの製作















回路図

PCB設計




PCB組み立て








メカナムホイールロボット Arduinoコード
/* === Arduino Mecanum Wheels Robot === Radio control with NRF24L01 by Dejan, www.HowToMechatronics.com Libraries: RF24, https://github.com/tmrh20/RF24/ AccelStepper by Mike McCauley: https://www.airspayce.com/mikem/arduino/AccelStepper/index.html */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <AccelStepper.h>
RF24 radio(48, 49); // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 42, 43); // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2
AccelStepper RightBackWheel(1, 44, 45); // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4
int wheelSpeed = 1500;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte j1PotX;
byte j1PotY;
byte j1Button;
byte j2PotX;
byte j2PotY;
byte j2Button;
byte pot1;
byte pot2;
byte tSwitch1;
byte tSwitch2;
byte button1;
byte button2;
byte button3;
byte button4;
};
Data_Package data; //Create a variable with the above structure
void setup() {
// Set initial seed values for the steppers
LeftFrontWheel.setMaxSpeed(3000);
LeftBackWheel.setMaxSpeed(3000);
RightFrontWheel.setMaxSpeed(3000);
RightBackWheel.setMaxSpeed(3000);
radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.startListening(); // Set the module as receiver
Serial.begin(115200);
}
void loop() {
// Check whether we keep receving data, or we have a connection between the two modules
currentTime = millis();
if ( currentTime - lastReceiveTime > 1000 ) {
// If current time is more then 1 second since we have recived the last data, that means we have lost connection
resetData(); // If connection is lost, reset the data. It prevents unwanted behavior
}
// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
lastReceiveTime = millis(); // At this moment we have received the data
}
// Set speed - left potentiometer
wheelSpeed = map(data.pot1, 0, 255, 100, 3000);
if (data.j1PotX > 150) { moveSidewaysLeft(); }
else if (data.j1PotX < 100) { moveSidewaysRight(); }
else if (data.j1PotY > 160) { moveForward(); }
else if (data.j1PotY < 100) { moveBackward(); }
else if (data.j2PotX < 100 & data.j2PotY > 160) { moveRightForward(); }
else if (data.j2PotX > 160 & data.j2PotY > 160) { moveLeftForward(); }
else if (data.j2PotX < 100 & data.j2PotY < 100) { moveRightBackward(); }
else if (data.j2PotX > 160 & data.j2PotY < 100) { moveLeftBackward(); }
else if (data.j2PotX < 100) { rotateRight(); }
else if (data.j2PotX > 150) { rotateLeft(); }
else { stopMoving(); }
// Execute the steps
LeftFrontWheel.runSpeed();
LeftBackWheel.runSpeed();
RightFrontWheel.runSpeed();
RightBackWheel.runSpeed();
// Monitor the battery voltage
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.00) * 3;
// If voltage is below 11V turn on the LED
if (voltage < 11) { digitalWrite(led, HIGH); }
else { digitalWrite(led, LOW); }
}
void moveForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(0);
}
void resetData() {
// Reset the values when there is no radio connection - Set initial default values
data.j1PotX = 127;
data.j1PotY = 127;
data.j2PotX = 127;
data.j2PotY = 127;
data.j1Button = 1;
data.j2Button = 1;
data.pot1 = 1;
data.pot2 = 1;
data.tSwitch1 = 1;
data.tSwitch2 = 1;
data.button1 = 1;
data.button2 = 1;
data.button3 = 1;
data.button4 = 1;
}/* === Arduino Mecanum Wheels Robot === Smartphone control via Bluetooth by Dejan, www.HowToMechatronics.com Libraries: RF24, https://github.com/tmrh20/RF24/ AccelStepper by Mike McCauley: https://www.airspayce.com/mikem/arduino/AccelStepper/index.html */
#include <SoftwareSerial.h>
#include <AccelStepper.h>
SoftwareSerial Bluetooth(A8, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)
// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 42, 43); // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2
AccelStepper RightBackWheel(1, 44, 45); // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4
#define led 14
int wheelSpeed = 1500;
int dataIn, m;
int lbw[50], lfw[50], rbw[50], rfw[50]; // for storing positions/steps
int index = 0;
void setup() {
// Set initial seed values for the steppers
LeftFrontWheel.setMaxSpeed(3000);
LeftBackWheel.setMaxSpeed(3000);
RightFrontWheel.setMaxSpeed(3000);
RightBackWheel.setMaxSpeed(3000);
Serial.begin(38400);
Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
Bluetooth.setTimeout(1);
delay(20);
pinMode(led, OUTPUT);
}
void loop() {
// Check for incoming data
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read(); // Read the data
if (dataIn == 0) { m = 0; }
if (dataIn == 1) { m = 1; }
if (dataIn == 2) { m = 2; }
if (dataIn == 3) { m = 3; }
if (dataIn == 4) { m = 4; }
if (dataIn == 5) { m = 5; }
if (dataIn == 6) { m = 6; }
if (dataIn == 7) { m = 7; }
if (dataIn == 8) { m = 8; }
if (dataIn == 9) { m = 9; }
if (dataIn == 10) { m = 10; }
if (dataIn == 11) { m = 11; }
if (dataIn == 12) { m = 12; }
if (dataIn == 14) { m = 14; }
// Set speed
if (dataIn >= 16) { wheelSpeed = dataIn * 10; Serial.println(wheelSpeed); }
}
if (m == 4) { moveSidewaysLeft(); }
if (m == 5) { moveSidewaysRight(); }
if (m == 2) { moveForward(); }
if (m == 7) { moveBackward(); }
if (m == 3) { moveRightForward(); }
if (m == 1) { moveLeftForward(); }
if (m == 8) { moveRightBackward(); }
if (m == 6) { moveLeftBackward(); }
if (m == 9) { rotateLeft(); }
if (m == 10) { rotateRight(); }
if (m == 0) { stopMoving(); }
//Serial.println(dataIn);
// If button "SAVE" is pressed
if (m == 12) {
if (index == 0) {
LeftBackWheel.setCurrentPosition(0);
LeftFrontWheel.setCurrentPosition(0);
RightBackWheel.setCurrentPosition(0);
RightFrontWheel.setCurrentPosition(0);
}
lbw[index] = LeftBackWheel.currentPosition();
lfw[index] = LeftFrontWheel.currentPosition();
rbw[index] = RightBackWheel.currentPosition();
rfw[index] = RightFrontWheel.currentPosition();
index++;
m = 0;
}
if (m == 14) {
runSteps();
if (dataIn != 14) {
stopMoving();
memset(lbw, 0, sizeof(lbw));
memset(lfw, 0, sizeof(lfw));
memset(rbw, 0, sizeof(rbw));
memset(rfw, 0, sizeof(rfw));
index = 0;
}
}
LeftFrontWheel.runSpeed();
LeftBackWheel.runSpeed();
RightFrontWheel.runSpeed();
RightBackWheel.runSpeed();
// Monitor the battery voltage
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.00) * 3;
// If voltage is below 11V turn on the LED
if (voltage < 11) { digitalWrite(led, HIGH); }
else { digitalWrite(led, LOW); }
}
void runSteps() {
for (int i = index - 1; i >= 0; i--) {
// Run through all steps(index)
LeftFrontWheel.moveTo(lfw[i]);
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.moveTo(lbw[i]);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.moveTo(rfw[i]);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.moveTo(rbw[i]);
RightBackWheel.setSpeed(wheelSpeed);
while (LeftBackWheel.currentPosition() != lbw[i] & LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) {
LeftFrontWheel.runSpeedToPosition();
LeftBackWheel.runSpeedToPosition();
RightFrontWheel.runSpeedToPosition();
RightBackWheel.runSpeedToPosition();
if (Bluetooth.available() > 0) {
// Check for incomding data
dataIn = Bluetooth.read();
if ( dataIn == 15) {
// If button "PAUSE" is pressed
while (dataIn != 14) {
// Wait until "RUN" is pressed again
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read();
if ( dataIn == 13) { stopMoving(); break; }
}
}
}
if (dataIn >= 16) { wheelSpeed = dataIn * 10; dataIn = 14; }
if ( dataIn == 13) { break; }
}
}
}
// Go back through steps
for (int i = 1; i <= index - 1; i++) {
// Run through all steps(index)
LeftFrontWheel.moveTo(lfw[i]);
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.moveTo(lbw[i]);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.moveTo(rfw[i]);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.moveTo(rbw[i]);
RightBackWheel.setSpeed(wheelSpeed);
while (LeftBackWheel.currentPosition() != lbw[i]& LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) {
LeftFrontWheel.runSpeedToPosition();
LeftBackWheel.runSpeedToPosition();
RightFrontWheel.runSpeedToPosition();
RightBackWheel.runSpeedToPosition();
if (Bluetooth.available() > 0) {
// Check for incomding data
dataIn = Bluetooth.read();
if ( dataIn == 15) {
// If button "PAUSE" is pressed
while (dataIn != 14) {
// Wait until "RUN" is pressed again
if (Bluetooth.available() > 0) {
dataIn = Bluetooth.read();
if ( dataIn == 13) { stopMoving(); break; }
}
}
}
if (dataIn >= 16) { wheelSpeed = dataIn * 10; dataIn = 14; }
if ( dataIn == 13) { break; }
}
}
}
}
void moveForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
LeftFrontWheel.setSpeed(wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(-wheelSpeed);
RightFrontWheel.setSpeed(-wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(wheelSpeed);
RightFrontWheel.setSpeed(wheelSpeed);
RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
LeftFrontWheel.setSpeed(-wheelSpeed);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
LeftFrontWheel.setSpeed(0);
LeftBackWheel.setSpeed(0);
RightFrontWheel.setSpeed(0);
RightBackWheel.setSpeed(0);
}

製造プロセス
- Bluetooth 制御 Raspberry Pi ロボットに音声フィードバックを追加して構築
- ArduinoとHC-SR04で作るサーボ駆動障害物回避ロボット
- Arduino UNOで作る完全自律ライントラッカーロボット ─ 入門に最適な自作キット
- Arduino Nanoで音声制御ロボットを自作
- PiBot:Arduino駆動の精密ピアノ演奏ロボット
- LittleArm 2C: 3Dプリント製Arduinoロボットアーム – STEM教育向け耐久設計
- 自律型ホームアシスタントロボット「O'nine」の構築 – ROS、Alexa、ロボットアーム完全ガイド
- Arduinoロボットアーム「LittleArm」をAndroidアプリでBluetooth制御
- Arduino向けスマート屋内ナビゲーションロボットキット
- WiDC: Wi-Fi FPVロボット – ライブ映像付きリモートコントロール
- Arduino UNOで作る会話型ヒューマノイドロボット「モフィザ」