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
运行及测试结果
Qt部分只需要在上期的基础上添加一个DHT11的ipc对象,还有一个DHT11的信号,用于触发温湿度仪表的显示。
成果演示