请选择 进入手机版 | 继续访问电脑版
查看: 1858|回复: 7

[智能家居挑战赛] 【智能家居挑战赛】+智能远程烟雾监测系统之MQ135空气质量

[复制链接]
  • TA的每日心情

    2024-2-5 12:06
  • 签到天数: 627 天

    [LV.9]以坛为家II

    94

    主题

    1628

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4429

    热心会员

    最后登录
    2024-2-5
    发表于 2021-3-24 14:38:27 | 显示全部楼层 |阅读模式
    下面我们来测试下MQ135空气质量传感器。本身这个传感器电路并没有什么可讲的,就是个分压电路。
    但是对于测得的电压转浓度这一块,确实比较麻烦,因为规格书未提供任何公式,仅提供了产品的曲线。
    我们先来看下MQ135的工作电路:
    AA1.png
    其中红框部分为正在的工作电路,RL为负载分压电阻,我们测试的就是它两端的电压。
    蓝框为电阻丝加入电路,对于我们计时气体没有管理。
    模块真实电路,在上面电路上,还加了比较电路,以便超出阀值,便输出TTL报警信号。
    AA2.png
    我们本次,不使用DOut(比较输出功能),仅连接VCC GND 及Aout(分压电压)。
    我们选择P1.31 (ADC的5通道)为Aout的连接引脚。
    我们看下规格书给出的浓度曲线:
    AA4.png
    纵坐标是Rs/Ro,横坐标就是气体浓度。
    理论上,我们获取了Rs的值(可通过测试的ADC电压然后通过分压计算出:Rs=(Vc/VRL-1)×RL,VRL为ADC测试的电压,RL根据模块电路为1K)
    Ro值表示传感器在100ppm 氨气中的电阻值(根本没有条件测试)。
    然后取出对应的几点,然后拟合成曲线方程。
    以下来自推算方法,直接参考CSDN博客:
    https://blog.csdn.net/weixin_38075894/article/details/111589375?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

    模拟方程网站:
    http://www.qinms.com/webapp/curvefit/cf.aspx

    AA7.png
    我直接用了它的结果:
    这样我们得到相关的浓度公式:
    AA6.png
    将Ro,RL,Vcc,Vout代入使用C语言计算得到:
    Vout为ADC测得的分压值。RL为1K,VCC为5V。
    ppm = pow((3.4880*Ro*Vout)/(5-Vout),(1.0/0.3203));
    我们知道Ro是Rs的一个特殊的分值(表示在含100ppm 氨气、20℃/65%RH下的Rs电
    阻值)。
    AA9.png
    既然不确定Ro,为了继续做下去。我们假设当前空气的环境就是Ro的环境。
    下面我们写ADC相关代码,测试当前的Rs值,用作Ro:
    1. #include "adc.h"
    2. #include "chip.h"
    3. #include "sys.h"
    4. #include "delay.h"

    5. /*********************************************************************************************************
    6. ** 函数名称:  void INT_CHAR(uint32_t s)
    7. ** 函数功能:  将4位整型数据转变成字符型,便于显示。
    8. ** 输入参数:  要转换的整型数据:uint32_t s
    9. ** 输出参数:  转换后的字符型数据存储的在dis[]数组中
    10. ** 返回值:    无
    11. *********************************************************************************************************/
    12. unsigned char dis[7];

    13. void INT_CHAR(uint32_t s)
    14. {
    15.         

    16.             dis[0] = s/1000%10 +0x30;
    17.             dis[1] = '.';
    18.       dis[2] = s/100%10 +0x30;
    19.             dis[3] = s/10%10 +0x30;
    20.             dis[4] = s/1%10 +0x30;
    21.             dis[5] = 'V';
    22.       dis[6] = '\0';

    23. }
    24. /*********************************************************************************************************
    25. ** 函数名:    ADC_Init (void)
    26. ** 函数功能:       ADC初始化
    27. ** 输入参数:   无
    28. ** 输出参数:   无
    29. ** 返回值:     无
    30. *********************************************************************************************************/
    31. void ADC_Init (void) {
    32.         static ADC_CLOCK_SETUP_T ADCSetup;        
    33.         
    34.    ADCSetup.adcRate=4;//ADC时钟分配系数5  4+1
    35.    ADCSetup.burstMode=0;        
    36.         Chip_ADC_Init(LPC_ADC,&ADCSetup);//使能ADC时钟
    37.         Chip_IOCON_PinMux(LPC_IOCON, 1, 31, IOCON_MODE_INACT, IOCON_FUNC3);//设置P1.31 为ADC的5通道
    38.         Chip_ADC_EnableChannel(LPC_ADC,ADC_CH5,ENABLE);//使能通道5
    39.         Chip_ADC_SetStartMode(LPC_ADC,ADC_START_NOW,ADC_TRIGGERMODE_RISING);//ADC正常工作模式

    40. }
    41. /*********************************************************************************************************
    42. ** 函数名:   void ADC_StartCnv (void)
    43. ** 函数功能:       启动转换
    44. ** 输入参数:   无
    45. ** 输出参数:   无
    46. ** 返回值:     无
    47. *********************************************************************************************************/
    48. void ADC_StartCnv (void) {

    49. Chip_ADC_SetStartMode(LPC_ADC,ADC_START_NOW,ADC_TRIGGERMODE_RISING);//启动转换
    50. }

    51. /*********************************************************************************************************
    52. ** 函数名:    void ADC_StopCnv (void)
    53. ** 函数功能:       停止转换
    54. ** 输入参数:   无
    55. ** 输出参数:   无
    56. ** 返回值:     无
    57. *********************************************************************************************************/
    58. void ADC_StopCnv (void) {
    59.         Chip_ADC_SetStartMode(LPC_ADC,ADC_NO_START,ADC_TRIGGERMODE_RISING);// 停止转换
    60. }

    61. /*********************************************************************************************************
    62. ** 函数名:    uint16_t ADC_Get (void)
    63. ** 函数功能:       获取转换值
    64. ** 输入参数:   无
    65. ** 输出参数:   无
    66. ** 返回值:     ADC值
    67. *********************************************************************************************************/
    68. uint16_t ADC_Get (void) {
    69.   uint16_t val;

    70.         ADC_StartCnv();           //启动转换        
    71.   ADC_GetCnv(&val);          //获取AD值         
    72.         ADC_StopCnv();
    73.   return (val);
    74. }

    75. /*********************************************************************************************************
    76. ** 函数名:    uint32_t ADC_GetCnv (void)
    77. ** 函数功能:       获取转换值
    78. ** 输入参数:   无
    79. ** 输出参数:   无
    80. ** 返回值:     ADC值
    81. *********************************************************************************************************/
    82. void  ADC_GetCnv (uint16_t *adGdr) {
    83.          Chip_ADC_ReadValue(LPC_ADC,5,adGdr);

    84. }

    85. //多次采样,并获取平均值
    86. u16 Get_Adc_Average(u8 times)
    87. {
    88.         u32 temp_val=0;
    89.         u8 t;
    90.         for(t=0;t<times;t++)
    91.         {
    92.                 temp_val+=ADC_Get();
    93.                 delay_ms(5);
    94.         }
    95.         return temp_val/times;
    96. }

    复制代码
    我们在main函数里面,一直输出当前测的的电压(理论上要等48小时以上,我们做实验,直接忽略):
    1.    ADC_Data=Get_Adc_Average(8);
    2.                
    3.       ADC_Data = (ADC_Data * 3300)/4095;

    4.                         INT_CHAR(ADC_Data);                                                                    // 整型数据转换成字符型
    5.                         LCD_DisplayAsciiString (30,60,dis,16,Black,White);
    6.                   printf("adc=%s\r\n",dis);
    复制代码
    我们查看串口输出,在0.78V左右。我们算出此时的Rs,Rs=(5/0.78-1)×1K=5.41K。我们把这个值当作Ro,即Ro=5.41K
    我们带入公式:
    ppm = pow((3.4880*Ro*Vout)/(5-Vout),(1.0/0.3203));
    ppm = pow((3.4880*5.41*Vout)/(5-Vout),(1.0/0.3203));
    我们把它加到while循环里,查看输出:
    1. //tmp1=(3.4880*Ro*ADC_Data/1000.0)/(5.0-ADC_Data/1000.0);
    2.                   tmp1=(3.4880*5.41*ADC_Data/1000.0)/(5.0-ADC_Data/1000.0);
    3.                         tmp2=(1.0/0.3203);
    4.                         ppm = pow(tmp1,tmp2);
    5.                         
    6.       sprintf(tmp, "%.4f", ppm);
    7.                         printf("ppm=%s\r\n",tmp);
    8.                
    9.                         delay_ms(5000);
    复制代码
    下载,查看:
    AA10.png
    好了,MQ135空气质量检测就到这了。其中Ro取值仅是实验,不准,仅供参考!
    水了一篇,谢谢观看~
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    7 天前
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2021-3-24 16:45:31 | 显示全部楼层
    这种传感器还需要做数值模拟啊
    我一直以为这些只是简单的映射关系呢!
    以后在此类项目的时候要注意了。
    谢谢分享
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    难过
    2021-5-21 09:12
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    2

    主题

    33

    帖子

    0

    注册会员

    Rank: 2

    积分
    84
    最后登录
    2023-3-14
    发表于 2021-4-10 20:08:08 | 显示全部楼层
    好像没看到远程,本来点进来是很期待的,然后只发现在分析传感器,,,期待能早点看到标题中的远程的功能。
    今天天气不错!签到!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2023-1-31 09:34
  • 签到天数: 202 天

    [LV.7]常住居民III

    7

    主题

    1515

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3811
    最后登录
    2024-2-19
    发表于 2021-5-9 00:35:08 | 显示全部楼层
    不知你的远程控制采用的通讯方式是什么,在帖子中没有看到啊
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-27 10:12
  • 签到天数: 100 天

    [LV.6]常住居民II

    3

    主题

    1031

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1320
    最后登录
    2024-3-27
    发表于 2021-5-12 17:30:20 | 显示全部楼层
    好像没看到远程,本来点进来是很期待的,然后只发现在分析传感器,,,期待能早点看到标题中的远程的功能。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-4-7 20:47
  • 签到天数: 537 天

    [LV.9]以坛为家II

    69

    主题

    2521

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    7065
    最后登录
    2024-4-9
    发表于 2021-5-13 22:24:12 | 显示全部楼层
    看看            
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-12-30 08:07
  • 签到天数: 87 天

    [LV.6]常住居民II

    0

    主题

    242

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1097
    最后登录
    2022-12-30
    发表于 2021-5-14 16:23:00 | 显示全部楼层
    没看到远程部分。。。
    生命不息,奋斗不止!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-1 10:45
  • 签到天数: 144 天

    [LV.7]常住居民III

    10

    主题

    383

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1258
    最后登录
    2024-4-1
    发表于 2021-5-15 10:40:41 | 显示全部楼层
    怎么样可以获取demo code.
    加油加油
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-17 03:54 , Processed in 0.137161 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表