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