Skip to content

Commit cb00a2d

Browse files
committed
[add] dht11 sensor driver to rt-thread sensor framwork
Signed-off-by: MurphyZhao <[email protected]>
0 parents  commit cb00a2d

File tree

5 files changed

+423
-0
lines changed

5 files changed

+423
-0
lines changed

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# DHT11 数字温湿度传感器
2+
3+
## 简介
4+
5+
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有枀高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个 NTC 测温元件,幵与一个高性能 8 位单片机相连接,对外提供单总线通讯接口。更多 DHT11 的使用说明请参考 DHT11 厂家数据手册。
6+
7+
## 注意事项
8+
9+
DHT11 是采用单总线通讯的传感器,本软件包采用 GPIO 模拟单总线时序。DHT11 的一次完整读时序需要 20ms,时间过长,故无法使用关中断或者关调度的方式实现独占 CPU 以保证时序完整正确。因此可能出现读取数据失败的情况,请用户注意。
10+
11+
## 联系人信息
12+
13+
维护人:
14+
15+
- 维护:[MurphyZhao](https://github.com/murphyzhao)
16+
- 主页:https://github.com/murphyzhao/dht11_rtt

SConscript

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from building import *
2+
3+
# get current dir path
4+
cwd = GetCurrentDir()
5+
6+
src = []
7+
inc = [cwd]
8+
9+
src += ['sensor_dallas_dht11.c']
10+
11+
if GetDepend(['PKG_USING_DHT11_SAMPLE']):
12+
src += ['dht11_sample.c']
13+
14+
group = DefineGroup('dht11', src, depend = ['PKG_USING_DHT11'], CPPPATH = inc)
15+
Return('group')

dht11_sample.c

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright (c) 2006-2018, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2019-08-01 LuoGong the first version.
9+
* 2019-08-15 MurphyZhao add lock and modify code style
10+
*/
11+
12+
#include <rtthread.h>
13+
#include <rtdevice.h>
14+
#include "sensor.h"
15+
#include "sensor_dallas_dht11.h"
16+
#include "drv_gpio.h"
17+
18+
/* Modify this pin according to the actual wiring situation */
19+
#define DHT11_DATA_PIN GET_PIN(B, 12)
20+
21+
static void read_temp_entry(void *parameter)
22+
{
23+
rt_device_t dev = RT_NULL;
24+
struct rt_sensor_data sensor_data;
25+
rt_size_t res;
26+
rt_uint8_t get_data_freq = 1; /* 1Hz */
27+
28+
dev = rt_device_find("temp_dht11");
29+
if (dev == RT_NULL)
30+
{
31+
return;
32+
}
33+
34+
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
35+
{
36+
rt_kprintf("open device failed!\n");
37+
return;
38+
}
39+
40+
rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)(&get_data_freq));
41+
42+
while (1)
43+
{
44+
res = rt_device_read(dev, 0, &sensor_data, 1);
45+
46+
if (res != 1)
47+
{
48+
rt_kprintf("read data failed! result is %d\n", res);
49+
rt_device_close(dev);
50+
return;
51+
}
52+
else
53+
{
54+
if (sensor_data.data.temp >= 0)
55+
{
56+
uint8_t temp = (sensor_data.data.temp & 0xffff) >> 0; // get temp
57+
uint8_t humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi
58+
rt_kprintf("temp:%d, humi:%d\n" ,temp, humi);
59+
}
60+
}
61+
62+
rt_thread_delay(1000);
63+
}
64+
}
65+
66+
static int dht11_read_temp_sample(void)
67+
{
68+
rt_thread_t dht11_thread;
69+
70+
dht11_thread = rt_thread_create("dht_tem",
71+
read_temp_entry,
72+
RT_NULL,
73+
1024,
74+
RT_THREAD_PRIORITY_MAX / 2,
75+
20);
76+
if (dht11_thread != RT_NULL)
77+
{
78+
rt_thread_startup(dht11_thread);
79+
}
80+
81+
return RT_EOK;
82+
}
83+
INIT_APP_EXPORT(dht11_read_temp_sample);
84+
85+
static int rt_hw_dht11_port(void)
86+
{
87+
struct rt_sensor_config cfg;
88+
89+
cfg.intf.user_data = (void *)DHT11_DATA_PIN;
90+
rt_hw_dht11_init("dht11", &cfg);
91+
92+
return RT_EOK;
93+
}
94+
INIT_COMPONENT_EXPORT(rt_hw_dht11_port);

sensor_dallas_dht11.c

+263
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/*
2+
* Copyright (c) 2006-2018, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2019-08-01 LuoGong the first version.
9+
* 2019-08-15 MurphyZhao add lock and modify code style
10+
*
11+
*/
12+
13+
#include "sensor_dallas_dht11.h"
14+
#include <rtdevice.h>
15+
#include <rthw.h>
16+
#include "sensor.h"
17+
#include "board.h"
18+
#include <stdint.h>
19+
20+
#define SENSOR_DEBUG
21+
#define DBG_TAG "sensor.dht11"
22+
23+
#ifdef SENSOR_DEBUG
24+
#define DBG_LVL DBG_LOG
25+
#else
26+
#define DBG_LVL DBG_ERROR
27+
#endif /* SENSOR_DEBUG */
28+
#include <rtdbg.h>
29+
30+
#define SENSOR_TEMP_RANGE_MAX (100)
31+
#define SENSOR_TEMP_RANGE_MIN (0)
32+
#define SENSOR_HUMI_RANGE_MAX (100)
33+
#define SENSOR_HUMI_RANGE_MIN (0)
34+
35+
#ifndef RT_USING_PIN
36+
#error "Please enable RT_USING_PIN"
37+
#endif
38+
39+
#ifndef rt_hw_us_delay
40+
RT_WEAK void rt_hw_us_delay(rt_uint32_t us)
41+
{
42+
rt_uint32_t delta;
43+
44+
us = us * (SysTick->LOAD / (1000000 / RT_TICK_PER_SECOND));
45+
delta = SysTick->VAL;
46+
47+
while (delta - SysTick->VAL < us) continue;
48+
}
49+
#endif
50+
51+
static void dht11_reset(rt_base_t pin)
52+
{
53+
rt_pin_mode(pin, PIN_MODE_OUTPUT);
54+
55+
rt_pin_write(pin, PIN_LOW);
56+
rt_thread_mdelay(20); /* 20ms */
57+
58+
rt_pin_write(pin, PIN_HIGH);
59+
rt_hw_us_delay(30); /* 30us*/
60+
}
61+
62+
static uint8_t dht11_check(rt_base_t pin)
63+
{
64+
uint8_t retry = 0;
65+
rt_pin_mode(pin, PIN_MODE_INPUT);
66+
67+
while (rt_pin_read(pin) && retry < 100)
68+
{
69+
retry++;
70+
rt_hw_us_delay(1);
71+
}
72+
73+
if(retry >= 100)
74+
{
75+
return CONNECT_FAILED;
76+
}
77+
78+
retry = 0;
79+
while (!rt_pin_read(pin) && retry < 100)
80+
{
81+
retry++;
82+
rt_hw_us_delay(1);
83+
};
84+
85+
if(retry >= 100)
86+
{
87+
return CONNECT_FAILED;
88+
}
89+
90+
return CONNECT_SUCCESS;
91+
}
92+
93+
static uint8_t dht11_read_bit(rt_base_t pin)
94+
{
95+
uint8_t retry = 0;
96+
while (rt_pin_read(pin) && retry < 100)
97+
{
98+
retry++;
99+
rt_hw_us_delay(1);
100+
}
101+
retry = 0;
102+
103+
while (!rt_pin_read(pin) && retry < 100)
104+
{
105+
retry++;
106+
rt_hw_us_delay(1);
107+
}
108+
109+
rt_hw_us_delay(40);
110+
if(rt_pin_read(pin))
111+
return 1;
112+
return 0;
113+
}
114+
115+
static uint8_t dht11_read_byte(rt_base_t pin)
116+
{
117+
uint8_t i, dat = 0;
118+
119+
for (i = 1; i <= 8; i++)
120+
{
121+
dat <<= 1;
122+
dat |= dht11_read_bit(pin);
123+
}
124+
125+
return dat;
126+
}
127+
128+
static uint8_t dht11_read_Data(rt_base_t pin,uint8_t *temp,uint8_t *humi)
129+
{
130+
uint8_t i, buf[5];
131+
dht11_reset(pin);
132+
133+
if(dht11_check(pin) == 0)
134+
{
135+
for(i=0; i<5; i++) /* read 40 bits */
136+
{
137+
buf[i] = dht11_read_byte(pin);
138+
}
139+
140+
if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
141+
{
142+
*humi = buf[0];
143+
*temp = buf[2];
144+
}
145+
}
146+
else
147+
{
148+
return 1;
149+
}
150+
151+
return 0;
152+
}
153+
154+
uint8_t dht11_init(rt_base_t pin)
155+
{
156+
uint8_t ret = 0;
157+
158+
dht11_reset(pin);
159+
ret = dht11_check(pin);
160+
161+
return ret;
162+
}
163+
164+
int32_t dht11_get_temperature(rt_base_t pin)
165+
{
166+
static int32_t temOLD = 0;
167+
uint8_t humi=0, temp = 0;
168+
int32_t temNEW;
169+
170+
dht11_read_Data(pin, &temp, &humi);
171+
172+
temNEW = (humi << 16)|(temp<<0);
173+
174+
if((temNEW != temOLD) && (temNEW !=0))
175+
{
176+
temOLD = temNEW;
177+
}
178+
return temOLD;
179+
}
180+
181+
static rt_size_t dht11_polling_get_data(rt_sensor_t sensor, struct rt_sensor_data *data)
182+
{
183+
rt_int32_t temperature_humidity;
184+
temperature_humidity = dht11_get_temperature((rt_base_t)sensor->config.intf.user_data);
185+
data->data.temp = temperature_humidity;
186+
data->timestamp = rt_sensor_get_ts();
187+
return 1;
188+
}
189+
190+
static rt_size_t dht11_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len)
191+
{
192+
RT_ASSERT(buf);
193+
194+
if (sensor->config.mode == RT_SENSOR_MODE_POLLING)
195+
{
196+
return dht11_polling_get_data(sensor, buf);
197+
}
198+
199+
return 0;
200+
}
201+
202+
static rt_err_t dht11_control(struct rt_sensor_device *sensor, int cmd, void *args)
203+
{
204+
return RT_EOK;
205+
}
206+
207+
static struct rt_sensor_ops sensor_ops =
208+
{
209+
dht11_fetch_data,
210+
dht11_control
211+
};
212+
213+
static struct rt_sensor_device dht11_dev;
214+
int rt_hw_dht11_init(const char *name, struct rt_sensor_config *cfg)
215+
{
216+
rt_err_t result = RT_EOK;
217+
rt_sensor_t sensor = &dht11_dev;
218+
219+
rt_memset(sensor, 0x0, sizeof(struct rt_sensor_device));
220+
221+
if (!dht11_init((rt_base_t)cfg->intf.user_data))
222+
{
223+
sensor->module = rt_calloc(1, sizeof(struct rt_sensor_module));
224+
if (sensor->module == RT_NULL)
225+
{
226+
LOG_E("Memory error.");
227+
result = -RT_ENOMEM;
228+
goto __exit;
229+
}
230+
231+
sensor->info.type = RT_SENSOR_CLASS_TEMP ;
232+
sensor->info.vendor = RT_SENSOR_VENDOR_DALLAS;
233+
sensor->info.model = "DHT11";
234+
sensor->info.unit = RT_SENSOR_UNIT_DCELSIUS;
235+
sensor->info.intf_type = RT_SENSOR_INTF_ONEWIRE;
236+
sensor->info.range_max = SENSOR_TEMP_RANGE_MAX;
237+
sensor->info.range_min = SENSOR_TEMP_RANGE_MIN;
238+
sensor->info.period_min = 100; /* Read ten times in 1 second */
239+
240+
sensor->config = *cfg;
241+
sensor->ops = &sensor_ops;
242+
243+
/* dht11 sensor register */
244+
result = rt_hw_sensor_register(sensor, name, RT_DEVICE_FLAG_RDONLY, RT_NULL);
245+
if (result != RT_EOK)
246+
{
247+
LOG_E("device register err code: %d", result);
248+
goto __exit;
249+
}
250+
}
251+
else
252+
{
253+
LOG_E("dht11 init failed");
254+
result = -RT_ERROR;
255+
goto __exit;
256+
}
257+
return RT_EOK;
258+
259+
__exit:
260+
if (sensor->module)
261+
rt_free(sensor->module);
262+
return result;
263+
}

0 commit comments

Comments
 (0)