用stm32最小系统板做的一个小东西,mq5检测烟雾浓度,到达阈值后自动开启风扇,风扇用的是直流电机,是pwm驱动。开启风扇前正常显示浓度,一旦到达阈值后,风扇能够自动开启。但是显示的mq5浓度就会异常。从之前的20左右,变成200多,数值异常。有没有友友知道是怎么回事啊,电机是5v,其他是3.3v,用的adc数模转换
4条回答 默认 最新
关注引自免费微信小程序:皆我百晓生
看起来你遇到的问题可能是因为电气干扰导致的ADC读数不准确。当直流电机启动时,它可能会产生电磁干扰(EMI),这可能会对ADC的输入信号造成影响。解决这个问题的方法有多种,我会列举几个常见的建议:
-
电源隔离: 由于电机工作电压为5V,而你的微控制器的工作电压是3.3V,可能存在电源噪声。尝试为电机提供独立的电源,并使用电容(例如0.1uF和10uF并联)进行滤波,同时在微控制器供电线路上也做同样的处理。
-
地线隔离: 确保你的电路板上有一个良好的接地设计。电机的地线和微控制器的地线应分别连接到单点并确保接触良好。有时,使用双绞线连接地线可以减少噪声。
-
屏蔽: 如果可能,将ADC输入引脚及其相关线路用金属屏蔽层包围,以减少辐射噪声的影响。
-
软件补偿: 在程序中,你可以设置一个短暂的时间窗口,在这个时间段内不读取ADC值。让电机稳定运行一段时间后再开始采集MQ5的数据。这样可以让系统的噪声逐渐平息。
-
ADC采样速率调整: 尝试降低ADC的采样速率,减小读取频率可能会降低受干扰的可能性。但也要注意,过低的采样速率可能会影响实时性。
-
硬件滤波: 使用低通滤波器(如RC滤波器)在ADC输入端可以减少高频噪声。
-
软件滤波: 在获取ADC值之后,可以使用简单的滑动平均算法来过滤掉一些随机噪声。
下面是一个简单的滑动平均算法示例代码,用于处理ADC读数:
#include <stdint.h> #define WINDOW_SIZE 5 // 滑动窗口大小 volatile uint16_t adc_buffer[WINDOW_SIZE]; // 存储ADC读数的缓冲区 volatile uint8_t buffer_index = 0; // 缓冲区当前索引 volatile uint16_t average_adc_value = 0; // 平均ADC值 // 假设adc_read函数是从ADC读取值的函数 void update_average_adc() { uint16_t new_adc_value = adc_read(); adc_buffer[buffer_index] = new_adc_value; buffer_index = (buffer_index + 1) % WINDOW_SIZE; // 循环滚动缓冲区 // 计算滑动平均值 for (uint8_t i = 0; i < WINDOW_SIZE; i++) { average_adc_value += adc_buffer[i]; } average_adc_value /= WINDOW_SIZE; } // 获取平均ADC值 uint16_t get_average_adc_value() { return average_adc_value; }记得根据实际情况调整
WINDOW_SIZE,较大的窗口会增加抗噪能力,但也可能导致响应速度变慢。在主循环中调用update_average_adc()函数,然后在需要读取浓度值的地方调用get_average_adc_value()。请尝试这些方法,并观察是否能改善ADC读数的稳定性。如果有进一步的问题或需要更深入的分析,请随时告诉我。
解决 无用评论 打赏 举报 编辑记录-