python画锯齿波_用Python控制硬件35-自制二三十元成本的信号测量采集控制系统
如前篇所介紹,用Shell Lab測試臺軟件配合之前介紹的任意款實驗板,都能方便地實現ADC電壓測量,但遇到兩個問題:
- 示例代碼雖然眾多,但大都默認ShellLab類型的控制器,需要手動改為Mcush.Mcush類型才能運行,比較繁瑣。
- 基礎的adc命令只能進行低速測量,不能控制采樣率實現高速測量(需要更高階的ShellLab采集器的daq指令)。
為了解決上述問題,將Shell Lab T1采集器固件做了部分移植,適配一批資源較為充裕的實驗板,定制成專用固件(簡稱“Shell Lab社區版固件”系列)解決上述兩個問題,方便大家實驗。
優先移植到STM32F401CC/411CE實驗板上,參考介紹:
PengShulin:用Python控制硬件33-基于STM32F401CC和STM32F411CE的迷你實驗板?zhuanlan.zhihu.com移植完成的“Shell Lab社區版固件”下載地址:
F401CC板子:
http://www.linkongsoft.com/shell-lab/firmware/ShellLabCommunity_WeActF401CC.bin
http://www.linkongsoft.com/shell-lab/firmware/ShellLabCommunity_WeActF401CC.hex
F411CE板子
http://www.linkongsoft.com/shell-lab/firmware/ShellLabCommunity_WeActF411CE.bin
http://www.linkongsoft.com/shell-lab/firmware/ShellLabCommunity_WeActF411CE.hex
燒入固件(注意BIN二進制代碼需指定寫入地址0x08000000),完成后連上USB串口終端,看看有哪些變化(以F401CC為例)?
$ dmesg ... [683194.776689] usb 1-4: new full-speed USB device number 117 using xhci_hcd [683194.962409] usb 1-4: New USB device found, idVendor=ffff, idProduct=ffff [683194.962422] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [683194.962429] usb 1-4: Product: Shell Lab Community Version [683194.962436] usb 1-4: Manufacturer: Linkong Software [683194.962442] usb 1-4: SerialNumber: 31003B001351353234363331 [683194.963681] cdc_acm 1-4:1.0: ttyACM0: USB ACM device $USB設備類型變成:“Shell Lab Community Version”
=>*idn? ShellLab-WeAct-F401CC,1.0 31003B001351353234363331 =>設備類型識別變成ShellLab。
=>daq --help usage: daq [-c <command>] [-i <index>] [-v <value>] options:-c/--cmd info|(de)init|start|stop|reset|done|read|freq|vref|channel_mask-i/--idx index param-v/--val value param =>支持daq命令,用于指定采樣率測量波形。
下面打開Shell Lab測試臺軟件,調出示例腳本“daq”-->“FFT analysis”:
準備信號發生器,生成1KHz正弦波(偏置1.5V,幅度1V),輸入PA0引腳,點擊“運行”:
可以看到采到了0.016秒的波形(包含4096個采樣點),下圖是FFT分析結果(分析帶寬是采樣率的一半:256kHz/2=128kHz),并在較大的幾個峰位置標注了幅度。
點擊導航欄的方向箭頭按鈕,然后用鼠標右鍵可以拖動圖表區,實現縮放移動功能,以便觀察細節。動態效果:
256k采樣率采集波形并FFT分析https://www.zhihu.com/video/1182229714634170368繼續換幾種波形看看:
三角波,可以看到諧波的組成與方波相似(1/3/5/7...),只是衰減地很快:
鋸齒波,可以看到諧波組成的變化(1/2/3/4...):
調幅波,中心頻率和兩個邊頻:
更多的波形請讀者自行實驗了。下面分析一下完整的示范腳本代碼(加了中文注釋):
# 6 - daq - FFT analysis # 腳本開始先確定采樣參數(通道、采樣率、點數) CHANNEL = 0 # input channel SAMPLE_RATE = 256000 # HZ SAMPLE_LENGTH = 4096 SAMPLE_TIME = SAMPLE_LENGTH / float(SAMPLE_RATE) # FFT峰值檢測標注的最大數量限制 PEAKS_LIMIT = 10 # FFT是否需要加窗函數的開關 ADD_WINDOW = False WINDOW_TYPE = 'hamming'# 下面切換至繪圖區域,準備幾個字圖,每個都有命名,方便后續控制 # 這是FFT相位子圖的開關,默認關閉,開啟后會增加一個子圖 FFT_PHASE_PLOT = False # True p = getPlotPanel() p.addPlot( 'wave', 211, label_y='Signal voltage' ) p.setLimit( 'wave', top=3.3, right=SAMPLE_TIME, auto=False ) p.setLegend( 'wave','Channel %d'% CHANNEL ) if FFT_PHASE_PLOT:p.addPlot( 'fft', 413, label_y='FFT Amplitude', label_x="Frequency (Hz)" )p.setLimit( 'fft', right=SAMPLE_RATE/2, auto=False )p.addPlot( 'fft2', 414, label_y='FFT Phase', label_x="Frequency (Hz)" )p.setLimit( 'fft2', right=SAMPLE_RATE/2, auto=False ) else:p.addPlot( 'fft', 212, label_y='FFT Amplitude', label_x="Frequency (Hz)" )p.setLimit( 'fft', right=SAMPLE_RATE/2, auto=False )# 創建控制器對象并初始化 s = ShellLab(PORT) s.daq_init( freq=SAMPLE_RATE, length=SAMPLE_LENGTH, channels=[CHANNEL] )while True:# 啟動測量s.daq_start()# 循環等待測量結束while True:done = s.daq_done()info('Sampling (%d / %d)'% (done, SAMPLE_LENGTH))if done >= SAMPLE_LENGTH:breaktime.sleep(0.01)# 測量完成,讀數據(因為只有一個通道,傳入第0通道的參數),返回數據列表info('Reading...')dat = s.daq_read(0) # read the first channel# 開始畫圖info('Ploting...')# 先繪制原始波形dat_x = numpy.linspace(0, SAMPLE_TIME, SAMPLE_LENGTH, endpoint=False)p.resetData( 'wave' )p.addData( 'wave', dat, dat_x )# 根據需要,數據加窗if ADD_WINDOW:window = scipy.signal.get_window( WINDOW_TYPE, len(dat) )dat_offset = numpy.mean(dat)dat = (dat-dat_offset) * window + dat_offset# 快速傅立葉變換fft_x = numpy.linspace(0, SAMPLE_RATE, SAMPLE_LENGTH, endpoint=False)fft_raw = numpy.fft.fft(dat)/(SAMPLE_LENGTH/2)fft_abs = abs(fft_raw)fft_abs[0] = 0 # reset the waveform offset#fft_abs_max = max(fft_abs)p.resetData( 'fft' )#p.addData( 'fft', fft_abs, fft_x ) # plot the whole spectrum rangep.addData( 'fft', fft_abs[:SAMPLE_LENGTH/2], fft_x[:SAMPLE_LENGTH/2] )if FFT_PHASE_PLOT:fft_phase = numpy.angle(fft_raw) / math.pi * 180p.resetData( 'fft2' )p.addData( 'fft2', fft_phase[:SAMPLE_LENGTH/2], fft_x[:SAMPLE_LENGTH/2] )# 查找譜圖峰值并排序fft_max = max(fft_abs[:SAMPLE_LENGTH/2])peaks, props = scipy.signal.find_peaks(fft_abs[:SAMPLE_LENGTH/2],height=fft_max/5)def peak_sort( fa, fb ):global fft_absreturn 1 if (fft_abs[fa] >= fft_abs[fb]) else -1peaks = list(peaks)peaks.sort( peak_sort, reverse=True )# 添加峰值標注p.resetAnnotation('fft') # dynamic marker needs to be clear for next roundfor idx in peaks[:PEAKS_LIMIT]:# 默認標注幅度,可以改為頻率或自定義txt = '%f'%fft_abs[idx] # add amplitude#txt = '%f'%fft_x[idx] # add freq value#txt = peaks.index(idx) + 1 # add sequencep.addAnnotation( 'fft', txt, xy=(fft_x[idx],fft_abs[idx]) )# 復位,準備下一循環 s.daq_reset()上面代碼的理解需要一定的數字信號處理基礎,這里就不展開了。
熟悉Python的同學應該已經發現了, Shell Lab測試臺軟件集成了數值分析庫numpy,才能方便地進行矩陣分析,快速傅立葉變換。
沒錯,除此之外還集成了scipy庫進行科學計算,集成了matplotlib庫用于繪圖。
至此,你可以用二三十元的成本獲得一個簡易的4通道12位精度的信號測量采集控制系統,你可以改動腳本把數據存下來,還具備數據記錄功能。
對比F401CC和F411CE兩種板子有什么區別呢?主要是后者SRAM容量大了64K字節,所以單次的測量深度更長。
實測:前者最大12000點,后者最大39000點,推薦后者。
注:Shell Lab測試臺軟件對個人用戶免費,目前處于公測階段,歡迎試用。
總結
以上是生活随笔為你收集整理的python画锯齿波_用Python控制硬件35-自制二三十元成本的信号测量采集控制系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: amd cpu不能在cmd环境下运行ja
- 下一篇: uniapp打包成html5包个ios壳