这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 06树莓派5DHT11

共4条 1/1 1 跳转至

06树莓派5DHT11

菜鸟
2025-06-26 10:39:09     打赏

06 树莓派5 DHT11

一,环境及硬件连接

开始是打算通过python实现这一部分功能的,但是发现各种方式都无法实现,最终采用wiringPi+c的方式实现了,树莓派5是不支持wiringPi库的,需要自己编译安装。

#源地址
#https://github.com/WiringPi/WiringPi
git clone https://gitee.com/dnspeak/WiringPi.git
cd WiringPi
sudo build.sh

正确接线

DHT11 VCC → 树莓派3.3V(物理引脚1或17)

DATA → GPIO4(如GPIO4,物理引脚7)

GND → 树莓派GND(物理引脚6/9/14等)

二,代码部分

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <jansson.h>

#define MAX_TIMINGS 85
#define DHT_PIN 7       // GPIO7 (BCM编号)
#define UDP_PORT 10002
#define TARGET_IP "127.0.0.1"  // 目标IP地址

int data[5] = {0, 0, 0, 0, 0};
int sockfd;
struct sockaddr_in servaddr;

// 初始化UDP套接字
void init_udp() {
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket创建失败");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(UDP_PORT);
    servaddr.sin_addr.s_addr = inet_addr(TARGET_IP);
}

// 发送JSON格式数据
void send_data(float humidity, float temperature) {
    json_t *root = json_object();
    json_object_set_new(root, "sensor", json_string("DHT11"));
    json_object_set_new(root, "humidity", json_real(humidity));
    json_object_set_new(root, "temperature", json_real(temperature));
    
    char *json_str = json_dumps(root, JSON_COMPACT);
    sendto(sockfd, json_str, strlen(json_str), 0, 
          (const struct sockaddr *)&servaddr, sizeof(servaddr));
    
    free(json_str);
    json_decref(root);
}

// 读取DHT11传感器数据
void read_dht_data() {
    uint8_t laststate = HIGH;
    uint8_t counter = 0;
    uint8_t j = 0, i;
    float fah, cel;
    
    data[0] = data[1] = data[2] = data[3] = data[4] = 0;
    
    pinMode(DHT_PIN, OUTPUT);
    digitalWrite(DHT_PIN, LOW);
    delay(18);
    digitalWrite(DHT_PIN, HIGH);
    delayMicroseconds(40);
    pinMode(DHT_PIN, INPUT);

    for (i = 0; i < MAX_TIMINGS; i++) {
        counter = 0;
        while (digitalRead(DHT_PIN) == laststate) {
            counter++;
            delayMicroseconds(1);
            if (counter == 255) break;
        }
        laststate = digitalRead(DHT_PIN);
        
        if (counter == 255) break;
        
        if ((i >= 4) && (i % 2 == 0)) {
            data[j/8] <<= 1;
            if (counter > 16) data[j/8] |= 1;
            j++;
        }
    }

    if ((j >= 40) && 
        (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF))) {
        
        cel = data[2] + (data[3] / 10.0);
        fah = cel * 1.8f + 32;
        
        printf("湿度 = %d.%d %% 温度 = %d.%d *C (%.1f *F)\n",
            data[0], data[1], data[2], data[3], fah);
        
        send_data((float)data[0] + data[1]/10.0, cel);
    } else {
        printf("数据校验失败! (接收 %d 位)\n", j);
    }
}

int main() {
    printf("Raspberry Pi DHT11 温度湿度测试\n");
    
    if (wiringPiSetup() == -1) {
        fprintf(stderr, "wiringPi初始化失败!\n");
        return 1;
    }
    
    init_udp();
    
    while (1) {
        read_dht_data();
        delay(1000);  // 每1秒读取一次
    }
    
    close(sockfd);
    return 0;
}

编译

gcc -o dht11_udp dht11_udp.c -lwiringPi -ljansson

运行

sudo ./dht11_udp

测试

#安装netcat-openbsd
sudo apt update
sudo apt install netcat-openbsd
#端口监听
nc -u -l -p 10002

运行及测试结果

微信图片_20250626102651.png微信图片_20250626102741.png

Qt部分只需要在上期的基础上添加一个DHT11的ipc对象,还有一个DHT11的信号,用于触发温湿度仪表的显示。

成果演示

微信图片_20250626102745.jpg微信图片_20250626102749.jpg



专家
2025-06-26 20:50:28     打赏
2楼

感谢分享


专家
2025-06-26 20:51:47     打赏
3楼

感谢分享


专家
2025-06-26 20:53:21     打赏
4楼

感谢分享


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]