【4G模块】中移物联ML302 + GD32F407 使用支持MQTT协议AT指令接入阿里云物联网平台

目录

 

〇、目的、GD32、ML302相关简介

0.目的:

1.ML302:

2.LTE Cat.1:

3.GD32F407

    一、GD芯片创建工程写驱动:LED、串口4、4G模块

1.创建工程

2.LED的GPIO驱动

3.debug串口驱动

扫描二维码关注公众号,回复: 11934132 查看本文章

4.4G模组的供电、开机、串口

二、测试ML302能否正常连接TCP服务器 AT指令说明

三、使用MQTT协议连接阿里云物联网平台

四、成果展示:


〇、目的、GD32、ML302相关简介

0.目的:

使用手上的开发板(mcu为gd32f407+4G模组中移物联ML302),连接阿里云物联网平台,实现数据的上行和下行。

使用4G模组支持的mqtt协议AT指令。

其实就是测试一些这个开发板和模组,顺便学习一下......

1.ML302:

ML302 是中国移动最新推出的 LTE Cat.1 模块。ML302 支持 LTE- TDD/LTE- FDD/GSM,同时支持 GNSS/BT/
Wi- Fi Scan。采用 LCC+LGA 封装方式。ML302丰富的 Internet 协议、行业标准接口和功能,支持 Windows、Linux 和 Android 驱动。ML302 可广泛应用到 M2M多个领域中,如共享、金融支付、POC、工业控制等。

这个4G模组真的是太好用了,丰富的AT指令,想比之前的8266可以少些很多代码。

2.LTE Cat.1:

简单说,就是“低配版”的4G终端!

3.GD32F407

兆易创新为国内存储的龙头企业,主营业务包括存储器,微处理器以及传感器等。

据说芯片和ST的是pin_to_pin兼容,但是因版权还是有一些小差别,这里我使用的GD官方的开发库。(本来打算用STM32CubeMX直接生成工程,但这样还要改动底层的一些东西....)

下载GD固件库(去官网):http://www.gd32mcu.com/cn/download?kw=GD32F4
【GD32相关芯片资料】 有需要请参考 这份资料很全,GD所有芯片系列固件库、datasheet、用户手册...
 链接:百度网盘-官网公开资料 (全) 
提取码:20fc

    
一、GD芯片创建工程写驱动:LED、串口4、4G模块

1.创建工程

创建工程有两种方式:1是按照固件库中的模板直接打开直接换文件直接用,2是自己创建一个空工程,再一个一个文件添加到工程中,这里我选择的方法2。

创建工程,选择芯片型号(提前下载DFP芯片安装包),添加文件组,设置魔术棒中的选项(宏、路径...),编译....

2.LED的GPIO驱动

查看开发板原理图,找到LED的电路图和芯片的GPIO

按照GD固件库中的示例对GPIO进行编程。

led.h

#ifndef LED_H
#define LED_H

#ifdef __cplusplus
 extern "C" {
#endif

#include "gd32f4xx.h"
#include "systick.h"
     
/* exported types */
typedef enum 
{
    LED1 = 0,
    LED2 = 1,
    LED3 = 2
} led_typedef_enum;


/*
        PD10  --> LED1
		PD11  --> LED2
*/
/* eval board low layer led */
#define LEDn                             2U

#define LED1_PIN                         GPIO_PIN_10
#define LED1_GPIO_PORT                   GPIOD
#define LED1_GPIO_CLK                    RCU_GPIOD
  
#define LED2_PIN                         GPIO_PIN_11
#define LED2_GPIO_PORT                   GPIOD
#define LED2_GPIO_CLK                    RCU_GPIOD
  

/* function declarations */
/* configures led GPIO */
void gd_eval_led_init(led_typedef_enum lednum);
/* turn on selected led */
void gd_eval_led_on(led_typedef_enum lednum);
/* turn off selected led */
void gd_eval_led_off(led_typedef_enum lednum);
/* toggle the selected led */
void gd_eval_led_toggle(led_typedef_enum lednum);


void zdw_led_loop(void);
void zdw_led1_on(void);
void zdw_led2_on(void);
void zdw_led1_off(void);
void zdw_led2_off(void);

void zdw_bsp_led_init(void);

#ifdef __cplusplus
}
#endif



#endif

led.c

#include "led.h"

/* private variables */
static uint32_t GPIO_PORT[LEDn] = {LED1_GPIO_PORT, LED2_GPIO_PORT};
static uint32_t GPIO_PIN[LEDn] = {LED1_PIN, LED2_PIN};
static rcu_periph_enum GPIO_CLK[LEDn] = {LED1_GPIO_CLK, LED2_GPIO_CLK};


/*!
    \brief      configure led GPIO
    \param[in]  lednum: specify the Led to be configured
      \arg        LED1
      \arg        LED2
      \arg        LED3
    \param[out] none
    \retval     none
*/
void  gd_eval_led_init (led_typedef_enum lednum)
{
    /* enable the led clock */
    rcu_periph_clock_enable(GPIO_CLK[lednum]);
    /* configure led GPIO port */ 
    gpio_mode_set(GPIO_PORT[lednum], GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN[lednum]);
    gpio_output_options_set(GPIO_PORT[lednum], GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN[lednum]);

    GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

/*!
    \brief      turn on selected led
    \param[in]  lednum: specify the Led to be turned on
      \arg        LED1
      \arg        LED2
    \param[out] none
    \retval     none
*/
void gd_eval_led_on(led_typedef_enum lednum)
{
    GPIO_BOP(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

/*!
    \brief      turn off selected led
    \param[in]  lednum: specify the Led to be turned off
      \arg        LED1
      \arg        LED2
    \param[out] none
    \retval     none
*/
void gd_eval_led_off(led_typedef_enum lednum)
{
    GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

/*!
    \brief      toggle selected led
    \param[in]  lednum: specify the Led to be toggled
      \arg        LED1
      \arg        LED2
    \param[out] none
    \retval     none
*/
void gd_eval_led_toggle(led_typedef_enum lednum)
{
    GPIO_TG(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}


void zdw_led_loop(void)
{
    /* turn on led1, turn off led3 */
    gd_eval_led_on(LED1);        
    delay_1ms(100);
    gd_eval_led_off(LED1);
    
    /* turn on led2, turn off led1 */
    gd_eval_led_on(LED2);
    delay_1ms(200);
    gd_eval_led_off(LED2);        
}

void zdw_led1_on(void)
{
    gd_eval_led_on(LED1);
}
void zdw_led2_on(void)
{
    gd_eval_led_on(LED2);
}
void zdw_led1_off(void)
{
    gd_eval_led_off(LED1);
}
void zdw_led2_off(void)
{
    gd_eval_led_off(LED2);
}

void zdw_bsp_led_init(void)
{
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);
}

发现GD库和ST的固件库以及HAL库的结构体编程思想有些差别,但是总体的流程是一样的。函数的功能也看函数名就能猜到大概意思。

3.debug串口驱动

uart_debug.h

#ifndef UART_DEBUG_H
#define UART_DEBUG_H

#include "gd32f4xx_usart.h"
#include <stdio.h>

#define COMn                             1U
#define EVAL_COM0                        UART4
#define EVAL_COM0_CLK                    RCU_UART4

#define EVAL_COM0_TX_PIN                 GPIO_PIN_12
#define EVAL_COM0_RX_PIN                 GPIO_PIN_2

#define EVAL_COM0_GPIO_TX_PORT              GPIOC
#define EVAL_COM0_GPIO_TX_CLK               RCU_GPIOC
#define EVAL_COM0_TX_AF                     GPIO_AF_8

#define EVAL_COM0_GPIO_RX_PORT              GPIOD
#define EVAL_COM0_GPIO_RX_CLK               RCU_GPIOD
#define EVAL_COM0_RX_AF                     GPIO_AF_8


/* configure COM port */
void gd_eval_com_init(uint32_t com);

//
void nvic_debug_uart_config(void);

#endif

uart_debug.c

#include "uart_debug.h"

static rcu_periph_enum COM_CLK[COMn] = {EVAL_COM0_CLK};
static uint32_t COM_TX_PIN[COMn] = {EVAL_COM0_TX_PIN};
static uint32_t COM_RX_PIN[COMn] = {EVAL_COM0_RX_PIN};

/*!
    \brief      configure COM port
    \param[in]  COM: COM on the board
      \arg        EVAL_COM0: COM on the board
    \param[out] none
    \retval     none
*/
void gd_eval_com_init(uint32_t com)
{
    /* enable GPIO clock */
    uint32_t COM_ID = 0;
    if(EVAL_COM0 == com)
    {
        COM_ID = 0U;
    }

    rcu_periph_clock_enable( EVAL_COM0_GPIO_TX_CLK);
    rcu_periph_clock_enable( EVAL_COM0_GPIO_RX_CLK);

    /* enable USART clock */
    rcu_periph_clock_enable(COM_CLK[COM_ID]);

    /* connect port to USARTx_Tx Rx*/
    gpio_af_set(EVAL_COM0_GPIO_TX_PORT, EVAL_COM0_TX_AF, COM_TX_PIN[COM_ID]);
    gpio_af_set(EVAL_COM0_GPIO_RX_PORT, EVAL_COM0_RX_AF, COM_RX_PIN[COM_ID]);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(EVAL_COM0_GPIO_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,COM_TX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM0_GPIO_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_TX_PIN[COM_ID]);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(EVAL_COM0_GPIO_RX_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP,COM_RX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM0_GPIO_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_RX_PIN[COM_ID]);

    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com,115200U);
    usart_receive_config(com, USART_RECEIVE_ENABLE);
    usart_transmit_config(com, USART_TRANSMIT_ENABLE);
    usart_enable(com);
    
    /* enable the USART receive interrupt */
    usart_interrupt_enable(com, USART_INT_RBNE);
    
    //config nvic
    nvic_debug_uart_config();
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM0, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE));
    return ch;
}

//config nvic
void nvic_debug_uart_config(void)
{
    nvic_irq_enable(UART4_IRQn, 0, 1);
}


这里使用中断的方法接受串口数据:

gd32f4xx_it.c

#include "gd32f4xx_it.h"
#include "main.h"
#include "systick.h"

#include "uart_debug.h"
#include "uart_4G.h"

/*!
    \brief      this function handles NMI exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void NMI_Handler(void)
{
}

/*!
    \brief      this function handles HardFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void HardFault_Handler(void)
{
    /* if Hard Fault exception occurs, go to infinite loop */
    while (1){
    }
}

/*!
    \brief      this function handles MemManage exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void MemManage_Handler(void)
{
    /* if Memory Manage exception occurs, go to infinite loop */
    while (1){
    }
}

/*!
    \brief      this function handles BusFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void BusFault_Handler(void)
{
    /* if Bus Fault exception occurs, go to infinite loop */
    while (1){
    }
}

/*!
    \brief      this function handles UsageFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void UsageFault_Handler(void)
{
    /* if Usage Fault exception occurs, go to infinite loop */
    while (1){
    }
}

/*!
    \brief      this function handles SVC exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SVC_Handler(void)
{
}

/*!
    \brief      this function handles DebugMon exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void DebugMon_Handler(void)
{
}

/*!
    \brief      this function handles PendSV exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void PendSV_Handler(void)
{
}

/*!
    \brief      this function handles SysTick exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void SysTick_Handler(void)
{
    //led_spark();
    delay_decrement();
}

extern int count_zdw;
//debug uart : 
void UART4_IRQHandler(void)
{
    uint8_t ch = 0;
    //
    if((RESET != usart_interrupt_flag_get(EVAL_COM0, USART_INT_FLAG_RBNE)) && 
       (RESET != usart_flag_get(EVAL_COM0, USART_FLAG_RBNE))){
        /* receive data */
        ch = (usart_data_receive(EVAL_COM0) & 0x7F);
        
        //then : send again
        usart_data_transmit(COM_4G_UART, (uint8_t)ch);
    }
    
  
//    if((RESET != usart_flag_get(EVAL_COM0, USART_FLAG_TBE)) && 
//       (RESET != usart_interrupt_flag_get(EVAL_COM0, USART_INT_FLAG_TBE))){
//        /* transmit data */
//        usart_data_transmit(EVAL_COM0, txbuffer[txcount++]);
//        if(txcount >= rxcount)
//        {
//            usart_interrupt_disable(EVAL_COM0, USART_INT_TBE);
//        }
//    }
}


/*!
\brief      this function handles USART1 :4G
    \param[in]  none
    \param[out] none
    \retval     none
*/
void USART1_IRQHandler(void)
{
    uint8_t ch = 0;
    count_zdw++;
    
    if((RESET != usart_interrupt_flag_get(COM_4G_UART, USART_INT_FLAG_RBNE)) && 
       (RESET != usart_flag_get(COM_4G_UART, USART_FLAG_RBNE))){
        /* receive data */
        ch = (usart_data_receive(COM_4G_UART) & 0x7F);
        
        //then : send to uart4 again
        usart_data_transmit(EVAL_COM0, (uint8_t)ch);
    }
}

4.4G模组的供电、开机、串口

uart_4G.h

#ifndef UART_4G_H
#define UART_4G_H

/*
Power:MCU_PWR_4G  			PB8
PowerOn:MCU_POWERON_MODULE	PD5
UART1:  MCU_USART1_TX   PA2
        MCU_USART1_RX  	PA3
*/

#include "gd32f4xx_usart.h"
#include <stdio.h>

//GPIO -- Power : 
#define MCU_PWR_4G_PIN          GPIO_PIN_8
#define MCU_PWR_4G_GPIO_PORT    GPIOB
#define MCU_PWR_4G_GPIO_CLK     RCU_GPIOB

//GPIO -- PowerOn :1s
#define MCU_POWERON_MODULE_PIN  GPIO_PIN_5
#define MCU_POWERON_MODULE_PORT GPIOD
#define MCU_POWERON_MODULE_CLK  RCU_GPIOD

//Power GPIO config
void zdw_power_4G_gpio_config(void);
//Power enable  : 1 second
void zdw_power_4G_enable_1s(void);


//PowerOn : GPIO config
void zdw_poweron_4G_gpio_config();
//PowerOn :
void zdw_poweron_4G(void);

//UART 
#define COM_4G_UART         USART1
#define COM_4G_CLK          RCU_USART1

#define COM_4G_TX_PIN       GPIO_PIN_2
#define COM_4G_TX_PORT      GPIOA
#define COM_4G_TX_CLK       RCU_GPIOA
#define COM_4G_TX_AF        GPIO_AF_7

#define COM_4G_RX_PIN       GPIO_PIN_3
#define COM_4G_RX_PORT      GPIOA
#define COM_4G_RX_CLK       RCU_GPIOA
#define COM_4G_RX_AF        GPIO_AF_7

//config 4G_Uart
void gd_4G_uart_com_init(void);

//USART1 send data : send data to 4G
void zdw_uart1_send_data_len(char* data,int len);

//USART1 send string :send data to 4G
void zdw_uart1_send_string(char* str);


//4G
//4G model init :main use
void zdw_4G_model_init(void);

#endif

uart_4G.c

#include "uart_4G.h"
#include "systick.h"

//congig nvic
static void nvic_4G_uart_config(void)
{
    nvic_irq_enable(USART1_IRQn, 0, 1);
}

//config 4G_Uart : USART1
void gd_4G_uart_com_init(void)
{
    /* enable GPIO clock */
    rcu_periph_clock_enable(COM_4G_TX_CLK);
    rcu_periph_clock_enable(COM_4G_RX_CLK);
    
    /* enable USART clock */
    rcu_periph_clock_enable(COM_4G_CLK);
    
    /* connect port to USARTx_Tx Rx*/
    gpio_af_set(COM_4G_TX_PORT, COM_4G_TX_AF, COM_4G_TX_PIN);
    gpio_af_set(COM_4G_RX_PORT, COM_4G_RX_AF, COM_4G_RX_PIN);
    
    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(COM_4G_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,COM_4G_TX_PIN);
    gpio_output_options_set(COM_4G_TX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_4G_TX_PIN);
    
    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(COM_4G_RX_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP,COM_4G_RX_PIN);
    gpio_output_options_set(COM_4G_RX_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_4G_RX_PIN);
    
    /* USART configure */
    usart_deinit(COM_4G_UART);
    usart_baudrate_set(COM_4G_UART,115200U);
    usart_receive_config(COM_4G_UART, USART_RECEIVE_ENABLE);
    usart_transmit_config(COM_4G_UART, USART_TRANSMIT_ENABLE);
    usart_enable(COM_4G_UART);   

    /* enable the USART receive interrupt */
    usart_interrupt_enable(COM_4G_UART, USART_INT_RBNE);
    
    //config nvic
    nvic_irq_enable(USART1_IRQn, 0, 1);
}

//USART1 send data : send data to 4G
void zdw_uart1_send_data_len(char* data,int len)
{
    int i = 0;
    for(i = 0;i < len;i++)
    {
        usart_data_transmit(COM_4G_UART, data[i]);
    }
}

//USART1 send string :send data to 4G
void zdw_uart1_send_string(char* str)
{
    unsigned int k=0;
    do
    {
        usart_data_transmit(COM_4G_UART,(uint8_t *)(str + k));
        k++;
    }  while(*(str + k)!='\0');
}



//Power :configure power GPIO
void zdw_power_4G_gpio_config(void)
{
    /* enable the Power clock */
    rcu_periph_clock_enable(MCU_PWR_4G_GPIO_CLK);
    
    /* configure Power GPIO port */ 
    gpio_mode_set(MCU_PWR_4G_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,MCU_PWR_4G_PIN);
    gpio_output_options_set(MCU_PWR_4G_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCU_PWR_4G_PIN);

    GPIO_BC(MCU_PWR_4G_GPIO_PORT) = MCU_PWR_4G_PIN;
}
//Power enable  : 1second
void zdw_power_4G_enable_1s(void)
{
    GPIO_BOP(MCU_PWR_4G_GPIO_PORT) = MCU_PWR_4G_PIN;
    delay_1ms(1000);
    GPIO_BC(MCU_POWERON_MODULE_PORT) = MCU_POWERON_MODULE_PIN;
}

//PowerOn : GPIO config
void zdw_poweron_4G_gpio_config(void)
{
    /* enable the Power clock */
    rcu_periph_clock_enable(MCU_POWERON_MODULE_CLK);
    
    /* configure Power GPIO port */ 
    gpio_mode_set(MCU_POWERON_MODULE_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,MCU_POWERON_MODULE_PIN);
    gpio_output_options_set(MCU_POWERON_MODULE_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MCU_POWERON_MODULE_PIN);

    GPIO_BC(MCU_POWERON_MODULE_PORT) = MCU_POWERON_MODULE_PIN;
}
//PowerOn : 
void zdw_poweron_4G(void)
{
    GPIO_BOP(MCU_POWERON_MODULE_PORT) = MCU_POWERON_MODULE_PIN;
}

    
//4G model init :main use
void zdw_4G_model_init(void)
{       
    //Power
    zdw_power_4G_gpio_config();
    zdw_power_4G_enable_1s();
    delay_1ms(1000);    
    
    //PowerOn
    zdw_poweron_4G_gpio_config();
    zdw_poweron_4G();
    
    //uart1 init:rx tx
    gd_4G_uart_com_init();
}

main.c

#include "main.h"
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>

#include "led.h"
#include "uart_debug.h"
#include "uart_4G.h"

void zdw_bsp_init()
{
    //LED 
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);
    
    //UART4 debug
    gd_eval_com_init(UART4);
    
    //4G model init
    zdw_4G_model_init();
}

int count_zdw = 0;

int main()
{
    systick_config(); 
    
    zdw_bsp_init();
    
    printf("zhaodawei test begin!\n\n");
    
    while(1)
    {
        //zdw_led_loop();
    }
}

程序完成,运行,检测LED和串口能够正常运行。检测4G模块的灯闪烁(1秒闪一下有问题,2秒闪一下才正常通网)。


二、测试ML302能否正常连接TCP服务器 AT指令说明

中移物联官网下载资料:AT指令说明、mqtt协议用户手册

测试1:

我这里最后一个指令AT+CGATCT=1,1 回复失败,后来发现是SIM卡的问题

先使用AT+CEREG? 先查询驻网成功没有,驻网成功后才可以激活pdp.

这里的AT+CEREG? 结果是:0,2 (2说明网络不通,查AT指令手册分析结果)

显然我的SIM卡联网失败,换了张卡。

测试TCP连接:AT+MIPOPEN=1,"TCP","121.36.7.137",22

//这个IP和PORT是ubuntu的一个公网IP,可以用来测试。


三、使用MQTT协议连接阿里云物联网平台

查看ML302的mqtt用户手册:

按照手册,配置需要的AT指令:

1.
		AT+MQTTCFG 配置 MQTT 传输连接参数
		实例:AT+MQTTCFG="183.230.40.39",6002,"532337966",60,"246883","VACC79esEWuVK5j73b3cqWzrD7U=",0,””,0
		我的阿里云:
			AT+MQTTCFG="a1yhReNQYpD.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883,"zhaodawei|securemode=3,signmethod=hmacsha1|",60,"wifi_test&a1yhReNQYpD","3EA8327F255BDE5A280ECA0A2C7F9*********",0,"",0
		2.
		AT+MQTTOPEN 设置 MQTT 相关连接标志并开始连接服务器。
		AT+MQTTOPEN=1,1,0,0,0, "",""
		我的阿里云:
			AT+MQTTOPEN=1,1,0,0,0, "",""
			
		查询 MQTT 连接状态: AT+MQTTSTAT?
		
		3.订阅、发布
		AT+MQTTSUB="dev/gsm/u",2  //示例
		我的阿里云:订阅	
			AT+MQTTSUB="/a1yhReNQYpD/wifi_test/user/led",0
		
		AT+MQTTPUB="dev/gsm/u",2,0,0,"update message"  //示例
		我的阿里云:发布
			AT+MQTTPUB="/a1yhReNQYpD/wifi_test/user/led",2,0,0,"LED is OFF!"
		
		4.关闭连接:
		断开 MQTT 连接  AT+MQTTDISC

四、成果展示:

AT指令连接阿里云:

设备显示在线

发布消息:I Love You

设备接受到消息:I Love You

猜你喜欢

转载自blog.csdn.net/zDavid_2018/article/details/109099671