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

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

このチュートリアルでは、以前の動画で作ったメカナムホイールロボット台車と、3Dプリントロボットアーム(これも以前の動画で作ったArduinoプロジェクト)を連携させ、自動動作させる方法を紹介します。

以下の動画を見るか、書面チュートリアルをお読みください。

概要

メカナムホイールロボットは、前回の動画と同じようにカスタムビルドのAndroidアプリで制御できます。それに加えて、今回のアプリにはロボットアーム制御用のボタンも追加されています。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

元のロボットアーム制御アプリはスライダーで各関節を制御していましたが、アームの安定性に問題がありました。今回の方式の方がはるかに安定して動作するため、更新版のロボットアーム制御アプリとArduinoコードを元のプロジェクトにも提供します。

このロボットの最大の特徴は、動きを記録し、自動で繰り返し実行できることです。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

Saveボタンで各ステップのモーター位置を保存し、Runボタンを押せば記録した動きを繰り返し自動実行します。

Arduinoロボットの組み立て

メカナムホイール台車はすでに組み立て済みです。詳細は前回の動画をご覧ください。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

3Dプリントしたロボットアーム部品とサーボモーターを組み立てます。プロジェクトの3Dモデルはこちら。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

Thangsで3Dモデルを探索・ダウンロードできます。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

3Dモデルのダウンロード(Thangs)

STLファイル(3Dプリント用):

ロボットアームの第1サーボ(ヨー軸)は、メカナム台車のトップカバーに直接取り付けます。

位置をマークし、10mmドリルで複数穴を開けます。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

ヤスリで穴をつなげ、サーボ用の開口部を整形。M3ボルト・ナット4本でトッププレートに固定。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

このサーボの出力軸に、付属のラウンドホーンを使ってロボットアームのウェスト(腰)パーツを取り付けます。しかしこのままだとパーツがプレートから約8mm浮いてしまうため、8mm厚のMDFボード2枚を挟んでウェストパーツが滑れるようにし、関節を安定させました。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

ラウンドホーンは付属のタッピングネジでウェストパーツに、付属ボルトでサーボシャフトに固定。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

第2サーボ(ショルダー)を配置し、3Dプリントパーツにタッピングネジで固定。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

ラウンドホーンを次のパーツに取り付け、サーボ出力軸のボルトで2パーツを連結。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

パーツ固定前に、可動範囲がフルに取れるか確認してください。ここではショルダー関節にゴムバンドを追加し、残りのアームとペイロードの重量を支えるサーボを少し補助しています。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

同様に残りのロボットアームを組み立てます。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

グリッパー機構を組み立てます。SG90サーボで制御し、まずカスタム設計のギア付きリンクを取り付け、反対側にもう1つのギア付きリンクをM4ボルト・ナットで連結。他のリンクもすべてM4ボルト・ナットで接続。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

グリッパーの3Dモデルは元々3mm穴でしたが、M3ボルトが足りなかったため4mmドリルで拡張しM4ボルトを使用。

グリッパー機構を組み立てたら最後のサーボに固定し、ロボットアーム完成。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

配線整理を行います。サーボ配線をロボットアームの専用穴に通し、トッププレートに10mmドリルで穴を開けて配線を通します。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

ジップタイで配線をまとめ、Arduinoボードに接続するだけになりました。

Arduinoロボットの回路図

このプロジェクトの回路図と接続方法です。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

必要なコンポーネント:

  • ステッピングモーター – NEMA 17
  • DRV8825ステッピングドライバー
  • MG996Rサーボモーター
  • SG90マイクロサーボモーター
  • HC-05 Bluetoothモジュール
  • Li-Poバッテリー
  • Arduino Megaボード

前回のチュートリアルでメカナムホイールロボット部分の仕組みとカスタムPCBの作り方を説明しました。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

このPCBには5V電圧レギュレーター(LM350、最大3A)を搭載し、サーボモーター(5V動作)を接続できるようにしています。ロボットアームの6個のサーボは約2〜3Aの電流を消費するため、レギュレーターはギリギリ対応可能ですが、かなり発熱します。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

そのためヒートシンクを取り付け、さらに小型12V DCファンで強制空冷しています。ヒートシンクだけでは冷却不足でした。

サーボの信号線をArduinoデジタルピン5〜10に、電源はPCB上の5Vピンヘッダーから取ります。全配線を台車内部に押し込み、トッププレートを2つのナットで固定して完成です。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御
Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

Arduinoコード

コードが長いため、セクションごとに解説付きで掲載し、最後に完全なソースコードを載せます。

まず6個のサーボ、4個のステッピングモーター、Bluetooth通信を定義し、必要な変数を宣言。setup()ではステッピングモーターの最大速度設定、サーボ接続ピン定義、Bluetooth通信開始、ロボットアームの初期位置設定を行います。

#include <SoftwareSerial.h>
#include <AccelStepper.h>
#include <Servo.h>
Servo servo01;
Servo servo02;
Servo servo03;
Servo servo04;
Servo servo05;
Servo servo06;
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 lbw[50], lfw[50], rbw[50], rfw[50]; // arrays for storing positions/steps
int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // current position
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // previous position
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // for storing positions/steps
int speedDelay = 20;
int index = 0;
int dataIn;
int m = 0;
void setup() {
  // Set initial seed values for the steppers
  LeftFrontWheel.setMaxSpeed(3000);
  LeftBackWheel.setMaxSpeed(3000);
  RightFrontWheel.setMaxSpeed(3000);
  RightBackWheel.setMaxSpeed(3000);
  pinMode(led, OUTPUT);
  servo01.attach(5);
  servo02.attach(6);
  servo03.attach(7);
  servo04.attach(8);
  servo05.attach(9);
  servo06.attach(10);
  Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
  Bluetooth.setTimeout(5);
  delay(20);
  Serial.begin(38400);
  // Move robot arm to initial position
  servo1PPos = 90;
  servo01.write(servo1PPos);
  servo2PPos = 100;
  servo02.write(servo2PPos);
  servo3PPos = 120;
  servo03.write(servo3PPos);
  servo4PPos = 95;
  servo04.write(servo4PPos);
  servo5PPos = 60;
  servo05.write(servo5PPos);
  servo6PPos = 110;
  servo06.write(servo6PPos);
}

loop()では着信データの有無をチェックするところから始まります。

// Check for incoming data
if (Bluetooth.available() > 0) {
  dataIn = Bluetooth.read(); // Read the data

このデータはスマートフォン/Androidアプリから送られてきます。アプリがどんなデータを送っているか見てみましょう。AndroidアプリはMIT App Inventorで作成。適切な画像を背景にしたシンプルなボタンで構成されています。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

アプリのブロックを見ると、ボタンがクリックされたときに1バイトの数字を送信するだけです。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

受信した数字に応じてArduinoに動作を指示します。例えば「2」を受信したら、moveForward()カスタム関数でメカナムホイール台車を前進させます。

if (dataIn == 2) { m = 2; }
if (m == 2) { moveForward(); }

このカスタム関数は4つのステッピングモーターすべてを正回転させます。

void moveForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}

他の方向への移動も、ホイールを適切な方向に回転させるだけです。

ロボットアームの制御も同じ方式です。アプリにボタンがあり、ボタンを押し続けている間、対応する関節が特定方向に動きます。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

前述の通り、元のロボットアーム制御アプリではスライダーでサーボ位置を制御していましたが、テキストをArduinoに送信する必要があり、Arduinoがテキストを取りこぼしてエラーになったり、アームが震えたり異常動作する問題がありました。今回はボタンがタッチダウンされたときに1バイトの数字を送るだけなので、そうした問題が解消されています。

Arduinoロボットアームとメカナムホイール台車のシームレス連携制御

Arduinoコードはその数字のwhileループに入り、ボタンを離す(タッチアップで「0」=何もしないが送信される)までループ内に留まります。

// Move servo 1 in positive direction
while (m == 16) {
  if (Bluetooth.available() > 0) {
    m = Bluetooth.read();
  }
  servo01.write(servo1PPos);
  servo1PPos++;
  delay(speedDelay);
}
// Move servo 1 in negative direction
while (m == 17) {
  if (Bluetooth.available() > 0) {
    m = Bluetooth.read();
  }
  servo01.write(servo1PPos);
  servo1PPos--;
  delay(speedDelay);
}

押されたボタンに応じてサーボが正方向/負方向に動きます。すべてのサーボで同じ原理です。移動速度はスライダーからの値(100〜250)で変更します。

// If arm speed slider is changed
if (dataIn > 101 & dataIn < 250) {
  speedDelay = dataIn / 10; // Change servo speed (delay time)
}

10で割って10〜25の値にし、whileループ内のdelay(マイクロ秒)としてサーボ駆動速度を制御します。

ロボットの動きを記録するには、Saveボタンが押されるたびにサーボとステッピングモーターの現在位置を配列に保存します。

// If button "SAVE" is pressed
if (m == 12) {
  //if it's initial save, set the steppers position to 0
  if (index == 0) {
    LeftBackWheel.setCurrentPosition(0);
    LeftFrontWheel.setCurrentPosition(0);
    RightBackWheel.setCurrentPosition(0);
    RightFrontWheel.setCurrentPosition(0);
  }
  lbw[index] = LeftBackWheel.currentPosition(); // save position into the array
  lfw[index] = LeftFrontWheel.currentPosition();
  rbw[index] = RightBackWheel.currentPosition();
  rfw[index] = RightFrontWheel.currentPosition();
  servo01SP[index] = servo1PPos; // save position into the array
  servo02SP[index] = servo2PPos;
  servo03SP[index] = servo3PPos;
  servo04SP[index] = servo4PPos;
  servo05SP[index] = servo5PPos;
  servo06SP[index] = servo6PPos;
  index++; // Increase the array index
  m = 0;
}

Runボタンを押すとrunSteps()カスタム関数が呼ばれ、for/whileループで記録済みステップを順に実行します。

if (m == 14) {
  runSteps();
  // If button "RESET" is pressed
  if (dataIn != 14) {
    stopMoving();
    memset(lbw, 0, sizeof(lbw)); // Clear the array data to 0
    memset(lfw, 0, sizeof(lfw));
    memset(rbw, 0, sizeof(rbw));
    memset(rfw, 0, sizeof(rfw));
    memset(servo01SP, 0, sizeof(servo01SP)); // Clear the array data to 0
    memset(servo02SP, 0, sizeof(servo02SP));
    memset(servo03SP, 0, sizeof(servo03SP));
    memset(servo04SP, 0, sizeof(servo04SP));
    memset(servo05SP, 0, sizeof(servo05SP));
    memset(servo06SP, 0, sizeof(servo06SP));
    index = 0; // Index to 0
  }
}

最初の位置から最後の位置まで実行し、それを繰り返します。そのためステップ保存時には、最初のステップと最後のステップが同じ位置になるようロボットを配置する必要があります。実行中も台車とアームの速度変更、一時停止、全ステップリセットが可能です。

このアプリと編集可能なプロジェクトファイルはこちらからダウンロードできます:

このArduinoロボットプロジェクトの完全なソースコード:

/* Arduino Robot Arm and Mecanum Wheels Robot Smartphone Control via Bluetooth by Dejan, www.HowToMechatronics.com */
#include <SoftwareSerial.h>
#include <AccelStepper.h>
#include <Servo.h>
Servo servo01;
Servo servo02;
Servo servo03;
Servo servo04;
Servo servo05;
Servo servo06;
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 lbw[50], lfw[50], rbw[50], rfw[50]; // arrays for storing positions/steps
int servo1Pos, servo2Pos, servo3Pos, servo4Pos, servo5Pos, servo6Pos; // current position
int servo1PPos, servo2PPos, servo3PPos, servo4PPos, servo5PPos, servo6PPos; // previous position
int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; // for storing positions/steps
int speedDelay = 20;
int index = 0;
int dataIn;
int m = 0;
void setup() {
  // Set initial seed values for the steppers
  LeftFrontWheel.setMaxSpeed(3000);
  LeftBackWheel.setMaxSpeed(3000);
  RightFrontWheel.setMaxSpeed(3000);
  RightBackWheel.setMaxSpeed(3000);
  pinMode(led, OUTPUT);
  servo01.attach(5);
  servo02.attach(6);
  servo03.attach(7);
  servo04.attach(8);
  servo05.attach(9);
  servo06.attach(10);
  Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
  Bluetooth.setTimeout(5);
  delay(20);
  Serial.begin(38400);
  // Move robot arm to initial position
  servo1PPos = 90;
  servo01.write(servo1PPos);
  servo2PPos = 100;
  servo02.write(servo2PPos);
  servo3PPos = 120;
  servo03.write(servo3PPos);
  servo4PPos = 95;
  servo04.write(servo4PPos);
  servo5PPos = 60;
  servo05.write(servo5PPos);
  servo6PPos = 110;
  servo06.write(servo6PPos);
}
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; }
    if (dataIn == 16) { m = 16; }
    if (dataIn == 17) { m = 17; }
    if (dataIn == 18) { m = 18; }
    if (dataIn == 19) { m = 19; }
    if (dataIn == 20) { m = 20; }
    if (dataIn == 21) { m = 21; }
    if (dataIn == 22) { m = 22; }
    if (dataIn == 23) { m = 23; }
    if (dataIn == 24) { m = 24; }
    if (dataIn == 25) { m = 25; }
    if (dataIn == 26) { m = 26; }
    if (dataIn == 27) { m = 27; }
    // Move the Mecanum wheels platform
    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(); }
    // Mecanum wheels speed
    if (dataIn > 30 & dataIn < 100) { wheelSpeed = dataIn * 20; }
    // Move robot arm
    // Move servo 1 in positive direction
    while (m == 16) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo01.write(servo1PPos);
      servo1PPos++;
      delay(speedDelay);
    }
    // Move servo 1 in negative direction
    while (m == 17) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo01.write(servo1PPos);
      servo1PPos--;
      delay(speedDelay);
    }
    // Move servo 2
    while (m == 19) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo02.write(servo2PPos);
      servo2PPos++;
      delay(speedDelay);
    }
    while (m == 18) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo02.write(servo2PPos);
      servo2PPos--;
      delay(speedDelay);
    }
    // Move servo 3
    while (m == 20) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo03.write(servo3PPos);
      servo3PPos++;
      delay(speedDelay);
    }
    while (m == 21) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo03.write(servo3PPos);
      servo3PPos--;
      delay(speedDelay);
    }
    // Move servo 4
    while (m == 23) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo04.write(servo4PPos);
      servo4PPos++;
      delay(speedDelay);
    }
    while (m == 22) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo04.write(servo4PPos);
      servo4PPos--;
      delay(speedDelay);
    }
    // Move servo 5
    while (m == 25) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo05.write(servo5PPos);
      servo5PPos++;
      delay(speedDelay);
    }
    while (m == 24) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo05.write(servo5PPos);
      servo5PPos--;
      delay(speedDelay);
    }
    // Move servo 6
    while (m == 26) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo06.write(servo6PPos);
      servo6PPos++;
      delay(speedDelay);
    }
    while (m == 27) {
      if (Bluetooth.available() > 0) { m = Bluetooth.read(); }
      servo06.write(servo6PPos);
      servo6PPos--;
      delay(speedDelay);
    }
    // If arm speed slider is changed
    if (dataIn > 101 & dataIn < 250) {
      speedDelay = dataIn / 10; // Change servo speed (delay time)
    }
    // If button "SAVE" is pressed
    if (m == 12) {
      //if it's initial save, set the steppers position to 0
      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();
      servo01SP[index] = servo1PPos;
      servo02SP[index] = servo2PPos;
      servo03SP[index] = servo3PPos;
      servo04SP[index] = servo4PPos;
      servo05SP[index] = servo5PPos;
      servo06SP[index] = servo6PPos;
      index++;
      m = 0;
    }
    // If button "RUN" is pressed
    if (m == 14) {
      runSteps();
      // If button "RESET" is pressed
      if (dataIn != 14) {
        stopMoving();
        memset(lbw, 0, sizeof(lbw));
        memset(lfw, 0, sizeof(lfw));
        memset(rbw, 0, sizeof(rbw));
        memset(rfw, 0, sizeof(rfw));
        memset(servo01SP, 0, sizeof(servo01SP));
        memset(servo02SP, 0, sizeof(servo02SP));
        memset(servo03SP, 0, sizeof(servo03SP));
        memset(servo04SP, 0, sizeof(servo04SP));
        memset(servo05SP, 0, sizeof(servo05SP));
        memset(servo06SP, 0, sizeof(servo06SP));
        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 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);
}
// Automatic mode custom function - run the saved steps
void runSteps() {
  while (dataIn != 13) {
    // Run the steps over and over again until "RESET" button is pressed
    for (int i = 0; i <= index - 2; i++) {
      // Run through all steps(index)
      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) { break; }
            }
          }
        }
        // If speed slider is changed
        if (dataIn > 100 & dataIn < 150) {
          speedDelay = dataIn / 10;
        }
        // Mecanum wheels speed
        if (dataIn > 30 & dataIn < 100) {
          wheelSpeed = dataIn * 10;
          dataIn = 14;
        }
      }
      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();
      }
      // Servo 1
      if (servo01SP[i] == servo01SP[i + 1]) { }
      if (servo01SP[i] > servo01SP[i + 1]) {
        for ( int j = servo01SP[i]; j >= servo01SP[i + 1]; j--) {
          servo01.write(j);
          delay(speedDelay);
        }
      }
      if (servo01SP[i] < servo01SP[i + 1]) {
        for ( int j = servo01SP[i]; j <= servo01SP[i + 1]; j++) {
          servo01.write(j);
          delay(speedDelay);
        }
      }
      // Servo 2
      if (servo02SP[i] == servo02SP[i + 1]) { }
      if (servo02SP[i] > servo02SP[i + 1]) {
        for ( int j = servo02SP[i]; j >= servo02SP[i + 1]; j--) {
          servo02.write(j);
          delay(speedDelay);
        }
      }
      if (servo02SP[i] < servo02SP[i + 1]) {
        for ( int j = servo02SP[i]; j <= servo02SP[i + 1]; j++) {
          servo02.write(j);
          delay(speedDelay);
        }
      }
      // Servo 3
      if (servo03SP[i] == servo03SP[i + 1]) { }
      if (servo03SP[i] > servo03SP[i + 1]) {
        for ( int j = servo03SP[i]; j >= servo03SP[i + 1]; j--) {
          servo03.write(j);
          delay(speedDelay);
        }
      }
      if (servo03SP[i] < servo03SP[i + 1]) {
        for ( int j = servo03SP[i]; j <= servo03SP[i + 1]; j++) {
          servo03.write(j);
          delay(speedDelay);
        }
      }
      // Servo 4
      if (servo04SP[i] == servo04SP[i + 1]) { }
      if (servo04SP[i] > servo04SP[i + 1]) {
        for ( int j = servo04SP[i]; j >= servo04SP[i + 1]; j--) {
          servo04.write(j);
          delay(speedDelay);
        }
      }
      if (servo04SP[i] < servo04SP[i + 1]) {
        for ( int j = servo04SP[i]; j <= servo04SP[i + 1]; j++) {
          servo04.write(j);
          delay(speedDelay);
        }
      }
      // Servo 5
      if (servo05SP[i] == servo05SP[i + 1]) { }
      if (servo05SP[i] > servo05SP[i + 1]) {
        for ( int j = servo05SP[i]; j >= servo05SP[i + 1]; j--) {
          servo05.write(j);
          delay(speedDelay);
        }
      }
      if (servo05SP[i] < servo05SP[i + 1]) {
        for ( int j = servo05SP[i]; j <= servo05SP[i + 1]; j++) {
          servo05.write(j);
          delay(speedDelay);
        }
      }
      // Servo 6
      if (servo06SP[i] == servo06SP[i + 1]) { }
      if (servo06SP[i] > servo06SP[i + 1]) {
        for ( int j = servo06SP[i]; j >= servo06SP[i + 1]; j--) {
          servo06.write(j);
          delay(speedDelay);
        }
      }
      if (servo06SP[i] < servo06SP[i + 1]) {
        for ( int j = servo06SP[i]; j <= servo06SP[i + 1]; j++) {
          servo06.write(j);
          delay(speedDelay);
        }
      }
    }
  }
}

このプロジェクトは動作しますが、完璧ではありません。メカナムホイールのスリップや安価なサーボモーターの性能限界により、自動動作の精度は高くありません。これらのサーボは3Dプリントパーツの重量を保持するのに十分な力がないため、静止時でも震えたりジッターしたりすることがあります。

このチュートリアルがお役に立てば幸いです。質問はコメント欄でどうぞ。Arduinoプロジェクトコレクションもご覧ください。


製造プロセス

  1. Arduino & Raspberry Pi でインターネット制御ビデオストリーミングロボットを構築
  2. シンプルPiロボット - Raspberry Piで2WD自律ローバーを構築
  3. ArduinoとHC-SR04で作るサーボ駆動障害物回避ロボット
  4. ArduinoとAndroidでRoomba Create 2をリモコン操作 ─ Bluetooth経由のステップバイステップガイド
  5. Arduino & MPU6050:SG90 & MG996Rサーボの精密制御
  6. スマートなArduino制御ロボットアームの製作:簡単DIYチュートリアル
  7. LittleArm 2C: 3Dプリント製Arduinoロボットアーム – STEM教育向け耐久設計
  8. DIY ハンドジェスチャー制御 Arduino ロボットアーム - ステップバイステップ構築ガイド
  9. プログラマブル3軸ロボットアームキット:Arduino+Bluetoothでローカル/リモート制御
  10. Arduinoロボットアーム「LittleArm」をAndroidアプリでBluetooth制御
  11. KUKA KMR iiwa:インダストリー4.0対応の移動型協働ロボットアーム