Raspberry Pi 4B +Python3 的 AdafruitDHT库 修改

树莓派 通过DHT11模块采集环境温湿度:

方法:1、Python + RPi.GPIO 直接使用GPIO库来控制实现,其中在树莓派实验室(网站)上有实现,很多博客也有相关实现,,但是目前个人测试,都没有成功。(猜测:python直接控制gpio的延时不好控制,设备有限,放弃此方法);

方法:2、纯C语言实现,非常好,不需要辣么多累赘的东西。弊端,由于本人还需要用到python的http协议库,所以不想去用C自己去实现。所以此方法没有完全执行。

方法:3、Python+wiringpi2库,仍然是在Python 里面,各种问题都被解决掉,比较好。

方法:4、C语言WiringPi.h,这个还可以,树莓派实验中有两种实现方法,都测试过,基本上实现没有障碍,主要在于程序有没有优化(封装函数+校验和)。

方法:5、Python +AdafruitDHT库,这个Adafruit库是封装好的,地址http://github.com/adafruit/Adafruit_Python_DHT,确实挺好的,但是(2020/10/31)截至目前,这个库最少4年没有更新了,里面还是树莓派3B的适配。

本人对其进行了舔砖加瓦;

git下载下后,

修改1、setup.py

elif pi_version == 4:
        extensions.append(Extension("Adafruit_DHT.Raspberry_Pi_2_Driver",
                                    ["source/_Raspberry_Pi_2_Driver.c", "source/common_dht_read.c", "source/Raspberry_Pi_2/pi_2_dht_read.c", "source/Raspberry_Pi_2/pi_2_mmio.c"],
                                    libraries=['rt'],
                                    extra_compile_args=['-std=gnu99']))

修改2、Adafruit_DHT/platform_detect.py

def pi_version():
    """Detect the version of the Raspberry Pi.  Returns either 1, 2, 3 or
    None depending on if it's a Raspberry Pi 1 (model A, B, A+, B+),
    Raspberry Pi 2 (model B+), Raspberry Pi 3,Raspberry Pi 3 (model B+), Raspberry Pi 4
    or not a Raspberry Pi.
    """
    # Check /proc/cpuinfo for the Hardware field value.
    # 2708 is pi 1
    # 2709 is pi 2
    # 2835 is pi 3 
    # 2837 is pi 3b+
    # 2711 is pi 4b
    # Anything else is not a pi.
    with open('/proc/cpuinfo', 'r') as infile:
        cpuinfo = infile.read()
    # Match a line like 'Hardware   : BCM2709'
    match = re.search('^Hardware\s+:\s+(\w+)$', cpuinfo,
                      flags=re.MULTILINE | re.IGNORECASE)
    if not match:
        # Couldn't find the hardware, assume it isn't a pi.
        return None
    if match.group(1) == 'BCM2708':
        # Pi 1
        return 1
    elif match.group(1) == 'BCM2709':
        # Pi 2
        return 2
    elif match.group(1) == 'BCM2835':
        # Pi 3 
        return 3
    elif match.group(1) == 'BCM2837':
        # Pi 3b+
        return 3
    elif match.group(1) == 'BCM2711':
        # Pi 4b
        return 4
    else:
        # Something else, not a pi.
        return None

修改3、Adafruit_DHT/common.py

def get_platform():
    """Return a DHT platform interface for the currently detected platform."""
    plat = platform_detect.platform_detect()
    if plat == platform_detect.RASPBERRY_PI:
        # Check for version 1 or 2 of the pi.
        version = platform_detect.pi_version()
        if version == 1:
            from . import Raspberry_Pi
            return Raspberry_Pi
        elif version == 2:
            from . import Raspberry_Pi_2
            return Raspberry_Pi_2
        elif version == 3:
            """Use Pi 2 driver even though running on Pi 3"""
            from . import Raspberry_Pi_2
            return Raspberry_Pi_2
        elif version == 4:
            from . import Raspberry_Pi_2
            return Raspberry_Pi_2
        else:
            raise RuntimeError('No driver for detected Raspberry Pi version available!')
    elif plat == platform_detect.BEAGLEBONE_BLACK:
        from . import Beaglebone_Black
        return Beaglebone_Black
    else:
        raise RuntimeError('Unknown platform.')

修改4、source/_Raspberry_Pi_2_Driver.c

static PyObject* Raspberry_Pi_2_Driver_read(PyObject *self, PyObject *args)
{
    // Parse sensor and pin integer arguments.
    int sensor, pin;
    if (!PyArg_ParseTuple(args, "ii", &sensor, &pin)) {
        return NULL;
    }
    // Call dht_read and return result code, humidity, and temperature.
    float humidity = 0, temperature = 0;
    int result = 0;
    do{
        result = pi_2_dht_read(sensor, pin, &humidity, &temperature);
    }while(result != 0);   //主要修改逻辑,让C语言库专注读取数据,避免因为Python的延时(不让python参与底层数据的获取工作),直接返回结果
    
    return Py_BuildValue("iff", result, humidity, temperature);
}

可以返回Adafruit_Python_DHT目录

sudo python3 setup.py install

安装OKO (会在Adafruit_Python_DHT\build\lib.linux-armv7l-3.7\Adafruit_DHT\Raspberry_Pi_2_Driver.cpython-37m-arm-linux-gnueabihf.so,生成动态链接库,会自动拷贝到/usr/local/lib/python3.7/dist-packages/Adafruit_DHT-1.4.0-py3.7-linux-armv7l.egg/Adafruit_DHT/目录)

进入examples目录

测试 python3 AdafruitDHT.py 11 4

11为传感器类型DHT11

4为 树莓派BCM编码引脚号

可以正常获取数据ok