平時咱們會遇到不一樣種類的電機,主要常見的是步進電機,無刷直流電機,有刷直流電機,其實這幾種電機的工做原理相似,都是用電流產生磁場吸引電機裏的轉子旋轉,這也就是爲何咱們用一些電機驅動芯片(並非全部的驅動)能夠驅動一個步進電機或者兩個直流電機。這篇博客主要是講什麼是步進電機以及如何驅動步進電機,如何設置定時器。若是你們對個人博客有任何疑問,歡迎你們和我討論。git
電路圖以下(摘自Pololu A4988,連接):
github
我搭出來的電路的模樣:
測試
首先咱們須要研究一下步進電機和它的驅動的datasheet。ui
我用第一張圖給你們簡單地講解下步進電機是如何工做的:2A和2B是一條「導線」的兩端,1A和1B是另一條「導線」的兩端,經過把這兩條導線在電機內纏繞,會讓他們在通電的時候各自產生磁場。磁場的方向根據洛倫茲法則能夠得出,和電流的方向,繞線的方向有關。產生的磁場會吸引電機內部中心的轉子旋轉。經過兩根導線交替產生不一樣方向的磁場,以此來吸引轉子周而復始的旋轉。更多的你們能夠百度。spa
下面這張圖是NEMA (17HS16-2004S1)的datasheet:
操作系統
咱們注意到在上圖的電機datasheet裏面額定電壓是2V,額定電流是2A每一個Phase,這個Phase指的就是上面提到的2A/2B或者是1A/1B的導線。咱們應該如何理解這裏的額定電壓和電流?它們指的是:當我給2A和2B端或1A和1B端加上2V的電壓,會有2A的電流流過導線,根據歐姆定律,咱們獲得導線兩端的電阻是1歐(在datasheet上,Resistance/Phase那一行也寫着1歐姆)。3d
因此咱們可不能夠認爲交替地在2A/2B和1A/1B上加上2V的電壓就可讓電機轉動?答案是:是的。咱們加的是額定電壓,固然可讓電機轉動。但問題是電機不會有足夠的轉速和扭矩,緣由是根據法拉第電磁感應定律,除了咱們電壓所產生的電流外,還會有電磁感應產生的電流,而電磁感應的電流和電壓所產生的電流是反向的,所以雖然咱們在導線兩端加上了額定電壓,可是在最初的一段時間內,獲得的電流會比額定電流少不少。若是電流不夠大,那麼產生的磁場是不夠移動轉子的。這時候咱們想到的辦法是:能夠提升加在導線兩端的打壓來抵消由磁場產生的反向電流,而電機的驅動就是提升兩端的電壓,一般能夠提升到額定電壓的10倍,固然咱們須要限制驅動芯片提供給電機的電流,這個咱們後面會更詳細地說。orm
市面上有不少步進電機的驅動,除了此次用的A4988,還有A3988,DRV8871等等。它們的工做方式也類似,都是1)在電機每一個Phase兩端加幾倍於額定電壓的電壓值,2)控制每一個Phase的最大電流,這樣的步進電機驅動被稱爲chopper driver,就是說爲了提供不超過某個上限電流,它會在特定的時間點中止爲電機提供電壓。以下圖所示:
blog
能夠看到圖中,當電流超過了上限值I,驅動就會中止提供電壓,這時由於磁場做用,電流並不會瞬間爲0,而是會逐漸減少(時間常數 = LR)。當電流小於上限值I,驅動又會從新提供電壓。因此經過這種達到,既在電機每一個Phase兩端提供了高電壓,又控制了電流。根據上面電機的datasheet中的AMP/PHASE,咱們獲得咱們須要保證每一個Phase的電流不超過2A。圖片
下面咱們來看看A4988的datasheet:
首先咱們須要弄懂的是,Arduino應該如何讓驅動開始驅動步進電機工做。以下圖所示:
和第一張圖對應,STEP須要輸入脈衝信號(最上面RESET信號,我認爲標識錯了,由於STEP和下面的Phase1,Phase2都是正常工做時的樣子)。電機驅動會控制電流輸出,圖中的Phase1和Phase2。有幾點咱們能夠注意到,首先每次STEP的上升沿,是Phase1或者Phase2發生變化的地方,並且STEP在每一個上升沿只會有一個Phase發生方向的改變。好比第二個上升沿,Phase 1的電流仍是70.71%,而Phase 2的電流就從-70.71%改變到+70.71%,這裏的正負號表明電流的方向,這個是和步進電機的機械結構相關的,好比咱們不會把步進電機從0度直接到180度,而是會0度先到90度,再到180度。第二點,咱們能夠想到,若是想加快電機的轉動速度,咱們須要作的就是減小每一個脈衝的寬度,固然這個脈衝的寬度會有最小值,最小值在於當咱們設置了某個脈衝寬度,電機驅動在沒有等到電機中的轉子轉到指定的位置的時候,就產生了下一次的脈衝,換句話說就是機械裝置還沒來得轉到合適的地方,電信號就產生改變。第三點,Phase1和Phase2的電流能夠有如下這四種組合,(Phase1, Phase2) = (+70.71%, +70.71%), (+70.71%, -70.71%), (-70.71%, -70.71%), (-70.71%, +70.71%),每個組合表明了轉子的一個旋轉位置,從一個組合到下一個組合會使得轉子從當前位置旋轉到下一個位置。
如今咱們知道咱們須要PWM(脈衝方波)發送給驅動,這樣驅動產生合適的電流控制電機了。下一步咱們須要搞懂的是如何設置最大的電流上限,根據電機的datasheet,咱們知道每一個Phase的最大電流不能夠超過2A。以下圖截取自A4988 datasheet:
根據上面的截圖,咱們知道 Imax = Vref / (8 * Rs)。在pololu的A4988 的電路圖以下圖因此:
Rcs是68毫歐,Vref有一個鏈接一個滑動變阻器組成一個分壓電路,因此咱們須要用保證Vref 不高於1.088V便可。
具體方法你們能夠百度,把滑動變阻器調節到合適的位置便可,好比參考這個連接。
如今咱們來講說,Arduino如何產生PWM脈衝。嵌入式的定時器是很是有用的功能,不少東西都是在定時器的基礎上搭起來的,好比說操做系統。Arduino使用的是Atmel328P芯片,你們能夠下載Atmel328P的芯片手冊,這款芯片上一共有三個定時器,兩個8-bit timer,一個16-bit timer。我選擇的是8-bit的TIMER2。想了解定時器的功能和寄存器功能的話,能夠讀一下atmel328p datasheet。我在這裏主要和你們介紹下這個定時器不一樣的計數方式,參考TCCR2A裏的WGM21和WGM20,TCCR2B裏的WGM22。TIMER2能夠控制兩個GPIO來產生PWM輸出,分別是OC2A和OC2B。
第一種是正常工做的模式,這時8bit的計數寄存器會從0計數到255,而後返回0,從新計數。我設置計數器使用Normal mode,每62.5ns計數一次。每次compare match的時候就toggle OC2A和OC2B pin,OCR2A = 64, OCR2B = 192,因此當計數器計數到64時,會toggle OC2A pin,計數到192時,會toggle OC2B pin。
能夠想象到,計數256次(62.5ns * 256 = 16us),OC2A和OC2B會toggle一次,並且OC2A和OC2B toggle的時間會相差128次計數,由於OCR2A和OCR2B相差了128。
產生的波形以下圖,裏面的黃色和藍色的波形表明OC2A和OC2B pin上產生的電壓,測量點A到測量點B是toggle兩次的時間(16us*2 = 32us):
第二種計數模式是PWM Phase Correct模式。在計數方式上,它會從0計數到255,而後再從255到0。而它是PWM 模式的,和第一種的區別就在於,咱們能夠設置當計數到255和到compare match的時候OC2A, OC2B pin的電平高低,從而控制脈衝的寬度。
產生的波形以下圖,OCR2A = OCR2B = 32,一個pin設置爲compare match時設高電平,0xFF時設低電平;另一個相反,compare match時低電平,0xFF時高電平。從測量點A到測量點B的時間應該是計數器從32->255->32,一共447*62.5us=27.9us。
第三種計數模式是CTC模式。這種模式的計數方式是從0到OCRA,再返回0,所以與第一種normal mode不一樣的是,這種模式能夠到OCRA而不是0xff,換句話說是週期是能夠調整的。若是是toggle pin的話,duty cycle通常是固定的50%(固然能夠產生中斷從新設置OCRA寄存器從而改變週期)。
產生的波形以下圖,OCR2A = 64,OCR2B = 10,OC2A和OC2B都是toggle,因此當計數器counter等於64時,OC2A 會toggle而後計數器清零,當計數器counter等於10的時候,OC2B會toggle,但並不影響計數器繼續計數。A 和B的週期都應該是(62.5*64 = 4us)
第四種是Fast PWM模式,且在0xFF清零。這種和第二種PWM, Phase Correct (Mode 1)很是類似,只不過計數方式是從0到255再返回0。
產生的波形以下圖,OCR2A = OCR2B = 32,一個pin設置爲compare match時設高電平,0xFF時設低電平;另一個相反,compare match時低電平,0xFF時高電平。從測量點A到測量點B一共是一個週期,就是256*62.5 = 16us
第五種和第六種我放在一塊兒,由於兩種模式比較類似,這兩種產生的波形的週期和duty cycle均可以很是方便地改變。
拿Fast PWM(Mode 7)舉例來講,由於在計數器和OCRA同樣的時候會清零,並且得決定在compare match和清零的時候發生什麼事(參考WGM和COM bit),因此OCA pin是沒法輸出PWM波的(清零和compare match在一塊兒)。咱們一般把OCR2A和OCR2B配合只用,OCR2A決定週期,OCR2B決定duty cycle,OC2B pin產生所須要的PWM波形,好比說我要產生一個週期是8usec(62.5nsec128),duty cycle 25%(62.5nsec32),可讓OCR2A = 128, OCR2B = 32,而後設置在清零時置OC2B高電平,compare match時置低電平。
產生的波形以下圖所示:
以上講的全部類型的PWM設置的代碼都在GitHub上,你們能夠任意下載修改測試。GitHub Repo連接。
到目前,咱們已經知道硬件該如何鏈接,該如何設置最大電流,該如何設置Atmel328P的PWM。
我使用了Timer2 Fast PWM (Mode 7)來產生週期可變的PWM信號,這樣能夠方便地讓電機開始時從最慢逐漸變快,在電機要停下來的時候從最快的速度逐漸變慢直到中止,這樣能夠增大電機的扭矩和穩定性。
整個控制步進電機的代碼在GitHub上,連接