聲音引導(dǎo)系統(tǒng)完整硬件設(shè)計(jì)和源代碼
第一章前言
本系統(tǒng)是基于PIC單片機(jī)為主控制器的聲音引導(dǎo)系統(tǒng),主要由可移動聲源,信號分析處理電路,無線數(shù)據(jù)傳輸模塊,液晶顯示模塊等部分組成。本設(shè)計(jì)采用PIC單片機(jī)作為核心器件,音頻脈沖信號由單片機(jī)控制產(chǎn)生,發(fā)聲移動平臺用PMMA(Acrylic)制作,平臺的移動由直流減速電機(jī)完成,用ASSP芯片MMC-1和L298來實(shí)現(xiàn)電機(jī)的控制,用語音接收電路采集信號,并對信號進(jìn)行處理后通過無線數(shù)據(jù)傳輸,實(shí)現(xiàn)可移動聲源的智能控制。同時應(yīng)用數(shù)碼管顯示平均速度。
第二章方案設(shè)計(jì)與論證
總體方案架構(gòu):
對于聲源的定位有多種辦法,比如測量接收端的幅值,聲音測距,測量兩個接收點(diǎn)的時間差等。我們首先選用的即時測量幅值的方案。但在實(shí)際測量過程中發(fā)現(xiàn)此方案不僅受環(huán)境影響極大,而且在聲音距離大于50厘米后經(jīng)過盡可能的放大后變化仍然達(dá)不到單片機(jī)最小采樣的精度5mV(10位精度ad),因此放棄了此方案。使用聲音測距的方案在經(jīng)過實(shí)際測試后發(fā)現(xiàn)由于聲波存在相位的問題,對定位精度影響很大,返回的數(shù)據(jù)亦呈現(xiàn)出一個正弦變化的函數(shù)關(guān)系,同時,在聲源行進(jìn)過程中的影響也是很大,所以也放棄了此方案。最終我們采用了計(jì)算兩點(diǎn)時間差值的方法,在考慮相位的情況下,取每次高電平的中點(diǎn)作為有效數(shù)據(jù)點(diǎn)。聲源產(chǎn)生的信號如下:
經(jīng)不斷測試,在脈沖信號階段最佳的頻率為4kHz,接收的信號最穩(wěn)定,抗干擾最強(qiáng)。
一個周期為50ms,在前25ms內(nèi)產(chǎn)生脈沖信號,在后25ms持續(xù)低電平。如果三個接收點(diǎn)接收低電平的持續(xù)時間均超過10ms,則可視為一個新周期的開始。
可移動聲源的最大速度為16cm/s,則每一個處理周期為50ms,此段時間之前聲源移動的最大距離 = 16cm/s×0.05s = 0.8cm<1cm,可見此精度足以滿足誤差為1cm的系統(tǒng)需求。
舉例,三個聲源某一時刻可能接收到的聲音信號,經(jīng)比較輸出后波形如下:
因此只要檢測首次出現(xiàn)高電平的時間差dT1和dT2即可判斷聲源是否到達(dá)OX或者OY軸。
2.1主控芯片的選擇
方案一
采用51系列單片機(jī)進(jìn)行控制。此方案的優(yōu)點(diǎn)是成本很低,為保證為系統(tǒng)設(shè)計(jì)的總體構(gòu)架對時間要求很高,需要不斷的計(jì)算出高電平的中間值,為保證系統(tǒng)能按需求進(jìn)行正常工作,單片機(jī)的處理速度必須考慮的一個問題。雖然51系列單片機(jī)支持最高晶振頻率為24MHz,但此時穩(wěn)定性會相應(yīng)下降,此外51系列單片機(jī)IO資源均較少,對其他功能的擴(kuò)展限制很大。此外,本方案還需同時處理無線數(shù)據(jù)發(fā)送接收,產(chǎn)生聲音信號,系統(tǒng)計(jì)時,與MMC-1芯片通信,pid電機(jī)掉接等任務(wù),限于51系列單片機(jī)處理速度因此放棄了此方案。
方案二
采用PIC系列單片機(jī)進(jìn)行控制。此方案優(yōu)點(diǎn)是PIC是RISC結(jié)構(gòu)內(nèi)核,而且PIC單片機(jī)是四分頻的,而51系列單片機(jī)是12分頻的,所以指令速度比51單片機(jī)快得多,因此在同樣晶振下有著更快的處理運(yùn)算速度,因此非常適合處理采集的聲音測量值。雖然PIC單片機(jī)比51系列單片機(jī)成本高一些,但就整體而言卻有著更高的性價比。因此最終采用PIC單片機(jī)。
2.2聲源系統(tǒng)方案
方案一
用蜂鳴器作為發(fā)聲器件,用高耐壓、大電流達(dá)林頓管ULN2003進(jìn)行功率放大 ,此電路結(jié)構(gòu)簡單,易于控制,價格低廉,功耗低。但在實(shí)際測試中發(fā)現(xiàn)由于發(fā)出聲音相對較弱,因此外界極容易造成干擾,處理數(shù)據(jù)時精度達(dá)不到所需要求,因此放棄使用蜂鳴器。
方案二
用揚(yáng)聲器作為發(fā)聲器件,用TDA2822進(jìn)行功率放大,此電路能夠得到比蜂鳴器更強(qiáng)的音頻信號,雖然功率有些大,但能產(chǎn)生足夠的振幅,干擾相對較小,因此選擇此方案。
2.3移動平臺系統(tǒng)方案
方案一
購買普通玩具小車改裝成移動平臺,玩具小車一般由兩個直流電機(jī)組成,前輪用一個控制方向,后輪用一個控制速度
方案二
購買有機(jī)玻璃等材料自己制作移動平臺、采用兩個步進(jìn)電機(jī)分別控制左右兩個輪子,用一個萬向輪作支撐。
方案三
仍購買有機(jī)玻璃等材料自己制作移動平臺采用兩個直流減速電機(jī)分別控制左右兩個輪子,用一個萬向輪作支撐。
以上三種方案中,方案一是常見的平臺移動控制方法,但是由于玩具小車轉(zhuǎn)向的角度很難控制,而且電機(jī)容易卡死,可能造成電機(jī)燒毀,加上題目中要求可移動生源轉(zhuǎn)直角彎,此方案很難做到。方案二雖然采用步進(jìn)電機(jī)左右輪分開控制的策略,而且能夠精確控制轉(zhuǎn)速和計(jì)算路程,但一般小型步進(jìn)電機(jī)產(chǎn)生的力矩較小,難以達(dá)到要求。方案三中只要直流減速電機(jī)安裝較好,其控制就能達(dá)到較高的精度,對于負(fù)載較多的移動平臺而言,此方案最為實(shí)用。
2.4聲音接收方案
方案一
購買集成好的拾音器模塊,這種方法能有效采集到音頻信號,但是集成模塊價格較為昂貴,性價比不高,有大材小用之嫌,因此不用。
方案二
用駐極體話筒和晶體管制作簡單的音頻采集放大電路。此方法成本低,功耗小,外圍器件少,電路簡單,而音質(zhì)也較佳為。經(jīng)綜合考慮,我們決定采用此方案。
2.5顯示方案
方案一
LCD12864進(jìn)行背光顯示,此方案能夠?qū)崟r顯示能容豐富、清晰,顯示信息容量大,但是此液晶功耗大(開啟背光時12864接近500mA),而且需要安裝面積大,占用I/O資源較多,價格較為昂貴,因此不采用。
方案二
用數(shù)碼管進(jìn)行顯示,控制簡單,亮度大,價格低廉,在較強(qiáng)的光線下也能顯示清晰的數(shù)據(jù),所以選擇數(shù)碼管進(jìn)行顯示。[!--empirenews.page--]
2.6 無線方案
采用NRF905為主控芯片的無線通信模塊,通信頻率高,傳輸速度較快,能夠勝任本系統(tǒng)要求的任務(wù)。
第三章硬件電路設(shè)計(jì)
3.1音頻信號發(fā)生電路的設(shè)計(jì)
我們采用用TDA2822對音頻信號進(jìn)行功率放大,該芯片性價比很高。揚(yáng)聲器的頻率直接由單片機(jī)給出,單片機(jī)輸出的脈沖信號通過揚(yáng)聲器反映出來。具體電路圖見附圖1。
3.2電機(jī)控制電路設(shè)計(jì)
本題必須采用組委會提供的電機(jī)控制ASSP芯片(型號MMC-1)實(shí)現(xiàn)可移動聲源的運(yùn)動。MMC-1為多通道兩相四線式步進(jìn)電機(jī)/直流電機(jī)控制芯片,基于十六位通用的MCU固化專用程序?qū)崿F(xiàn)。通過USAT或SPI串行接口,為主控CPU擴(kuò)展專用電機(jī)控制功能。在此次比賽中由于硬件資源有限,而整個系統(tǒng)對主控CPU的性能有要求很高,如電機(jī)驅(qū)動與音頻信號都會用到PWM,51單片機(jī)沒有PWM,而PIC單片機(jī)也只有兩路PWM,為了提高性價比,這款芯片很有必要!整個電機(jī)驅(qū)動電路請見附圖2、附圖3、附圖4、附圖5。
3.3音頻信號接收電路
為了降低小車的功耗,減少作品成本,以三極管為基本放大環(huán)節(jié)的話筒功放電路,外圍元件少,制作簡單,音質(zhì)卻出乎意料的好。其主要特點(diǎn)是效率高、耗電省,靜態(tài)工作電流典型值只有6mA左右,具體電路如圖所示。該電路輸出端的信號不能直接給單片機(jī),由于環(huán)境中不確定的噪聲很多,所以必須濾波,我們選取帶通濾波,其中中心頻率為:F=1/2<<<<<<<<<<<<<<<<<<<<<<<<<π R C
由于環(huán)境中的干擾的頻率大多分布在2KHZ以下,于是便要求音頻信號頻率要在它之上,在測試中發(fā)現(xiàn)并不是頻率越高越好,隨著頻率升高,音頻信號的響度也隨著降低,響度太低也會使信號的檢測變困難,經(jīng)過測試發(fā)現(xiàn)聲音引導(dǎo)系統(tǒng)最佳頻率是4KHZ。由于采用相位比較算法,單片機(jī)得到的理想值是一個數(shù)字信號,通過電壓比較器將輸出的信號通過電壓比較,輸出方波信號。這樣可以使得干擾基本上消失,而且控制也相對比較簡單,更值得一提的是,通過比較器的可調(diào)比較電壓,可以在不同的環(huán)境下通過調(diào)節(jié)比較器的比較電壓,達(dá)到抗干擾的目的。具體的濾波比較電路請見附圖六、附圖七。
3.4測速電路設(shè)計(jì)
本聲源移動平臺采用雙電機(jī)差速控制,由于是差速控制,兩電機(jī)轉(zhuǎn)速不一定一樣,所以要通過測定兩個電機(jī)的轉(zhuǎn)速來確定,最簡單的算法是取平均值。性價比最高的一種方法是通過光電管配合自制的光電碼盤來實(shí)現(xiàn)。光電管通過電壓比較器使得當(dāng)光電管處于光電碼盤黑白上時輸出高低電平信號,再通過單片機(jī)計(jì)數(shù)、運(yùn)算的出速度值,還可以算出路程。
V=相鄰碼盤距離/通過相鄰碼盤所用的時間
S=V*T
第四章軟件設(shè)計(jì)
4.1 總體構(gòu)架分析:
所有數(shù)據(jù)采集、處理以及計(jì)算均在聲音接收部分完成,在處理完成后通過無線模塊發(fā)送給聲源,聲源根據(jù)接收到的命令采取不同的控制策略。此外聲源部分和聲音接收部分均采用AvrX操作系統(tǒng),同時進(jìn)行多個操作,保證了系統(tǒng)系統(tǒng)運(yùn)行的實(shí)時性。
聲源部分:
Task1: 產(chǎn)生系統(tǒng)所需的聲音信號。
Task2:電機(jī)速度檢測,與MMC-1電機(jī)驅(qū)動芯片進(jìn)行通信,構(gòu)成電機(jī)速度的閉環(huán)控制。
Task3:記錄系統(tǒng)運(yùn)行時間,并時時顯示速度。
Task4:無線數(shù)據(jù)通信,時時接收控制指令。
聲音接收部分:
Task1:信號的接受和處理
Task2:對接受的信號進(jìn)行計(jì)算,產(chǎn)生不同的控制命令。
Task3:對更新的控制命令通過無線模塊發(fā)送到移動聲源。
4.2 PID電機(jī)調(diào)速的設(shè)計(jì):
因?yàn)閷?shí)現(xiàn)本題必須實(shí)用精確控制,因此必須采用閉環(huán)的控制系統(tǒng),對雙電機(jī)進(jìn)行精確控制以達(dá)到精度控制要求。而此系統(tǒng)中同時要求電機(jī)進(jìn)行前進(jìn)和后退,因此需采用位置式PID控制。
經(jīng)過不斷的測試,比例,積分,微分常數(shù)目前調(diào)出的最佳參數(shù)如下:
Kp: 1.6 Ki: 2.1 Kd:1.4 具體部分代碼參見附錄。[!--empirenews.page--]
第五章調(diào)試及結(jié)果分析
5.1音頻信號采集模塊調(diào)試
次數(shù) |
聲源離接收器的距離/cm |
波形是否有變化 |
1 |
10 |
是 |
2 |
50 |
是 |
3 |
100 |
是 |
4 |
150 |
不定 |
5 |
200 |
否 |
5.2路程測量測試
次數(shù) |
測試距離(cm) |
實(shí)際距離(cm) |
誤差計(jì)算 |
1 |
45 |
47 |
4.44% |
2 |
50 |
51 |
2.00% |
3 |
55 |
57 |
5.18% |
4 |
60 |
59 |
1.67% |
調(diào)試儀器:20MHz雙蹤示波器、信號發(fā)生器、數(shù)字萬用表、秒表、米尺等
5.3結(jié)果分析
經(jīng)測試,在外界干擾不是太強(qiáng)的情況下,可移動聲源能夠通過接收器方傳回的數(shù)據(jù)精確地定位,精度在1—3cm.
PID調(diào)試部分代碼:
// define difference : the difference between the latest data and the previous data
// define U0 : the PWM to send to the moto
int main (void)
{
······ // Omitted the previous code
int P = 0 , D = 0 ;
tcount++ ;
CarState.E0 = BitNum ;
if ( CarState.E0 == CarState.E1 ) if ( CarState.E0 == 0 ) FlagD = 0 ;
else if ( CarState.E0 < CarState.E1 ) FlagD = -1 ;
else if ( CarState.E0 > CarState.E1 ) FlagD = 1 ;
P = CarState.E0 * Kp ;
D = Kd * KdS * ( CarState.E0 + 3*CarState.E1 - 3*CarState.E2 - CarState.E3 ) ;
if ( D < - 30 * KdS ) D = -30*KdS ;
else if ( D > 30*KdS ) D = 30*KdS ;
if ( D != 0 ) D_old = D ;
if ( D_old < -10 ) D_old++ ;
else if ( D_old > 10 ) D_old-- ;
if ( (CarState.E0 > -3)&&(CarState.E0 < 3) ) S = 0 ;
else if ( ( FlagD == -1) && ( CarState.E0 <= -1 ) )
if ( S > ( BitNum * BitNum * 20 * KsS ) ) S-- ;
else if ( ( FlagD == -1) && ( CarState.E0 >= -1 ) ) S = 0 ; //
else if ( ( FlagD == 1 ) && ( CarState.E0 <= 1 ) ) S = 0 ; //
else if ( ( FlagD == 1 ) && ( CarState.E0 >= 1 ) )
if ( S < ( BitNum * BitNum * 20 * KsS) ) S++ ; //
u8_pwm_a = U0 + P + ( D_old / KdS )+ ( S / KsS ); // ;
······ // Omitted the following code
}