資料介紹
描述
在這個項目中,我們將使用一些特殊功能以極快的速度從 Raspberry Pi Pico 的模數轉換器 (ADC) 捕獲數據,然后對數據進行快速傅里葉變換。這是許多項目的常見任務,例如涉及音頻處理或無線電的項目。
如果您正在閱讀這篇文章,那么您很可能已經有了一個想要從中收集數據的傳感器。就我而言,我有一個麥克風連接到我的 Pico 的 A0 輸入。如果您只是來這里學習,您可以讓模擬輸入懸空而不連接任何東西。
1. 背景
Raspberry Pi Pico 如此有用的一個主要原因是其過多的硬件功能可以將處理器從執行常規 I/O 任務中解放出來。在我們的例子中,我們將使用 Pico 的直接內存訪問 (DMA) 模塊。這是一項硬件功能,可以自動執行涉及以極快的速度將大量數據傳入和傳出內存到 IO 的任務。
DMA 模塊可以配置為一旦準備好就從 ADC 中提取樣本。以最快的速度,您可以以高達 0.5 MHz 的頻率進行采樣!
收集完所有這些數據后,您可能會想要對其進行一些處理。一項常見任務是將您的信息從時域轉換為頻域以進行進一步處理。就我而言,我有一個麥克風,我想從中收集音頻樣本,然后計算樣本中包含的最大頻率分量。最常用的算法是快速傅里葉變換。
2. ADC 采樣代碼
?
如果您還沒有這樣做,我強烈建議您在 GitHub 上克隆 Raspberry Pi 的pico-examples庫。這是我開始使用的所有采樣代碼的地方。以下代碼的很大一部分來自此存儲庫中的 dma_capture 示例。
我將通過我的軟件的一些關鍵元素來解釋發生了什么。您可以在代碼部分找到完整的程序。
// set sample rate
adc_set_clkdiv(CLOCK_DIV);
這條線決定了 ADC 收集樣本的速度。“clkdiv”指的是時鐘分頻,它允許您拆分 48 MHz 基本時鐘以以較低的速率進行采樣。目前,收集一個樣本需要 96 個周期。這會產生每秒 48、000、000 個周期/每個樣本 96 個周期 = 每秒 500、000 個樣本的最大采樣率。
為了更慢地采樣,您可以增加時鐘分頻。將 CLOCK_DIV 設置為 960 會使每個樣本的周期數增加 10 倍,即每秒產生 50、000 個樣本。您猜對了,將 CLOCK_DIV 設置為 9600 會產生每秒 5, 000 個樣本。
void sample(uint8_t *capture_buf) {
adc_fifo_drain();
adc_run(false);
dma_channel_configure(dma_chan, &cfg,
capture_buf, // dst
&adc_hw->fifo, // src
NSAMP, // transfer count
true // start immediately
);
gpio_put(LED_PIN, 1);
adc_run(true);
dma_channel_wait_for_finish_blocking(dma_chan);
gpio_put(LED_PIN, 0);
}
這個函數實際上是從 ADC 收集樣本。處理器復位 ADC,清空其緩沖區,然后開始采樣。它還會在采樣期間打開 LED,這樣您就可以看到發生了什么。
3. FFT碼
// get NSAMP samples at FSAMP
sample(cap_buf);
// fill fourier transform input while subtracting DC component
uint64_t sum = 0;
for (int i=0;isum;i++)>+=cap_buf[i];}
float avg = (float)sum/NSAMP;
for (int i=0;ifloat;i++)>)cap_buf[i]-avg;}
上面的這一部分用來自 ADC 的樣本填充 cap_buf 數組,然后為傅里葉變換庫對其進行預處理。對于許多應用程序,在應用傅里葉變換之前從數據序列中減去平均值是有利的。沒有這個,任何 DC 電平(高于零的信號偏移)都會導致接近零的輸出頻率區間具有巨大的幅度。我使用的庫KISS FFT期望信號具有浮點類型,因此我還在轉換樣本的同時減去平均值。
// compute fast fourier transform
kiss_fftr(cfg , fft_in, fft_out);
// compute power and calculate max freq component
float max_power = 0;
int max_idx = 0;
// any frequency bin over NSAMP/2 is aliased (nyquist sampling theorum)
for (int i = 0; i < NSAMP/2; i++) {
float power = fft_out[i].r*fft_out[i].r+fft_out[i].i*fft_out[i].i;
if (power>max_power) {
max_power=power;
max_idx = i;
}
}
float max_freq = freqs[max_idx];
printf("Greatest Frequency Component: %0.1f Hz\n",max_freq);
下一部分計算 FFT,然后計算輸出數據中的最大頻率分量。FFT 的輸出是復值,因此要獲得可用的功率值,您可以取復數結果的大小。
另請注意,我們不會循環遍歷 FFT 的所有 NSAMP 輸出值,而是只對 NSAMP/2 進行 bin 處理。由于Nyquist 采樣定理,任何大于 1/2 采樣率的頻率都會混疊在一起,因此這些 bin 對我們沒有用處。這是信號處理中的一個基本結果,如果您不熟悉,值得進一步研究!
在音頻的情況下,人耳通常可以聽到高達 20 kHz 左右的頻率。我使用 960 的 CLOCK_DIV 值,產生 50 kHz 的采樣率。因此,我可以捕獲的最大非混疊頻率是 25 kHz,這應該綽綽有余!
// BE CAREFUL: anything over about 9000 here will cause things
// to silently break. The code will compile and upload, but due
// to memory issues nothing will work properly
#define NSAMP 1000
最后要指出的代碼是 NSAMP,即收集的樣本數。在信號處理中,樣本數量的增加和減少之間存在基本的權衡。更多的樣本將需要更長的時間來收集和處理,但會產生更高分辨率的傅里葉變換。更少的樣本將導致更短的采樣周期和更快的處理,但您的傅立葉變換將更加精細。
對于 Pico,我發現分配過多內存會導致難以調試的故障。如果您將 NSAMP 設置得太大,您的 Pico 將沒有足夠的內存來分配給保存樣本的數組。代碼仍然可以正常編譯和上傳,但您可能會遇到一些奇怪的行為。在我的示例中,將 NSAMP 保持在 9000 以下似乎沒問題。
3.編譯上傳
如果您還沒有這樣做,請下載Raspberry Pi Pico 入門。這是一個可靠的資源,可為您提供設置構建系統以及編譯 C/C++ 代碼并將其上傳到 Pico 所需的一切。
下面的所有說明都適用于 macOS/Linux,但我想 CMake 在 Windows 上也有類似的過程。
- 要編譯我的代碼,首先在 GitHub 上克隆我的存儲庫。
- 導航到 adc_fft 目錄
- 創建一個名為“build”的目錄
- 在里面導航,然后輸入“cmake../”
- 輸入“make”,如果你正確安裝了 Pico 構建系統,一切都應該編譯
- 將您的 Pico 置于引導加載程序模式,然后將 adc_fft.uf2 文件拖放到出現的驅動器中
應該就是這樣!您可以通過 USB 監控程序的輸出。它將輸出從 A0 采樣的數據中的最大頻率分量,并且 LED 應快速閃爍。
在我的例子中,我將麥克風連接到模擬引腳,并通過從揚聲器輸入麥克風音調來驗證我的代碼是否正確。如果您有任何問題,請告訴我!
- 用電機和Raspberry Pi Pico組裝人體骷髏
- 遠程編程Raspberry Pi Pico
- Raspberry Pi Pico多功能入門套件
- 在Raspberry Pi Pico上連接Wi-Fi變得容易
- RP2040 Raspberry Pi Pico遇見LoRa
- Raspberry Pi Pico作為HID鼠標
- 基于Raspberry pi pico的音量控制宏鍵盤 3次下載
- 免費Pico模擬器上的Raspberry Pi Pico和LCD1602接口
- 使用Raspberry Pi Pico的LED序列
- Raspberry Pi Pico:使用PIO驅動伺服
- 如何在Raspberry Pi Pico中使用OLED顯示器
- 印有PINOUT的Raspberry Pi pico分線板
- 適用于Raspberry Pi 4的Raspberry Pi Pico開發板
- 基于BME680和Raspberry Pi Pico的氣象站
- raspberry pi Pico使用MicroPython變磚后的解決方法
- 5分鐘內將Raspberry Pi Pico變成簡單的示波器+波形發生器 1522次閱讀
- 基于Raspberry Pi 5的蜂窩物聯網項目 1027次閱讀
- 使用Raspberry Pi Pico W和MicroPython開發物聯網應用 1673次閱讀
- Pico W的無線功能 883次閱讀
- 用于測試項目的4個最佳樹莓派Raspberry Pi模擬器 5985次閱讀
- 基于Raspberry Pi Pico的云端溫濕度監測站設計 1773次閱讀
- 基于樹莓派產品 Raspberry Pi微控制器板的優缺點 2710次閱讀
- 如何從Raspberry Pi Pico的模數轉換器捕獲數據計算? 2580次閱讀
- 基于Raspberry Pi Pico開發先進的家庭自動化系統 2850次閱讀
- 基于FONA通過UART與Raspberry Pi進行通訊的方案介紹 2122次閱讀
- 基于在Raspberry Pi Zero W的基礎上實現設計微型機器人 2106次閱讀
- 微雪電子ZeroW| Raspberry Pi ZeroW主板簡介 2429次閱讀
- 微雪電子Raspberry Pi 3 Model主板簡介 2873次閱讀
- 利用Raspberry Pi構建存儲和虛擬化時間序列數據 884次閱讀
- 一文了解Raspberry Pi 4各項性能跑分 2.9w次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數據手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關電源設計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數字電路基礎pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅動電路設計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多