簡易數據采集分析流程.stm32+python


背景:

對於一些需要快速驗證傳感器性能,或者某些實驗需要快速采集數據並且需要直觀顯示成波形或者圖片, 搭建一個簡易方便的數據采集分析系統是有必要的.

本文主要介紹以下幾個方面:

數據采集整體框架.

Pc使用python設定相關參數: fs, 采樣點數 采樣時間 etc..

MCU使用自帶ADC 根據pc設定的采樣率fs進行采集后通過uart將數據回傳.

Python可以直接對數據簡單處理,或者保存成csv方便導入matlab進行更進一步數據分析. 

Ex1: ADC規則組同時采集 ADC dual channel mode cfg.(strict sample multiple channel at same time)

Ex2: ADC采樣率自動配置 adc sample rate automatic cfg.

 

Py & mcu 自定簡易通信協議. eg:

  1. Py send ‘#f=1000’, ‘#sc=1024’       (此處表示采樣率1000hz, 采樣點數1024)
  2. Mcu 解析uart接收的命令. 配置參數后進行采樣. 在采樣完成的DMA傳輸完成IRQ里(使用DMA可以提高最大采樣速率)將數據上傳upload.

 

串口助手抓到的數據格式(字符串, 假設我這里是2個通道同時采樣)

采集adc值 + 換行

adc1 , adc2 + ’\r\n’

123,333
124,334
120,330 xxx,xxx

 

Python實現簡易串口讀寫與存儲.

1. 環境搭建: (打開命令行cmd.exe,  輸入以下命令安裝serial模塊)

pip install serial

2. 開始寫代碼: 打開串口, 讀寫操作

包含頭文件 import serial

import serial ser = serial.Serial('com19', 115200) #按照參數打開串口
ser.set_buffer_size(rx_size=20480) #為了設置合適的緩沖區
if ser.isOpen():            #檢查打開成功 
    print('open port successful') data = b'f=' + bytes(fs, encoding='ascii') + b'\r\n' ser.write(data) # only bytes array is supported.
lines = '' #所有的行
while True: # 在這里阻塞2s等待, 讀取rx buffer的數據
    time.sleep(2) cnt = ser.inWaiting() # bytes to read in rx buffer 
    if (cnt > 0): data = ser.read(cnt) lines = str(data, encoding='ascii') # 轉碼成字符串
        break

 

3. 保存成csv . 用於存檔或者導入MATLAB等其他數據分析處理軟件

csv_file = open(f_name + '.csv' , 'w') # 創建並打開一個文件
csv_file.write(lines) # 如果接收時已經是csv格式可以直接寫入

for i in range(len(adc1)):    # 或者解析成list后再按需存入
    csv_file.write(adc1[i] + ',' + adc2[i] + '\n') csv_file.close() # 寫完記得關閉.

 

4.簡單的python繪圖 - matplotlib

0. 安裝matplotlib

pip install matplotlib

1.導入並使用它的pylab來繪圖

import matplotlib.pylab as pl lines = str(lines, encoding='ascii').splitlines()  #.split('\r\n')
light_cnt = len(lines) # 光強數據長度
print('cnt = ', light_cnt) light_data = [] # 光強數據 
for line in lines: # 分割成一行一行, 每行2個數據
    # if line is not '':
 light_data.append(int(line)) print(int(line)) N = light_cnt axis_x = np.linspace(1, N, num=N) pl.plot(axis_x, light_data) pl.title('charge time= %dms' % charge_time) pl.show()

更詳細繪圖代碼參考 https://www.jianshu.com/p/78ba36dddad8

簡單操作 - matlab 繪多個子圖相關

1. 同一張圖繪制多條曲線:

plot(y1);

Hold on;

plot(y2);

2. 同一個頁面繪制多張圖用於對比:

figure(1); %創建畫布.

subplot(1, 2, 1);%在1行*2列里,畫第1個圖

subplot(1, 2, i);

%在1行*2列的格子畫第i個圖 ,1<i<=總數

例如subplot(2, 3, i)就是這樣的.i=1~6

簡單操作 - matlab 讀取 csv文件

M = csvread(csv_name); %返回M是一個矩陣.
M(:,1) %可以取第一列.(ch1的數據) :表示所有行
M(:,2) %可以取第二列, 以此類推.
plot(M); %按默認 畫出圖
title( ['f=' num2str(freq)]) %畫圖后title函數用於加上格式化的標題

 

Ex1: ADC dual channel mode cfg.(strictly sample multiple channel at same time)

多ADC同時規則采樣配置(嚴格的同時,同一時鍾邊沿采樣)步驟 (單ADC在同一時間最多只能采樣1個channel)

  1. stm32f4支持最多3ADC同時采樣,稱為dual mode/ triple mode.
  2. 多ADC時, ADC1=master, ADC2/3 = slave.

    只可能存在2種搭配,dual:ADC1+ADC2. Triple:ADC1+ADC2+ADC3.

    多ADC無法同時采集同一個pin.

   3. 如果開啟DMA傳輸, 只需要為master(也就是ADC1) 配置即可.

    Slave會由master進行觸發轉換.

    DMA的src data addr 配置成專門的ADC-CDR 寄存器.

    單個data size = word. 在dual mode時, 相當於ADC1+ADC2分別在高半字和低半字

 

Ex2: adc sample rate automatic cfg.

要計算ADC采樣率, 需要單次轉換所需時鍾周期tc cycle和ADC時鍾頻率 fa.

單次轉換cycle = sampling cycle + n-bit resolution cycle.

例如配置為 3 sampling cycle, 12bit采樣時, 總共需要的轉換時間= 15cycle.也就是每15個ADC clock 可以采樣一次.

然后對於STM32F4, ADC clock 來自APB2 clock. 於是fa與APB2分頻值APB2_clk_div以及ADC配置的ADC_CLK_DIV相關.

將這些所有可能的分頻值adc_div, apb2_clk_div與單次轉換周期tc組合起來,可以構成i*j*k種組合方式,用for來遍歷計算.然后取手冊上可行的ADC clock范圍(0.6M~36Mhz)來計算可以所有算出可配置的ADC采樣率fs. 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM