1 /*
2 * Copyright (C) 2022 HiHope Open Source Organization .
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 *
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <stdint.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include "ohos_init.h"
23 #include "cmsis_os2.h"
24 #include "iot_i2c.h"
25 #include "iot_gpio.h"
26 #include "iot_pwm.h"
27 #include "iot_errno.h"
28 #include "hi_io.h"
29 #include "hi_adc.h"
30 #include "aht20.h"
31 #include "oled_ssd1306.h"
32 #include "config_params.h"
33
34 #ifndef ARRAY_SIZE
array_size(a)35 array_size(a)
36 {
37 sizeof(a)/sizeof(a[0])
38 }
39 #endif
40
41 #define MS_PER_S 1000
42 #define BEEP_PIN_NAME 9
43 #define BEEP_PIN_FUNCTION 5
44 #define WIFI_IOT_PWM_PORT_PWM0 0
45 #define FIVE 5
46 #define THREE 3
47 #define TWO 2
48 #define FOUR 4
49 #define NUM_ONE 2593
50 #define NUM_TWO 1078
51 #define ONE_THOUSAND 1000
52 #define NINE 9
53 #define ONE_POINT_EIGHT 1.8
54 #define ATTR.STACK_SIZE 4096
55
56 #define GAS_SENSOR_CHAN_NAME 5
57
58 #define AHT20_BAUDRATE (400*1000)
59 #define AHT20_I2C_IDX 0
60
61 #define ADC_RESOLUTION 2048
62 #define IOT_GPIO_KEY 5
63
64 unsigned int g_sensorStatus = 0;
65 unsigned int g_tempMax = 35;
66 unsigned int g_tempMin = 0;
67 unsigned int g_humiMax = 40;
68 unsigned int g_humiMin = 0;
69 unsigned int g_gasValue = 2000;
70
71 float g_humidity = 0.0f;
72 float g_temperature = 0.0f;
73 float g_gasValuetemp = 0.0f;
74
75 #define LENGTH 32
76 char tempMax[LENGTH] = {0};
77 char tempMin[LENGTH] = {0};
78 char humiMax[LENGTH] = {0};
79 char humiMin[LENGTH] = {0};
80 char gasValue[LENGTH] = {0};
81
GetValue(void)82 int GetValue(void)
83 {
84 int ret = UtilsGetValue(PARAM_TEMP_MAX, tempMax, LENGTH);
85 if (ret < 0) {
86 printf("get tempMax value failed, ret is %d\r\n", ret);
87 } else {
88 g_tempMax = atoi(tempMax);
89 printf("g_tempMax is %u\r\n", g_tempMax);
90 }
91 ret = UtilsGetValue(PARAM_TEMP_MIN, tempMin, LENGTH);
92 if (ret < 0) {
93 printf("get tempMin value failed, ret is %d\r\n", ret);
94 } else {
95 g_tempMin = atoi(tempMin);
96 printf("g_tempMin is %u\r\n", g_tempMin);
97 }
98 ret = UtilsGetValue(PARAM_HUMI_MAX, humiMax, LENGTH);
99 if (ret < 0) {
100 printf("get humiMax value failed, ret is %d\r\n", ret);
101 } else {
102 g_humiMax = atoi(humiMax);
103 printf("g_tempMax is %u\r\n", g_humiMax);
104 }
105 ret = UtilsGetValue(PARAM_HUMI_MIN, humiMin, LENGTH);
106 if (ret < 0) {
107 printf("get humiMin value failed, ret is %d\r\n", ret);
108 } else {
109 g_humiMin = atoi(humiMin);
110 printf("g_humiMin is %u\r\n", g_humiMin);
111 }
112
113 ret = UtilsGetValue(PARAM_GAS_VALUE, gasValue, LENGTH);
114 if (ret < 0) {
115 printf("get gasValue value failed, ret is %d\r\n", ret);
116 } else {
117 g_gasValue = atoi(gasValue);
118 printf("g_gasValue is %u\r\n", g_gasValue);
119 }
120
121 return ret;
122 }
123
ConvertToVoltage(unsigned short data)124 static float ConvertToVoltage(unsigned short data)
125 {
126 return (float)data * ONE_POINT_EIGHT * FOUR / ATTR.STACK_SIZE;
127 }
128
OnButtonPressed(char * arg)129 static void OnButtonPressed(char *arg)
130 {
131 (void) arg;
132 printf("OnButtonPressed\r\n");
133
134 g_sensorStatus = 0;
135 printf("g_beepState is %u\r\n", g_sensorStatus);
136 }
137
EnvironmentTask(int * arg)138 static void EnvironmentTask(int *arg)
139 {
140 uint32_t retval = 0;
141 float gasSensorResistance = 0.0f;
142 static char line[32] = {0};
143
144 OledInit();
145 OledFillScreen(0);
146 IoTI2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);
147
148 // set BEEP pin as PWM function
149 IoTGpioInit(BEEP_PIN_NAME);
150 retval = hi_io_set_func(BEEP_PIN_NAME, BEEP_PIN_FUNCTION);
151 if (retval != IOT_SUCCESS) {
152 printf("IoTGpioInit(9) failed, %0X!\n", retval);
153 }
154 IoTGpioSetDir(NINE, IOT_GPIO_DIR_OUT);
155 IoTPwmInit(WIFI_IOT_PWM_PORT_PWM0);
156
157 while (IOT_SUCCESS != AHT20_Calibrate()) {
158 usleep(ONE_THOUSAND);
159 }
160
161 while (1) {
162 retval = AHT20_StartMeasure();
163 if (retval != IOT_SUCCESS) {
164 printf("trigger measure failed!\r\n");
165 }
166
167 retval = AHT20_GetMeasureResult(&g_temperature, &g_humidity);
168 if (retval != IOT_SUCCESS) {
169 printf("get humidity data failed!\r\n");
170 }
171
172 unsigned short data = 0;
173 if (hi_adc_read(GAS_SENSOR_CHAN_NAME, &data, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0)
174 == IOT_SUCCESS) {
175 float Vx = ConvertToVoltage(data);
176
177 // Vcc ADC GND
178 // | ______ | ______ |
179 // +---| MG-2 |---+---| 1kom |---+
180 // ------ ------
181 // 查阅原理图,ADC 引脚位于 1K 电阻和燃气传感器之间,燃气传感器另一端接在 5V 电源正极上
182 // 串联电路电压和阻止成正比:
183 // Vx / 5 == 1kom / (1kom + Rx)
184 // => Rx + 1 == 5/Vx
185 // => Rx = 5/Vx - 1
186 // 甲烷浓度计算
187 g_gasValuetemp = 1 / (1 + gasSensorResistance) * (-NUM_ONE) + NUM_TWO;
188
189 if (g_gasValuetemp < 0) {
190 g_gasValuetemp = 0;
191 }
192 }
193
194 int ret = GetValue();
195 if (ret < 0) {
196 printf("get value failed!, ret is %d\r\n", ret);
197 }
198 OledFillScreen(0x00);
199
200 OledShowString(0, 0, "Sensor values:", 1);
201
202 if (snprintf_s(line, sizeof(line), "temp: %.2f", g_temperature) == TRUE) {
203 OledShowString(0, 1, line, 1);
204 }
205 if (snprintf_s(line, sizeof(line), "humi: %.2f", g_humidity) == TRUE) {
206 OledShowString(0, TWO, line, 1);
207 }
208
209 if (snprintf_s(line, sizeof(line), "gas: %.2f ppm", g_gasValuetemp) == TRUE) {
210 OledShowString(0, THREE, line, 1);
211 }
212 }
213 }
214
EnvironmentDemo(void)215 static void EnvironmentDemo(void)
216 {
217 osThreadAttr_t attr;
218
219 IoTGpioInit(BEEP_PIN_NAME);
220 hi_io_set_func(BEEP_PIN_NAME, BEEP_PIN_FUNCTION);
221 IoTPwmInit(WIFI_IOT_PWM_PORT_PWM0);
222
223 IoTGpioInit(IOT_GPIO_KEY);
224 hi_io_set_func(IOT_GPIO_KEY, 0);
225 IoTGpioSetDir(IOT_GPIO_KEY, IOT_GPIO_DIR_IN);
226 hi_io_set_pull(IOT_GPIO_KEY, 1);
227
228 IoTGpioRegisterIsrFunc(IOT_GPIO_KEY, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW,
229 OnButtonPressed, NULL);
230
231 attr.name = "EnvironmentTask";
232 attr.attr_bits = 0U;
233 attr.cb_mem = NULL;
234 attr.cb_size = 0U;
235 attr.stack_mem = NULL;
236 attr.stack_size = ATTR.STACK_SIZE;
237 attr.priority = osPriorityNormal;
238
239 if (osThreadNew(EnvironmentTask, NULL, &attr) == NULL) {
240 printf("[EnvironmentDemo] Failed to create EnvironmentTask!\n");
241 }
242 }
243
244 APP_FEATURE_INIT(EnvironmentDemo);