寫此部落格的主要目的是為了記錄下來除錯過程中所遇到的問題,更重要的是記錄下來解決遇到的那些問題的方法,以供之後此後遇到問題之參考。
該寫字機械人或叫機械臂的主控晶元為stm32f103c8t6,機械臂擁有三個水平自由度,乙個豎直自由度,該機械臂的關節處均用的是舵機驅動。
從此出發,我們便需要用stm32的定時器外設產生四路能夠準確驅動舵機的pwm波。初始化定時器外設的部分**如下。
gpio_inittypedef gpio_initstructure;
tim_timebaseinittypedef tim_timebasestructure;
tim_ocinittypedef tim_ocinitstructure;
rcc_apb1periphclockcmd
(rcc_apb1periph_tim3, enable)
;// ①使能 tim3時鐘
rcc_apb2periphclockcmd
(rcc_apb2periph_gpioa , enable)
;//①使能 gpio 外設時鐘使能
rcc_apb2periphclockcmd
(rcc_apb2periph_gpiob , enable)
; gpio_initstructure.gpio_pin = gpio_pin_6;
//tim3_ch1
gpio_initstructure.gpio_mode = gpio_mode_af_pp;
//復用推挽輸出
gpio_initstructure.gpio_speed = gpio_speed_50mhz;
gpio_init
(gpioa,
&gpio_initstructure)
; tim_timebasestructure.tim_period = arr;
//設定在下乙個更新事件裝入活動的自動重裝載暫存器週期的值 80k
tim_timebasestructure.tim_prescaler =psc;
//設定用來作為 timx 時鐘頻率除數的預分頻值 不分頻
tim_timebasestructure.tim_clockdivision =0;
//設定時鐘分割:tdts = tck_tim
tim_timebasestructure.tim_countermode = tim_countermode_up;
//向上計數
tim_timebaseinit
(tim3,
&tim_timebasestructure)
;//②初始化 timx
tim_ocinitstructure.tim_ocmode = tim_ocmode_pwm1;
//脈寬調變模式 2
tim_ocinitstructure.tim_outputstate = tim_outputstate_enable;
//比較輸出使能
tim_ocinitstructure.tim_pulse=
500;
//設定待裝入捕獲比較暫存器的脈衝值
tim_ocinitstructure.tim_ocpolarity = tim_ocpolarity_high;
//輸出極性高
tim_oc1init
(tim3,
&tim_ocinitstructure)
;//③初始化外設 timx
tim_oc1preloadconfig
(tim3, tim_ocpreload_enable)
;//ch1預裝載使能
tim_ctrlpwmoutputs
(tim3,enable)
;//⑤moe 主輸出使能
tim_arrpreloadconfig
(tim3, enable)
;//使能 timx 在 arr 上的預裝載暫存器
tim_cmd
(tim3, enable)
;//④使能 tim3
上面的程式便是產生了可以控制舵機的旋轉的四路pwm訊號由於篇幅原因只寫了一路。舵機的控制週期為20ms,控制高電平的時間便可以讓其轉動,0.5ms對應-90°,1ms對應-45°…2.5ms對應+90°,最多到+90°。我使其初始化時讓三個水平舵機處於-90°,乙個豎直舵機處於0°(裝配原因要使其水平於桌面)。
舵機設計的機械結構如下
先以舵機2為原點建立乙個直角座標系,現在的目標便是在該平面任意給定的兩個點之間如何準確的畫出一條直線,出於該機械結構的考慮,由於舵機不論怎樣運動畫出的均為曲線,所以只能將直線劃分為很多小段,在每一小段上舵機運動畫出的軌跡確為曲線,但若該小段非常微小,則在大的範圍該直線上可以近似看作是一條曲線,若要精確繪製只需減小每一段微元的長度。
設定先初始位置,將舵機二三均設定為-90°,使機械臂伸展開來沿x周正方向,每個關節只能逆時針旋轉。那麼在所確定的第一象限的任意乙個點(在臂展半徑範圍之內),便可計算出要達到該點倆個舵機應該所處的角度,那麼將倆個水平舵機轉到計算的應該所處的角度即可到達我們規定要轉動到的位置座標。
第乙個函式實現的功能便是給定任意乙個合理的目標點,我們便控制倆個水平舵機的角度將機械臂旋轉至該點。具體物理量如下圖
//li臂長
#define l2 6.5
//l2臂長
#define pi 3.1415926
//pi
void
set_xy
(double x_1,
double y_1)
下面便設計第二個函式,該函式實現的是分很多微元從當前點移動到目標點,會套用之前寫的第乙個函式以實現。
void
movepot
(double x,
double y,
double prex,
double prey )
for(i=
0;i<=c;i++
)prex=prex+dx;
prey=prey+dy;
//更新座標
printf
("初始座標%f%f"
,prex,prey)
;}
第三個函式實現抬筆落筆功能,**如下
void
lift
(int sta)
//1抬筆0落筆
else
}//慢慢落下
}
第四第五個函式便實現了使機械臂先抬筆之後以乙個較慢的速度移動到目標點之後再慢慢落下(quikmove函式)
void
movepotslow
(double x,
double y,
double prex,
double prey )
//抬起來較快移動
for(i=
0;i<=c;i++
)prex=prex+dx;
prey=prey+dy;
//更新座標
}void
quickmove
(double x,
double y,
double prex,
double prey)
//快速移動先抬後落
設計了如上的函式之後我們便可以利用上述函式來進行繪製圖形或者寫字,畫三角形的具體步驟舉例如下:
quickmove(13
,5,0
,17.5);
//先呼叫此函式讓筆從起始點快速抬筆移動到畫三角形處再落筆
movepot(13
,10,13
,5);
//再呼叫此函式讓筆從現在點(13,5)畫到(13,10)
movepot(9
,6,13
,10);
//再呼叫此函式讓筆從現在點(13,10)畫到(9,6)
movepot(13
,6,9
,6);
//再呼叫此函式讓筆從現在點(9,6)畫到(13,6)三角形畫好
本程式在除錯過程中也遇到了很多問題,還有待解決的便是座標定位的準確性問題。但寫個正字三角形還是可以的。效果圖如下
換根粗筆效果或許更好一點。除錯的時候是乙個乙個函式試其能否完成該函式功能。
基於STM32的平衡車機械人設計 硬體電路設計
今天分享乙個stm32f103為主控的自平衡車機械人的硬體電路設計。親測完全可用,且沒有任何問題 電路原理圖 電源部分採用12v鋰電池作為輸入,分三路穩壓,其中7805作為5v感測器的供電以及后級ams1117的電源輸入端,一路ams117 3.3單獨給cpu供電,另外一路給3.3v感測器供電。本方...
基於STM32的機器學習(手勢識別)
第一次寫部落格,希望能給研究微控制器ai的同仁乙個好的啟示。如有不當,多多指正。所用到的感測器是10g的雷達晶元,晶元出來的是中頻訊號,需要根據這些中頻訊號做手勢識別。微控制器模擬有無目標,當沒有目標時,微控制器模擬if輸出中頻訊號,雷達晶元輸出lo 本振訊號 混頻器的作用是將lo if rf。得到...
造一台寫字機械人
問 如何用波浪線畫出鋼鐵俠?2018年的時候就看到過寫字機這種神奇的東西了,也有人叫他寫字機機械人,基本的架構是這樣的 1.首先pc端執行上位機,用來生成g 並且向下位機傳送g 通過反饋監測執行進度 將g 放在sd卡中效果差不多 2.下位機執行g 直譯器 目前大多數用的都是開源的grbl 通過串列埠...