把树莓派外接的DHT11接收的温湿度发送到emqx上

一、准备

接线参考了文章(树莓派接温湿度传感器显示温度湿度):

**DHT11:**接收温湿度

MQTT 部分 :在 main 函数中初始化 MQTT 客户端,并在每次成功读取到温度后,将数据打包成 JSON 格式(如 {"temp": 28, "humi": 60})发送到 EMQX。

LED 逻辑:保留了温度超过 30 度闪烁的功能。

新建一个文件,例如 main.c,并将以下代码完整复制进去。

复制代码
#include <wiringPi.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h> // 用于 sleep
#include <stdlib.h>

// 引入 Paho MQTT 库头文件
#include "MQTTClient.h"

// --- 硬件引脚定义 ---
#define DHT_PIN 7
#define LED_PIN 0
#define TEMP_THRESHOLD 30 // 报警温度阈值

// --- MQTT 配置 ---
#define ADDRESS     "tcp://localhost:1883" // 如果EMQX在本地,用localhost;如果是远程,填IP
#define CLIENTID    "RPI_DHT11_Sensor"
#define TOPIC       "sensor/dht11_data"
#define QOS         1
#define TIMEOUT     10000L

// --- DHT11 读取函数  ---
int readDHT11(int *temperature, int *humidity) {
    uint8_t data[5] = {0}; // DHT11 返回 5 字节数据
    uint8_t lastState = HIGH;
    uint8_t counter = 0;
    uint8_t j = 0;

    pinMode(DHT_PIN, OUTPUT);
    digitalWrite(DHT_PIN, LOW);
    delay(18);
    digitalWrite(DHT_PIN, HIGH);
    delayMicroseconds(40);
    pinMode(DHT_PIN, INPUT);

    // 等待响应信号
    for(int i=0; i<85; i++){
        counter = 0;
        while(digitalRead(DHT_PIN) == lastState){
            counter++;
            delayMicroseconds(1);
            if(counter == 255) break;
        }
        lastState = digitalRead(DHT_PIN);
        if(counter == 255) break;

        // 解析数据位 (从第4个脉冲开始是数据)
        if((i >= 4) && (i % 2 == 0)){
            data[j/8] <<= 1;
            if(counter > 50){
                data[j/8] |= 1;
            }
            j++;
        }
    }

    // 校验数据完整性
    if((j >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xff))){
        *humidity = data[0];
        *temperature = data[2];
        return 0; // 成功
    } else {
        return -1; // 失败
    }
}

// --- LED 闪烁函数 ---
void blink_led(int times, int delay_ms){
    for(int i=0; i<times; i++){
        digitalWrite(LED_PIN, HIGH);
        delay(delay_ms);
        digitalWrite(LED_PIN, LOW);
        delay(delay_ms);
    }
}

int main(void) {
    int temperature = 0;
    int humidity = 0;

    // 1. 初始化 WiringPi
    if(wiringPiSetup() == -1){
        printf("WiringPi Setup Error!\n");
        return -1;
    }
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, LOW);

    // 2. 初始化 MQTT 客户端
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;
    int rc;

    MQTTClient_create(&client, ADDRESS, CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    printf("Connecting to EMQX at %s...\n", ADDRESS);
    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
    printf("Connected to EMQX successfully.\n");

    // 3. 主循环:读取传感器 -> 发送 MQTT
    while(1) {
        if(readDHT11(&temperature, &humidity) == 0) {
            printf("Read Success -> Temp: %d C, Humi: %d %%\n", temperature, humidity);

            // LED 报警逻辑
            if(temperature >= TEMP_THRESHOLD){
                blink_led(3, 300);
            }

            // --- MQTT 发送逻辑 ---
            char payload[100];
            // 将数据格式化为 JSON 字符串
            sprintf(payload, "{\"temperature\": %d, \"humidity\": %d}", temperature, humidity);

            pubmsg.payload = payload;
            pubmsg.payloadlen = (int)strlen(payload);
            pubmsg.qos = QOS;
            pubmsg.retained = 0;

            MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
            printf("Message sent to topic %s: %s\n", TOPIC, payload);

            // 等待消息发送完成
            MQTTClient_waitForCompletion(client, token, TIMEOUT);
        } else {
            printf("Sensor read failed, retrying...\n");
        }

        // 间隔 2 秒
        sleep(2);
    }

    // 断开连接并清理
    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);

    return 0;
}

这里我是用vs code 远程连接的,这样方便看,好修改,不用在nano里黑灯瞎火的写了。如果有需要的小伙伴,我是看了这篇 VS Code远程连接树莓派超详细教程(图文),写得特别好,而且操作简单,很好配置,大家可以自行选择。

二、编译代码

由于使用了 wiringPipaho-mqtt-c 两个库,编译时需要同时链接它们。

在终端执行以下命令(假设你的代码文件名为 main.c

bash 复制代码
gcc main.c -o dht_mqtt -lwiringPi -lpaho-mqtt3c
  • -lwiringPi:链接 GPIO 控制库。
  • -lpaho-mqtt3c:链接 Paho MQTT C 客户端库。

这里提个醒,因为我是重新写了镜像,所有很多东西来不及配置,都忘记了,所以只能边写边添加,要什么就加什么。这里我报错是因为没有配置Paho MQTT C 库。

所以如果也有这种情况的小伙伴,就输入:

bash 复制代码
sudo apt-get install libpaho-mqtt-dev

添加即可,然后记得编译哦。

三、运行程序

bash 复制代码
sudo ./dht_mqtt

四、验证结果

这里我是用mqttx工具,比较方便的看到数据情况。

也可以使用EMQX:

打开浏览器访问你的 EMQX 管理后台(通常是 http://树莓派IP:18083)。

进入 WebSocket 工具页面。

订阅主题 sensor/dht11_data。

应该能实时看到树莓派发送过来的 JSON 数据。

这里只是使用了简单的温湿度传感器,大家可以自行添加更加复杂的传感器,编写代码,制作项目。( •̀ ω •́ )y

相关推荐
bush42 小时前
嵌入式linux学习记录四
linux·运维·学习
Deitymoon2 小时前
FreeRTOS——列表与列表项
stm32·单片机·嵌入式硬件
总结所学2 小时前
电路定理 叠加定理 基尔霍夫定律
单片机·嵌入式硬件
会编程的土豆2 小时前
Go 方法接收者超清晰笔记(类型名 vs 变量名)
开发语言·笔记·golang
峥嵘life2 小时前
Android 蓝牙设备连接广播详解-2026
android·python·学习
楼田莉子3 小时前
Docker学习:Docker介绍及其架构介绍
运维·后端·学习·docker·容器·架构
fanged3 小时前
C++的汇编实现(TODO)
笔记
星夜夏空993 小时前
FreeRTOS学习(7)——任务列表
java·前端·学习
不羁的木木3 小时前
Form Kit(卡片开发服务)学习笔记01-核心概念与架构设计
笔记·学习·harmonyos