Robofun 機器人論壇

標題: 用Arduino控制一顆步進馬達! [打印本頁]

作者: vegewell    時間: 2012-1-25 19:19
標題: 用Arduino控制一顆步進馬達!
用Arduino控制一顆步進馬達!

Arduino 接 L298N ic
(手機拍的影像比較不清楚)
[youtube]CGwKFL2LtxE[/youtube]
作者: vegewell    時間: 2012-1-25 19:21
另外要接電容比較好
作者: pizg    時間: 2012-1-27 19:44
另外要接電容比較好
vegewell 發表於 2012-1-25 19:21

您好,
一顆規格不詳盡的步進馬達,
請問如何量測它的:
1.最高轉速?
2.一圈走幾步? 或步進角度?
3.不同的磁激方式會影響它的步進角度嗎?
作者: vegewell    時間: 2012-1-28 13:07
回復 3# pizg


    新年恭喜!
步進馬達沒有額定轉速,
是看信號的頻率,
我現在用arduino,最多是做到近三轉一秒,
有人做到約一分鐘六百轉,
要知道步進角度,
你就在程式裡讓它走兩百步,
如果正好轉一圈,就表示是步進角度是1.8,
只有特別的驅動器有不同的磁激方式,
L298N好像做不到.
作者: pizg    時間: 2012-1-29 14:30
本帖最後由 pizg 於 2012-1-29 14:35 編輯

回復 4# vegewell

1."步進馬達沒有額定轉速,是看信號的頻率"
那麼信號頻率跟馬達轉速是一個怎樣的關係?
齒輪減速比也應該要考慮進去吧?

2.底下是一個範例程式:
#include <Stepper.h>
// 把這個值改成馬達所對應的步數
#define STEPS 100
// 建立Stepper類別的新實例,並指定馬達的步數以及所連接的腳位
Stepper stepper(STEPS, 8, 9, 10, 11);
// 用來儲存感測器讀入的數值
int previous = 0;
void setup()
{
  // 將馬達的速度設定成30RPM
  stepper.setSpeed(30);
}
void loop()
{
  // 讀入可變電阻的值
  int val = analogRead(0);
  // 根據變動的幅度來轉動馬達
  stepper.step(val - previous);
  // 把目前的回傳值儲存起來
  previous = val;
}

a.上述程式可以設定馬達的STEPS, 請問如何知道該顆步進馬達的STEPS是多少?(廠商未提供)
b.stepper.setSpeed(30); 這一行設定轉速為30rpm, 請問馬達真的會是30rpm嗎? 又如果設成stepper.setSpeed(30000); 它真的會轉那麼快嗎?
c.請問您的"三轉一秒"是怎麼做到的, 可否貼上程式碼分享一下?

我用的是ULN2003, 5線式步進馬達, 可以做到一相, 二相, 一二相磁激.
作者: vegewell    時間: 2012-1-30 11:38
回復 5# pizg

你用ULN2003 控制的 5線式步進馬達應該是這種:

步進角度:5.625 x 1/64
減速比:1/64
這顆步進馬達裡面有減速齒輪,
信號頻率越大,馬達轉速越快,
馬達的STEPS是由自己設定的,這句stepper.step(200);就是只走200 STEPS,
stepper.setSpeed(30); 這一行設定轉速為30rpm, 我的馬達真的會是30rpm,
又如果設成stepper.setSpeed(30000); 它就不會動,
我的是四線馬達,跟你的不一樣,最多接近三轉一秒,
code如下:
#include <Stepper.h>
// change this to the number of steps on your motor
#define STEPS 200
//steps:代表馬達轉完一圈需要多少步數。如果馬達上有標示每步的度數,
//將360除以這個角度,就可以得到所需要的步數(例如:360/3.6=100)。(int)
// create an instance of the stepper class, specifying
// the number of steps of the motor and the pins it's
// attached to
Stepper stepper(STEPS, 2, 3, 4, 5);
//Stepper stepper(STEPS, 26, 28, 32, 34);
void setup()
{
stepper.setSpeed(140);// 將馬達的速度設定成140RPM 最大  150~160
}
void loop()
{
stepper.step(100);//正半圈
delay(1000);
stepper.step(-100);//反半圈
delay(1000);
stepper.step(200);//正1圈
delay(1000);
stepper.step(-200);//反1圈
delay(1000);
stepper.step(300);//正1圈半
delay(1000);
stepper.step(-300);//反1圈半
delay(1000);
stepper.step(1600);//正8圈
delay(1000);
stepper.step(-1600);//反8圈
delay(1000);
}
作者: pizg    時間: 2012-1-31 00:19
本帖最後由 pizg 於 2012-1-31 19:22 編輯

我用的的確是如你所貼的步進馬達. 減速比:1/64
, 但我對它的步進角度=5.625存疑.

另外當我試您的程式 STEPS=200, stepper.step(100) 時, 它走不到半圈,
而 stepper.step(200)也走不到1圈, 大概只有1/2圈.

於是我試了又試, 當STEPS=64,stepper.step(512) 時, 它剛好走1圈,
stepper.step(1024) 時, 它剛好走2圈,所以
步進角應該是 360/512=0.703度.
(一二相磁激方式(8拍)乘上減速比64等於512).

另外, 當setSpeed=300時, 它也不是rpm=300. 真正的轉速有待再測定.
有一點讓我納悶的是, STEPS=128, Speed=200時的速度竟然比STEPS=64, Speed=200時快一倍,而兩者的 stepper.step(512)也都是走1圈.

試到最後只要STEPS的值乘上stepper.step(值)不大於25600就都可行, 也就是
STEPS=64, Speed=400;
STEPS=128, Speed=200;
STEPS=256, Speed=100;
STEPS=512, Speed=50;
其速度都一樣, 而且stepper.step(512), 都剛好走1圈.
至此終於搞懂我的步進馬達的STEPS=512, Speed Max=50rpm.

由於步進馬達是相對角度轉動, 每次開始的角度都不一定, 在實際應用時應該搭配一個起始角度感測器(它可以是微動開關也可以是紅外線開關).

說到這兒, 我還是搞不懂函數STEPS和setSpeed的關係如何?
作者: nichal    時間: 2012-1-31 11:16
http://122.146.66.69/joomla/inde ... ing-motor/109--st28

我有試過這種馬達
規格應該是對的
只是有沒有失步得自己試了才知道

這裡的5.625
代表馬達本體是一圈 360/5.625 = 64步(換相64次)
再加上減速比是1/64
所以輸出軸一圈要送64*64=4096步才可以轉一圈
另外換相的啟動頻率不可以低於550pps
也就是啟動時的換相頻率每秒至少換相550次
不然應該連轉都轉不起來
啟動後可以把速度降下來
但要確定是連續運轉
一旦停下來就得再以550pps的方式送信號

之前我有在另一篇文章回覆
要降速
可以把8步當成1步用
也就是每8步的速度都是以550pps以上來送
但是8步後可以間隔半秒一秒再送下一個8步
(8小步為1大步)
這樣可以把速度降下來
還可以確定馬達一定會轉在定位上
只是這樣就降低瞭解析度
一圈剩下512個大步

提供您參考~~~~
作者: vegewell    時間: 2012-1-31 11:57
回復 7# pizg

nichal分析的很有道理,
就我所知,
你這顆步進馬達裡面有減速齒輪,拆開來就看得到,
所以步進角度:5.625經過減速齒輪,就變成如你所說的0.703度
所以你的Speed Max=50rpm,變慢很正常,
你這顆步進馬達,我本來也要買,後來沒買到,
所以所知有限,
大概就這樣.
如果你要搞懂函數STEPS和setSpeed的關係如何,
應該要從<Stepper.h>裡面去瞭解,
作者: vegewell    時間: 2012-1-31 12:02
回復 8# nichal

孩子長大一點了,
肩膀所要負的責任還有很長的時間,
加油.
作者: pizg    時間: 2012-1-31 21:31
本帖最後由 pizg 於 2012-2-1 00:08 編輯

回復 8# nichal

首先要感謝兩位大大的詳細解說.

我的馬達是五線四相,減速比1/64,  額定電壓是5V, 其餘不詳.
網頁 http://122.146.66.69/joomla/inde ... ing-motor/109--st28 上的是12V, 我的可以用到12V嗎?

"這裡的5.625代表馬達本體是一圈 360/5.625 = 64步(換相64次), 再加上減速比是1/64
所以輸出軸一圈要送64*64=4096步才可以轉一圈..."
您的意思是不是STEPS應該設成4096才對?
如果STEPS=4096, setSpeed只能設到7, 大於7就無法轉動了. 此時的setSpeed會變成無意義的指令, 因為它無法反應馬達的實際轉速,
所以我的STEPS還是設成512, 如此setSpeed才能做到我要的實際轉速.

"另外換相的啟動頻率不可以低於550pps, 也就是啟動時的換相頻率每秒至少換相550次, 不然應該連轉都轉不起來"
請問這550pps要如何做, 程式碼怎麼寫?

"啟動後可以把速度降下來, 但要確定是連續運轉, 一旦停下來就得再以550pps的方式送信號,
要降速可以把8步當成1步用, 也就是每8步的速度都是以550pps以上來送, 但是8步後可以間隔半秒一秒再送下一個8步(8小步為1大步), 這樣可以把速度降下來, 還可以確定馬達一定會轉在定位上"
請問降速的程式碼該怎麼寫, Stepper.h所提供的函數無法做到吧?

"只是這樣就降低瞭解析度, 一圈剩下512個大步"
如果要達到最高解析度 360度 / 4096步 = 0.088 度/步, 真的可以做到嗎? 需要自己寫一相/二相/一二相磁激驅動嗎?
另外, 以這個馬達而言, 如果不管它的解析度如何, 請問它的最高轉速可以達到多少?

底下是我自訂的驅動函數, 竟然跟前面分析的結果不同, 1024步才走1圈, 步進角度=360/1024=0.3516,
步數若小於8不會轉動, 所以步進角度還需乘上8, 得到2.8125, 這是為什麼?
//自訂的步進函數 by PizG 2012-01-31
//一二相磁激, 逆時針轉動
//每轉1圈停0.5秒
int Pin0 = 6; //A
int Pin1 = 10;  //B
int Pin2 = 9;  //A_
int Pin3 = 11;  //B_

void setup()
{
  pinMode(Pin0, OUTPUT);
  pinMode(Pin1, OUTPUT);
  pinMode(Pin2, OUTPUT);
  pinMode(Pin3, OUTPUT);
}


void loop()
{
  myStep(1024); //1024步=轉1圈
  delay(500);
}

//一二相磁激, 逆時針轉動
void myStep(int _step)
{
  for(int i=0; i<_step; i++) {

  int n = i % 8;
  switch(n){
    case 0:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, HIGH);
      break;
    case 1:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, HIGH);
      digitalWrite(Pin3, HIGH);
      break;
     

    case 2:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, HIGH);
      digitalWrite(Pin3, LOW);
      break;
     

    case 3:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, HIGH);
      digitalWrite(Pin2, HIGH);
      digitalWrite(Pin3, LOW);
      break;
     

    case 4:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, HIGH);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, LOW);
      break;
     

    case 5:
      digitalWrite(Pin0, HIGH);
      digitalWrite(Pin1, HIGH);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, LOW);
      break;
      case 6:
     

      digitalWrite(Pin0, HIGH);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, LOW);
      break;
     

    case 7:
      digitalWrite(Pin0, HIGH);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, HIGH);
      break;
     

    default:
      digitalWrite(Pin0, LOW);
      digitalWrite(Pin1, LOW);
      digitalWrite(Pin2, LOW);
      digitalWrite(Pin3, LOW);
      break;
  }
  delay(1);
  }

}
作者: nichal    時間: 2012-2-1 08:58
我沒用過Arduino
所以只能提供概念

至於何謂1步
其實有很多意見
有的規格會說當A相回到A相
這樣算一步(也就是我的1大步)
也有人說
當A變反相或B變反相就算一步
(這是標準步進馬達的步數定義)
但是因為有微步進的驅動法則
所以步數這種東西在定義上很亂
一般都以寫的程式所呈現的現象為主

詳細的寫法
可以Google一下步進驅動法則
祝你順利
作者: nichal    時間: 2012-2-1 09:02
另外.....
不要被函數綁死了
函數也是人定義規劃出來的
瞭解基本原理才寫得出自己想要的東西~~~

加油!!
作者: nichal    時間: 2012-2-1 09:03
回復 10# vegewell


孩子還是很小啦!!
只是有比較聽話一點點了~~~

謝謝V大關心~~
作者: pizg    時間: 2012-2-1 13:13
回復 13# nichal


    感謝n大的指導.
呵~~我該去看一下stepper.h在做什麼了.
作者: vegewell    時間: 2012-2-1 14:57
回復 11# pizg
像你這顆馬達,
只有四種step寫法:

digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
亂寫的話,很容易把馬達燒壞,
請參考:
http://arduino.cc/hu/Tutorial/StepperUnipolar
我的四線馬達則如下:


    ======================
Stepwire 1wire 2wire 3wire 4
1Highlowhighlow
2lowhighhighlow
3lowhighlowhigh
4highlowlowhigh

作者: pizg    時間: 2012-2-1 22:41
本帖最後由 pizg 於 2012-2-1 22:45 編輯

回復 16# vegewell


感謝v大的提醒.
您說的方法是一相磁激, 我的馬達跑起來是沒問題, 另外我也試過二相和一二相磁激,
目前仍看不出有異狀, 呵~~~那就讓它多跑個幾天吧, 或許真會壞掉.

我發現"Arduino一試就上手"書中有不少錯誤的地方,
例如, 在"Arduino與控制馬達"這一章中的圖8-37與範例程式8-2對不起來,
而且程式碼的註解也不太對.
如果作者有看到此文, 可否說明一下.
作者: 你馬子    時間: 2012-9-23 15:01
我想試試看 請問一下
小弟剛學 剛好碰到這方面
可以教一下如何做 有電路圖嗎
作者: t706845    時間: 2013-8-9 00:26
可以請問一下嘛
為何我照著上面的方法接線與寫程式
結果馬達只會震動而不是轉動
作者: vegewell    時間: 2013-8-9 22:22
本帖最後由 vegewell 於 2013-8-9 22:28 編輯

回復 19# t706845

>>>為何我照著上面的方法接線與寫程式
>>>結果馬達只會震動而不是轉動
   我不清楚你是照什麼圖連線
是否類似如下圖:記住這是5v電源,更高壓有其他接法,


步進馬達四條線是兩條一組,
(某兩條接合時有煞車的感覺)
你可以試換線看看,




歡迎光臨 Robofun 機器人論壇 (https://robofun.net/forum/) Powered by Discuz! X3.2