發(fā)板實(shí)現(xiàn)軟件定義無(wú)線電接收)
1. 從一塊二十塊錢(qián)的開(kāi)發(fā)板說(shuō)起ESP32做SDR這件事到底靠不靠譜第一次在群里看到有人甩出一句“ESP32能當(dāng)SDR用了”我的反應(yīng)和大多數(shù)人一樣——眩暈癱坐不至于但確實(shí)愣了幾秒。ESP32這塊芯片玩嵌入式的人太熟了二十來(lái)塊錢(qián)一片雙核240MHz帶WiFi和藍(lán)牙平時(shí)干的是讀傳感器、點(diǎn)燈、驅(qū)動(dòng)屏幕、跑個(gè)小車(chē)的活兒。SDR是什么軟件定義無(wú)線電傳統(tǒng)印象里那是需要高速ADC、FPGA、動(dòng)輒幾百兆采樣率的東西跟一個(gè)主打低功耗物聯(lián)網(wǎng)的MCU怎么看都不像能扯上關(guān)系。但仔細(xì)扒了一圈資料、翻了幾個(gè)開(kāi)源項(xiàng)目之后我發(fā)現(xiàn)這事沒(méi)那么玄乎也沒(méi)那么簡(jiǎn)單。說(shuō)它“能當(dāng)SDR”準(zhǔn)確的理解應(yīng)該是ESP32可以在極其有限的條件下實(shí)現(xiàn)特定頻段、特定帶寬的無(wú)線電信號(hào)接收與簡(jiǎn)單解調(diào)而不是替代一臺(tái)RTL-SDR或者Airspy。這個(gè)區(qū)別非常關(guān)鍵直接決定了你對(duì)這個(gè)項(xiàng)目的預(yù)期也決定了你會(huì)不會(huì)花了兩天時(shí)間最后罵罵咧咧地放棄。這篇文章適合幾類(lèi)人看手里有ESP32開(kāi)發(fā)板、對(duì)無(wú)線電感興趣但沒(méi)接觸過(guò)SDR的嵌入式玩家玩過(guò)RTL-SDR、想看看MCU能做到什么程度的無(wú)線電愛(ài)好者以及單純好奇“這玩意兒到底怎么實(shí)現(xiàn)的”的技術(shù)圍觀群眾。我會(huì)從原理層面講清楚為什么ESP32能做這件事、它的物理極限在哪里然后給出可復(fù)現(xiàn)的實(shí)操路徑最后把我踩過(guò)的坑和排查經(jīng)驗(yàn)整理出來(lái)。不管你是剛點(diǎn)亮第一塊ESP32的新手還是已經(jīng)用ESP-IDF寫(xiě)過(guò)不少項(xiàng)目的老手應(yīng)該都能從中找到有用的東西。2. 核心原理拆解ESP32憑什么能碰SDR的邊2.1 先搞清楚SDR到底在干什么要理解ESP32能不能做SDR得先弄明白SDR的本質(zhì)。傳統(tǒng)無(wú)線電接收機(jī)的信號(hào)鏈路是硬件搭出來(lái)的天線收到信號(hào)經(jīng)過(guò)濾波、放大、混頻、檢波最后出來(lái)音頻或者數(shù)據(jù)。每一級(jí)都是固定的電路想換個(gè)頻段就得換硬件。SDR的思路是把盡可能多的處理搬到軟件里天線信號(hào)經(jīng)過(guò)最少的模擬前端通常就是一個(gè)寬帶放大器加一個(gè)高速ADC數(shù)字化之后濾波、混頻、解調(diào)全部用代碼算出來(lái)。這里面的核心瓶頸是ADC。根據(jù)奈奎斯特采樣定理你要接收中心頻率為f、帶寬為B的信號(hào)ADC的采樣率至少要到2B以上實(shí)際中還要考慮過(guò)采樣和抗混疊。FM廣播帶寬約200kHz那采樣率至少400ksps航空波段AM信號(hào)帶寬窄一些大概幾十ksps就夠。所以SDR對(duì)ADC的要求取決于你想接收什么信號(hào)。RTL-SDR之所以便宜好用是因?yàn)樗昧薘820T2這顆調(diào)諧芯片把射頻信號(hào)先降到中頻再用一顆8bit、2.4Msps的ADC采樣通過(guò)USB把IQ數(shù)據(jù)送到電腦上處理。關(guān)鍵點(diǎn)在于真正的高速采樣和下變頻是硬件芯片干的電腦只負(fù)責(zé)后面的數(shù)字信號(hào)處理。2.2 ESP32的硬件底子到底夠不夠ESP32的射頻部分本來(lái)是為WiFi和藍(lán)牙設(shè)計(jì)的支持2.4GHz頻段內(nèi)部有射頻收發(fā)鏈路。但問(wèn)題在于這條鏈路是封閉的你沒(méi)法直接拿到原始IQ數(shù)據(jù)。ESP32的ADC是SAR型標(biāo)稱(chēng)12位實(shí)際有效位數(shù)大概9到10位采樣率理論上最高2Msps但這是在特定條件下的極限值實(shí)際用起來(lái)受WiFi藍(lán)牙共存、DMA帶寬、CPU負(fù)載影響很大。那為什么還有人做出來(lái)了關(guān)鍵在于思路的轉(zhuǎn)變不去碰2.4GHz的WiFi射頻鏈路而是用ESP32的ADC直接采樣外部輸入的模擬信號(hào)。也就是說(shuō)你需要外接一個(gè)簡(jiǎn)單的模擬前端——一根天線、一個(gè)合適的帶通濾波器、可能再加一級(jí)LNA——把信號(hào)送到ESP32的ADC引腳上。ESP32負(fù)責(zé)的是采樣和后續(xù)的數(shù)字信號(hào)處理射頻前端的工作交給了外部電路。這個(gè)方案的本質(zhì)是ESP32充當(dāng)了一個(gè)低速ADC加DSP處理器的角色。它的采樣率決定了能處理的信號(hào)帶寬它的算力決定了能跑多復(fù)雜的解調(diào)算法。根據(jù)社區(qū)里幾個(gè)開(kāi)源項(xiàng)目的實(shí)測(cè)數(shù)據(jù)ESP32在穩(wěn)定工作的情況下ADC采樣率大概能跑到1Msps左右對(duì)應(yīng)理論帶寬500kHz。實(shí)際上考慮到抗混疊和算法開(kāi)銷(xiāo)能有效處理的帶寬大概在100到200kHz之間。2.3 為什么這件事值得折騰你可能會(huì)問(wèn)花這么大勁就為了接收一兩百kHz帶寬的信號(hào)有什么意義直接買(mǎi)個(gè)RTL-SDR不好嗎這個(gè)問(wèn)題我認(rèn)真想過(guò)。從純功能角度ESP32做SDR確實(shí)打不過(guò)任何一款入門(mén)級(jí)SDR接收機(jī)。但它有幾個(gè)獨(dú)特的價(jià)值點(diǎn)第一它是一個(gè)完全獨(dú)立的嵌入式方案不需要連接電腦可以做成一個(gè)巴掌大的獨(dú)立接收設(shè)備配上屏幕和電池就能戶外使用第二它的成本極低一塊ESP32加上幾個(gè)分立元件總成本可能不到三十塊錢(qián)第三也是最重要的一點(diǎn)它是一個(gè)極好的學(xué)習(xí)平臺(tái)。當(dāng)你親手用ADC采樣、用代碼實(shí)現(xiàn)FFT、用算法解調(diào)出第一個(gè)信號(hào)的時(shí)候你對(duì)SDR的理解會(huì)發(fā)生質(zhì)的變化這是插上RTL-SDR點(diǎn)開(kāi)SDR#軟件永遠(yuǎn)得不到的體驗(yàn)。注意ESP32做SDR接收接收頻段取決于你外接的模擬前端。ESP32本身不負(fù)責(zé)調(diào)諧它只是采樣。你想接收什么頻段就需要對(duì)應(yīng)的前端電路把信號(hào)搬移到ADC能處理的范圍內(nèi)。3. 實(shí)操前的準(zhǔn)備工作硬件選型和軟件環(huán)境搭建3.1 硬件清單與選型邏輯動(dòng)手之前先把東西備齊。我列一個(gè)最小系統(tǒng)的清單然后解釋每一項(xiàng)為什么這么選。組件推薦型號(hào)選型理由大致成本主控板ESP32-WROOM-32最通用的型號(hào)社區(qū)資料多ADC引腳引出方便15-25元天線拉桿天線或自制偶極子根據(jù)目標(biāo)頻段裁剪長(zhǎng)度短波用長(zhǎng)線FM用半波振子5-20元帶通濾波器自制LC或成品濾除目標(biāo)頻段外的強(qiáng)信號(hào)防止ADC飽和5-15元低噪放可選MMIC如BGA2801弱信號(hào)時(shí)提升信噪比強(qiáng)信號(hào)時(shí)不需要3-10元偏置器自制給LNA供電同時(shí)隔離射頻和直流2-5元顯示屏SSD1306 OLED 128x64顯示頻譜和解調(diào)信息I2C接口省引腳8-15元連接線杜邦線、SMA轉(zhuǎn)接線射頻連接盡量短減少損耗和干擾若干關(guān)于ESP32型號(hào)的選擇我建議用ESP32-WROOM-32或者ESP32-S3。WROOM-32的好處是資料最全ADC引腳在GPIO32到GPIO39之間其中GPIO34到GPIO39是輸入-only適合做ADC輸入。S3的話算力更強(qiáng)有向量指令可以加速FFT但價(jià)格稍貴資料相對(duì)少一些。如果你是第一次做這個(gè)項(xiàng)目從WROOM-32開(kāi)始最穩(wěn)妥。天線這塊要重點(diǎn)說(shuō)一下。很多人隨便拿一根杜邦線就當(dāng)天線用結(jié)果什么信號(hào)都收不到然后懷疑是代碼問(wèn)題。天線的長(zhǎng)度和形式直接決定了你能否有效接收目標(biāo)頻段的信號(hào)。一個(gè)簡(jiǎn)單的計(jì)算公式半波振子長(zhǎng)度米等于150除以頻率MHz。比如你想接收100MHz附近的FM廣播半波振子大概1.5米接收短波7MHz那就要20米左右了。實(shí)際中受空間限制可以用四分之一波長(zhǎng)或者加感線圈來(lái)縮短。3.2 軟件環(huán)境搭建從Arduino IDE到ESP-IDF軟件環(huán)境這塊我推薦兩條路線根據(jù)你的經(jīng)驗(yàn)水平來(lái)選。如果你之前主要用Arduino IDE開(kāi)發(fā)ESP32那繼續(xù)用Arduino框架是最快上手的路徑。需要安裝的東西Arduino IDE 2.x版本、ESP32開(kāi)發(fā)板支持包建議用2.0.11或2.0.14版本穩(wěn)定性好、以及必要的庫(kù)。安裝ESP32支持包的時(shí)候國(guó)內(nèi)網(wǎng)絡(luò)環(huán)境下載可能比較慢可以找離線包手動(dòng)安裝。具體操作是在Arduino IDE的“首選項(xiàng)”里填入開(kāi)發(fā)板管理器地址然后在開(kāi)發(fā)板管理器里搜索esp32安裝。如果下載速度實(shí)在受不了去社區(qū)找對(duì)應(yīng)版本的離線包解壓到Arduino的hardware目錄下也能用。如果你追求性能和底層控制那就上ESP-IDF。ESP-IDF是樂(lè)鑫官方的開(kāi)發(fā)框架對(duì)ADC、DMA、I2S的控制更直接做高速采樣的時(shí)候優(yōu)勢(shì)明顯。安裝ESP-IDF推薦用VSCode加ESP-IDF插件的方式比純命令行友好很多。安裝過(guò)程中會(huì)下載工具鏈和Python環(huán)境同樣可能遇到網(wǎng)絡(luò)慢的問(wèn)題可以配置國(guó)內(nèi)鏡像源加速。安裝完成之后用idf.py create-project創(chuàng)建一個(gè)新項(xiàng)目就可以開(kāi)始了。提示不管用哪個(gè)框架都建議先把一個(gè)最簡(jiǎn)單的ADC采樣程序跑通用串口打印原始數(shù)據(jù)確認(rèn)硬件連接和基礎(chǔ)功能沒(méi)問(wèn)題再往上疊加SDR相關(guān)的代碼。這樣出問(wèn)題的時(shí)候排查范圍小很多。3.3 采樣率與時(shí)鐘配置的關(guān)鍵參數(shù)這是整個(gè)項(xiàng)目最核心的技術(shù)點(diǎn)之一。ESP32的ADC時(shí)鐘源來(lái)自APB時(shí)鐘默認(rèn)80MHz通過(guò)分頻器產(chǎn)生ADC的工作時(shí)鐘。在Arduino框架下analogRead()函數(shù)的采樣率大概只有幾十ksps遠(yuǎn)遠(yuǎn)不夠。要跑到1Msps左右必須用底層寄存器操作或者I2S DMA的方式。用I2S DMA采ADC數(shù)據(jù)是社區(qū)里比較成熟的方案。原理是把ADC配置成連續(xù)采樣模式通過(guò)I2S外設(shè)的DMA通道把數(shù)據(jù)搬運(yùn)到內(nèi)存緩沖區(qū)CPU只需要處理緩沖區(qū)里的數(shù)據(jù)不用管采樣時(shí)序。這樣可以把采樣率做到比較高同時(shí)CPU還有余力做信號(hào)處理。具體的配置參數(shù)I2S采樣率設(shè)置為1MHzDMA緩沖區(qū)大小設(shè)為1024或2048個(gè)采樣點(diǎn)雙緩沖模式。ADC衰減設(shè)為11dB對(duì)應(yīng)輸入范圍0到3.3V左右分辨率設(shè)為12位。實(shí)際有效位數(shù)大概9到10位所以信噪比不會(huì)太好但對(duì)于接收較強(qiáng)的廣播信號(hào)來(lái)說(shuō)夠用了。這里有個(gè)坑要注意ESP32的ADC在WiFi開(kāi)啟的時(shí)候噪聲會(huì)明顯增大。如果你不需要WiFi功能在采樣期間把WiFi關(guān)掉信噪比會(huì)好很多。如果確實(shí)需要WiFi盡量把采樣和WiFi傳輸在時(shí)間上錯(cuò)開(kāi)。4. 從采樣到解調(diào)完整信號(hào)鏈的實(shí)現(xiàn)過(guò)程4.1 模擬前端電路的設(shè)計(jì)與搭建ESP32的ADC輸入范圍是0到3.3V衰減11dB時(shí)而且只能接受正電壓。射頻信號(hào)是交流信號(hào)有正有負(fù)所以需要加一個(gè)直流偏置電路把信號(hào)抬升到1.65V左右讓交流信號(hào)在1.65V上下擺動(dòng)這樣ADC才能正確采樣。最基本的偏置電路用兩個(gè)等值電阻分壓產(chǎn)生1.65V然后通過(guò)一個(gè)隔直電容把射頻信號(hào)耦合進(jìn)來(lái)。但這樣做的缺點(diǎn)是輸入阻抗不夠穩(wěn)定而且沒(méi)有濾波。更好的做法是用一個(gè)運(yùn)算放大器搭一個(gè)偏置加法電路同時(shí)兼做低通抗混疊濾波。運(yùn)放選帶寬足夠的型號(hào)比如NE5532或者OPA2350增益帶寬積至少要到幾十MHz。帶通濾波器根據(jù)你的目標(biāo)頻段來(lái)設(shè)計(jì)。以接收FM廣播88到108MHz為例你需要一個(gè)中心頻率98MHz、帶寬20MHz左右的帶通濾波器??梢杂肔C集總參數(shù)做但98MHz的頻率下電感電容的值很小手工焊接比較困難。更實(shí)際的做法是用一個(gè)成品FM帶通濾波器或者用傳輸線結(jié)構(gòu)的濾波器。如果目標(biāo)頻段更低比如短波或者中波LC濾波器的實(shí)現(xiàn)就容易得多。低噪放這塊如果信號(hào)比較強(qiáng)比如本地FM廣播可以不加。如果信號(hào)弱加一級(jí)MMIC放大器會(huì)有明顯改善。注意LNA的增益不要太高否則強(qiáng)信號(hào)會(huì)讓ADC飽和產(chǎn)生嚴(yán)重的互調(diào)失真。我一般會(huì)加一個(gè)可調(diào)衰減器或者用PIN二極管做AGC但這就復(fù)雜了新手可以先不加根據(jù)實(shí)際接收效果再?zèng)Q定。4.2 采樣數(shù)據(jù)的預(yù)處理去偏置與數(shù)字濾波ADC采到的原始數(shù)據(jù)是0到4095之間的整數(shù)對(duì)應(yīng)0到3.3V。信號(hào)的中心在1.65V左右對(duì)應(yīng)ADC讀數(shù)大概2048。第一步預(yù)處理就是把直流偏置去掉把數(shù)據(jù)變成以0為中心的有符號(hào)數(shù)。這個(gè)操作很簡(jiǎn)單每個(gè)采樣值減去2048就行。接下來(lái)是數(shù)字濾波。雖然模擬前端已經(jīng)有抗混疊濾波但ESP32的ADC采樣率是1MHz而實(shí)際有用的信號(hào)帶寬可能只有100kHz所以還需要數(shù)字低通濾波來(lái)進(jìn)一步抑制帶外噪聲。在ESP32上跑FIR濾波是可行的但要注意算力開(kāi)銷(xiāo)。一個(gè)64階的FIR濾波器在240MHz主頻下處理1Msps的采樣流大概占用不到10%的CPU。如果階數(shù)太高比如256階那CPU占用就會(huì)很明顯了。更高效的做法是用CIC濾波器或者簡(jiǎn)單的滑動(dòng)平均。滑動(dòng)平均本質(zhì)上是一個(gè)FIR濾波器系數(shù)全為1實(shí)現(xiàn)起來(lái)只需要加減法不需要乘法速度極快。比如16點(diǎn)滑動(dòng)平均可以把采樣率從1MHz降到62.5kHz同時(shí)濾除高頻噪聲。降采樣之后的數(shù)據(jù)量小了后續(xù)FFT和解調(diào)的負(fù)擔(dān)也輕了。實(shí)操心得預(yù)處理階段的數(shù)據(jù)類(lèi)型選擇很重要。用float做運(yùn)算方便但慢用int16_t做定點(diǎn)運(yùn)算快但要注意溢出。我建議在濾波和降采樣階段用int32_t累加輸出用int16_tFFT階段再轉(zhuǎn)float。這樣兼顧速度和精度。4.3 FFT頻譜分析與信號(hào)識(shí)別有了預(yù)處理后的IQ數(shù)據(jù)實(shí)際上ESP32做的是實(shí)數(shù)采樣嚴(yán)格來(lái)說(shuō)只有I路沒(méi)有Q路但可以通過(guò)希爾伯特變換或者直接對(duì)實(shí)數(shù)做FFT來(lái)獲取頻譜下一步就是做FFT看頻譜。ESP32上跑FFT推薦用樂(lè)鑫官方提供的esp-dsp庫(kù)里面有針對(duì)ESP32優(yōu)化的FFT函數(shù)支持實(shí)數(shù)FFT和復(fù)數(shù)FFT速度比手寫(xiě)的快很多。FFT的點(diǎn)數(shù)選擇要權(quán)衡頻率分辨率和時(shí)間分辨率。1024點(diǎn)FFT在62.5kHz采樣率下頻率分辨率是61Hz時(shí)間窗口約16ms。對(duì)于看FM廣播的頻譜來(lái)說(shuō)這個(gè)分辨率足夠了。2048點(diǎn)的話分辨率翻倍但計(jì)算量也翻倍。我一般用1024點(diǎn)在ESP32上跑一次大概幾百微秒完全跟得上實(shí)時(shí)顯示。頻譜出來(lái)之后你可以通過(guò)找峰值來(lái)確定信號(hào)的中心頻率。比如在88到108MHz范圍內(nèi)經(jīng)過(guò)下變頻后對(duì)應(yīng)到基帶的0到20MHz再經(jīng)過(guò)采樣和降采樣后對(duì)應(yīng)到0到31.25kHz找到幅度最大的幾個(gè)峰那就是電臺(tái)信號(hào)。然后根據(jù)峰值的位置把信號(hào)搬移到零頻附近做進(jìn)一步解調(diào)。4.4 FM解調(diào)的實(shí)現(xiàn)細(xì)節(jié)FM解調(diào)的核心是求瞬時(shí)頻率。對(duì)于實(shí)數(shù)采樣信號(hào)可以先做希爾伯特變換得到解析信號(hào)然后求相鄰采樣點(diǎn)的相位差相位差就對(duì)應(yīng)瞬時(shí)頻率。另一種更簡(jiǎn)單的方法是對(duì)信號(hào)做反正切鑒頻把信號(hào)延遲一個(gè)采樣周期然后計(jì)算原信號(hào)和延遲信號(hào)的叉積與點(diǎn)積叉積除以點(diǎn)積的反正切就是相位差。在ESP32上實(shí)現(xiàn)FM解調(diào)我推薦用第二種方法因?yàn)橛?jì)算量小不需要做希爾伯特變換。具體步驟是對(duì)預(yù)處理后的信號(hào)x[n]計(jì)算x[n]和x[n-1]的叉積cross等于x[n]乘以x[n-1]的共軛的虛部對(duì)于實(shí)數(shù)信號(hào)cross等于x[n]乘以x[n-1]的延遲版本這里需要先構(gòu)造解析信號(hào)或者用近似方法點(diǎn)積dot等于x[n]乘以x[n-1]的實(shí)部。然后相位差等于atan2(cross, dot)。這個(gè)相位差就正比于瞬時(shí)頻率偏移也就是解調(diào)出來(lái)的音頻信號(hào)。解調(diào)出來(lái)的音頻信號(hào)還需要經(jīng)過(guò)低通濾波和去加重。去加重是FM廣播的標(biāo)準(zhǔn)處理時(shí)間常數(shù)一般是75微秒美國(guó)或50微秒歐洲。去加重的實(shí)現(xiàn)就是一個(gè)簡(jiǎn)單的一階高通濾波器用代碼幾行就能搞定。最后把音頻信號(hào)通過(guò)DAC輸出或者通過(guò)I2S送到外部DAC芯片就能聽(tīng)到聲音了。ESP32自帶兩個(gè)8位DAC引腳GPIO25和GPIO26可以直接輸出音頻。但8位分辨率對(duì)于音頻來(lái)說(shuō)有點(diǎn)低會(huì)有明顯的量化噪聲。更好的方案是用I2S接一個(gè)外部DAC比如MAX98357或者PCM5102音質(zhì)會(huì)好很多。如果只是聽(tīng)個(gè)響內(nèi)置DAC也湊合能用。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 采樣數(shù)據(jù)全是噪聲怎么辦這是最常見(jiàn)的問(wèn)題十有八九是模擬前端的問(wèn)題。排查步驟按順序來(lái)先用示波器或者萬(wàn)用表確認(rèn)ADC輸入引腳的直流電平是不是在1.65V左右。如果偏差太大檢查偏置電路的分壓電阻是不是焊錯(cuò)了或者虛焊。然后確認(rèn)天線有沒(méi)有接好天線和ADC輸入之間的耦合電容是不是合適。如果這些都正常那可能是信號(hào)太弱需要加LNA或者換更好的天線。還有一個(gè)容易被忽略的點(diǎn)ESP32開(kāi)發(fā)板上的ADC引腳可能被其他功能占用了。比如GPIO34在某些板子上接了攝像頭或者SD卡。用之前查一下開(kāi)發(fā)板的原理圖確認(rèn)引腳是空閑的。另外ADC2的引腳在WiFi開(kāi)啟時(shí)是不能用的只能用ADC1的引腳GPIO32到GPIO39。5.2 頻譜顯示有信號(hào)但解調(diào)不出聲音這種情況通常是解調(diào)參數(shù)不對(duì)。首先確認(rèn)你解調(diào)的信號(hào)確實(shí)是FM信號(hào)而不是AM或者數(shù)字信號(hào)。FM廣播的信號(hào)帶寬大概200kHz在頻譜上看起來(lái)是一個(gè)比較寬的峰而AM信號(hào)是一個(gè)窄峰。如果確認(rèn)是FM檢查鑒頻器的參數(shù)延遲采樣點(diǎn)數(shù)是不是1atan2的計(jì)算是不是正確去加重的截止頻率是不是設(shè)對(duì)了。另一個(gè)可能的原因是采樣率不夠。如果ADC實(shí)際采樣率只有500kHz那能處理的信號(hào)帶寬只有250kHz對(duì)于200kHz帶寬的FM信號(hào)來(lái)說(shuō)勉強(qiáng)夠用但邊緣可能會(huì)失真??梢栽囍档湍繕?biāo)信號(hào)的帶寬要求或者提高采樣率。5.3 編譯速度慢和燒錄失敗的處理用Arduino IDE編譯ESP32項(xiàng)目尤其是帶WiFi和藍(lán)牙庫(kù)的項(xiàng)目編譯時(shí)間可能長(zhǎng)達(dá)幾分鐘。加快編譯速度的方法有幾個(gè)關(guān)閉不需要的庫(kù)用預(yù)編譯的庫(kù)文件升級(jí)電腦的CPU和內(nèi)存這個(gè)最直接但成本高或者換用PlatformIO。PlatformIO的編譯緩存機(jī)制比Arduino IDE好很多第二次編譯同樣的項(xiàng)目會(huì)快很多。燒錄失敗的話先檢查USB線是不是數(shù)據(jù)線有些線只能充電不能傳數(shù)據(jù)然后確認(rèn)開(kāi)發(fā)板驅(qū)動(dòng)裝好了。ESP32燒錄的時(shí)候需要進(jìn)入下載模式有些板子自動(dòng)下載電路做得不好需要手動(dòng)按住BOOT鍵再按RESET鍵。如果串口一直顯示“等待上電同步”大概率是這個(gè)問(wèn)題。問(wèn)題現(xiàn)象可能原因排查方法解決方案采樣全是噪聲偏置電壓不對(duì)萬(wàn)用表測(cè)ADC引腳電壓調(diào)整分壓電阻確認(rèn)在1.65V頻譜無(wú)信號(hào)峰天線未接好檢查天線連接和長(zhǎng)度重新裁剪天線確保接觸良好解調(diào)無(wú)聲音鑒頻參數(shù)錯(cuò)誤檢查延遲和atan2計(jì)算調(diào)整延遲點(diǎn)數(shù)驗(yàn)證去加重編譯超時(shí)庫(kù)太多查看編譯日志移除無(wú)用庫(kù)換PlatformIO燒錄失敗未進(jìn)入下載模式觀察串口輸出手動(dòng)按住BOOT再?gòu)?fù)位WiFi開(kāi)啟后噪聲大ADC2與WiFi沖突確認(rèn)使用的ADC通道換用ADC1引腳或關(guān)閉WiFi5.4 提升接收效果的幾個(gè)實(shí)用技巧第一個(gè)技巧是給ADC輸入加一個(gè)簡(jiǎn)單的RC低通濾波器截止頻率設(shè)在采樣率的一半以下。比如采樣率1MHzRC截止頻率設(shè)500kHz。這個(gè)濾波器可以濾除高頻噪聲改善信噪比。電阻選1kΩ電容選300pF左右。第二個(gè)技巧是用多個(gè)ADC引腳做時(shí)間交織采樣。ESP32有兩個(gè)ADC理論上可以交替采樣把等效采樣率翻倍。但實(shí)際中兩個(gè)ADC之間的一致性不好需要校準(zhǔn)實(shí)現(xiàn)起來(lái)比較復(fù)雜。新手不建議嘗試。第三個(gè)技巧是在FFT之前加窗函數(shù)。不加窗的話頻譜泄漏會(huì)比較嚴(yán)重弱信號(hào)可能被強(qiáng)信號(hào)的旁瓣淹沒(méi)。漢寧窗或者漢明窗都是不錯(cuò)的選擇計(jì)算量也不大。esp-dsp庫(kù)里有現(xiàn)成的窗函數(shù)可以調(diào)用。6. 這個(gè)項(xiàng)目的邊界在哪里理性看待ESP32 SDR的能力折騰了這么久我對(duì)ESP32做SDR的能力邊界有了比較清晰的認(rèn)識(shí)。它能做的事情接收本地強(qiáng)信號(hào)的FM廣播、接收航空波段AM信號(hào)、接收氣象衛(wèi)星的APT信號(hào)需要合適的天線和前端、做簡(jiǎn)單的頻譜監(jiān)測(cè)。它不能做的事情接收弱信號(hào)、處理寬帶信號(hào)、替代專(zhuān)業(yè)SDR接收機(jī)、做高精度的信號(hào)分析。如果你追求的是實(shí)用性想穩(wěn)定接收各種信號(hào)那還是買(mǎi)一臺(tái)RTL-SDR或者更好的接收機(jī)。但如果你追求的是學(xué)習(xí)價(jià)值想真正理解SDR的工作原理那ESP32這個(gè)平臺(tái)能給你的東西遠(yuǎn)超它的價(jià)格。當(dāng)你第一次從自己焊的電路上、從自己寫(xiě)的代碼里聽(tīng)到電臺(tái)主持人的聲音時(shí)那種成就感是插上成品設(shè)備永遠(yuǎn)體會(huì)不到的。最后分享一個(gè)我在調(diào)試過(guò)程中總結(jié)的小經(jīng)驗(yàn)每次修改代碼之后先用一個(gè)已知的信號(hào)源比如信號(hào)發(fā)生器或者另一個(gè)ESP32發(fā)射的測(cè)試信號(hào)驗(yàn)證接收鏈路是否正常再去接收真實(shí)信號(hào)。這樣可以快速區(qū)分是代碼問(wèn)題還是信號(hào)問(wèn)題省去很多瞎猜的時(shí)間。另外把關(guān)鍵的中間數(shù)據(jù)通過(guò)串口打印出來(lái)比如ADC原始值、濾波后的值、FFT的峰值位置比盯著屏幕上的最終結(jié)果瞎調(diào)要高效得多。