【XR806开发板试用】基于MQTT与Cjson库的花式点灯

一、项目介绍

久闻openharmony大名,一直没有机会接触,感谢极术社区和全志社区的这次活动,让我能够了解并上手这个系统。

openhamony 1.1的内核是基于liteos内核系统进行构建的,liteos作为物联网系统,结合xr806小型开发板,特别适合用于构建iot项目,同时openharmony拥有丰富的中间件,使得开发变得容易,因此考虑结合mqtt与cjson这两个iot开发过程中必不可少的两项技术来进行花式点灯。下图是xr806的配置图。

在这里插入图片描述

二、环境准备

1、mqtt系统搭建

MQTT协议作为一种轻量、简单、开放和易于实现的协议,由服务端与客户端构成,客户端负责发布与订阅消息,服务端则负责完成客户端的管理与设备间的信息交互。本项目中就是通过云服务器来实现pc与开发板间的交互。

1.1、客户端(开发板)

本项目使用所提供的开发包中的mqtt例程进行改写的,该例程调用Eclipse Paho MQTT开发库进行编写,使用MQTTClient-C库,将开发板作为客户端。可以在该目录下找到例程。

harmony\device\xradio\xr806\xr\_skylark\project\example\mqtt

1.2、客户端(PC)

本项目中使用MQTT.fx软件来作为PC的客户端,MQTT.fx是一款也是基于Eclipse Paho库的软件,通过配置后与服务端进行交互。主界面如下图所示,通过添加服务器的地址来与服务器进行交互。
在这里插入图片描述
在这里插入图片描述

.png")

1.3、服务端

本项目中服务端使用阿里云服务器进行mqtt服务端搭建,有云服务器的小伙伴可以参考这篇文章。

https://blog.csdn.net/qq\_45168614/article/details/107183583

没有云服务可以使用阿里云或者腾讯云的提供的物联网服务,也提供了mqtt服务器的功能,并且功能更加强大。

mqtt服务端的界面如下图所示。
在这里插入图片描述
.png")

三、代码编写

main.c代码如下:

/*
 * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the
 *       distribution.
 *    3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
 *       its contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include <string.h>
#include "wifi_device.h"
#include "wifi_hotspot.h"
#include "cjson/cJSON.h"
#include "common/framework/platform_init.h"
#include "net/wlan/wlan.h"
#include "common/framework/net_ctrl.h"
#include "net/mqtt/MQTTClient-C/MQTTClient.h"
#include "iot_gpio.h"                                                           //(8)

#define MQTT_DEMO_THREAD_STACK_SIZE (8 * 1024) /* ssl need more stack */
static OS_Thread_t mqtt_demo_thread;
static OS_Thread_t blink_thread;

static MQTTPacket_connectData mqtt_demo_connectData = MQTTPacket_connectData_initializer;
static Client mqtt_demo_client;
static Network mqtt_demo_network;

#define WIFI_DEVICE_CONNECT_AP_SSID "xtg2018" //填写wifi名称
#define WIFI_DEVICE_CONNECT_AP_PSK "xtg2018"  //填写wifi密码

#define MQTT_DEMO_CLIENT_ID "IOT control"
#define MQTT_DEMO_HOST_NAME "xxx.xxx.xxx.xxx" //填写mqtt服务器地址
#define MQTT_DEMO_PORT      "1883"
#define MQTT_DEMO_USERNAME  "easitmickly"     //填写mqtt用户名
#define MQTT_DEMO_PASSWORD  ""                //填写mqtt密码
#define MQTT_DEMO_TOPIC     "/vo84Hm3xbUj/xr806_senor_set0/data"
#define MQTT_DEMO_TOPIC2    "/vo84Hm3xbUj/xr806_senor_set1/data"
#define GPIO_ID_PA21 21

#define MQTT_DEMO_BUF_SIZE (2*1024)

#define MQTT_DEMO_MSG_TEXT "mqtt demo test"
static OS_Thread_t g_main_thread;

void wifi_scan_connect(){
    if(WIFI_SUCCESS != EnableWifi()){
        printf("Error:wifi enable fail!\n");
        return;
    }
    if(WIFI_SUCCESS != Scan()){
        printf("Error:wifi scan fail!\n");
    }
    printf("WIFI SCAN STARTED!\n");
    OS_Sleep(3);

    WifiScanInfo scan_result[30];
    unsigned int scan_num = 30;

    if(WIFI_SUCCESS != GetScanInfoList(scan_result, &scan_num)){
        printf("Error: get scan result fail!\n");
        return;
    }
    printf("Scan successful,you've got:\n");
    for(int i = 0;i < scan_num;i++){
        printf("SSID: %s ",scan_result[i].ssid);
        printf("RSSI: %d",scan_result[i].rssi);
    }
    printf("Scan End \n");
    const char ssid_want_connect[] = WIFI_DEVICE_CONNECT_AP_SSID;
    const char psk[] = WIFI_DEVICE_CONNECT_AP_PSK;
    printf("Connecting...");
    if(WIFI_STA_ACTIVE == IsWifiActive()){
        printf("Wifi is active.\n");
    }
    OS_Sleep(1);
    WifiDeviceConfig config = {0};
    int netId = 0;
    int i;
    for(i = 0;i < scan_num;i++){
        if(0 == strcmp(scan_result[i].ssid, ssid_want_connect)){
            memcpy(config.ssid, scan_result[i].ssid, WIFI_MAX_SSID_LEN);
            memcpy(config.bssid, scan_result[i].bssid, WIFI_MAC_LEN);
            strcpy(config.preSharedKey, psk);
            config.securityType = scan_result[i].securityType;
            config.wapiPskType = WIFI_PSK_TYPE_ASCII;
            config.freq = scan_result[i].frequency;
            break;
        }
    }
    if(i >= scan_num){
        printf("Error: No SSID SET FOUND!\n");
        return;
    }
    printf("Found Correct SSID in Scan List!\n");
    if(WIFI_SUCCESS != AddDeviceConfig(&config, &netId)){
        printf("Error: Add Device config failed!\n");
        return;
    }
    printf("Add Device Config successful!\n");
    if(WIFI_SUCCESS != ConnectTo(netId)){
        printf("Error: Connect to Wifi FAILED!\n");
        return;
    }
    printf("Connect to %s successful!\n",config.ssid);
    OS_Sleep(3);
}

static int mqtt_demo_init(void)
{
    char *send_buf;
    char *recv_buf;

    /* init client id */
    mqtt_demo_connectData.clientID.cstring = MQTT_DEMO_CLIENT_ID;
    /* init keep alive interval */
    mqtt_demo_connectData.keepAliveInterval = 30; // 30s
    /* enable session reuse */
    mqtt_demo_connectData.cleansession = 0;
    /* set mqtt version */
    mqtt_demo_connectData.MQTTVersion = 4; //Version of MQTT 3.1.1

    /* send/recv buffer must free when mqtt deinit */
    send_buf = malloc(MQTT_DEMO_BUF_SIZE);
    if (send_buf == NULL) {
        printf("no memory\n");
        return -1;
    }
    recv_buf = malloc(MQTT_DEMO_BUF_SIZE);
    if (recv_buf == NULL) {
        free(send_buf);
        printf("no memory\n");
        return -1;
    }

    /* init network */
    NewNetwork(&mqtt_demo_network);
    /* init mqtt client object */
    MQTTClient(&mqtt_demo_client, &mqtt_demo_network, 6000,
               (unsigned char *)send_buf, MQTT_DEMO_BUF_SIZE,
               (unsigned char *)recv_buf, MQTT_DEMO_BUF_SIZE);

    /**
     * set will function, when this client disconnect,
     * server will sent the message to every client in MQTT_DEMO_TOPIC
     */
    mqtt_demo_connectData.willFlag = 1;
    mqtt_demo_connectData.will.topicName.cstring = MQTT_DEMO_TOPIC;
    mqtt_demo_connectData.will.message.cstring = "I am disconnected";
    mqtt_demo_connectData.will.retained = 0;
    mqtt_demo_connectData.will.qos = 0;

    /* set username and password */
    mqtt_demo_connectData.username.cstring = MQTT_DEMO_USERNAME;
    mqtt_demo_connectData.password.cstring = MQTT_DEMO_PASSWORD;

    return 0;
}

static int mqtt_demo_connect(char *host_name, char *host_port)
{
    int ret = -1;

    /* need connect the server in tcp level first, if use ssl, use TLSConnectNetwork() */
    ret = ConnectNetwork(&mqtt_demo_network, host_name, atoi(host_port));
    if (ret != 0) {
        printf("mqtt connect faild, ret:%d, host:%s, port:%s\n", ret, host_name, host_port);
        goto exit;
    }

    /* if tcp level connected, then connect mqtt level */
    ret = MQTTConnect(&mqtt_demo_client, &mqtt_demo_connectData);
    if (ret != 0) {
        printf("mqtt connect faild, ret:%d\n", ret);
        /* disconnect the tcp level */
        mqtt_demo_network.disconnect(&mqtt_demo_network);
        goto exit;
    }
    printf("mqtt connected\n");

exit:
    return ret;
}

static void mqtt_demo_msg_cb(MessageData *data)
{
    printf("get a message, topic: %.*s, msg: %.*s\n", data->topicName->lenstring.len,
           data->topicName->lenstring.data, data->message->payloadlen,
           (char *)data->message->payload);
    parse_json((char *)data->message->payload);
}

void Led_blink(void *arg)
{
    int *pinter = (int *)arg;
    int inter = *pinter;
    printf("transport inter is %d\n", *pinter);
    while(1)
    {
        IoTGpioSetOutputVal(GPIO_ID_PA21, 0);
        OS_MSleep(1000 * inter);
        IoTGpioSetOutputVal(GPIO_ID_PA21, 1);
         OS_MSleep(1000 * inter);
    }
}

int parse_json(char *s)
{
    cJSON *root = cJSON_Parse(s);
    if(!root) {
        printf("get root faild !\n");
        return -1;
    }
     
    cJSON *js_list = cJSON_GetObjectItem(root, "list");
    if(!js_list) {
        printf("no list!\n");
        return -1;
    }
    printf("list type is %d\n",js_list->type);
     
    cJSON *pin = cJSON_GetObjectItem(js_list, "pin style");
    if(!pin) {
        printf("No pin style!\n");
        return -1;
    }
    printf("pin style is %s\n",pin->valuestring);
    
    cJSON *inter = cJSON_GetObjectItem(js_list, "inter");
    if(!inter) {
        printf("no inter!\n");
        return -1;
    }
    printf("inter is %d\n",inter->valueint);

    if(pin)
    {
        OS_ThreadDelete(&blink_thread);
        if (0 == strcmp(pin->valuestring, "open"))
        {
            IoTGpioSetOutputVal(GPIO_ID_PA21, 1);
        }
        else if(0 == strcmp(pin->valuestring, "close"))
        {
            IoTGpioSetOutputVal(GPIO_ID_PA21, 0);
        }
        else if(0 == strcmp(pin->valuestring, "blink"))
        {
            if(inter)
            {
                if(OS_ThreadCreate(&blink_thread, "BlinkThread", Led_blink, &inter->valueint, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
                {
                    printf("[ERR] Create BlinkThread Failed\n");
                }
            }
        }
        else
        {
            printf("unknown pin style\n");
        }
    }

    if(root)
    cJSON_Delete(root);
    return 0;
}

static int mqtt_demo_subscribe(char *topic)
{
    int ret = -1;

    if (mqtt_demo_client.isconnected) {
        /* set the message callback */
        ret = MQTTSubscribe(&mqtt_demo_client, topic, 0, mqtt_demo_msg_cb);
        if (ret != 0)
            printf("mqtt subscribe faild ret:%d\n", ret);
    }
    return ret;
}

static int mqtt_demo_unsubscribe(char *topic)
{
    int ret = -1;

    if (mqtt_demo_client.isconnected) {
        ret = MQTTUnsubscribe(&mqtt_demo_client, topic);
        if (ret != 0)
            printf("mqtt unsubscribe faild, ret:%d\n", ret);
    }
    return ret;
}

static int mqtt_demo_publish(char *topic, char *msg)
{
    int ret = -1;

    MQTTMessage message;

    memset(&message, 0, sizeof(message));
    message.qos = 0;
    message.retained = 0; /* disable retain the message in server */
    message.payload = msg;
    message.payloadlen = strlen(msg);

    ret = MQTTPublish(&mqtt_demo_client, topic, &message);
    if (ret != 0)
        printf("mqtt publish faild, ret:%d\n", ret);

    return ret;
}

static int mqtt_demo_disconnect(void)
{
    int ret = -1;

    if (mqtt_demo_client.isconnected) {
        /* need disconnect mqtt level first */
        ret = MQTTDisconnect(&mqtt_demo_client);
        if (ret != 0)
            printf("mqtt disconnect fail, ret:%d\n", ret);
        /* then disconnect tcp level */
        mqtt_demo_network.disconnect(&mqtt_demo_network);
    }

    return ret;
}

static void mqtt_demo_deinit(void)
{
    if (mqtt_demo_client.buf) {
        free(mqtt_demo_client.buf);
        mqtt_demo_client.buf = NULL;
    }
    if (mqtt_demo_client.readbuf) {
        free(mqtt_demo_client.readbuf);
        mqtt_demo_client.readbuf = NULL;
    }
}

static void mqtt_demo_fun(void *arg)
{
    int ret;
    int reconnect_times = 0;

    /* mqtt init */
    mqtt_demo_init();

    /* mqtt connect */
    ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
    if (ret != 0)
        goto exit;

    /* subscribe topic */
    ret = mqtt_demo_subscribe(MQTT_DEMO_TOPIC2);
    if (ret != 0)
        goto exit;

    while (1) {
        /* publish message to topic */
        mqtt_demo_publish(MQTT_DEMO_TOPIC, MQTT_DEMO_MSG_TEXT);
        ret = MQTTYield(&mqtt_demo_client, 300);
        if (ret != 0) {
            printf("mqtt yield err, ret:%d\n", ret);
reconnect:
            printf("mqtt reconnect\n");
            mqtt_demo_disconnect();
            ret = mqtt_demo_connect(MQTT_DEMO_HOST_NAME, MQTT_DEMO_PORT);
            if (ret != 0) {
                reconnect_times++;
                if (reconnect_times > 5)
                    goto exit;
                OS_MSleep(5000); //5s
                goto reconnect;
            }
        }
        OS_MSleep(1000); //1s
    }

exit:
    mqtt_demo_unsubscribe(MQTT_DEMO_TOPIC2);
    mqtt_demo_disconnect();
    mqtt_demo_deinit();

    OS_ThreadDelete(&mqtt_demo_thread);
}

static void MainThread(void *arg)
{
    wifi_scan_connect();
}

int main(void)
{
    IoTGpioInit(GPIO_ID_PA21);
    IoTGpioSetDir(GPIO_ID_PA21, IOT_GPIO_DIR_OUT);

    if(OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
    {
        printf("[ERR] Create MainThread Failed\n");
    }

     OS_MSleep(10000); //10s

    if (OS_ThreadCreate(&mqtt_demo_thread,
                            "mqtt_demo_thread",
                            mqtt_demo_fun,
                            (void *)NULL,
                            OS_THREAD_PRIO_APP,
                            MQTT_DEMO_THREAD_STACK_SIZE) != OS_OK) {
        printf("[ERR] Create MainThread Failed\n");
    }

}


SYS_RUN(main);

build文件如下:

import("//device/xradio/xr806/liteos_m/config.gni")

static_library("app_mqtt") {
   configs = []

   sources = [
      "main.c",
   ]

   cflags = board_cflags

   include_dirs = board_include_dirs
   include_dirs += [
      ".",
      "//kernel/liteos_m/kernel/arch/include",
      "//base/iot_hardware/peripheral/interfaces/kits",
      "//utils/native/lite/include",
      "//foundation/communication/wifi_lite/interfaces/wifiservice",
      "//device/xradio/xr806/xr_skylark/include/cjson",
      "//device/xradio/xr806/xr_skylark/project"
   ]
}

main.c代码使用mqtt例程与wifi例程中提供的函数,并调用cjson库。

    if(OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
    {
        printf("[ERR] Create MainThread Failed\n");
    }

     OS_MSleep(10000); //10s

    if (OS_ThreadCreate(&mqtt_demo_thread,
                            "mqtt_demo_thread",
                            mqtt_demo_fun,
                            (void *)NULL,
                            OS_THREAD_PRIO_APP,
                            MQTT_DEMO_THREAD_STACK_SIZE) != OS_OK) {
        printf("[ERR] Create MainThread Failed\n");
    }

main函数中首先对led端口进行初始化,然后初始化wifi,延时10s使得wifi连接网络,最后进行mqtt连接。

int parse_json(char *s)
{
    cJSON *root = cJSON_Parse(s);
    if(!root) {
        printf("get root faild !\n");
        return -1;
    }
     
    cJSON *js_list = cJSON_GetObjectItem(root, "list");
    if(!js_list) {
        printf("no list!\n");
        return -1;
    }
    printf("list type is %d\n",js_list->type);
     
    cJSON *pin = cJSON_GetObjectItem(js_list, "pin style");
    if(!pin) {
        printf("No pin style!\n");
        return -1;
    }
    printf("pin style is %s\n",pin->valuestring);
    
    cJSON *inter = cJSON_GetObjectItem(js_list, "inter");
    if(!inter) {
        printf("no inter!\n");
        return -1;
    }
    printf("inter is %d\n",inter->valueint);

    if(pin)
    {
        if (0 == strcmp(pin->valuestring, "open"))
        {
            IoTGpioSetOutputVal(GPIO_ID_PA21, 1);
        }
        else if(0 == strcmp(pin->valuestring, "close"))
        {
            IoTGpioSetOutputVal(GPIO_ID_PA21, 0);
        }
        else if(0 == strcmp(pin->valuestring, "blink"))
        {
            if(inter)
            {
                if(OS_ThreadDelete(&blink_thread))
                {
                    printf("[ERR] Create OS_ThreadDelete BlinkThread Failed\n");
                }
                if(OS_ThreadCreate(&blink_thread, "BlinkThread", Led_blink, &inter->valueint, OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK)
                {
                    printf("[ERR] Create BlinkThread Failed\n");
                }
            }
        }
        else
        {
            printf("unknown pin style\n");
        }
    }

    if(root)
    cJSON_Delete(root);
    return 0;
}

parse\_json函数对接受到的json消息进行解析,消息体中包含两个参数:点灯类型和跳动间隔。消息体如下:

{“list”:{“pin style”:“blink”,“inter”:3}}

pin style有三个参数:open、close和blink,而inter参数则在blink状态生效。当pin style参数为blink时,将进入Led\_blink线程,循环点灯。

四、效果展示

服务端展示的两个客户端状态如图所示:
在这里插入图片描述
.png")

pc端收到的开发板消息如下图:
在这里插入图片描述
.png")

开发板显示消息如下:

====================================================================
    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


[2022-01-22 13:28:55.546]# RECV ASCII>

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        : 0c:6d:88:3d:34:01
    in use        : 0c:6d:88:3d:34:02
====================================================================

wlan mode:a
[VFS INF] SPIFFS mount success.

platform information ===============================================
XR806 SDK v1.2.0  Jan 19 2022 20:05:38

heap space [0x229344, 0x247c00), size 125116

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:05:b9:0e
    in use        : 0c:6d:88:3d:34:01
====================================================================

IoTGpioInit port0, pin21
[net INF] no need to switch wlan mode 0
WIFI SCAN STARTED!


[2022-01-22 13:28:56.088]# RECV ASCII>
[net INF] msg <wlan scan success>


[2022-01-22 13:28:58.579]# RECV ASCII>
Scan successful,you've got:
SSID: xtgy2018 RSSI: 122SSID: LUCIO_Wi-Fi5 RSSI: 42SSID: ChinaNet-KFVB6L RSSI: 38SSID: TP-LINK_shc RSSI: 34SSID: CMCC-V5xN RSSI: 32SSID: ziroom501 RSSI: 26SSID: ChinaNet-UnjV RSSI: 22SSID: ChinaNet-aDhv RSSI: 6SSID: CMCC-FSU6 RSSI: -2SSID: 201 RSSI: -6SSID:  RSSI: -16SSID: CMCC-d5Nj RSSI: -20Scan End 
Connecting...Wifi is active.


[2022-01-22 13:28:59.593]# RECV ASCII>
Found Correct SSID in Scan List!
Add Device Config successful!
[net INF] no need to switch wlan mode 0


[2022-01-22 13:29:00.354]# RECV ASCII>
en1: Trying to associate with cc:2d:21:86:4b:01 (SSID='xtg2018' freq=2437 MHz)
Connect to xtgy2018 successful!


[2022-01-22 13:29:00.512]# RECV ASCII>
en1: Associated with cc:2d:21:86:4b:01
en1: WPA: Key negotiation completed with cc:2d:21:86:4b:01 [PTK=CCMP GTK=TKIP]
en1: CTRL-EVENT-CONNECTED - Connection to cc:2d:21:86:4b:01 completed [id=0 id_str=]
[net INF] msg <wlan connected>
[net INF] netif is link up
[net INF] start DHCP...


[2022-01-22 13:29:01.401]# RECV ASCII>
[net INF] netif (IPv4) is up
[net INF] address: 192.168.0.128
[net INF] gateway: 192.168.0.1
[net INF] netmask: 255.255.255.0
[net INF] msg <network IPv6 state>


[2022-01-22 13:29:02.398]# RECV ASCII>
[net INF] IPv6 addr state change: 0x0 --> 0x1
[net INF] msg <>


[2022-01-22 13:29:04.396]# RECV ASCII>
WAR drop=1117, fctl=0x00d0.


[2022-01-22 13:29:05.536]# RECV ASCII>
hiview init success.
console init success


[2022-01-22 13:29:05.631]# RECV ASCII>
mqtt connected


[2022-01-22 13:29:14.784]# RECV ASCII>
get a message, topic: /vo84Hm3xbUj/xr806_senor_set1/data, msg: {"list":{"pin style":"blink","inter":3}}
list type is 64
pin style is blink
inter is 3
[os E] OS_ThreadDelete():110, handle 0
transport inter is 3

可以从消息中看出已经连接上了wifi与mqtt服务器,并接受到了从pc端发送的消息,视频演示如下:

https://www.bilibili.com/video/BV12q4y1A7zM/?aid=550751435&cid=489852768&page=1

可以看出已经达到想要的效果。

感谢阅读!感兴趣可以交流,谢谢。~~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/596255.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

美团KV存储squirrel和Celler学习

文章目录 美团在KV存储squirrel优化和改进在水平方向1、对Gossip协议进行优化 在垂直扩展方面1、forkless RDB数据复制优化2、使用多线程&#xff0c;充分利用机器的多核能力 在高可用方面 美团持久化kv存储celler优化和改进水平扩展优化1、使用bulkload进行数据导入2、线程模型…

Adobe系列软件安装

双击解压 先运行Creative_Cloud_Set_Up.exe。 完毕后&#xff0c;运行AdobeGenP.exe 先Path&#xff0c;选路径&#xff0c;如 C:\Program Files\Adobe 后Search 最后Patch。 关闭软件&#xff0c;修图&#xff01;

电力能源箱3D可视化:开启智慧能源管理新篇章

随着科技的不断进步&#xff0c;电力能源箱的管理与维护逐渐向着智能化、可视化的方向发展。3D可视化技术的崛起&#xff0c;不仅极大地提升了能源管理的效率&#xff0c;更以其直观、生动的特点&#xff0c;引领着电力能源管理领域迈入了一个全新的时代。 电力能源箱作为电力系…

解决一个朋友的nbcio-boot的mysql数据库问题

1、原先安装mysql5.7数据库&#xff0c;导入我的项目里的带数据有报错信息 原因不明 2、只能建议用docker进行msyql5.7的安装 如下&#xff0c;可以修改成自己需要的信息 docker run -p 3306:3306 --name mastermysql -v /home/mydata/mysql/data:/var/lib/mysql -e MYSQL_R…

为什么感觉没有效果

以前在辅导小儿作业的时候&#xff0c;我会在常用的搜索引擎里去寻找答案&#xff0c;一般情况下都能解决问题。 但是最近一段时间&#xff0c;我发现&#xff0c;搜索引擎搜出来的结果还没有利用短视频搜出来的答案更全面&#xff0c;短视频软件不仅可以显示AI整理出来的答案…

js api part4

其他事件 页面加载事件 外部资源&#xff08;如图片、外联CSS和JavaScript等&#xff09;加载完毕时触发的事件 原因&#xff1a;有些时候需要等页面资源全部处理完了做一些事情&#xff0c;老代码喜欢把 script 写在 head 中&#xff0c;这时候直接找 dom 元素找不到。 事件…

2010-2022年上市公司彭博ESG披露评分、分项得分数据

2010-2022年上市公司彭博ESG披露评分、分项得分数据 1、时间&#xff1a;2010-2022年 2、来源&#xff1a;Bloomberg ESG 指数 3、指标&#xff1a;股票代码、股票简称、年份、ESG披露评分、环境披露评分、社会信息披露评分、治理披露评分 4、范围&#xff1a;上市公司 5、…

OpenNJet:下一代云原生应用引擎

OpenNJet&#xff1a;下一代云原生应用引擎 前言一、技术架构二、新增特性1. 透明流量劫持2. 熔断机制3. 遥测与故障注入 三、Ubuntu 发行版安装 OpentNJet1. 添加gpg 文件2. 添加APT 源3. 安装及启动4. 验证 总结 前言 OpenNJet&#xff0c;是一款基于强大的 NGINX 技术栈构建…

Java苍穹外卖04-

一、缓存菜品 1.问题说明 2.实现思路 就是点击到这个分类的时候就可以展示相应的菜品数据 3.代码实现 在user的菜品的contoller中&#xff1a;增加判断redis中是否存在所需数据&#xff0c;不存在添加&#xff0c;存在直接取得 这里注意&#xff1a;你放进去用的是List<Di…

【Osek网络管理测试】[TG3_TC3]tSleepRequestMin_L

&#x1f64b;‍♂️ 【Osek网络管理测试】系列&#x1f481;‍♂️点击跳转 文章目录 1.环境搭建2.测试目的3.测试步骤4.预期结果5.测试结果 1.环境搭建 硬件&#xff1a;VN1630 软件&#xff1a;CANoe 2.测试目的 验证DUT进入NMLimpHome状态后请求睡眠的最短时间是否正确…

Flink时间语义 | 大数据技术

⭐简单说两句⭐ ✨ 正在努力的小叮当~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &a…

SpringBoot+Vue+Element-UI实现学生综合成绩测评系统

前言介绍 学生成绩是高校人才培养计划的重要组成部分&#xff0c;是实现人才培养目标、培养学生科研能力与创新思维、检验学生综合素质与实践能力的重要手段与综合性实践教学环节。而学生所在学院多采用半手工管理学生成绩的方式&#xff0c;所以有必要开发学生综合成绩测评系…

校园寄取快递代拿小程序源码系统 带完整的安装代码包以及搭建教程

在数字化快速发展的今天&#xff0c;校园生活也在不断地与时俱进&#xff0c;向着更加便捷、高效的方向迈进。为了满足学生们对于快递寄取代拿的便捷需求&#xff0c;小编给大家分享一款校园寄取快递代拿小程序源码系统&#xff0c;该系统不仅提供了完整的安装代码包&#xff0…

矩池云jupyter运行opengait代码 未完成版

文章目录 前言——矩池云的使用技巧1.切换源 一、下载数据集二、下载模型三、环境配置1.查看python、torch、torchvision版本2.查看一些包版本是否过高3.下载包 四、开始训练1.设置环境变量2.遇到的问题&#xff08;1&#xff09;torch.cuda.is_available()返回false&#xff0…

python绘图(pandas)

matplotlib绘图 import pandas as pd abs_path rF:\Python\learn\python附件\pythonCsv\data.csv df pd.read_csv(abs_path, encodinggbk) # apply根据多列生成新的一个列的操作&#xff0c;用apply df[new_score] df.apply(lambda x : x.数学 x.语文, axis1)# 最后几行 …

接口自动化测试拓展:接口Mock的理念与实战场景!

接口自动化测试是软件开发过程中不可或缺的一环。在实际开发中&#xff0c;我们常常会遇到需要依赖其他模块的接口或者服务来完成测试的情况。而在开发初期或者接口尚未完成的情况下&#xff0c;就需要使用接口Mock来模拟未实现的接口功能。接口Mock是一种模拟接口行为的技术&a…

基于树的时间序列预测(LGBM)

在大多数时间序列预测中&#xff0c;尽管有Prophet和NeuralProphet等方便的工具&#xff0c;但是了解基于树的模型仍然具有很高的价值。尤其是在监督学习模型中&#xff0c;仅仅使用单变量时间序列似乎信息有限&#xff0c;预测也比较困难。因此&#xff0c;为了生成足够的特征…

每日两题 / 24. 两两交换链表中的节点 25. K 个一组翻转链表(LeetCode热题100)

24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 定义三个指针&#xff0c;交换前先保存ntnt指针为next->next&#xff0c;cur和next两个节点&#xff0c;然后将pre->next指向next 若pre为空&#xff0c;说明当前交换的节点为头两个节点&#xff0c;…

《Python编程从入门到实践》day20

#尝试在python3.11文件夹和pycharm中site-packages文件夹中安装&#xff0c;最终在scripts文件夹中新建py文件成功导入pygame运行程序 #今日知识点学习 import sysimport pygameclass AlienInvasion:"""管理游戏资源和行为的类"""def __init__(…

动态规划——背包问题(01,完全,多重)

一、01背包问题 1.题目描述 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。输出最大价值。 01背包问题特点&…