やったこと
- ステッピングモーター&L6470キット購入
- キット半田付け&接続
- Arduinoコーディング
ステッピングモーター&L6470キット購入
以下を秋月電子より購入
1. L6470使用 ステッピングモータードライブキット
2. ステッピングモーターST-42BYG0506H
キット半田付け&接続
キットを説明書通りに半田付けする.
半田付けしたキットとArduinoを接続する.
Arduinoへのピンアサインは以下のとおり.(のちにコードに出てくるのでこの順番です.)
Arduino側 | L6470側 |
---|---|
d9 | 1 |
d10 | 8 |
d11 | 7 |
d12 | 5 |
d13 | 6 |
GND | 3 |
Arduinoコーディング
コーディングは以下.
loop関数内を編集するといった具合.
参考はhttp://spinelify.blog.fc2.com/blog-entry-41.html.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
#include "SPI.h" #include "MsTimer2.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 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); SPI.begin(); SPI.setDataMode(SPI_MODE3); SPI.setBitOrder(MSBFIRST); Serial.begin(9600); digitalWrite(PIN_SPI_SS, HIGH); L6470_resetdevice(); //残留コマンドの削除とリセット L6470_setup(); //L6470を設定 MsTimer2::set(100, fulash); MsTimer2::start(); delay(2000); } void loop(){ testDrive(); /* rotateTest(); */ } void rotateTest(){ L6470_move(1,16000); L6470_hardhiz(); //回転急停止、保持トルクなし L6470_move(0,16000); L6470_hardhiz(); //回転急停止、保持トルクなし } void testDrive(){ L6470_run(0,50000); delay(10000); L6470_softstop(); L6470_busydelay(500); L6470_run(1,16000); delay(1); L6470_softstop(); L6470_busydelay(500); } void L6470_setup(){ //L6470_setparam_acc(0x40); //default 0x08A (12bit) (14.55*val+14.55[step/s^2]) L6470_setparam_acc(0x08A); //default 0x08A (12bit) (14.55*val+14.55[step/s^2]) //L6470_setparam_dec(0x40); //default 0x08A (12bit) (14.55*val+14.55[step/s^2]) L6470_setparam_acc(0x08A); //default 0x08A (12bit) (14.55*val+14.55[step/s^2]) //L6470_setparam_maxspeed(0x40); //default 0x041 (10bit) (15.25*val+15.25[step/s]) //L6470_setparam_maxspeed(0xFFFFFF); //default 0x041 (10bit) (15.25*val+15.25[step/s]) // When half step // L6470_setparam_maxspeed(0x5C); //default 0x041 (10bit) (15.25*val+15.25[step/s]) L6470_setparam_maxspeed(0xFFFFFF); //default 0x041 (10bit) (15.25*val+15.25[step/s]) L6470_setparam_minspeed(0x00); //default 0x000 (1+12bit) (0.238*val[step/s]) L6470_setparam_fsspd(0xff); //default 0x027 (10bit) (15.25*val+7.63[step/s]) //L6470_setparam_fsspd(0x3ff); //default 0x027 (10bit) (15.25*val+7.63[step/s]) //L6470_setparam_fsspd(0x027); //default 0x027 (10bit) (15.25*val+7.63[step/s]) L6470_setparam_kvalhold(0x80); //default 0x29 (8bit) (Vs[V]*val/256) L6470_setparam_kvalrun(0xd0); //default 0x29 (8bit) (Vs[V]*val/256) L6470_setparam_kvalacc(0x80); //default 0x29 (8bit) (Vs[V]*val/256) L6470_setparam_kvaldec(0x60); //default 0x29 (8bit) (Vs[V]*val/256) //L6470_setparam_stepmood(0x03); //default 0x07 (1+3+1+3bit) L6470_setparam_stepmood(0x07); //default 0x07 (1+3+1+3bit) } void fulash(){ Serial.print("0x"); Serial.print( L6470_getparam_abspos(),HEX); Serial.print(" "); Serial.print("0x"); Serial.println( L6470_getparam_speed(),HEX); } /*ver 1.00 2013/4/24*/ /*ver 1.01 2013/12/14 コメント追記*/ /*L6470 コントロール コマンド 引数----------------------- dia 1:正転 0:逆転, spd (20bit)(0.015*spd[step/s]) pos (22bit) n_step (22bit) act 1:絶対座標をマーク 0:絶対座標リセット mssec ミリ秒 val 各レジスタに書き込む値 --------------------------- L6470_run(dia,spd); //指定方向に連続回転 L6470_stepclock(dia); //指定方向にstepピンのクロックで回転 L6470_move(dia,n_step); //指定方向に指定数ステップする L6470_goto(pos); //指定座標に最短でいける回転方向で移動 L6470_gotodia(dia,pos); //回転方向を指定して指定座標に移動 L6470_gountil(act,dia,spd); //指定した回転方向に指定した速度で回転し、スイッチのONで急停止と座標処理 L6470_relesesw(act,dia); //スイッチがOFFに戻るまで最低速度で回転し、停止と座標処理 L6470_gohome(); //座標原点に移動 L6470_gomark(); //マーク座標に移動 L6470_resetpos(); //絶対座標リセット L6470_resetdevice(); //L6470リセット L6470_softstop(); //回転停止、保持トルクあり L6470_hardstop(); //回転急停止、保持トルクあり L6470_softhiz(); //回転停止、保持トルクなし L6470_hardhiz(); //回転急停止、保持トルクなし L6470_getstatus(); //statusレジスタの値を返す (L6470_getparam_status();と同じ) L6470_busydelay(msec); //busyフラグがHIGHになってから、指定ミリ秒待つ。 レジスタ書き込みコマンド L6470_setparam_abspos(val); //[R, WS]現在座標default 0x000000 (22bit) L6470_setparam_elpos(val); //[R, WS]コイル励磁の電気的位置default 0x000 (2+7bit) L6470_setparam_mark(val); //[R, WR]マーク座標default 0x000000 (22bit) //ありませんL6470_spped //[R] 現在速度read onry (20bit) L6470_setparam_acc(val); //[R, WS] 加速度default 0x08A (12bit) (14.55*val+14.55[step/s^2]) L6470_setparam_dec(val); //[R, WS] 減速度default 0x08A (12bit) (14.55*val+14.55[step/s^2]) L6470_setparam_maxspeed(val); //[R, WR]最大速度default 0x041 (10bit) (15.25*val+15.25[step/s]) L6470_setparam_minspeed(val); //[R, WS]最小速度default 0x000 (1+12bit) (0.238*val+[step/s]) L6470_setparam_fsspd(val); //[R, WR]μステップからフルステップへの切替点速度default 0x027 (10bit) (15.25*val+7.63[step/s]) L6470_setparam_kvalhold(val); //[R, WR]停止時励磁電圧default 0x29 (8bit) (Vs[V]*val/256) L6470_setparam_kvalrun(val); //[R, WR]定速回転時励磁電圧default 0x29 (8bit) (Vs[V]*val/256) L6470_setparam_kvalacc(val); //[R, WR]加速時励磁電圧default 0x29 (8bit) (Vs[V]*val/256) L6470_setparam_kvaldec(val); //[R, WR]減速時励磁電圧default 0x29 (8bit) (Vs[V]*val/256) L6470_setparam_intspd(val); //[R, WH]逆起電力補償切替点速度default 0x0408 (14bit) (0.238*val[step/s]) L6470_setparam_stslp(val); //[R, WH]逆起電力補償低速時勾配default 0x19 (8bit) (0.000015*val[% s/step]) L6470_setparam_fnslpacc(val); //[R, WH]逆起電力補償高速時加速勾配default 0x29 (8bit) (0.000015*val[% s/step]) L6470_setparam_fnslpdec(val); //[R, WH]逆起電力補償高速時減速勾配default 0x29 (8bit) (0.000015*val[% s/step]) L6470_setparam_ktherm(val); //[R, WR]不明default 0x0 (4bit) (0.03125*val+1) //ありませんL6470_adcout //[R] read onry (5bit) ADCによる逆起電力補償の大きさかな? L6470_setparam_ocdth(val); //[R, WR]過電流しきい値default 0x8 (4bit) (375*val+375[mA]) L6470_setparam_stallth(val); //[R, WR]失速電流しきい値?default 0x40 (7bit) (31.25*val+31.25[mA]) L6470_setparam_stepmood(val); //[R, WH]ステップモードdefault 0x07 (1+3+1+3bit) L6470_setparam_alareen(val); //[R, WS]有効アラームdefault 0xff (1+1+1+1+1+1+1+1bit) L6470_setparam_config(val); //[R, WH]各種設定default 0x2e88 (3+3+2+1+1+1+1+1+3bit) //L6470_status //[R]状態read onry (16bit) [R]:読み取り専用 [WR]:いつでも書き換え可 [WH]:書き込みは出力がハイインピーダンスの時のみ可 [WS]:書き換えはモータが停止している時のみ可 レジスタ読み込みコマンド(返り値 long型) L6470_getparam_abspos(); L6470_getparam_elpos(); L6470_getparam_mark(); L6470_getparam_speed(); L6470_getparam_acc(); L6470_getparam_dec(); L6470_getparam_maxspeed(); L6470_getparam_minspeed(); L6470_getparam_fsspd(); L6470_getparam_kvalhold(); L6470_getparam_kvalrun(); L6470_getparam_kvalacc(); L6470_getparam_kvaldec(); L6470_getparam_intspd(); L6470_getparam_stslp(); L6470_getparam_fnslpacc(); L6470_getparam_fnslpdec(); L6470_getparam_ktherm(); L6470_getparam_adcout(); L6470_getparam_ocdth(); L6470_getparam_stallth(); L6470_getparam_stepmood(); L6470_getparam_alareen(); L6470_getparam_config(); L6470_getparam_status(); */ void L6470_setparam_abspos(long val){L6470_transfer(0x01,3,val);} void L6470_setparam_elpos(long val){L6470_transfer(0x02,2,val);} void L6470_setparam_mark(long val){L6470_transfer(0x03,3,val);} void L6470_setparam_acc(long val){L6470_transfer(0x05,2,val);} void L6470_setparam_dec(long val){L6470_transfer(0x06,2,val);} void L6470_setparam_maxspeed(long val){L6470_transfer(0x07,2,val);} void L6470_setparam_minspeed(long val){L6470_transfer(0x08,2,val);} void L6470_setparam_fsspd(long val){L6470_transfer(0x15,2,val);} void L6470_setparam_kvalhold(long val){L6470_transfer(0x09,1,val);} void L6470_setparam_kvalrun(long val){L6470_transfer(0x0a,1,val);} void L6470_setparam_kvalacc(long val){L6470_transfer(0x0b,1,val);} void L6470_setparam_kvaldec(long val){L6470_transfer(0x0c,1,val);} void L6470_setparam_intspd(long val){L6470_transfer(0x0d,2,val);} void L6470_setparam_stslp(long val){L6470_transfer(0x0e,1,val);} void L6470_setparam_fnslpacc(long val){L6470_transfer(0x0f,1,val);} void L6470_setparam_fnslpdec(long val){L6470_transfer(0x10,1,val);} void L6470_setparam_ktherm(long val){L6470_transfer(0x11,1,val);} void L6470_setparam_ocdth(long val){L6470_transfer(0x13,1,val);} void L6470_setparam_stallth(long val){L6470_transfer(0x14,1,val);} void L6470_setparam_stepmood(long val){L6470_transfer(0x16,1,val);} void L6470_setparam_alareen(long val){L6470_transfer(0x17,1,val);} void L6470_setparam_config(long val){L6470_transfer(0x18,2,val);} long L6470_getparam_abspos(){return L6470_getparam(0x01,3);} long L6470_getparam_elpos(){return L6470_getparam(0x02,2);} long L6470_getparam_mark(){return L6470_getparam(0x03,3);} long L6470_getparam_speed(){return L6470_getparam(0x04,3);} long L6470_getparam_acc(){return L6470_getparam(0x05,2);} long L6470_getparam_dec(){return L6470_getparam(0x06,2);} long L6470_getparam_maxspeed(){return L6470_getparam(0x07,2);} long L6470_getparam_minspeed(){return L6470_getparam(0x08,2);} long L6470_getparam_fsspd(){return L6470_getparam(0x15,2);} long L6470_getparam_kvalhold(){return L6470_getparam(0x09,1);} long L6470_getparam_kvalrun(){return L6470_getparam(0x0a,1);} long L6470_getparam_kvalacc(){return L6470_getparam(0x0b,1);} long L6470_getparam_kvaldec(){return L6470_getparam(0x0c,1);} long L6470_getparam_intspd(){return L6470_getparam(0x0d,2);} long L6470_getparam_stslp(){return L6470_getparam(0x0e,1);} long L6470_getparam_fnslpacc(){return L6470_getparam(0x0f,1);} long L6470_getparam_fnslpdec(){return L6470_getparam(0x10,1);} long L6470_getparam_ktherm(){return L6470_getparam(0x11,1);} long L6470_getparam_adcout(){return L6470_getparam(0x12,1);} long L6470_getparam_ocdth(){return L6470_getparam(0x13,1);} long L6470_getparam_stallth(){return L6470_getparam(0x14,1);} long L6470_getparam_stepmood(){return L6470_getparam(0x16,1);} long L6470_getparam_alareen(){return L6470_getparam(0x17,1);} long L6470_getparam_config(){return L6470_getparam(0x18,2);} long L6470_getparam_status(){return L6470_getparam(0x19,2);} void L6470_run(int dia,long spd){ if(dia==1) L6470_transfer(0x51,3,spd); else L6470_transfer(0x50,3,spd); } void L6470_stepclock(int dia){ if(dia==1) L6470_transfer(0x59,0,0); else L6470_transfer(0x58,0,0); } void L6470_move(int dia,long n_step){ if(dia==1) L6470_transfer(0x41,3,n_step); else L6470_transfer(0x40,3,n_step); } void L6470_goto(long pos){ L6470_transfer(0x60,3,pos); } void L6470_gotodia(int dia,int pos){ if(dia==1) L6470_transfer(0x69,3,pos); else L6470_transfer(0x68,3,pos); } void L6470_gountil(int act,int dia,long spd){ if(act==1) if(dia==1) L6470_transfer(0x8b,3,spd); else L6470_transfer(0x8a,3,spd); else if(dia==1) L6470_transfer(0x83,3,spd); else L6470_transfer(0x82,3,spd); } void L6470_relesesw(int act,int dia){ if(act==1) if(dia==1) L6470_transfer(0x9b,0,0); else L6470_transfer(0x9a,0,0); else if(dia==1) L6470_transfer(0x93,0,0); else L6470_transfer(0x92,0,0); } void L6470_gohome(){ L6470_transfer(0x70,0,0); } void L6470_gomark(){ L6470_transfer(0x78,0,0); } void L6470_resetpos(){ L6470_transfer(0xd8,0,0); } void L6470_resetdevice(){ L6470_send_u(0x00);//nop命令 L6470_send_u(0x00); L6470_send_u(0x00); L6470_send_u(0x00); L6470_send_u(0xc0); } void L6470_softstop(){ L6470_transfer(0xb0,0,0); } void L6470_hardstop(){ L6470_transfer(0xb8,0,0); } void L6470_softhiz(){ L6470_transfer(0xa0,0,0); } void L6470_hardhiz(){ L6470_transfer(0xa8,0,0); } long L6470_getstatus(){ long val=0; L6470_send_u(0xd0); for(int i=0;i<=1;i++){ val = val << 8; digitalWrite(PIN_SPI_SS, LOW); // ~SSイネーブル。 val = val | SPI.transfer(0x00); // アドレスもしくはデータ送信。 digitalWrite(PIN_SPI_SS, HIGH); // ~SSディスエーブル } return val; } void L6470_transfer(int add,int bytes,long val){ int data[3]; L6470_send(add); for(int i=0;i<=bytes-1;i++){ data[i] = val & 0xff; val = val >> 8; } if(bytes==3){ L6470_send(data[2]); } if(bytes>=2){ L6470_send(data[1]); } if(bytes>=1){ L6470_send(data[0]); } } void L6470_send(unsigned char add_or_val){ while(!digitalRead(PIN_BUSY)){ } //BESYが解除されるまで待機 digitalWrite(PIN_SPI_SS, LOW); // ~SSイネーブル。 SPI.transfer(add_or_val); // アドレスもしくはデータ送信。 digitalWrite(PIN_SPI_SS, HIGH); // ~SSディスエーブル。 } void L6470_send_u(unsigned char add_or_val){//busyを確認せず送信するため用 digitalWrite(PIN_SPI_SS, LOW); // ~SSイネーブル。 SPI.transfer(add_or_val); // アドレスもしくはデータ送信。 digitalWrite(PIN_SPI_SS, HIGH); // ~SSディスエーブル。 } void L6470_busydelay(long time){//BESYが解除されるまで待機 while(!digitalRead(PIN_BUSY)){ } delay(time); } long L6470_getparam(int add,int bytes){ long val=0; int send_add = add | 0x20; L6470_send_u(send_add); for(int i=0;i<=bytes-1;i++){ val = val << 8; digitalWrite(PIN_SPI_SS, LOW); // ~SSイネーブル。 val = val | SPI.transfer(0x00); // アドレスもしくはデータ送信。 digitalWrite(PIN_SPI_SS, HIGH); // ~SSディスエーブル } return val; } |
これで簡単に動いてくれました.
はまったこと
- 定格内(DC12V2Aが望ましい)の電源をL6470側につけなければ動かない.
- Strawberry Linux品
の接続方法を参考では書いてあるがあくまで秋月のに従って接続する必要がある.
制作の参考になれば幸いです.