| 位置決めスライダープログラム |
Arduino UNOから、SPIインタフェイスを介し、L6470ドライブキットにコマンド送信しステッピングモータを制御します。キットにも取扱説明書が付属していますが、素人の私には簡単には判りませんので、“北の国から電子工作”というサイトで公開されているARDUINOプログラムを勉強させて頂きました。有難うございます。
先回投稿“位置決めスライダーの製作①”で掲載した動画のArduino UNOのプログラムを参考に掲載します。
#include <SPI.h>
// ピン定義。
#define PIN_SPI_MOSI 11
#define PIN_SPI_MISO 12
#define PIN_SPI_SCK 13
#define PIN_SPI_SS 10
#define PIN_BUSY 9
#define PIN_5 5
#define PIN_6 6
#define PIN_7 7
#define PIN_8 8
int sw_sts_5 = LOW; // 初期入力状態設定
int sw_sts_6 = LOW; // 初期入力状態設定
// 起動時実行
void setup()
{
delay(1000);
pinMode(PIN_SPI_MOSI, OUTPUT);
pinMode(PIN_SPI_MISO, INPUT);
pinMode(PIN_SPI_SCK, OUTPUT);
pinMode(PIN_SPI_SS, OUTPUT);
pinMode(PIN_BUSY, INPUT);
pinMode(PIN_5, INPUT );
pinMode(PIN_6, INPUT );
pinMode(PIN_7, OUTPUT );
pinMode(PIN_8, OUTPUT );
SPI.begin();
SPI.setDataMode(SPI_MODE3);
SPI.setBitOrder(MSBFIRST);
digitalWrite(PIN_SPI_SS, HIGH);
L6470_rst_device(); // L6470リセット
L6470_set_parameter(); // L6470パラメータ設定
delay(500);
get_origin(); // 原点復帰動作
L6470_data_transfer(0x60,3,(long)2307); // 絶対値移動指令(目盛30mm位置)
}
// メインループ
void loop(){
}
// 原点復帰動作
void get_origin(){
digitalWrite( PIN_7 , LOW );
digitalWrite( PIN_8 , LOW );
if(digitalRead( PIN_5 )){
L6470_data_transfer(0x51,3,8000); // 反-原点方向(右)中速移動
delay(50);
while(digitalRead( PIN_5 )){ delay(500); }
L6470_data_transfer(0xb0,0,0); // 回転停止(トルク保持)
L6470_wait_not_busy(500);
}
L6470_data_transfer(0x50,3,8000); // 原点方向(左)中速移動
while(!digitalRead( PIN_5 )){}
L6470_data_transfer(0xb0,0,0); // 回転停止、保持トルクあり
L6470_wait_not_busy(500);
L6470_data_transfer(0x51,3,500); // 反-原点方向(右)低速移動
delay(50);
while(digitalRead( PIN_5 )){}
L6470_data_transfer(0xb0,0,0); // 回転停止(トルク保持)
L6470_wait_not_busy(500);
L6470_data_transfer(0x41,3,600); // 反-原点方向(右)長さ指定移動
L6470_wait_not_busy(100);
L6470_data_transfer(0xd8,0,0); // 原点情報初期化
L6470_wait_not_busy(800);
digitalWrite( PIN_7 , HIGH );
digitalWrite( PIN_8 , HIGH );
}
// 初期設定
void L6470_set_parameter(){
L6470_data_transfer(0x05,2,0x0e);
L6470_data_transfer(0x06,2,0x0e);
L6470_data_transfer(0x07,2,0x0e);
L6470_data_transfer(0x08,2,0x01);
L6470_data_transfer(0x15,2,0x3ff);
L6470_data_transfer(0x09,1,0x50);
L6470_data_transfer(0x0a,1,0x50);
L6470_data_transfer(0x0b,1,0x50);
L6470_data_transfer(0x0c,1,0x50);
// マクロステップ指定( 0x03 : 1/8 )
// 実測値:16000step=20.8cm → 15385step=20.0cm → 77step=1mm(→15400step=20.0cm)
// 計算値:1/8マイクロステップ→400*8(STEP/ROT)→3200(STEP/ROT))/40(mm/rot)=80(STEP/ROT)
L6470_data_transfer(0x16,1,0x03);
}
// L6470リセット
void L6470_rst_device(){
L6470_data_send_u(0x00); //nop命令
L6470_data_send_u(0x00);
L6470_data_send_u(0x00);
L6470_data_send_u(0x00);
L6470_data_send_u(0xc0);
}
// L6470送信データ加工
void L6470_data_transfer(int add,int bytes,long val){
int data[3];
L6470_data_send(add);
for(int i=0;i<=bytes-1;i++){
data[i] = val & 0xff;
val = val >> 8;
}
if(bytes==3){
L6470_data_send(data[2]);
}
if(bytes>=2){
L6470_data_send(data[1]);
}
if(bytes>=1){
L6470_data_send(data[0]);
}
}
// L6470データ送信(BUSY解除待機)
void L6470_data_send(unsigned char add_or_val){
while(!digitalRead(PIN_BUSY)){}
digitalWrite(PIN_SPI_SS, LOW); // ~SSイネーブル。
SPI.transfer(add_or_val); // アドレスもしくはデータ送信。
digitalWrite(PIN_SPI_SS, HIGH); // ~SSディスエーブル。
}
// L6470データ送信(BUSY状態関係なし)
void L6470_data_send_u(unsigned char add_or_val){
digitalWrite(PIN_SPI_SS, LOW); // ~SSイネーブル。
SPI.transfer(add_or_val); // アドレスもしくはデータ送信。
digitalWrite(PIN_SPI_SS, HIGH); // ~SSディスエーブル。
}
// BUSY解除待機
void L6470_wait_not_busy(long time){
// BUSY解除待機
while(!digitalRead(PIN_BUSY)){}
delay(time);
}
| スライダー移動量の計算 |
Arduino UNOプログラムから、L6470に対し、移動量指定する際の考え方を書いておきます。今回、プログラム104行目のマイクロステップ指定で “1/8”に細分化しています。表1に関連データと表2に表1データをもとに1mm移動するのに必要なSTEP数を計算します。
この計算では、80 [STEP/mm]となりました。
| 表1:スライダーの移動量を計算する為のデータ | ||
| No | 項 目 | 内 容 |
| 1 | L6470マイクロステップ設定 | 1/8 |
| 2 | ステッピングモーター分解能 |
400 [STEP/回転] |
| 3 | タイミングベルトピッチ | 2[mm] |
| 4 | プーリー歯数 | 20 |
表2:1mm移動するのに必要なSTEP数 |
||
| No | 項 目 | 内 容 |
| 1 | モーター1回転 当りSTEP数 |
8X 400 [STEP/回転]=3200 [STEP/回転] (マイクロステップ設定考慮) |
| 2 | モーター1回転 当り移動量 |
2[mm] X 20 = 40 [mm/回転] |
| 3 | 1mm当り STEP数 |
3200[STEP/回転] ÷ 40[mm/回転] = 80 [STEP/mm] |
ただ、実際に動かしてみると「目盛」と一致しません。プーリー端数やタイミングベルト伸びなどを疑いましたが、原因は「目盛」がパソコンから印刷しているため、実スケールと異なっていることでした。
参考までに実測方法について記載します。いきなり多く移動させるとオーバーランなどリスクがあるので、少しずつ移動量を増やし、“0” [mm]の位置から、16000 [STEP]移動させた時に「目盛」の 20.8 [cm] の位置に移動しましたので、次の様に計算します。
→ 16000 [STEP] ÷ 208 [mm] = 76.9 [STEP/mm]
市販の定規で改めて確認し、表2の計算が正しいことは確認出来ました。ただ、「目盛」を貼り直すと黒い塗装が剥がれてしまうなどの問題もあるので、実測値に基づき移動量計算をすることにしています。
| 主要パーツ |
主要パーツについて記載します。
タイミングベルトのセットが意外に安く助かりました。中国製の3Dプリンター等が安く販売されていますが、その補修パーツの様です。
| L6470ドライブキット | AE-L6470DRV | 秋月 電子 |
|
| ステッピングモーター | ST-42BYH1004-5013 | ||
| リミットSW(マイクロSW) | SS-10GL13 | ||
| フラットケーブル | DG01032-0012-01 | ||
| KeeYees GT2 タイミングベルト | ― | AMAZON | |
| ミニガイドレール | MRS15-400 | スガツネ工業 | |
| MR-15CS |
| まとめ |
次回は、位置決めスライダーをパソコンからシリアル通信で位置決めする方法を検討します。