Canmv k230 ADC+FFT测试
前面两节通过在k230中计算FFT,现在通过外部传感器采集数据,即ADC进行FFT测试
ADC基本信息及配置
ADC资料如下ADC电路
K230集成了一个分辨率为11bit(有效分辨率)的SARADC,最高采样率不小于1MHz。 其有以下特点:
1)信号输入范围:0-1.8V
2)支持6个通道输入
3)支持单次采样和连续采样
4)内部集成信号调理电路,截止频率在1/2带宽处。ADC可直接进行信号采样,或按需进行外围电路设计。
(输入信号直接符合奈奎斯特采样频率?未测试)
ADC代码
在canmv ide 的原始ADC案例并增加注释
# 初始化
from machine import ADC
adc = ADC(0,enable=True) #构造adc对象,通道0默认开启
# 1)此处设置连续采集一段时间样本用于FFT,主要函数如下
value = adc.value() #获取通道0的数值
print("value = %d" % value)
adc.deinit() #注销adc对象
# 2)进行FFT测试 可以参考前面的文章
连续获取数据,并存储数据为列表形式
采集数据程序
aa=[]
for i in range(1000):
value = adc.value()
aa.append(value)
adc.deinit() # 注销adc对象
print(aa)
数据显示
1)方法1
绘图程序,此时未接入电压输入,采集的信号输出到IDE中,可以复制导入到其他软件中绘制,如MATLAB或Excel等。
MATLAB绘制结果如上所示,获取的数据应该是0~4095,但实际上最高输出为4095,最低输出仅为52 ?
2)方法2
采用UART连接到串口工具,推荐VOFA+
增加UART代码
from machine import FPIOA
from machine import UART
# 实例化FPIOA
fpioa = FPIOA()
# 设置UART2
fpioa.set_function(5, fpioa.UART2_TXD)
fpioa.set_function(6, fpioa.UART2_RXD)
# UART2: baudrate 115200, 8bits, parity none, one stopbits
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
# UART write 格式为 'ch0,ch1,ch2\n' # VOFA+格式要求
ADC代码更改为
aa=[]
for i in range(1000):
value = adc.value() #获取通道0的数值
aa.append(value)
# 将获取的value输出到串口,采用format可以输出为变量,否则输出为'value'
uart.write("{0}\n".format(value))
adc.deinit()
连接USB转TTL模块,连接除canmv k230开发板中的大小核、IDE占用的3个串口外,出现的第四个串口,观察波形,更多信息查看VOFA+工具官网,输出结果如下所示
ADC输入及FFT测试
目前的SDK中ADC的采样频率好像是1kHz,又因为FFT支持的最小点数是64点,1000/64=15.625Hz,因此设置分辨率为fs/N
通过信号发生器输出16Hz的正弦信号,如正点原子示波器
可以看到ADC对于0V附近的电压不能准确显示,不确定什么问题
采集64个点进行FFT测试,采用自己编写FFT,官方提供的存在些问题
增加下面的代码
import math
from ulab import numpy as np
# 偏置值可通过(max-min)/2 计算得到
data = np.array(aa,dtype=np.float)-1200
data1=data[0:64]
a, b =np.fft.fft(data1) # a实部 b虚部
# 求幅值
FA1=[]
#st=time.time_ns()
for i in range(64):
FA=math.pow(a[i], 2)+math.pow(b[i], 2)
FA=math.sqrt(FA)/32
FA1.append(FA)
print('fft.fft :')
print(FA1)
输出如下图所示
根据分辨率=fs/N=1000/64=15.625,可以看到输出的第二个幅值峰值为1131.898,接近正弦波峰值。当采用128点FFT时,输出应该接近第三个幅值处
可以看到第三个频率处。
讨论
1)对于不在分辨率处的频率能够正确计算吗?
2)FFT的其他变形(如短时傅里叶)如何实现?