步驟1:電路圖
電路圖非常簡(jiǎn)單;整個(gè)項(xiàng)目由12V適配器供電。然后使用兩個(gè)7805電壓調(diào)節(jié)器將此12V轉(zhuǎn)換為+ 5V。一個(gè)標(biāo)記為+ 5V,另一個(gè)標(biāo)記為+ 5V(2)。具有兩個(gè)調(diào)節(jié)器的原因是當(dāng)伺服旋轉(zhuǎn)時(shí),它會(huì)吸入大量電流,從而產(chǎn)生電壓降。這種電壓降迫使PIC重新啟動(dòng),因此我們無(wú)法在同一+ 5V電壓軌上同時(shí)運(yùn)行PIC和伺服電機(jī)。因此標(biāo)有+ 5V的電源用于為PIC單片機(jī),LCD和電位計(jì)供電,標(biāo)有+ 5V(2)的獨(dú)立穩(wěn)壓器輸出用于為伺服電機(jī)供電。
提供0V至5V可變電壓的電位器的五個(gè)輸出引腳連接到PIC的模擬引腳An0至AN4。由于我們計(jì)劃使用定時(shí)器來(lái)產(chǎn)生PWM,因此伺服電機(jī)可以連接到任何GPIO引腳。我為伺服電機(jī)選擇了RD2到RD6的引腳,但它可以是您選擇的任何GPIO。
由于程序涉及大量調(diào)試,因此16x2 LCD顯示器也連接到PIC的portB。這將顯示正在控制的伺服電機(jī)的占空比。除此之外,我還擴(kuò)展了所有GPIO和模擬引腳的連接,以防將來(lái)需要連接任何傳感器。最后,我還連接了編程器引腳H1,使用ICSP編程選項(xiàng)直接使用pickit3對(duì)PIC進(jìn)行編程。
步驟2:在GPIO引腳上生成PWM信號(hào)以進(jìn)行伺服電機(jī)控制
電路準(zhǔn)備就緒后,我們必須弄清楚如何生成PWN PIC的GPIO引腳上的信號(hào)用于控制伺服電機(jī)。我們已經(jīng)使用Timer中斷方法累了類似的東西并且成功了。在這里,我們將建立在它之上。
所有業(yè)余愛(ài)好伺服電機(jī)的工作頻率為50Hz。這意味著伺服電機(jī)的一個(gè)完整脈沖周期為1/50(F = 1/T),即20ms。在這20ms內(nèi),控制信號(hào)僅為0到2ms,而其余信號(hào)總是關(guān)閉。下圖顯示了ON時(shí)間如何僅在0到2ms之間變化,將電機(jī)從0度旋轉(zhuǎn)到180度持續(xù)20ms。
考慮到這一點(diǎn),我們必須在這樣的情況下編寫(xiě)程序PIC從電位計(jì)讀取0到1204的方式并將其映射到0到100,這將是伺服電機(jī)的占空比。使用此占空比,我們可以計(jì)算伺服電機(jī)的ON時(shí)間。然后我們可以定期中斷初始化定時(shí)器中斷,使其與Arduino中的millis()函數(shù)類似。這樣,我們可以將狀態(tài)GPIO引腳切換為高電平達(dá)到所需的持續(xù)時(shí)間,并在20ms(一個(gè)完整周期)后將其關(guān)閉,然后重復(fù)相同的過(guò)程?,F(xiàn)在,我們已經(jīng)了解了邏輯,讓我們進(jìn)入程序。
步驟3:為機(jī)器人臂編程PIC16F8771A
總是像完整的程序一樣視頻可以在本頁(yè)末尾找到,代碼也可以從這里下載所有必要的文件。在本節(jié)中,我們將討論該程序背后的邏輯。該程序采用ADC模塊,定時(shí)器模塊和LCD模塊來(lái)控制機(jī)械臂。如果您不了解如何使用ADC功能或定時(shí)器功能或?qū)CD與PIC連接,則可以回退到相應(yīng)的鏈接以了解它們。假設(shè)讀者熟悉這些概念,下面給出了解釋。
定時(shí)器0端口配置
代碼中最重要的部分是將Timer 0設(shè)置為過(guò)流具體延遲。計(jì)算此延遲的公式可以給出為
Delay = ((256-REG_val)*(Prescal*4))/Fosc
通過(guò)使用OPTION_REG和TMR0寄存器,我們將Timer 0設(shè)置為以預(yù)分頻值32運(yùn)行,REG val設(shè)置為248.我們硬件中使用的晶體頻率(Fosc)為20Mhz。使用這些值,延遲可以計(jì)算為
Delay = ((256-248)*(32*4)) / (20000000)
= 0.0000512 seconds (or)
= 0.05 msec
所以現(xiàn)在我們已經(jīng)將計(jì)時(shí)器設(shè)置為每0.05ms溢出一次。下面給出了執(zhí)行相同操作的代碼
/*****Port Configuration for Timer ******/
OPTION_REG = 0b00000100; // Timer0 with external freq and 32 as prescalar // Also Enables PULL UPs
TMR0=248; // Load the time value for 0.0001s; delayValue can be between 0-256 only
TMR0IE=1; //Enable timer interrupt bit in PIE1 register
GIE=1; //Enable Global Interrupt
PEIE=1; //Enable the Peripheral Interrupt
/***********______***********/
在伺服電機(jī)的總0ms到2ms控制窗口中,我們可以用0.05msec的分辨率控制它,這使得我們可以在0度之間為電機(jī)提供(2/0.05)40個(gè)不同的位置到180度。如果您的MCU可以支持它以獲得更多位置和精確控制,您可以進(jìn)一步降低此值。
中斷服務(wù)程序(ISR)
現(xiàn)在我們將Timer 0設(shè)置為每0.05ms溢出一次,我們將TMR0IF中斷標(biāo)志設(shè)置為0.05ms。因此,在ISR函數(shù)中,我們可以重置該標(biāo)志并將名為count的變量遞增1。所以現(xiàn)在這個(gè)變量每0.05ms增加1。
void interrupt timer_isr() {
if(TMR0IF==1) // Timer flag has been triggered due to timer overflow -》 set to overflow for every 0.05ms {
TMR0 = 248; //Load the timer Value
TMR0IF=0; // Clear timer interrupt flag
count++; //Count increments by 1 for every 0.05ms }
計(jì)算占空比和導(dǎo)通時(shí)間
接下來(lái),我們必須計(jì)算所有五個(gè)伺服電機(jī)的占空比和導(dǎo)通時(shí)間。我們有五個(gè)伺服電機(jī),每個(gè)伺服電機(jī)用于控制臂的各個(gè)部分。因此,我們必須讀取所有五個(gè)的ADC值,并計(jì)算每個(gè)的占空比和導(dǎo)通時(shí)間。
ADC值將在0到1024的范圍內(nèi),只需將0.0976(100/1024 = 0.0976)乘以獲得的值即可轉(zhuǎn)換為0%至100%占空比。然后必須將此0到100%的占空比轉(zhuǎn)換為ON時(shí)間。我們知道,在100%占空比時(shí),ON時(shí)間必須為2ms(180度),因此乘以0.02(2/100 = 0.02)將0到100占空比轉(zhuǎn)換為0到2ms。但是我們的定時(shí)器變量計(jì)數(shù)設(shè)置為每0.05ms增加一次。這意味著每1ms計(jì)數(shù)值將為20(1/0.05 = 20)。所以我們必須將20乘以0.02來(lái)計(jì)算我們程序的準(zhǔn)確時(shí)間,這將給出0.4(0.02 * 20 = 0.4)的值。相同的代碼如下所示,你可以看到它使用for循環(huán)重復(fù)5次。結(jié)果值存儲(chǔ)在T_ON數(shù)組中。
for (int pot_num=0; pot_num《=3; pot_num++)
{ int Pev_val = T_ON[pot_num];
POT_val = (ADC_Read(pot_num)); //Read the value of POT using ADC
Duty_cycle = (POT_val * 0.0976); //Map 0 to 1024 to 0 to 100
T_ON[pot_num] = Duty_cycle* 0.4;//20*0.02
選擇要旋轉(zhuǎn)的電機(jī)
我們無(wú)法控制所有五個(gè)電機(jī),因?yàn)樗鼤?huì)使ISR代碼大幅減速整個(gè)微控制器。所以我們一次只能旋轉(zhuǎn)一個(gè)伺服電機(jī)。要選擇旋轉(zhuǎn)哪個(gè)伺服,微控制器會(huì)監(jiān)控所有五個(gè)伺服電機(jī)的開(kāi)啟時(shí)間,并將其與之前的準(zhǔn)時(shí)進(jìn)行比較。如果ON時(shí)間發(fā)生變化,我們可以得出結(jié)論,必須移動(dòng)特定的伺服。相同的代碼如下所示。
if (T_ON[pot_num] != Pev_val) {
Lcd_Clear();
servo = pot_num;
Lcd_Set_Cursor(2,11); Lcd_Print_String(“S:”);
Lcd_Print_Char(servo+‘0’);
if (pot_num==0)
{Lcd_Set_Cursor(1,1);
Lcd_Print_String(“A:”);}
else if (pot_num==1)
{Lcd_Set_Cursor(1,6);
Lcd_Print_String(“B:”);}
else if (pot_num==2)
{Lcd_Set_Cursor(1,11);
Lcd_Print_String(“C:”);}
else if (pot_num==3)
{Lcd_Set_Cursor(2,1);
Lcd_Print_String(“D:”);}
else if (pot_num==4)
{Lcd_Set_Cursor(2,6);
Lcd_Print_String(“E:”);}
char d2 = (Duty_cycle) %10;
char d1 = (Duty_cycle/10) %10;
Lcd_Print_Char(d1+‘0’);Lcd_Print_Char(d2+‘0’);
我們還在LCD屏幕上打印伺服占空比,以便用戶了解其當(dāng)前位置?;诮油〞r(shí)間的變化,可變伺服系統(tǒng)用0到4的數(shù)字更新,每個(gè)數(shù)字代表各個(gè)電動(dòng)機(jī)。
控制ISR內(nèi)部的伺服電機(jī)
在ISR內(nèi)部,變量計(jì)數(shù)每0.05ms增加一次,這意味著每1ms變量將增加20。使用它我們必須控制引腳以產(chǎn)生PWM信號(hào)。如果count的值小于導(dǎo)通時(shí)間,則使用下面的行
打開(kāi)該電機(jī)的GPIOPORTD = PORTD | servo_code[servo];
此處,數(shù)組servo_code []具有所有五個(gè)伺服電機(jī)的引腳細(xì)節(jié),并根據(jù)變量伺服中的值,將使用該特定伺服電機(jī)的代碼。然后邏輯OR(|)與現(xiàn)有的PORTD位,這樣我們就不會(huì)干擾其他電機(jī)的值,只更新這個(gè)特定的電機(jī)。類似地,關(guān)閉引腳
PORTD = PORTD & ~(servo_code[servo]);
我們使用邏輯反轉(zhuǎn)(?)運(yùn)算符反轉(zhuǎn)了位值,然后在PORTD上執(zhí)行AND(&)操作以僅關(guān)閉所需的引腳,同時(shí)將其他引腳保持在先前的狀態(tài)。完整的代碼段如下所示。
void interrupt timer_isr() {
if(TMR0IF==1) // Timer flag has been triggered due to timer overflow -》 set to overflow for every 0.05ms {
TMR0 = 248; //Load the timer Value
TMR0IF=0; // Clear timer interrupt flag
count++; //Count increments by 1 for every 0.05ms -》 count will be 20 for every 1ms (0.05/1 = 20)) }
int servo_code[] = {0b01000000, 0b00100000, 0b00010000, 0b00001000, 0b00000100 };
if (count 》= 20*20)
count=0;
if (count 《= (T_ON[servo]) )
PORTD = PORTD | servo_code[servo];
else
PORTD = PORTD & ~(servo_code[servo]); }
我們知道在GPIO引腳再次打開(kāi)之前,總周期必須持續(xù)20ms。因此,我們通過(guò)將count的值與400(上面討論的計(jì)算相同)進(jìn)行比較來(lái)檢查計(jì)數(shù)是否超過(guò)20ms,如果是,我們必須再次將計(jì)數(shù)初始化為零。
步驟4:PIC機(jī)械臂代碼的模擬
在將代碼送到真實(shí)硬件之前,最好先模擬代碼。所以我使用Proteus來(lái)模擬我的代碼并驗(yàn)證它是否正常工作。用于仿真的電路如下所示。我們使用示波器檢查是否按要求生成PWM信號(hào)。此外,我們可以驗(yàn)證LCD和伺服電機(jī)是否按預(yù)期旋轉(zhuǎn)。
正如您所見(jiàn),LCD根據(jù)第3電機(jī)的電位值顯示電機(jī)D的占空比為07。類似的,如果移動(dòng)另一個(gè)電位器,則該電位器的占空比及其電機(jī)編號(hào)將顯示在LCD上。示波器上顯示的PWM信號(hào)
使用示波器上的光標(biāo)選項(xiàng)測(cè)量的總循環(huán)周期為22.2ms,非常接近所需的20ms。最后,我們確信代碼有效,因此要繼續(xù)使用電路,我們可以將其焊接在穿孔板上或使用PCB。它不會(huì)在面包板上輕松工作,因?yàn)镻OT總是會(huì)因連接不良而產(chǎn)生一些問(wèn)題。
步驟5:使用EasyEDA進(jìn)行PCB設(shè)計(jì)
設(shè)計(jì)此PIC機(jī)器人手臂,我們選擇了名為EasyEDA的在線EDA工具。我已經(jīng)使用它很長(zhǎng)一段時(shí)間了,因?yàn)樗嫉孛娣e大,易于使用,所以非常方便。在設(shè)計(jì)PCB之后,我們可以通過(guò)其低成本PCB制造服務(wù)訂購(gòu)PCB樣品。他們還提供組件采購(gòu)服務(wù),他們擁有大量電子元件,用戶可以訂購(gòu)他們所需的組件以及PCB訂單。
在線計(jì)算和訂購(gòu)樣品
完成此設(shè)計(jì)后PIC Robot PCB,您可以通過(guò)JLCPCB.com訂購(gòu)PCB。要從JLCPCB訂購(gòu)PCB,您需要Gerber File。要下載PCB的Gerber文件,只需單擊EasyEDA編輯器頁(yè)面上的Generate Fabrication File按鈕,然后從那里下載Gerber文件,或者您可以單擊JLCPCB上的Order,如下圖所示。這會(huì)將您重定向到JLCPCB.com,在那里您可以選擇要訂購(gòu)的PCB數(shù)量,所需的銅層數(shù),PCB厚度,銅重量,甚至PCB顏色,如下圖所示:
選擇所有選項(xiàng)后,單擊“保存到購(gòu)物車(chē)”,然后您將進(jìn)入可以上傳我們從EasyEDA下載的Gerber文件的頁(yè)面。上傳您的Gerber文件,然后單擊“保存到購(gòu)物車(chē)”。最后安全地點(diǎn)擊Checkout以完成您的訂單,然后您將在幾天后獲得PCB。他們以非常低的速率制造PCB,價(jià)格為2美元。他們的建造時(shí)間也非常少,這是48小時(shí)DHL交付3-5天,基本上你會(huì)在訂購(gòu)后一周內(nèi)獲得你的PCB。
訂購(gòu)PCB后,您可以查看PCB的生產(chǎn)進(jìn)度以及日期和時(shí)間。您可以通過(guò)進(jìn)入“帳戶”頁(yè)面并點(diǎn)擊“生產(chǎn)進(jìn)度”進(jìn)行檢查。
訂購(gòu)PCB后幾天,我將PCB樣品裝在漂亮的包裝中。
在獲得這些碎片之后,我已經(jīng)在PCB上焊接了所有必需的元件。我也直接焊接POT而不是使用連接線,因?yàn)槲易畛跏褂玫哪妇€到母線可能會(huì)因?yàn)榻佑|松動(dòng)而產(chǎn)生奇怪的模擬輸出電壓。組裝完所有組件后,我的PCB看起來(lái)像這樣。
你可能已經(jīng)注意到這塊板上只有一個(gè)7805。那是因?yàn)樽畛跷艺J(rèn)為我可以通過(guò)調(diào)節(jié)器為PIC和伺服電機(jī)供電,后來(lái)我意識(shí)到我需要兩個(gè)。所以我使用外部電路通過(guò)你在這里看到的綠線為伺服電機(jī)供電。
然而,你不必?fù)?dān)心它,因?yàn)?我現(xiàn)在已對(duì)PCB進(jìn)行了更改。您可以使用修改過(guò)的PCB并焊接板上的穩(wěn)壓器。
PIC機(jī)器人手臂的工作
經(jīng)過(guò)所有的疲勞工作后,我們需要付出代價(jià)。焊接電路板上的所有組件并將程序上載到PIC控制器。完整代碼如下,或者可以從這里下載。電路板上提供的編程連接器可以幫助您直接使用Pickit 3上傳程序,而不會(huì)有太多麻煩。程序上傳后,您應(yīng)該看到LCD顯示當(dāng)前正在控制的伺服。要了解有關(guān)PIC單片機(jī)編程的更多信息,請(qǐng)按照上一個(gè)教程進(jìn)行操作。
從那里你可以簡(jiǎn)單地轉(zhuǎn)動(dòng)電位器并檢查伺服電機(jī)如何響應(yīng)每個(gè)電位器。一旦您了解了格式,您就可以控制機(jī)器人手臂執(zhí)行您需要執(zhí)行的任何操作并獲得樂(lè)趣。
-
PIC單片機(jī)
+關(guān)注
關(guān)注
65文章
693瀏覽量
102996 -
機(jī)械臂
+關(guān)注
關(guān)注
13文章
553瀏覽量
25323
發(fā)布評(píng)論請(qǐng)先 登錄
輝芒微FT61FC23-RB單片機(jī)兼容微芯PIC16F676芯片

Microchip發(fā)布PIC16F17576系列單片機(jī)
AN4121-采用PIC16F單片機(jī)進(jìn)行系統(tǒng)電源控制

AN4873-使用PIC單片機(jī)的集成運(yùn)算放大器測(cè)量水中的總?cè)芙夤腆w

TB3320-PIC單片機(jī)集成模擬外設(shè)入門(mén)

單片機(jī)Debug工具性能對(duì)比 單片機(jī)調(diào)試常用命令
機(jī)械臂的高效運(yùn)作,連接器起關(guān)鍵作用

單片機(jī)的中斷機(jī)制
PIC單片機(jī)的優(yōu)勢(shì)和不足之處
單片機(jī)燒錄程序的基本步驟是什么
OrangePi AIpro應(yīng)用:機(jī)械臂應(yīng)用開(kāi)發(fā)指南


評(píng)論