ロボットプログラミング教室 part3: ロボットアーム制御

目的

このパートでは、ダンボールでできた簡単なロボットアームを作り、動かすことを目的とします。

目次

手順

1. 材料を用意する

以下の材料をご用意ください。

Arduino
 ・Ardino Uno Rev3
  秋月電子通商
 もしくは
 ・ESP-WROOM-32 開発キット
  秋月電子通商

パソコン
 ・お持ちのものをお使いください。

使用するArduinoとパソコンに対応しているUSBケーブル
 ・上記のArdino UnoのUSB端子はType-Bで、ESP-WROOM-32 開発キットのUSB端子は、 micro-B端子です。Type-Bやmicro-B、Mini-Bがありますので 購入の際はご注意ください。もう一方の端子はお使いのパソコンにあった ものをご用意ください。
 ・また、通信に非対応のケーブルも販売されていますが、 本企画には使用できませんので、購入の際はご注意ください。

ブレッドボード
 ・ブレッドボードとして販売されているものであれば大丈夫です。
 ・動画や写真で使用しているものは以下のものです。
  秋月電子通商

ジャンパワイヤ
 ・両端がオス(ブレッドボードに挿すことができるピン状端子)になっているもの(オス-オス)をご用意ください。
 ・以下のもの以外でも大丈夫です。
  秋月電子通商

サーボモータ
 ・SG90
  秋月電子通商

ポテンショメータ
 ・10kΩ半固定ボリューム
  秋月電子通商

抵抗
 ・1kΩ抵抗
  秋月電子通商

ダンボール
 ・お持ちのものをお使いください。
 ・写真では、9cm×15cmと4cm×15cmに切ったものを使用しています。
 ・正確にこの大きさに切る必要はありませんが、サーボモータより十分大きく、扱いやすい大きさでお使いください。

2.アームを作る

9cm×15cmの大きい方のダンボール片の端からおよそ1cmのところにサーボモータを置き、その輪郭(りんかく)をマジックペンで描く。

マジックペンで書かれた枠の内側に穴を開ける。
このとき、枠よりも穴が少し小さくなるように開ける。
※穴を大きくし過ぎてしまうと、サーボモータがはまらなくなってしまいます。
ここでは、目打ちやハサミを使って穴を開けていますが、カッターなどでも穴を開けられます。ケガをしないよう、十分に注意して穴を開けてください。

開けた穴にサーボモータをはめ込む。
※少しきついかもしれませんが、頑張って押し込みます。
穴が小さすぎると思ったら、穴を大きくしてください。

もう一枚の、4cm×15cmの小さい方のダンボール片に、サーボモータに付属しているサーボホーンを、写真のようにセロテープで固定する。

サーボホーンをサーボモータの出力軸にはめる。

ここまででロボットアームの作成は完了です!
次は、パソコンでプログラムを打ち込む作業になります。

3. プログラムを打ち込む

Arduino IDEを起動します。
初めて使用する場合には、写真のような新規ファイルが表示されます。

新規ファイル内の内容を全て削除します。

以下のプログラムをコピーします。
少し長いですが、頑張ってください。

[Arduino Uno用プログラム]

#define n 50
#define d 0
#include <Servo.h>

Servo myservo;

void setup() {
  // put your setup code here, to run once:

  //3番をサーボモータにPWM出力するピンに指定する
  myservo.attach(3);

  //serial通信の設定。これによってパソコンと通信し、シリアルモニターに値が表示される
  Serial.begin(9600);
  Serial.println("シリアル通信始まるよ");

  //A5番ピンを、入力を読み取るためのピンとして設定する
  pinMode(A5, INPUT);
}

//初期設定
float value = 0;
float values[n]; //最新のポテンショメータの値をn回分記録しておく枠を作る
float value_ave = 0;
float value_ave_old = 0;
float angle = 0;

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

  //ポテンショメータの値の読み取り,
  value = analogRead(A5); //A5番のピンの電圧を読み取っている(0<=value<1023)

  //配列のn個の値を一つずつ前にずらす(先頭の一番古い値は消える)
  int i;
  for (i=0;i d || (value_ave - value_ave_old) < -d){
    //アーム角度の計算
    angle = (-90) + 180 * value / 1024;
    //サーボモータ保護のため、角度の範囲を設ける
    if(angle < -70){
      angle = -70;
    }
    if(angle >70){
      angle = 70;
    }
                                                                                                                                                                                                    
    //サーボモータに出力
    myservo.write(angle + 90);

    //value_ave_oldを更新
    value_ave_old = value_ave;
  }

  //Serial通信に表示
//  Serial.print("value_ave = ");
//  Serial.print(value_ave);
//  Serial.print("\n");
  Serial.print("angle = ");
  Serial.print(angle);
  Serial.print("\n");

  delay(20);
}

[ESP32用プログラム]

#define n 50
#define d 300
#include "esp32-hal-ledc.h"

void setup() {
  // put your setup code here, to run once:

  ledcSetup(1, 50, 12); // channel 1, 50 Hz(20ms), 12-bit
  ledcAttachPin(25, 1); // ピンの 25 番を channel 1 に設定する
  // 12bit なので、0~4095(2^12-1) までの範囲が 0~20ms に対応する
  // データシートによると、20msのサイクルの中で、パルス幅を
  // 次のようにして角度をコントロールできる。()内はPWMの値
  // 0.50ms(102) → -90度
  // 1.45ms(297) →   0度
  // 2.40ms(491) → +90度

  //serial通信の設定。これによってパソコンと通信し、シリアルモニターに値が表示される
  Serial.begin(9600);
  Serial.println("シリアル通信始まるよ");
  //34番ピンを、入力を読み取るためのピンとして設定する
  pinMode(34, INPUT);
}

//初期設定
float value = 0;
float values[n]; //最新のポテンショメータの値をn回分記録しておく枠を作る
float value_ave = 0;
float value_ave_old = 0;
float angle = 0;
float arm_value = 0;

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

  //ポテンショメータの値の読み取り,
  value = analogRead(34); //34番のピンの電圧を読み取っている(0<=value<4096)

  //配列のn個の値を一つずつ前にずらす(先頭の一番古い値は消える)
  int i;
  for (i=0;i d || (value_ave - value_ave_old) < -d){
    //アーム角度の計算
    angle = (-90) + 180 * value / 4096;
    //サーボモータ保護のため、角度の範囲を設ける
    if(angle < -70){
      angle = -70;
    }
    if(angle >70){
      angle = 70;
    }

    //アーム出力値の計算
    arm_value = 102 + (491 - 102) * (angle - (-90)) / 180;

    //サーボモータに出力
    ledcWrite(1, arm_value);
    //value_ave_oldを更新
    value_ave_old = value_ave;
  }

  //Serial通信に表示
//  Serial.print("value_ave = ");
//  Serial.print(value_ave);
//  Serial.print("\n");
  Serial.print("angle = ");
  Serial.print(angle);
  Serial.print("\n");
//  Serial.print("arm_value = ");
//  Serial.print(arm_value);
//  Serial.print("\n");

  delay(20);
}

コピーできたら、新規ファイルに貼り付け(ペースト)します。

左上のチェックマーク(「ファイル」という文字の下のマーク)をクリックして、コンパイルする。
その後、写真のように「コンパイルが完了しました。」と表示されればプログラムの打ち込みは終了です。

4.回路を構成する

以下の図や写真のように回路を構成する。
写真のように、それぞれのワイヤが正しく接続されていることを確認する。
回路図ではサーボモータのコードが直接ブレッドボードに挿さっていますが、実際にはジャンパワイヤで間をつなぐことになります。 写真を参考にしてください。

Arduino Uno用の回路





ESP32用の回路




ここまでで、ほぼ全ての準備が完了しました!
あとは動かすだけです!

5.動作させる

Arduino Unoもしくは ESP32がパソコンに接続されていないことを確認したあと、Arduino IDEの画面に戻り、「ツール」→「シリアルポート」で表示されるもの(COM)を確認する。
※「1. Arduinoとは」で行った手順と同じものです。

Arduino Unoもしくは ESP32をパソコンに接続し、同じように「ツール」→「シリアルポート」で 表示されるものを確認する。そのとき、Arduino Unoもしくは ESP32を接続する前は表示され ていなかったものが対応するCOMで、それをクリックする。

「ツール」→「シリアルプロッタ」をクリックする。
2枚目のような画面が表示されれば問題ない。

ポテンショメータを回して、シリアルプロッタに表示されるグラフが変動するか確認する。
このグラフは、アームの角度(-90〜90)を表している。
※アーム角度は、サーボモータが端まで動き壊れてしまうことを防ぐため、プログラムの中で、-70〜70の範囲でしか動かないように制限しています。
余裕があれば、その部分を見つけてみてください。70という数字に注目すると見つけやすいかもしれません。
※アームの動き始めと動き終わりにブルブルと震えることがあります。震えが酷い場合は、プログラムの上から2行めの"d"の右隣の数字を大きくしてみてください。

お疲れ様でした!
ポテンショメータを回して遊んでみてください!
多くのロボットは、腕や足などの関節にここで作成した仕組みが用いられています。それらをいくつも組み合わせてロボットをコントロールするための学問は「ロボティクス」と呼ばれていて、機械系の学科で学ぶことができます。
また、本企画使用した電子部品については、「メカトロニクス」という授業で学ぶことができます。
機械系では、プログラムによって実体をもつ"物"を動かし制御するための知識を得ることができます。
ロボットを扱うために必要なことが一通り学べるので、ロボットが好きな方、本企画で動く仕組みを面白いと思ってもらえた方は、ぜひ機械系の学科の他の企画ものぞいてみてください。
きっとより興味を持っていただけると思います。

参考としたサイト・文献

電子工作/ESP32

企画一覧
 研究室展示  自主プロ・メカトロ・IoT展示  遊星歯車展示  スターリングエンジン展示  電子工作教室  ロボットコントロール体験  ロボットプログラミング教室  ロボットモーション体験
 公式YouTube  公式Twitter  公式Facebook