⚙️

小型リニアアクチュエータをArduino+A4988+CNCシールドで駆動させる

commits8 min read

小型リニアアクチュエータをArduino+A4988+CNCシールドで駆動させる

2相ステッピングモータ搭載、小型リニアアクチュエータ(D8-MOTOR80形搭載)を手に入れたので、使ってみたメモです。

また、CNCシールドを使って二機のリニアアクチュエータを動かしました。

リニアアクチュエータ.png

リニアアクチュエータ(D8-MOTOR80形搭載)仕様

駆動電圧DC 12V
1相あたり800アンペア/相
コイル抵抗15 10%Ω/相
ステップ角18。 / step
励磁法1-2相励磁
ドライブモードバイポーラドライバ
125pps
1600 ppsを超える最大応答周波数
最大開始周波数が1100 ppsを超える
モーター表面温度80°C
ねじ棒径3mm
ねじ棒の長さ90 mm
スライダストローク80mm
ねじ棒ピッチ±0.5mm
長さ10.3 cm / 4.1インチ
重さ50グラム(約)


↑これは購入元のAmazonの説明書きだが、この情報以外に、製品の詳しい日本語の情報は全く見当たらず...
生産元の中国語の情報を参考にしました。

A4988の1A1B2A2Bには上記の図を参考に色を合わせてつなげば良いです。

翻訳↓

注意点: モーターは全てドライバによる駆動が必須です、直接電源を接続できません!ドライバーA4988を手配すること。
以下はドライバーのリンク。

製品参考データ:
製品型番: D8-MOTOR80
(ステッピング)モーター類型:2相4線
定格電圧: 9V-12V (電圧を上げていくと、トルクも上がります、ただしそれに伴って、発熱も大きくなります)
電流: 800mA/phase
スクリュー(ネジ棒)長さ: 90mm
レール長さ: 80mm
モーター直径: 15mm
スクリュー直径: 3mm
スクリューピッチ: ±0.5mm ※一歩の移動は0.25mm,もしさらに小さくしたい場合は、マイクロステップを採用できます。
歩角度: 18度
駆動方式: 2段階駆動
全体長さ: 15x105mm
重量: 46g
直線走行の速度は毎秒25mm

スクリーンショット 2020-11-06 21.07.11.png

赤 → A+
黄 → A-
青 → B+
黒 → B-

A+ A- B+ B- はA4988ドライバに対して
1A 1B 2A 2Bとする

Arduino UNO+CNCシールドを使用

Arduino UNOにCNCシールドを接続します。
これはピンに差し込むだけです。
また準備したA4988ドライバをそれぞれのソケットに接続します。

IMG_1907.JPG

CNCシールドとArduinoUNOのピンの対応は以下の通りです。

CNCシールド対応リスト.png

今回はxとzを使用しました。

A4988の使い方はこの記事が参考になります[1]

https://iot.keicode.com/arduino/arduino-stepper-motor-a4988.php

A4988にArduinoからパルス信号を送信すれば良いですね。
ちなみにどのようにパルス信号を生成するか、ちょっとまとめて見ました。
この計算例は1000ppsの場合です。

こういう便利な周波数の計算サイトもあります[2]↓(筆者はこれ使いました。)

https://keisan.casio.jp/exec/user/1341380413

以下はリニアアクチュエータを二機同時に動かすArduinoのスケッチ

125ppsから1100ppsで動作可能であることが、仕様にも記載がありますが、
とりあえず1000ppsで動作させてみる。


int Speed = 500;
int Step = 20;

const int xstep = 2;
const int xdir = 5;
const int zstep = 4;
const int zdir = 7;

void setup(){
  Serial.begin(9600);

  pinMode(xstep,OUTPUT);
  pinMode(xdir,OUTPUT);

  pinMode(zstep,OUTPUT);
  pinMode(zdir,OUTPUT);

  digitalWrite(zdir,HIGH);
  digitalWrite(xdir,HIGH);
}

void loop() {
  if(Serial.available()){
    byte buf;
    while (1) {
      if(Serial.available()){
        buf = Serial.read();
       }
       if(buf == 'A'){ 
        digitalWrite(zdir,HIGH);
        digitalWrite(xdir,HIGH);
        for (int u=0; u <=Step; u++){
           digitalWrite(xstep,HIGH);
           digitalWrite(zstep,HIGH);
           delayMicroseconds(Speed);
           digitalWrite(xstep,LOW);
           digitalWrite(zstep,LOW);
           delayMicroseconds(Speed);
        }
       } else if(buf == 'B'){
        digitalWrite(zdir,LOW);
        digitalWrite(xdir,LOW);
         for (int d=0; d <=Step; d++){
           digitalWrite(xstep,HIGH);
           digitalWrite(zstep,HIGH);
           delayMicroseconds(Speed);
           digitalWrite(xstep,LOW);
           digitalWrite(zstep,LOW);
           delayMicroseconds(Speed);
        }
       }
    }
  }
}

18deg/stepのモーターなので、1回転は20STEP。
1回転で0.5mm進む。

このスケッチでは、シリアルモニターにコマンドA Bを送信すると設定したステップ数まで進みます。

※12Vで使用すると結構発熱します、そのまま使用すると火傷したりしますので、必ず冷却処理してください!
私はステッピングモーターの後面から冷却するようにファンを取り付けています。

性能評価

とりあえず、1000ppsと500ppsで利用したかったので、そのパラメータでの性能評価を行ってみました。

評価方法

リニアアクチュエーターが錘を任意の地点へ正確に移動できるか評価します。
ちなみに、今回はリニアアクチュエーターを2機並列に並べて利用する際の性能測定である。

測定方法としては、2種類のパラメーター(500pps、1000pps)に対し、
それぞれ移動量を4種類(3cm、4cm、5cm、6cm)、荷重量(錘)を4種類(100g、200g、300g、400g)に設定し、そのパラメータでリニアアクチュエーターを駆動したときの移動量をレーザー距離計(国際標準化機構規格ISO16331-1適合品)で10回ずつ測定しました。

ちなみに、使用したレーザー距離計はLeicaのDISTO D510[3]です。
測定方法イメージ

ちなみに、測定結果はこんな感じです↓
(入力開始時間から処理終了信号を受けたUNIXエポック秒の差、レーザー距離計による移動量測定値の平均値)



測定の結果、1mm以内の誤差で、十分実用に耐えうる性能であると思われます。
ただ、連続稼働に関してはまだ検証が必要ですね。

最後に性能評価時に利用したスクリプトを上げておく↓

arduino_serial.py
#/usr/bin/env python3
# 2019 kazuya yuda.
# -*- coding: utf-8 -*-
import serial
import time

class MtCtl():
    def arduino_serial():
        #open serial
        Serialt = serial.Serial('/dev/tty.',9600,timeout=None)
        time.sleep(0.5)
        return Serialt
    def mt_send_process(St,val):
        St.write(val)
    def arduino_recive_process(CRt):
        while True:
            buf = CRt.readline()
            if buf == b'end\r\n':
                print("end command sended.")
                break
linearactuatortest.py
#!/usr/bin/env python3
# -*- Coding: utf-8 -*-
# 2019 kazuya yuda.
import time
from arduino_serial import MtCtl

def main():
    mtinfo=MtCtl.arduino_serial()
    print("何センチ移動しますか?:",end=" ")
    val = input()
    print(time.strftime('%X'))
    if val == "mode1":
        print("ok")
    else:
        start = time.time()
        for i in range(int(val)*2):
            MtCtl.mt_send_process(mtinfo,b'A')
        MtCtl.mt_send_process(mtinfo,b'E')
        MtCtl.arduino_recive_process(mtinfo)
    t = time.time() - start
    print(t)
    print("定位置に戻しますか?y,n:")
    val_2 = input()
    if val_2 == "y":
        for i in range(int(val)*2):
            MtCtl.mt_send_process(mtinfo,b'B')
        MtCtl.mt_send_process(mtinfo,b'E')
        MtCtl.arduino_recive_process(mtinfo)
	print("end command received.")
    else:
        pass

if __name__ == '__main__':
    main()

arduino側

linearactuator_test.ino
//リニアアクチュエーター性能評価用
//made by kazuya yuda.

//200step 5mm

//int Speed = 1000; // 500pps(hz)
//int Speed = 500;  // 1000pps(hz)
//int Speed = 455;  //1100pps(hz)(最大)


int Step = 200;


const int xstep = 2;
const int xdir = 5;
const int zstep = 4;
const int zdir = 7;

int PIN = 11;

void setup(){
  Wire.begin();
  Serial.begin(9600);

  pinMode(xstep,OUTPUT);
  pinMode(xdir,OUTPUT);

  pinMode(zstep,OUTPUT);
  pinMode(zdir,OUTPUT);

  pinMode(8,OUTPUT);
  digitalWrite(8,LOW);

  digitalWrite(zdir,HIGH);
  digitalWrite(xdir,HIGH);
  
}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available()){
    byte buf;
    byte var;
    while (1) {
      if(Serial.available()){
        buf = Serial.read();
      }
      if(buf == 'A'){ 
        digitalWrite(zdir,HIGH);
        digitalWrite(xdir,HIGH);
        for (int u=0; u <=Step; u++){
           digitalWrite(xstep,HIGH);
           digitalWrite(zstep,HIGH);
           delayMicroseconds(Speed);
           digitalWrite(xstep,LOW);
           digitalWrite(zstep,LOW);
           delayMicroseconds(Speed);
        }
        buf = 0;
       } else if(buf == 'B'){
         digitalWrite(zdir,LOW);
         digitalWrite(xdir,LOW);
         for (int d=0; d <=Step; d++){
           digitalWrite(xstep,HIGH);
           digitalWrite(zstep,HIGH);
           delayMicroseconds(Speed);
           digitalWrite(xstep,LOW);
           digitalWrite(zstep,LOW);
           delayMicroseconds(Speed);
         }
         buf = 0;
       } else if(buf == 'E'){
        Serial.println("end");
        buf = 0;
       }
     }
   }
}

とにかく小さいので使い勝手が良いですね!
とりあえず性能を確認できたので、時間があれば今度何か作る予定。

脚注
  1. 「Arduino と A4988 でステッピングモーターを制御する方法」 https://iot.keicode.com/arduino/arduino-stepper-motor-a4988.php ↩︎

  2. 「周波数→周期変換」 https://keisan.casio.jp/exec/user/1341380413 ↩︎

  3. 「Leica DISTO™」 https://leica-geosystems.com/ja-jp/products/disto-and-leica-lino/leica-disto ↩︎