简易数据采集分析流程.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. 

 

转载于:https://www.cnblogs.com/langgo/p/10758821.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值