前言
- 通过之前的模块实现温度数据的上报,采用mqtt的方式
- 用到的软件包有mqtt、lwip
- mqtt服务器采用mqttx提供的测试地址进行测试
- 线程之间通过消息队列进行通信
软件包
硬件io的初始化(根据实际情况配置)
定义一个应用的数据的管理结构体,统一管理数据
头文件
//
// Created by shchl on 2024/3/14.
//
#ifndef F4_OS_APP_DATA_H
#define F4_OS_APP_DATA_H
#include "board.h"
struct temperature_sensor {
rt_uint32_t value; /*当前温度的值*/
rt_uint32_t timestamp; /*时间戳*/
};/*温度*/
struct App_Data_Context {
struct temperature_sensor temp_sensor;
rt_mq_t temp_mq; /*温度的消息队列*/
};
typedef struct App_Data_Context *App_Data_Context_t;
extern App_Data_Context_t app_context;
#endif //F4_OS_APP_DATA_H
源文件
//
// Created by shchl on 2024/3/14.
//
#include "app_data.h"
#define DBG_ENABLE
#define DBG_TAG "app.data"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
App_Data_Context_t app_context;
int app_data_init(void) {
/*分配内存空间*/
app_context = rt_calloc(1, sizeof(struct App_Data_Context));
RT_ASSERT(app_context); /*推断分配成功*/
app_context->temp_mq = rt_mq_create("temp_mq",
sizeof(struct temperature_sensor),
10,
RT_IPC_FLAG_PRIO);
RT_ASSERT(app_context->temp_mq);
return 0;
}
INIT_ENV_EXPORT(app_data_init);
数据采集(温度)
源文件
#define NAME_STR(x) #x
#define THREAD(name) thread_##name
#define THREAD_FUNC(name) fn_##name
#define THREAD_ENTITY_NAME(name) NAME_STR(name)
#define THREAD_ENTITY_FUNC(name) THREAD_FUNC(name)
#define SENSOR_THREAD_ENTITY THREAD(sendor)
#define STACK_SIZE 1024
#define PRIORITY 15
#define TICK 20
static rt_thread_t SENSOR_THREAD_ENTITY;
void THREAD_ENTITY_FUNC(SENSOR_THREAD_ENTITY)(void *args) {
struct rt_sensor_data data;
rt_size_t res;
rt_device_t dev = rt_device_find("temp_ds18b20");
if (dev == NULL) {
LOG_E("not found temp_ds18b20");
return;
}
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) {
LOG_E("open device failed!");
return;
}
while (1) {
res = rt_device_read(dev, 0, &data, 1);
if (res != 1) {
LOG_E("read data failed!size is %d", res);
} else {
app_context->temp_sensor.value = data.data.temp;
app_context->temp_sensor.timestamp = data.timestamp;
rt_mq_send(app_context->temp_mq,
&app_context->temp_sensor,
sizeof(app_context->temp_sensor));
}
rt_thread_mdelay(1000);
}
}
int sensor_test() {
SENSOR_THREAD_ENTITY = rt_thread_create(THREAD_ENTITY_NAME(SENSOR_THREAD_ENTITY),
THREAD_ENTITY_FUNC(SENSOR_THREAD_ENTITY),
RT_NULL,
STACK_SIZE,
PRIORITY,
TICK);
if (SENSOR_THREAD_ENTITY) {
rt_thread_startup(SENSOR_THREAD_ENTITY);
}
return RT_EOK;
}
INIT_APP_EXPORT(sensor_test);
上报数据(mqtt)
宏定义部分
#define KAWAII_MQTT_LOG_LEVEL 4
#define KAWAII_MQTT_VERSION 4
#define KAWAII_MQTT_KEEP_ALIVE_INTERVAL 100
#define KAWAII_MQTT_THREAD_STACK_SIZE 4096
#define KAWAII_MQTT_THREAD_PRIO 5
#define KAWAII_MQTT_THREAD_TICK 50
#define KAWAII_MQTT_MAX_PACKET_ID 0xFFFE
#define KAWAII_MQTT_TOPIC_LEN_MAX 64
#define KAWAII_MQTT_ACK_HANDLER_NUM_MAX 64
#define KAWAII_MQTT_DEFAULT_BUF_SIZE 1024
#define KAWAII_MQTT_DEFAULT_CMD_TIMEOUT 4000
#define KAWAII_MQTT_MAX_CMD_TIMEOUT 20000
#define KAWAII_MQTT_MIN_CMD_TIMEOUT 1000
#define KAWAII_MQTT_RECONNECT_DEFAULT_DURATION 1000
#define PKG_USING_KAWAII_MQTT_TEST
#define KAWAII_MQTT_HOST "broker.emqx.io"
#define KAWAII_MQTT_PORT "1883"
#define KAWAII_MQTT_CLIENTID "rtthread001"
#define KAWAII_MQTT_USERNAME "rt-thread"
#define KAWAII_MQTT_PASSWORD "rt-thread"
#define KAWAII_MQTT_SUBTOPIC "rtt-sub"
#define KAWAII_MQTT_PUBTOPIC "rtt-pub123"
源文件
#include <stdio.h>
#include <rtthread.h>
#include "mqttclient.h"
#include "app_data.h"
static void sub_topic_handle1(void *client, message_data_t *msg) {
(void) client;
KAWAII_MQTT_LOG_I("-----------------------------------------------------------------------------------");
KAWAII_MQTT_LOG_I("%s:%d %s()...\ntopic: %s\nmessage:%s", __FILE__, __LINE__, __FUNCTION__, msg->topic_name,
(char *) msg->message->payload);
KAWAII_MQTT_LOG_I("-----------------------------------------------------------------------------------");
}
char buf[50];
static int mqtt_publish_handle(mqtt_client_t *client, struct temperature_sensor *temp) {
mqtt_message_t msg;
memset(&msg, 0, sizeof(msg));
msg.qos = QOS0;
sprintf(buf, "temp:%3d.%d C, timestamp:%5d", temp->value / 10, (rt_uint32_t) temp->value % 10,
temp->timestamp);
/*推送温度数据*/
// KAWAII_MQTT_LOG_I("temp:%3d.%d C, timestamp:%5d", temp->temp / 10, (rt_uint32_t) temp->temp % 10,
// temp->timestamp);
msg.payload = (void *) buf;
return mqtt_publish(client, KAWAII_MQTT_PUBTOPIC, &msg);
}
static void report_data(void *parameter) {
mqtt_client_t *client = NULL;
rt_thread_delay(6000);
mqtt_log_init();
client = mqtt_lease();
mqtt_set_host(client, KAWAII_MQTT_HOST);
mqtt_set_port(client, KAWAII_MQTT_PORT);
mqtt_set_user_name(client, KAWAII_MQTT_USERNAME);
mqtt_set_password(client, KAWAII_MQTT_PASSWORD);
mqtt_set_client_id(client, KAWAII_MQTT_CLIENTID);
mqtt_set_clean_session(client, 1);
KAWAII_MQTT_LOG_I("The ID of the Kawaii client is: %s ", KAWAII_MQTT_CLIENTID);
mqtt_connect(client);
mqtt_subscribe(client, KAWAII_MQTT_SUBTOPIC, QOS0, sub_topic_handle1); /*订阅主题*/
struct temperature_sensor temp;
rt_ssize_t result;
while (1) {
result = rt_mq_recv(app_context->temp_mq, &temp, sizeof(struct temperature_sensor), RT_WAITING_FOREVER);
if (result == sizeof(struct temperature_sensor)) {
mqtt_publish_handle(client, &temp);
} else {
KAWAII_MQTT_LOG_I("err code :%d", result);
mqtt_sleep_ms(4 * 1000);
}
}
}
int mqtt_report_data(void) {
rt_thread_t tid_mqtt;
tid_mqtt = rt_thread_create(
"report_data",
report_data,
RT_NULL,
2048,
17,
10);
if (tid_mqtt == RT_NULL) {
return -RT_ERROR;
}
rt_thread_startup(tid_mqtt);
return RT_EOK;
}
INIT_APP_EXPORT(mqtt_report_data);
MQTT测试工具
https://mqttx.app/zh