HaLake Magazine

コワーキングスペースHaLakeの技術情報発信サイト!IoT,AR,VRなど最新技術情報をお届け!

加湿器をロボアームで起動してみよう!

f:id:takumishinoda:20190223155651p:plain 今回は、ロボットのアームでHaLakeの加湿器の電源を特定の時間にオン・オフ管理できるようにしてみようと思います。
ロボアームの制御にはHaLake KitというHaLakeでプログラミング学習用に開発された、ESP8266を使用したボードを使用してWiFi経由で操作できるようにします。
操作命令はWiFi経由で行うので、ラズパイのNodejs環境から操作していきます。

今回学べること

  • Arduino・ESP8266でのサーボモータの扱い方
  • ESP8266でWebサーバを立てる方法
  • NodejsからHTTPでGETリクエストを投げる方法
  • Nodejsでcron構文を使って指定時間処理する方法


今回主に使ったもの

  • ロボットアーム(Romi用ロボットアームキット)
  • HaLake Kit
  • ラズベリーパイ 3B+

ロボットアームはSwitch Scienceで購入できる「Romi用ロボットアームキット」を使用しました。

www.switch-science.com

HaLake KitはHaLakeで開発されたボードですが、もしこの記事を参考に工作されたい方はESP8266チップを使用した「ESPr® Developer」などのボードでも開発ができます。

www.switch-science.com

ロボットアームの仕組み

ロボットなどの駆動部分にはサーボモータが使われています。
サーボモータとは、角度(位置)や速度を制御できるモータなので、ロボットの腕の角度を制御することができます。
今回使う「Romi用ロボットアームキット」のアームは下記画像の様に、駆動部がサーボモータ三つで構成されています。

f:id:takumishinoda:20190223114417j:plain
アームの各部位

赤い矢印がサーボモータの場所で、青い矢印がそれぞれの制御する可動部です。
それぞれサーボモータの角度を適当な角度にするとアームが動きます。
今回しようしたアームの各部位の可動領域の限界と制御するサーボモータの角度を計測したところ以下の様になりました。

ピンチのサーボ アームのサーボ 手首のサーボ
0° ~ 180° 0° ~ 100° 115° ~ 180°
開 ~ 閉 上 ~ 下 下 ~ 上

さらに、今回のロボットアームはそれぞれのサーボモータから4本線が出ていますが、使うのは赤・黒・白の線で役割は下の表の通りです。

電源(5V) GND 制御線



ロボットアームの制御

一般的にロボットアームの駆動部はサーボモータによって制御されています。
サーボモータの制御はArduino環境ではすでにライブラリが用意されており、とても簡単に制御できるようになっています。
またArduino環境ではESP8266でも同様に操作できるます。
実際の最も簡単なサーボモータ制御のプログラムは以下のようになります。

#include <Servo.h>

Servo servo; // Servoクラスのインスタンスを作る

void setup(){
  servo.attach(4); // GPIO4を制御線に設定
}

void loop(){
   servo.write(0); // サーボモータを0°に設定
   delay(1000);
   servo.write(90);
   delay(1000);
   servo.write(180);
   delay(1000);
}

このプログラムを実行するにはサーボモータの制御線はESP8266のGPIO4と接続しましょう。
このプログラムではサーボモータを一秒ごとに、0°->90°->180°->0°...を繰り返すようになります。
この様にServoクラスのattachメソッドでサーボの制御線を設定してwriteメソッドで角度を簡単に変えることができます。
先ほどのサーボモータとアームの動作関係を表した表を参考にすればアームの制御も簡単にできます。
複数のサーボを制御するには、以下の様にServoクラスのインスタンスを増やして実装できます.

#include <Servo.h>

Servo servo1; // Servoクラスのオブジェクトを作る
Servo servo2; // もう一つ作る

void setup(){
  servo1.attach(4); // こっちはGPIO4で制御
  servo2attach(5); // こっちはGPIO5で制御

  servo1.write(90); // 一つ目のサーボを90°に
  servo2.write(0); // もう一つを0°に
}

void loop(){
}



ESP8266でWebサーバを立てる

次にESP8266でWiFi経由のアーム操作をできる様にするためにWebサーバを立てていきます。
最小限のコードは以下の様になります。

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

char SSID[] = ""; // アクセスポイントのSSIDを設定
char PASS[] = ""; // アクセスポイントのパスワードを設定
ESP8266WebServer server(80); // ポート番号を渡す

void setup(){
  Serial.begin(115200);
  delay(500);

  WiFi.config(IPAddress(192,168,x,x), IPAddress(192,168,x,x), IPAddress(255,255,255,0));  // 引数のIPアドレスは各自編集してください
  WiFi.begin(SSID, PASS); // アクセスポイントに接続
  while(WiFi.status() != WL_CONNECTED){
    delay(1000);
    Serial.print(".");
  } 

  if(WiFi.status() != WL_CONNECTED){
    Serial.println("No Connection");
    ESP.restart();
  }
  else Serial.println(WiFi.localIP());

  server.on("/test", [](){ 
    if(server.args() > 0){ // もしクエリパラメータが一つ以上なら
      String argName = server.argName(0); // 一つ目のクエリパラメータの名前
      String arg = server.arg(0); // 一つ目のクエリパラメータの内容

      // 一つ目のクエリパラメータの表示
      Serial.print(argName + ": "); 
      Serial.println(arg);
    }

    server.send(200, "text/html",  "HOGE!!!"); // レスポンスの設定
  }); 

  server.begin();
}

void loop(){
  server.handleClient();
}


コードの重要点はまず、WiFiに接続するためのSSIDPASS変数はアクセスポイントのSSIDとパスワードを入力してください。
次にWiFiクラスのconfigメソッドでIPアドレスを固定している部分についてです。
第一引数に固定したいアドレス、第二引数にゲートウェイのアドレス、第三引数にサブネットマスクをIPAddressクラスのオブジェクトで渡します。
次は一番重要なWebサーバの部分についてです。
ESP8266WebServerクラスのインスタンスを作るにはポート番号を要求されますが、今回はHTTP標準の80ポートを指定しています。
ESP8266WebServerクラスのonメソッドでは第一引数で指定したパスにHTTPリクエストが来た時の挙動を記述します。
第二引数でコールバックを渡すことで挙動を設定でき、今回はGETリクエストのクエリパラメータを受け取り一つ目のパラメータ名と内容をシリアル通信で表示する様になっています。
今回はサーボモータの角度をクエリで制御していくのでこの技術は必須となります。
クエリパラメータの情報はargNameメソッドとargメソッドの第一引数に何個めのパラメータか数字(int型)を渡すことで取得できます。
あと、sendメソッドによってレスポンスを返します。
上のプログラムではHOGE!!!とレスポンスを返しているので、Chrome等でアクセスするとブラウザにHOGE!!!と表示されるかと思います。
ロボアームの制御をWiFi経由で行うには、このonメソッドの第二引数のコールバックで行なっていきます。

実装

これまでの知識があればWiFi経由でロボットアームの制御ができる様になります。
実際にHaLakeで稼働中のロボットアームの制御回路は以下の様になります。

f:id:takumishinoda:20190223164816j:plain

画像ではMOS FETが含まれていますが、これはサーボモータが待機中に電力を消費するので動かさない時に電源を切れる様にするためのものです。


実際にHaLakeで稼働中のロボアームの制御プログラムは下記のリポジトリにありますので、興味がある方は確認してみてください。

github.com

ここまでの説明でロボットアームの制御とWebサーバを利用してWiFi経由での制御の概要を学びました。
ここまでの説明では要点のみの説明でしたが、上記のリポジトリではそれらが応用されてGETリクエストでアームを制御できる様になっています。
リポジトリのプログラムではWebサーバのパスは以下の様に設定されています。
それぞれ制御のためのパスにクエリのpercentageパラメータに0-100で数字を記述すると制御ができます。
電源制御は、クエリのstateパラメータにtrueを渡すとロボアームの電源がつきそれ以外だと電源が切れます。

アーム制御 ピンチ制御 手首制御 電源制御
{ESP8266のIP}/arm?percentage=0 {ESP8266のIP}/hand?percentage=0 {ESP8266のIP}/wrist?percentage=0 {ESP8266のIP}/power?state=true


プログラムをESP8266に書き込んで、Webサーバにアクセスすると以下のようになります。

※ 注意:リポジトリのプログラムではそれぞれの駆動系を制御するためのURLが別れているので、以下のURLの順にGETリクエストを送ると図の様な動作になります。

1. {ESP8266のIP}/hand?percentage=30
2. {ESP8266のIP}/wrist?percentage=0
3. {ESP8266のIP}/arm?percentage=0
4. {ESP8266のIP}/arm?percentage=100

f:id:takumishinoda:20190223154007g:plain



おまけ:ラズパイから時間指定で制御

ラズパイ側のプログラムは単純で、先ほど紹介したESP8266で建てたWebサーバにアクセスしてアームを制御するだけのものとなります。
そこに特定の時間になったら制御するプログラムを追加していきます。
コードは以下の様になりますが、本プログラムは上記のリポジトリのプログラムを適用したESP8266が動作している環境で動作するものとなっているのでご注意ください。

const ns = require('node-schedule'); // cron構文で指定時間の処理が書ける
const fetch = require('node-fetch'); // GETリクエストができる

let ip = ''; //  IPアドレスを編集 

function mainProc(){
  return new Promise((res, rej) => {
    fetch('http://192.168.3.3/power?state=true') // node-fetchでGETリクエストを送信
      .then(() => { return fetch(`http://${ip}/hand?percentage=30`) })
      .then(() => { return fetch(`http://${ip}/wrist?percentage=0`) })
      .then(() => { return fetch(`http://${ip}/arm?percentage=0`) })
      .then(() => { return fetch(`http://${ip}/arm?percentage=100`) })
      .then(() => { return fetch(`http://${ip}/power?state=false`) })
      .then(() => { res() })
      .catch((err) => { rej(err) });
  })
}

var switchOn = ns.scheduleJob('30 7 * * 0,1,2,4,5,6', function () { // 水曜日以外の毎朝7:30に実行するという意味
  mainProc()
   .catch((err) => { console.log(err) });
});

プログラムの主な説明として、mainProc関数でWebサーバへのGETリクエストを外部モジュールのnode-fetchで行なっています。
また、指定時刻の処理をさせるために外部モジュールnode-scheduleを使ってcron構文で設定しています。

まとめ