一、开发环境搭建
1. 开发平台
- Windows 10
- WSL-Ubuntu-20.04
2. 适配 OpenHarmony 的 xr806 SDK
- 使用 repo + https 从 gitee 获取源码
repo init -u https://gitee.com/openharmony-sig/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify -m devboard_xr806.xml
repo sync -c
repo forall -c 'git lfs pull'
- OpenHarmony_1.0.1_release 分支里的 devboard_xr806.xml 中,跟 xr806 相关的部分仓库路径已经失效,所以需要从临时仓库获取xr806的代码
# device/xradio
cd device
git clone https://gitee.com/moldy-potato-chips/devboard_device_allwinner_xr806 xradio
# vendor/xradio
cd vendor
git clone https://gitee.com/moldy-potato-chips/devboard_vendor_allwinner_xr806 xradio
3. 工具链、LLVM、hb以及其他必要的库和工具,参考鸿蒙的开发文档
4. 遇到的问题:
在 WSL 中编译时,遇到了 mkimage 程序无法执行的问题,原因是 mkimage 是 32-bit的程序,最终按照一篇文章的方法解决了该问题,文章链接如下:
https://www.cnblogs.com/TatuCz/p/10330820.html
二、实现思路
1. 所需硬件或者服务
- 米家蓝牙温湿度计2代
- XR806开发板
- 阿里云物联网平台
2. 实现框图
3. 程序实现流程
三、代码实现
1. 主程序以及头文件
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "mqtt_client.h"
#include "net/wlan/wlan.h"
#include "net/mqtt/MQTTClient-C/MQTTClient.h"
#include <zephyr/types.h>
#include <ble/sys/byteorder.h>
#include <zephyr.h>
#include <settings/settings.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/conn.h>
#include <bluetooth/uuid.h>
#include <bluetooth/gatt.h>
void TempsensorBleMain(void)
{
wifi_init();
OS_Sleep(10);
mqtt_thread_init();
mqtt_init();
ble_init();
}
SYS_RUN(TempsensorBleMain);
2. 连接 WLAN AP
/* Wifi config */
#define WIFI_SSID "your_ssid"
#define WIFI_PSK "your_password"
static void wifi_init(void)
{
printf("Enable Wifi STA mode...\n");
/* switch to sta mode */
net_switch_mode(WLAN_MODE_STA);
/* set ssid and password to wlan, use WPA2|WPA3 compatible mode to connect AP. */
wlan_sta_set(WIFI_SSID, strlen(WIFI_SSID), WIFI_PSK);
/* start scan and connect to ap automatically */
wlan_sta_enable();
}
3. 连接阿里云 MQTT 服务
/* MQTT config */
#define MQTT_HOST "iot-as-mqtt.cn-shanghai.aliyuncs.com"
#define MQTT_PORT "1883"
#define MQTT_CLIENTID "xxxxxxxx|securemode=2,signmethod=hmacsha256,timestamp=2524608000000|"
#define MQTT_USERNAME "xxxxxxxx"
#define MQTT_PASSWORD "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#define MQTT_KEEPALIVE 30
#define MQTT_SSL 0
#define MQTT_CLEAN 0
#define MQTT_SUBSCRIBE_TOPIC "/xxxxxxxx/xr806_ble/user/get"
#define MQTT_PUBLISH_TOPIC "/sys/xxxxxxxx/xr806_ble/thing/event/property/post"
#define MQTT_BUF_SIZE (1024)
typedef enum {
MQTT_CMD_CONNECT,
MQTT_CMD_DISCONNECT,
MQTT_CMD_SUBSCRIBE,
MQTT_CMD_UNSUBSCRIBE,
MQTT_CMD_PUBLISH,
MQTT_CMD_EXIT
} MQTT_CMD;
struct mqtt_msg {
MQTT_CMD type;
void *data;
int data_len;
};
struct publish_info {
int qos;
int retain;
char topic[128];
char message[256];
};
struct subscribe_info {
int qos;
char topic[128];
};
struct unsubscribe_info {
char topic[128];
};
struct cmd_mqtt_common {
int ssl;
int alive;
int clean;
int will_qos;
int will_retain;
char *will_topic;
char *will_message;
char *username;
char *password;
char port[8];
char host[128];
char client_id[128];
char *sub_topic[MAX_MESSAGE_HANDLERS];
OS_Thread_t thread;
OS_Queue_t queue;
};
static struct cmd_mqtt_common cmd_mqtt;
static void mqtt_msg_cb(MessageData *data)
{
printf("[topic: %.*s] %.*s\n", data->topicName->lenstring.len,
data->topicName->lenstring.data, data->message->payloadlen,
(char *)data->message->payload);
}
static int mqtt_cmd_connect_handler(Client *client, Network *network,
void *data, int data_len)
{
int ret;
unsigned char *send_buf = NULL;
unsigned char *recv_buf = NULL;
MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
send_buf = malloc(MQTT_BUF_SIZE);
if (send_buf == NULL) {
printf("malloc fail.\n");
return -1;
}
recv_buf = malloc(MQTT_BUF_SIZE);
if (recv_buf == NULL) {
printf("malloc fail.\n");
goto err;
}
NewNetwork(network);
MQTTClient(client, network, 6000, send_buf, MQTT_BUF_SIZE, recv_buf,
MQTT_BUF_SIZE);
if (cmd_mqtt.ssl) {
/* this test has no ca cert, no client cert, no client pk, no client pwd */
ret = TLSConnectNetwork(network, cmd_mqtt.host, cmd_mqtt.port, NULL, 0,
NULL, 0, NULL, 0, NULL, 0);
if (ret != 0) {
printf("Return code from network ssl connect is -0x%04x\n", -ret);
goto err;
}
} else {
ret = ConnectNetwork(network, cmd_mqtt.host, atoi(cmd_mqtt.port));
if (ret != 0) {
printf("Return code from network connect is %d\n", ret);
goto err;
}
}
connectData.clientID.cstring = cmd_mqtt.client_id;
connectData.keepAliveInterval = cmd_mqtt.alive;
connectData.cleansession = cmd_mqtt.clean;
connectData.MQTTVersion = 4; //Version of MQTT 3.1.1
if (cmd_mqtt.will_topic && cmd_mqtt.will_message) {
connectData.willFlag = 1;
connectData.will.topicName.cstring = cmd_mqtt.will_topic;
connectData.will.message.cstring = cmd_mqtt.will_message;
connectData.will.retained = cmd_mqtt.will_retain;
connectData.will.qos = cmd_mqtt.will_qos;
}
if (cmd_mqtt.username) {
connectData.username.cstring = cmd_mqtt.username;
}
if (cmd_mqtt.password) {
connectData.password.cstring = cmd_mqtt.password;
}
ret = MQTTConnect(client, &connectData);
if (ret != 0) {
printf("Return code from MQTT connect is %d\n", ret);
network->disconnect(network);
goto err;
}
printf("MQTT connect success.\n");
return 0;
err:
free(send_buf);
free(recv_buf);
return -1;
}
static int mqtt_cmd_disconnect_handler(Client *client, Network *network,
void *data, int data_len)
{
int i;
int ret;
ret = MQTTDisconnect(client);
if (ret != 0) {
printf("Return code from MQTT disconnect is %d\n", ret);
network->disconnect(network);
return -1;
}
network->disconnect(network);
free(client->buf);
free(client->readbuf);
for (i = 0; i < MAX_MESSAGE_HANDLERS; i++) {
free(cmd_mqtt.sub_topic[i]);
cmd_mqtt.sub_topic[i] = NULL;
}
printf("MQTT disconnect success.\n");
return 0;
}
static int mqtt_cmd_subscribe_handler(Client *client, Network *network,
void *data, int data_len)
{
int i;
int ret;
int topic_len;
struct subscribe_info *info = data;
topic_len = strlen(info->topic) + 1;
for (i = 0; i < MAX_MESSAGE_HANDLERS; i++) {
if (cmd_mqtt.sub_topic[i] == NULL) {
cmd_mqtt.sub_topic[i] = malloc(topic_len);
if (cmd_mqtt.sub_topic[i] == NULL) {
return -1;
}
memcpy(cmd_mqtt.sub_topic[i], info->topic, topic_len);
break;
}
}
if (i >= MAX_MESSAGE_HANDLERS) {
printf("Subscribe topic limit %d\n", MAX_MESSAGE_HANDLERS);
return -1;
}
ret = MQTTSubscribe(client, cmd_mqtt.sub_topic[i], info->qos, mqtt_msg_cb);
if (ret != 0) {
printf("Return code from MQTT subscribe is %d\n", ret);
free(cmd_mqtt.sub_topic[i]);
cmd_mqtt.sub_topic[i] = NULL;
return -1;
}
printf("MQTT subscribe success.\n");
return 0;
}
static int mqtt_cmd_unsubscribe_handler(Client *client, Network *network,
void *data, int data_len)
{
int i;
int ret;
struct unsubscribe_info *info = data;
ret = MQTTUnsubscribe(client, info->topic);
if (ret != 0) {
printf("Return code from MQTT unsubscribe is %d\n", ret);
return -1;
}
for (i = 0; i < MAX_MESSAGE_HANDLERS; i++) {
if (cmd_mqtt.sub_topic[i] != NULL &&
!strncmp(cmd_mqtt.sub_topic[i], info->topic, strlen(info->topic))) {
free(cmd_mqtt.sub_topic[i]);
cmd_mqtt.sub_topic[i] = NULL;
}
}
if (i >= MAX_MESSAGE_HANDLERS) {
printf("MQTT unsubscribe fail.No such topic\n");
return -1;
}
printf("MQTT unsubscribe success.\n");
return 0;
}
static int mqtt_cmd_publish_handler(Client *client, Network *network,
void *data, int data_len)
{
int ret;
MQTTMessage message;
struct publish_info *info = data;
message.qos = info->qos;
message.retained = info->retain;
message.payload = info->message;
message.payloadlen = strlen(info->message);
ret = MQTTPublish(client, info->topic, &message);
if (ret != 0) {
printf("Return code from MQTT publish is %d\n", ret);
return -1;
}
printf("MQTT publish success.\n");
return 0;
}
static void mqtt_client_task(void *arg)
{
int exit = 0;
int connected = 0;
OS_Status status;
struct mqtt_msg *msg;
Client client;
Network network;
while (!exit) {
status = OS_MsgQueueReceive(&cmd_mqtt.queue, (void **)&msg, 0);
if (status != OS_OK) {
if (connected) {
MQTTYield(&client, 3000);
}
OS_MSleep(50);
continue;
}
printf("msg type:%d\n", msg->type);
switch (msg->type) {
case MQTT_CMD_CONNECT:
memset(&client, 0, sizeof(Client));
memset(&network, 0, sizeof(Network));
mqtt_cmd_connect_handler(&client, &network, msg->data,
msg->data_len);
connected = 1;
break;
case MQTT_CMD_DISCONNECT:
mqtt_cmd_disconnect_handler(&client, &network, msg->data,
msg->data_len);
connected = 0;
break;
case MQTT_CMD_SUBSCRIBE:
mqtt_cmd_subscribe_handler(&client, &network, msg->data,
msg->data_len);
break;
case MQTT_CMD_UNSUBSCRIBE:
mqtt_cmd_unsubscribe_handler(&client, &network, msg->data,
msg->data_len);
break;
case MQTT_CMD_PUBLISH:
mqtt_cmd_publish_handler(&client, &network, msg->data,
msg->data_len);
break;
case MQTT_CMD_EXIT:
exit = 1;
break;
default:
break;
}
free(msg->data);
free(msg);
}
OS_ThreadDelete(&cmd_mqtt.thread);
}
/* MQTT Client Thread */
static void mqtt_thread_init(void)
{
memset(&cmd_mqtt, 0, sizeof(cmd_mqtt));
if (OS_MsgQueueCreate(&cmd_mqtt.queue, 4) != OS_OK) {
printf("create queue failed\n");
return;
}
printf("mqtt msgqueue successed\n");
if (OS_ThreadCreate(&cmd_mqtt.thread,
"mqtt client",
mqtt_client_task,
NULL,
OS_THREAD_PRIO_APP,
(6 * 1024)) != OS_OK) {
printf("create thread failed\n");
OS_MsgQueueDelete(&cmd_mqtt.queue);
return;
}
}
static void mqtt_init(void)
{
OS_Status status;
struct mqtt_msg *msg;
struct subscribe_info *info;
/* MQTT configuration init */
strcpy(cmd_mqtt.host, MQTT_HOST);
strcpy(cmd_mqtt.port, MQTT_PORT);
strcpy(cmd_mqtt.client_id, MQTT_CLIENTID);
cmd_mqtt.username = MQTT_USERNAME;
cmd_mqtt.password = MQTT_PASSWORD;
cmd_mqtt.alive = MQTT_KEEPALIVE;
cmd_mqtt.ssl = MQTT_SSL;
cmd_mqtt.clean = MQTT_CLEAN;
/* Send 'Connect' message to MQTT thread */
msg = malloc(sizeof(struct mqtt_msg));
if (msg == NULL) {
return;
}
memset(msg, 0, sizeof(struct mqtt_msg));
msg->type = MQTT_CMD_CONNECT;
msg->data = NULL;
msg->data_len = 0;
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
if (status != OS_OK) {
free(msg);
return;
}
/* Send 'Subscribe' message to MQTT thread */
info = malloc(sizeof(struct subscribe_info));
if (info == NULL) {
return;
}
memset(info, 0, sizeof(struct subscribe_info));
info->qos = 0;
strcpy(info->topic, MQTT_SUBSCRIBE_TOPIC);
msg = malloc(sizeof(struct mqtt_msg));
if (msg == NULL) {
free(info);
return;
}
memset(msg, 0, sizeof(struct mqtt_msg));
msg->type = MQTT_CMD_SUBSCRIBE;
msg->data = info;
msg->data_len = sizeof(struct subscribe_info);
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
if (status != OS_OK) {
free(info);
free(msg);
return;
}
}
/* Publish Temperature/Humidity/Power to MQTT */
static void mqtt_publish_data(uint16_t temperature, uint16_t humidity, uint16_t power)
{
OS_Status status;
struct mqtt_msg *msg;
struct publish_info *info;
info = malloc(sizeof(struct publish_info));
if (info == NULL) {
return;
}
memset(info, 0, sizeof(struct publish_info));
info->qos = 0;
info->retain = 0;
strcpy(info->topic, MQTT_PUBLISH_TOPIC);
sprintf(info->message, "{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"Temperature\":{\"value\":%.2f}, \"Humidity\": {\"value\": %d}, \"Power\": {\"value\": %d}},\"method\":\"thing.event.property.post\"}",
temperature / 100.0, humidity, power);
msg = malloc(sizeof(struct mqtt_msg));
if (msg == NULL) {
free(info);
return;
}
memset(msg, 0, sizeof(struct mqtt_msg));
msg->type = MQTT_CMD_PUBLISH;
msg->data = info;
msg->data_len = sizeof(struct publish_info);
status = OS_MsgQueueSend(&cmd_mqtt.queue, msg, OS_WAIT_FOREVER);
if (status != OS_OK) {
free(info);
free(msg);
return;
}
return;
}
4. 连接米家蓝牙温湿度计,读取数据并发送给MQTT任务
/* BLE config */
#define MIJIA_SENSOR_ADDR "A4:C1:38:0E:B4:AB (public)"
#define MIJIA_SENSOR_HANDLE 0x36
#define CENTRAL_PERIOD 10000 // 10 seconds
/* Global variables */
static struct bt_conn *default_conn;
static OS_Timer_t central_timer;
static struct bt_gatt_read_params read_params;
static void start_scan(void);
static void mqtt_publish_data(uint16_t temperature, uint16_t humidity, uint16_t power);
/* Data processor - Temperature, Humidity, Power */
static uint8_t read_func(struct bt_conn *conn, uint8_t err,
struct bt_gatt_read_params *params,
const void *data, uint16_t length)
{
uint32_t i;
uint16_t temperature, humidity, power;
printf("Read complete: err 0x%02x length %u\n", err, length);
if (length == 5) {
/* Print raw data */
printf("Read Value:");
for (i = 0; i < length; i++) {
printf("%02x", ((const uint8_t *)data)[i]);
}
printf("\n");
/* Print processed data */
temperature = (((const uint8_t *)data)[1] << 8) | ((const uint8_t *)data)[0];
humidity = ((const uint8_t *)data)[2];
power = (((const uint8_t *)data)[4] << 8) | ((const uint8_t *)data)[3];
printf("Temperature: %.2f, Humidity: %d%%, Power: %dmV\n", temperature / 100.0, humidity, power);
/* Send data to mqtt thread */
mqtt_publish_data(temperature, humidity, power);
}
if (!data) {
(void)memset(params, 0, sizeof(*params));
return BT_GATT_ITER_STOP;
}
return BT_GATT_ITER_CONTINUE;
}
/* Read Temperature/Humidity/Power periodically */
static void central_timer_cb(void *arg)
{
int err;
if (!default_conn) {
printf("Not connected\n");
return;
}
if (read_params.func) {
printf("Read ongoing\n");
return;
}
read_params.func = read_func;
read_params.handle_count = 1;
read_params.single.handle = MIJIA_SENSOR_HANDLE;
read_params.single.offset = 0U;
err = bt_gatt_read(default_conn, &read_params);
if (err) {
printf("Read failed (err %d)\n", err);
} else {
printf("Read pending\n");
}
return;
}
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
int err;
struct bt_conn_info info;
err = bt_conn_get_info(conn, &info);
if (err) {
printf("Failed to get info\n");
return ;
}
printf("[H] Disconnected %s reason 0x%02x \n", bt_addr_str_real(&info.le.dst->a), reason);
if (default_conn != conn) {
return ;
}
default_conn = NULL;
start_scan();
}
static void connected(struct bt_conn *conn, uint8_t conn_err)
{
bt_addr_le_t rpa = {0};
int result;
struct bt_conn_info info;
OS_Status status;
if (conn_err) {
printf("[H] Connectionfailed reason %u\n", conn_err);
default_conn = NULL;
start_scan();
} else {
result = bt_conn_get_info(conn, &info);
if (result) {
printf("Failed to get info\n");
return ;
}
memcpy(&rpa, &info.le.src, sizeof(bt_addr_le_t));
printf("[H] Connected!! \n");
printf("========== Connection Parameter ==========\n");
printf("= Remote Address %s\n", bt_addr_str_real(&rpa.a));
printf("= Internval %d\n", info.le.interval);
printf("= Latency %d\n", info.le.latency);
printf("= Timeout %d\n", info.le.timeout);
printf("==========================================\n");
if (conn == default_conn) {
status = OS_TimerCreate(¢ral_timer, OS_TIMER_PERIODIC, central_timer_cb, NULL, CENTRAL_PERIOD);
if (status != OS_OK) {
printk("central timer create error (err 0x%02x)\n", status);
return ;
}
OS_TimerStart(¢ral_timer);
}
}
}
static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected,
};
static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
struct net_buf_simple *ad)
{
int err;
char dev[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(addr, dev, sizeof(dev));
printf("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n",
dev, type, ad->len, rssi);
/* Stop scanning and connect to MIJIA sensor while MIJIA sensor is found */
if (!strcmp(dev, MIJIA_SENSOR_ADDR)) {
err = bt_le_scan_stop();
if (err) {
printf("Stop LE scan failed (err %d)\n", err);
return;
}
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &default_conn);
if (err) {
printf("Create connection failed (err %d)\n", err);
start_scan();
return;
}
}
}
static void start_scan(void)
{
int err;
err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
if (err) {
printf("Scanning failed to start (err %d)\n", err);
return ;
}
printf("Scanning successfully started\n");
}
static void bt_ready(int err)
{
if (err) {
printf("Bluetooth init failed (err %d)\n", err);
return ;
}
err = settings_load();
if (err) {
printf("Settings load failed (err %d)", err);
return;
}
printf("Settings loaded");
bt_conn_cb_register(&conn_callbacks);
printf("Bluetooth initialized\n");
start_scan();
}
static void ble_init(void)
{
int err;
err = bt_ctrl_enable();
if (err) {
printf("Bluetooth Controller init failed (err %d)", err);
return;
}
err = bt_enable(bt_ready);
if (err) {
printf("Bluetooth init failed (err %d)", err);
}
return;
}
四、调试记录
=====================================================================
Hello! OpenHarmony!
System tag : OpenHarmony 1.1.2_LTS
====================================================================
use default flash chip mJedec 0x0
[FD I]: mode: 0x10, freq: 96000000Hz, drv: 0
[FD I]: jedec: 0x0, suspend_support: 1
mode select:e
wlan information ===================================================
firmware:
version : R0-XR_C07.08.52.65_02.84 May 27 2021 11:41:33-Y02.84
buffer : 8
driver:
version : XR_V02.05
mac address:
in use : 4c:a8:89:8c:54:01
in use : 4c:a8:89:8c:54:02
====================================================================
wlan mode:a
[VFS INF] SPIFFS mount success.
platform information ===============================================
XR806 SDK v1.2.0 Jan 3 2022 20:37:31
heap space [0x229cc8, 0x247c00), size 122680
cpu clock 160000000 Hz
HF clock 40000000 Hz
sdk option:
XIP : enable
INT LF OSC : enable
SIP flash : enable
mac address:
efuse : 80:74:84:21:53:51
in use : 4c:a8:89:8c:54:01
====================================================================
Enable Wifi STA mode...
[net INF] no need to switch wlan mode 0
console init success
en1: Trying to associate with 2e:15:e1:26:de:c4 (SSID='xxxxxxxx' freq=2412 MHz)
[net INF] msg <wlan scan success>
en1: Associated with 2e:15:e1:26:de:c4
en1: WPA: Key negotiation completed with 2e:15:e1:26:de:c4 [PTK=CCMP GTK=CCMP]
en1: CTRL-EVENT-CONNECTED - Connection to 2e:15:e1:26:de:c4 completed [id=0 id_str=]
[net INF] msg <wlan connected>
[net INF] netif is link up
[net INF] start DHCP...
[net INF] netif (IPv4) is up
[net INF] address: 192.168.6.189
[net INF] gateway: 192.168.6.1
[net INF] netmask: 255.255.255.0
[net INF] msg <network IPv6 state>
[net INF] IPv6 addr state change: 0x0 --> 0x1
[net INF] msg <>
mqtt msgqueue successed
ble controller open
version : 9.1.19
build sha1 : v9.1.19-20210601
build date : Jun 1 2021
build time : 19:32:17
platform : xr806
msg type:0
ble rf_init done!
BLE INIT ALL DONE!
BT Coex. Init. OK.
== XRadio BLE HOST V2.5.0 ==
hiview init success.[bt] [WRN] set_flow_control: Controller to host flow control not supported
WAR drop=1117, fctl=0x00d0.
[bt] [INF] bt_init: No ID address. App must call settings_load()
[bt] [INF] bt_dev_show_info: Identity: CF:BD:6B:5B:36:BD (random)
[bt] [INF] bt_dev_show_info: HCI: version 5.0 (0x09) revision 0x0113, manufacturer 0x063d
[bt] [INF] bt_dev_show_info: LMP: version 5.0 (0x09) subver 0x0113
Settings loadedBluetooth initialized
*************************************************
[RandomAddress 6D:20:CA:CE:17:E9 ]
*************************************************
Scanning successfully started
[DEVICE]: 24:95:D5:62:F4:5E (random), AD evt type 3, AD data len 31, RSSI -44
MQTT connect success.
msg type:2
MQTT subscribe success.
[DEVICE]: A4:C1:38:F6:A5:33 (public), AD evt type 0, AD data len 19, RSSI -77
[DEVICE]: A4:C1:38:0E:B4:AB (public), AD evt type 0, AD data len 19, RSSI -69
[H] Connected!!
========== Connection Parameter ==========
= Remote Address 21:69:E0:00:20:F0
= Internval 32
= Latency 0
= Timeout 400
==========================================
Read pending
Read complete: err 0x00 length 5
Read Value:5d0637830a
Temperature: 16.29, Humidity: 55%, Power: 2691mV
Read complete: err 0x00 length 0
msg type:4
MQTT publish success.
Read pending
Read complete: err 0x00 length 5
Read Value:5d0637830a
Temperature: 16.29, Humidity: 55%, Power: 2691mV
Read complete: err 0x00 length 0
msg type:4
MQTT publish success.
Read pending
Read complete: err 0x00 length 5
Read Value:5d0637830a
Temperature: 16.29, Humidity: 55%, Power: 2691mV
Read complete: err 0x00 length 0
msg type:4
MQTT publish success.
Read pending
Read complete: err 0x00 length 5
Read Value:5a0637830a
Temperature: 16.26, Humidity: 55%, Power: 2691mV
Read complete: err 0x00 length 0
msg type:4
MQTT publish success.
五、阿里云数据显示
- 刚开始记录数据时
- 过夜记录数据