【enebular】enebularで遠隔XYステージをつくる【改良版】

# ある日のこと...
こんにちは、宇宙エンジニアの[たくろーどん](https://dotstud.io/members/takudooon/)です。
前回，enebularを使って遠隔で操作できるXY軸ステージをつくってみました．
※[【enebularは神ですか？】enebular×Node-REDで研究室IoTに挑戦！](https://qiita.com/minwinmin/items/e57f6704881287b192e9)

動きは悪くなかったのですが，約5000円の予算でつくったこともあり研究用途でつかうとなると，少し不満がありました．

ということである日，先生に相談してみると

![oneday.png](https://qiita-image-store.s3.amazonaws.com/0/212276/83ad405a-632a-9c66-ad96-c85f9926c50b.png)

あっさり，OKがでたので...

![amazon.png](https://qiita-image-store.s3.amazonaws.com/0/212276/065272dc-3ee3-5e64-5e02-e4b90fef6f6d.png)



![driver.png](https://qiita-image-store.s3.amazonaws.com/0/212276/55ccb974-3e05-f9ac-04c9-5048b58f57f8.png)


Amazonで見つけた[格安のステージ(モーター付き)](https://www.amazon.co.jp/dp/B071JF1NHM/ref=twister_B071GC7YKB?_encoding=UTF8&psc=1)と[ステッピングモータのドライバ](https://www.amazon.co.jp/%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90-%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC%EF%BC%8CSODIAL-CNC%E5%8D%98%E8%BB%B8TB6600-4%E7%9B%B8%E3%83%8F%E3%82%A4%E3%83%96%E3%83%AA%E3%83%83%E3%83%89%E3%82%B9%E3%83%86%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0-%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90/dp/B01EIY7RSG/ref=sr_1_1?s=diy&ie=UTF8&qid=1544089008&sr=1-1&keywords=TB6600)を購入しました．
そして，これをいつも通りNefry BTで制御し快適な研究ライフをもくろみます．

# 全体の概要
## 回路図
![wire.png](https://qiita-image-store.s3.amazonaws.com/0/212276/5d2e1840-3d71-d373-5fa9-6245c0477bb2.png)

今回使用したステッピングモーター(NEMA 17)は，高い電圧・電流が必要なので，直流安定化電源を使用しています．詳細は仕様を見てみることをおすすめします．

## ステッピングモータのドライバ詳細
![driver2.png](https://qiita-image-store.s3.amazonaws.com/0/212276/2a87eaac-eabe-0cf2-7a9e-5b1a4b38ea25.png)
①にドライバの設定について(どれくらいのパルス・電流値で制御するか)書いてあります．
説明通り，②のスイッチをON・OFFすることで，ドライバ側の設定を変更でき，ステッピングモーターの動きを変更できます．こちらも詳細は仕様を見てみることをおすすめします．


## 実験系の概要図
![overroll.png](https://qiita-image-store.s3.amazonaws.com/0/212276/1983b597-4d5c-c25e-83a0-b7e4636d6a82.png)

こちらは，前回の自作XY軸ステージと同じ仕組みです．

## プログラム
### Nefry BT側

```c++

#include <Nefry.h>
#include <NefryFireBase.h>

#define short_range 550
#define medium_range 1050
#define long_range 10500

//インスタンス生成
NefryFireBase firebase;

const int ena = D2; //????
const int dir = D1; //モーターの回転方向を制御
const int pul = D0; //パルスの入出力を制御
const int interval = 1000;   //パルスを送る時間間隔

void setup() {
  pinMode(ena, OUTPUT);
  pinMode(dir, OUTPUT);
  pinMode(pul, OUTPUT);
  Serial.begin(115200);
  firebase.begin("自分のfirebaseのURL");
}

void loop() {、
  int motor = firebase.read("motor").toInt();
  DataElement elem = DataElement();

  if(motor == 1) {
    Serial.println("Back");
    for (int i=0; i<short_range; i++){
      digitalWrite(dir,LOW);
      digitalWrite(ena,LOW);
      digitalWrite(pul,HIGH);
      delayMicroseconds(interval);
      digitalWrite(pul,LOW);
      delayMicroseconds(interval);
    }
      elem.setValue("motor", 0);
      firebase.write("motor", &elem);//FireBaseのデータを書き込むFireBaseのデータを書き込む
      
      
  }else if(motor == 2){
    Serial.println("Foward");
    for (int i=0; i<short_range; i++){
      digitalWrite(dir,HIGH);
      digitalWrite(ena,LOW);
      digitalWrite(pul,HIGH);
      delayMicroseconds(interval);
      digitalWrite(pul,LOW);
      delayMicroseconds(interval);
    }
      elem.setValue("motor", 0);
      firebase.write("motor", &elem);//FireBaseのデータを書き込むFireBaseのデータを書き込む

  }else if(motor == 3){
    Serial.println("Foward_long");
    for (int i=0; i<medium_range; i++){
      digitalWrite(dir,LOW);
      digitalWrite(ena,LOW);
      digitalWrite(pul,HIGH);
      delayMicroseconds(interval);
      digitalWrite(pul,LOW);
      delayMicroseconds(interval);
    }
      elem.setValue("motor", 0);
      firebase.write("motor", &elem);//FireBaseのデータを書き込むFireBaseのデータを書き込む

    
  }else if(motor == 4){
    Serial.println("Foward_long");
    for (int i=0; i<medium_range; i++){
      digitalWrite(dir,HIGH);
      digitalWrite(ena,LOW);
      digitalWrite(pul,HIGH);
      delayMicroseconds(interval);
      digitalWrite(pul,LOW);
      delayMicroseconds(interval);
    }
      elem.setValue("motor", 0);
      firebase.write("motor", &elem);//FireBaseのデータを書き込むFireBaseのデータを書き込む
      
  }else if(motor == 5){
    Serial.println("long_long");
    for (int i=0; i<long_range; i++){
      digitalWrite(dir,LOW);
      digitalWrite(ena,LOW);
      digitalWrite(pul,HIGH);
      delayMicroseconds(interval);
      digitalWrite(pul,LOW);
      delayMicroseconds(interval);
    }
      elem.setValue("motor", 0);
      firebase.write("motor", &elem);//FireBaseのデータを書き込むFireBaseのデータを書き込む
      
  }else if(motor == 6){
    Serial.println("Foward_long");
    for (int i=0; i<long_range; i++){
      digitalWrite(dir,HIGH);
      digitalWrite(ena,LOW);
      digitalWrite(pul,HIGH);
      delayMicroseconds(interval);
      digitalWrite(pul,LOW);
      delayMicroseconds(interval);
    }
      elem.setValue("motor", 0);
      firebase.write("motor", &elem);//FireBaseのデータを書き込むFireBaseのデータを書き込む
     
  }

  stopMotor();
  delay(200);  
 }

 void stopMotor() {
   digitalWrite(dir, HIGH); // low CW(時計回り) / high CCW(反時計回り) 
   digitalWrite(ena, LOW);
   digitalWrite(pul, LOW);
  }

```

### マイコン側

```
[
    {
        "id": "be0d6811.0c5098",
        "type": "inject",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "topic": "",
        "payload": "{\"motor\":1}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 120,
        "y": 480,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "bcb4c067.326a5",
        "type": "inject",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "topic": "",
        "payload": "{\"motor\":2}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 119.99999618530273,
        "y": 551.9999961853027,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "3e380a81.fa6686",
        "type": "inject",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "topic": "",
        "payload": "{\"motor\":3}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 119.99999618530273,
        "y": 611.9999961853027,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "82bf19f7.816248",
        "type": "inject",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "topic": "",
        "payload": "{\"motor\":4}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 119.99999618530273,
        "y": 671.9999961853027,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "41ef2e0b.1028f",
        "type": "firebase modify",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "firebaseconfig": "",
        "childpath": "",
        "method": "set",
        "value": "msg.payload",
        "priority": "msg.priority",
        "x": 819.1001091003418,
        "y": 736.800051689148,
        "wires": [
            []
        ]
    },
    {
        "id": "a9fd5c2b.656f5",
        "type": "template",
        "z": "b1df9a03.d68bf8",
        "name": "HTML",
        "field": "payload",
        "fieldType": "msg",
        "format": "html",
        "syntax": "mustache",
        "template": "<!DOCTYPE html>\n<html lang=\"ja\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>加速度検出</title>\n</head>\n \n<body>\n<div id=\"datatxt\">データの表示</div> \n <btn class = 'btn'>\n  <a href=\"\">右</a>   \n </btn>\n<script>\n \n\n</script>\n</body>\n</html>",
        "x": 370.10003662109375,
        "y": 103.19999694824219,
        "wires": [
            [
                "6199aa01.d1ee44"
            ]
        ]
    },
    {
        "id": "6199aa01.d1ee44",
        "type": "template",
        "z": "b1df9a03.d68bf8",
        "name": "CSS",
        "field": "payload",
        "fieldType": "msg",
        "format": "css",
        "syntax": "mustache",
        "template": ".btn{\n    width:90px;\n    height:90px;\n    line-height:90px;\n}\n.btn a{\n    display:block;\n    width:100%;\n    height:100%;\n    text-decoration: none;\n    background:#FF8181;\n    text-align:center;\n    color:#FFFFFF;\n    font-size:20px;\n    font-weight:bold;\n    border-radius:50px;\n    -webkit-border-radius:50px;\n    -moz-border-radius:50px;\n    box-shadow:0px 5px 8px 0px #BBBBBB ;\n    text-shadow:0px 1px 1px #444444 ;\n}\n.btn a:hover{\n    background:#FF0303;\n    color:#FFFFFF;\n    margin-top:5px;\n    box-shadow:none;\n}",
        "x": 493.00000762939453,
        "y": 104.00000095367432,
        "wires": [
            [
                "4a88979.d9e9e68"
            ]
        ]
    },
    {
        "id": "b4b28800.b0f228",
        "type": "http in",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "url": "stage",
        "method": "get",
        "swaggerDoc": "",
        "x": 184,
        "y": 99,
        "wires": [
            [
                "a9fd5c2b.656f5"
            ]
        ]
    },
    {
        "id": "4a88979.d9e9e68",
        "type": "http response",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "x": 784,
        "y": 113,
        "wires": []
    },
    {
        "id": "d7d1d295.5d8bf",
        "type": "inject",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "topic": "",
        "payload": "{\"motor\":0}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 124.99999618530273,
        "y": 410.99999618530273,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "8b6bfa6d.367128",
        "type": "comment",
        "z": "b1df9a03.d68bf8",
        "name": "左",
        "info": "",
        "x": 83.10000419616699,
        "y": 511.8000240325928,
        "wires": []
    },
    {
        "id": "55d9a346.66ce3c",
        "type": "comment",
        "z": "b1df9a03.d68bf8",
        "name": "右",
        "info": "",
        "x": 81.99999618530273,
        "y": 444.9999990463257,
        "wires": []
    },
    {
        "id": "da155616.411bb8",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Back(5mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":1}",
        "payloadType": "json",
        "topic": "",
        "x": 610,
        "y": 200,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "fce48abb.06cc78",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Foward(5mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":2}",
        "payloadType": "json",
        "topic": "",
        "x": 620,
        "y": 240,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "e9c8c2c.cb14e4",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Back(10mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":3}",
        "payloadType": "json",
        "topic": "",
        "x": 610,
        "y": 280,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "44413259.eb1bec",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Foward(10mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":4}",
        "payloadType": "json",
        "topic": "",
        "x": 620,
        "y": 320,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "e5da3f9f.b4543",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "offset",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"distance_x\":0, \"distance_y\":0}",
        "payloadType": "json",
        "topic": "",
        "x": 590,
        "y": 160,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "8d1b8b68.150858",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Back(100mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":5}",
        "payloadType": "json",
        "topic": "",
        "x": 880,
        "y": 200,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "a7b7733a.5de8c",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Foward(100mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":6}",
        "payloadType": "json",
        "topic": "",
        "x": 880,
        "y": 240,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "ecc8e229.7d44b",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Back(10mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":7}",
        "payloadType": "json",
        "topic": "",
        "x": 870,
        "y": 280,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "13b94a18.4c5bd6",
        "type": "ui_button",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "f7557849.9ddfe8",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "Foward(10mm)",
        "color": "",
        "bgcolor": "",
        "icon": "",
        "payload": "{\"motor\":8}",
        "payloadType": "json",
        "topic": "",
        "x": 880,
        "y": 320,
        "wires": [
            [
                "41ef2e0b.1028f"
            ]
        ]
    },
    {
        "id": "839fb64e.6538f8",
        "type": "ui_gauge",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "group": "373ca1aa.76bade",
        "order": 0,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "gauge",
        "label": "units",
        "format": "{{value}}",
        "min": "-10",
        "max": 10,
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 990,
        "y": 100,
        "wires": []
    },
    {
        "id": "6535557a.547ddc",
        "type": "ui_text",
        "z": "b1df9a03.d68bf8",
        "group": "373ca1aa.76bade",
        "order": 0,
        "width": 0,
        "height": 0,
        "name": "",
        "label": "distance_x",
        "format": "{{msg.payload}}",
        "layout": "row-spread",
        "x": 920.1000137329102,
        "y": 46.4000129699707,
        "wires": []
    },
    {
        "id": "3117451a.3e75fa",
        "type": "firebase.on",
        "z": "b1df9a03.d68bf8",
        "name": "",
        "firebaseconfig": "",
        "childpath": "distance_x",
        "atStart": true,
        "eventType": "value",
        "queries": [
            {
                "name": "orderByChild",
                "value": "distance_x"
            }
        ],
        "x": 478.1000061035156,
        "y": 42.60000038146973,
        "wires": [
            [
                "839fb64e.6538f8",
                "6535557a.547ddc"
            ]
        ]
    },
    {
        "id": "f7557849.9ddfe8",
        "type": "ui_group",
        "z": "",
        "name": "Group",
        "tab": "f58979ef.30ad38",
        "order": null,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "373ca1aa.76bade",
        "type": "ui_group",
        "z": 0,
        "name": "Group",
        "tab": "5d8bed2f.3397a4",
        "order": null,
        "disp": true,
        "width": 6
    },
    {
        "id": "f58979ef.30ad38",
        "type": "ui_tab",
        "z": 0,
        "name": "Tab",
        "icon": "dashboard",
        "order": 0
    },
    {
        "id": "5d8bed2f.3397a4",
        "type": "ui_tab",
        "z": 0,
        "name": "Tab",
        "icon": "dashboard",
        "order": 0
    }
]

```

# 動かしてみる
操作画面はこのような感じです．
実測で，移動量をボタンで割り当てています．

![opretion_page.png](https://qiita-image-store.s3.amazonaws.com/0/212276/4fb7950b-543c-a5d5-63f1-c89f2a44c253.png)

そして，以下のように動きます！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">遠隔操作できるステージが、ちゃんと真空チャンバー内で動いてくれるので、研究費節約しつつ実験効率が半端なく上がった(できるだけ実験条件変えなくてよいのも◎)というのが週末のハイライト...お手軽IoT <a href="https://t.co/tYjeNX3fGD">pic.twitter.com/tYjeNX3fGD</a></p>&mdash; たくろーどん@宇宙エンジニア (@takudooon) <a href="https://twitter.com/takudooon/status/1071754297099005953?ref_src=twsrc%5Etfw">2018年12月9日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



# 終わりに
enebularは便利！