• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <hi_stdlib.h>
17 #include <math.h>
18 #include <hi_time.h>
19 #include "ohos_init.h"
20 #include "cmsis_os2.h"
21 #include "iot_pwm.h"
22 #include "iot_gpio.h"
23 #include "ssd1306_oled.h"
24 #include "iot_adc.h"
25 #include "iot_gpio_ex.h"
26 #include "app_demo_multi_sample.h"
27 #include "app_demo_i2c_oled.h"
28 #include "app_demo_mq2.h"
29 
30 #define MQ2_DEMO_TASK_STAK_SIZE    (1024 * 8)
31 #define MQ2_DEMO_TASK_PRIORITY    (25)
32 #define ADC_TEST_LENGTH    (20)
33 #define VLT_MIN    (100)
34 #define CAL_PPM    (25) // 校准环境中PPM值
35 #define RL    (1) // RL阻值
36 #define MQ2_RATIO    (1111)
37 
38 #define X_CONSTANT  (613.9f)
39 #define Y_CONSTANT  (-2.074f)
40 #define X_CONSTANT_2 (11.5428 * 22)
41 #define Y_CONSTANT_2 (0.6549)
42 #define VOILTAGE_5_V (5)
43 
44 #define PPM_THRESHOLD_300 (300)
45 #define PPM_THRESHOLD_3000 (3000)
46 #define SAMPLING_TIME (0xff)
47 
48 #define ADC_RANGE_MAX ((float)4096.0)
49 #define ADC_VOLTAGE_1_8_V  ((float)1.8)
50 #define ADC_VOLTAGE_4_TIMES (4)
51 
52 Mq2SensorDef combGas = {0};
53 float g_r0 = 22; /* R0 c初始值 */
SetCombuSensorValue(void)54 void SetCombuSensorValue(void)
55 {
56     combGas.g_combustibleGasValue = 0.0;
57 }
58 
GetCombuSensorValue(void)59 float GetCombuSensorValue(void)
60 {
61     return combGas.g_combustibleGasValue;
62 }
63 
64 /*
65  *  ppm:为可燃气体的浓度
66  *  VRL:电压输出值
67  *  Rs:器件在不同气体,不同浓度下的电阻值
68  *  R0:器件在洁净空气中的电阻值
69  *  RL:负载电阻阻值
70  */
Mq2PpmCalibration(float rS)71 void Mq2PpmCalibration(float rS)
72 {
73     g_r0 = rS / pow(CAL_PPM / X_CONSTANT, 1 / Y_CONSTANT);
74     printf("R0:%f\r\n", g_r0);
75 }
76 
77 /* MQ2传感器数据处理 */
Mq2GetPpm(float voltage)78 float Mq2GetPpm(float voltage)
79 {
80     float vol = voltage;
81     double ppm = 0;
82     static unsigned char flag = HI_TRUE;
83     static unsigned char count = 0;
84 
85     float VolDif = (VOILTAGE_5_V - vol);
86     float SeekModule = VolDif / vol;
87     float rS = SeekModule * RL; /* 计算 RS值 */
88     (void)memset_s(&ppm, sizeof(ppm), 0x0, sizeof(ppm));
89     if (flag) {
90         flag = 0;
91         IoTPwmInit(0);
92         IoSetFunc(HI_GPIO_9, HI_PWM_OUT); // gpio9 pwm
93         IoTGpioSetDir(HI_GPIO_9, IOT_GPIO_DIR_OUT);
94     }
95     ppm = pow(X_CONSTANT_2 * vol / (VOILTAGE_5_V - vol), 1.0 / Y_CONSTANT_2); /* 计算ppm */
96     if (ppm < PPM_THRESHOLD_300) { /* 排除空气中其他气体的干扰 */
97         ppm = 0;
98     }
99 
100     if (ppm > PPM_THRESHOLD_3000) { /* 当ppm 大于3000时,蜂鸣器报警 */
101         if (count < 1) {
102             count++;
103             IoTPwmStart(0, PWM_DUTY, PWM_SMALL_DUTY);
104         } else {
105             count = 0;
106             IoTPwmStop(0);
107         }
108     } else {
109         count = 0;
110         IoTPwmStop(0);
111     }
112     FloatToString(ppm, combGas.g_ahu20GasBuff);
113     return ppm;
114 }
115 
116 /* mq2 sesor get data from adc change */
Mq2GetData(void)117 void Mq2GetData(void)
118 {
119     unsigned short data = 0; /* 0 */
120     float voltage;
121     // ADC_Channal_2(gpio5)  自动识别模式  CNcomment:4次平均算法模式 CNend
122     unsigned int ret = AdcRead(IOT_ADC_CHANNEL_5, &data,
123                                IOT_ADC_EQU_MODEL_4, IOT_ADC_CUR_BAIS_DEFAULT, SAMPLING_TIME);
124     if (ret != HI_ERR_SUCCESS) {
125         printf("ADC Read Fail\n");
126         return HI_NULL;
127     }
128     voltage = (float)(data * ADC_VOLTAGE_1_8_V *
129         ADC_VOLTAGE_4_TIMES / ADC_RANGE_MAX); /* vlt * 1.8* 4 / 4096.0为将码字转换为电压 */
130     combGas.g_combustibleGasValue = Mq2GetPpm(voltage);
131     printf("g_combustibleGasValue is %lf\r\n", combGas.g_combustibleGasValue);
132 }
133