精华内容
下载资源
问答
  • ESP32MQTT

    2020-12-16 10:36:35
    这个实验的功能演示 ESP32MQTT 的使用方法。 这个实验的代码为工程“4_10_wifi_MQTT”目录。 4.10.1. 实验内容 学习 ESP32 注册移动 onenet MQTT 服务器 学习 ESP32 通过 MQTT 上传数据到移动 onenet 学习通过移动 ...

    这个实验的功能演示 ESP32MQTT 的使用方法。 这个实验的代码为工程“4_10_wifi_MQTT”目录。

    4.10.1. 实验内容

    学习 ESP32 注册移动 onenet MQTT 服务器
    学习 ESP32 通过 MQTT 上传数据到移动 onenet
    学习通过移动 onenet 下发数据控制开发板

    4.10.2. MQTT 介绍

    MQTT(消息队列遥测传输)是 ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP 协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协 议,为此,它需要一个消息中间件 (服务器)。
    MQTT 协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而 设计的协议,它具有以下主要的几项特性:
    (1) 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;

    (2) 对负载内容屏蔽的消息传输; (3) 使用 TCP/IP 提供网络连接; (4) 有三种消息发布服务质量:
     “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于 如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
     “至少一次”,确保消息到达,但消息重复可能会发生。
     “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失 会导致不正确的结果。
    (5) 小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量; 实现 MQTT 协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT 协议中有三种身份:发布
    者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。 在我们的这个实验里,消息的发布者是 ESP32 开发板开发板,服务器使用的是移动的 onenet MQTT 服
    务器。

    4.10.3. 函数介绍

    在这个实验里,我们使用到了 NVS、smartconfig、STAwifi 连接、DTH11 数据读取、ADC 光敏数据读取、
    LED 彩灯、显示屏 LCD、MQTT 和任务创建和通信。在介绍函数的时候,只介绍 MQTT 新知识部分。

    (1) MQTT 配置信息 esp_mqtt_client_config_t;
    通过这个结构体,可以配置 MQTT 的服务器 IP,PORT,用户名,密码,client ID,结构定义:

    typedef struct {
    mqtt_event_callback_t event_handle; /*回调*/
    const char *host; /*!< MQTT 服务器域名(ipv4 as string)*/ const char *uri; /*!< MQTT 服务器域名 */
    uint32_t port; /*!< MQTT 服务器端口*/
    const char *client_id; /*MQTT Client 的名字默认是 ESP32_加上 MAC 后 3hex*/ const char *username; /*MQTT 用户名*/
    const char *password; /*MQTT 密码*/
    const char *lwt_topic; /*!< LWT 主题,默认为空*/ const char *lwt_msg; /*!< LWT 信息,默认为空*/ int lwt_qos; /*!< LWT 消息质量*/
    int lwt_retain; /*!< LWT 保留消息标志*/ int lwt_msg_len; /*!< LWT 消息长度*/
    int disable_clean_session; /*!< mqtt clean session,默认为真*/ int keepalive; /*MQTT 心跳,默认 120 秒 */
    bool disable_auto_reconnect; /*错误,断开后重连,true 不连*/ void *user_context; /*用户信息 */
    int task_prio; /*!< MQTT 任务优先级,默认为 5,可以在 make menuconfig 中修改*/
    int task_stack; /*!< MQTT 任务堆栈大小,默认 6144 bytes,可以在 make menuconfig 中修改*/ int buffer_size; /*!< MQTT 收发缓存,默认 1024 */
    const char *cert_pem; /*指向用于服务器验证(使用 SSL)的 PEM 格式的证书数据的指针,默认值为空,不需 要验证服务器*/
    const char *client_cert_pem; /*指向用于 SSL 相互身份验证的 PEM 格式的证书数据的指针,默认值为空, 如果不需要相互身份验证,则不需要。如果不为空,还必须提供“客户机密钥”。*/
    const char *client_key_pem; /*指向用于 SSL 相互身份验证的 PEM 格式的私钥数据的指针,默认值为空, 如果不需要相互身份验证,则不需要。如果不为空,还必须提供“client-cert-pem”。*/
    

    (2) MQTT Client 初始化函数
    函数定义:

    	esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config);	
    

    参数说明:
    esp_mqtt_client_config_t *config:MQTT 配置参数 返回值:
    esp_mqtt_client_handle_t:MQTT 操作句柄,订阅、发布消息就通过这个句柄实现。

    (3) MQTT Client 启动函数
    函数定义:

    	esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client);
    
      参数说明:
    

    esp_mqtt_client_handle_t client:MQTT 操作句柄,初始化的返回值 返回值:
    ESP_OK:成功。

    (4) MQTT Client 停止函数
    函数定义:

    esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client);
    
    	  参数说明:
    

    esp_mqtt_client_handle_t client:MQTT 操作句柄,初始化的返回值 返回值:
    ESP_OK:成功。

    (5) MQTT Client 订阅主题函数
    函数定义:

    esp_err_t esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos);
    
    	  参数说明:
    

    esp_mqtt_client_handle_t client:MQTT 操作句柄,初始化的返回值 char *topic:订阅的主题
    int qos:服务质量 返回值:
    ESP_OK:成功。

    (6) MQTT Client 取消订阅主题函数
    函数定义:

    esp_err_t esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic);	
    
      参数说明:
    

    esp_mqtt_client_handle_t client:MQTT 操作句柄,初始化的返回值 char *topic:订阅的主题
    返回值:
    ESP_OK:成功。

    (7) MQTT Client 发布主题函数
    函数定义:

    int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain);
    

    参数说明:
    esp_mqtt_client_handle_t client:MQTT 操作句柄,初始化的返回值 char *topic:订阅的主题
    char *data:发布的数据 Int len:数据长度
    int qos:服务质量 返回值:
    消息 ID。

    4.10.4. 代码讲解

    使用 vs code 展开本实验的工程目录,如下图:
    在这里插入图片描述

    我们的这个实验,主要代码有 main 目录下,文件夹 components 下是之前讲过的 DHT11、LCD 和 LED
    驱动文件。
    下面按照程序启动的流程讲解。
    (1) 程序启动
    程序启动进入 app_main 后,读取 nvs 数据、初始化 LED、创建显示屏任务和创建检测传感器任务,根 据读取的 NVS 数据决定是启动 smartconfig 还是直接 wifi 连接。

    //用户函数入口,相当于 main 函数 void app_main(void)
    {
    ESP_ERROR_CHECK(nvs_flash_init()); tcpip_adapter_init(); read_Smartconfig();//读 smartconfig 配置 initLed();//LED  IO 口初始化
    
    //创建任务
    //事件组
    display_event_group  =  xEventGroupCreate(); xTaskCreate(display_task,  "display_task",  4096,  NULL,  2, NULL);
    xTaskCreate(sensor_check_task,  "sensor_check_task",  4096,  NULL,  10, NULL);
    
    //根据 NVS 数据决定是否要进入 Smartconfig if(1!=wifi_isConfig){
    led_red(LED_ON);//打开红灯,表示正在配置中 startSmartconfig();//配置 wifi 进入 smartconfig
    
    //通过事件刷新显示
    xEventGroupSetBits(display_event_group, SMARTCONFIG_DISPLAY_BIT);
    }else{
    
    //启动 STA,连接 AP wifi_init_sta();
    
    //通过事件刷新显示
    xEventGroupSetBits(display_event_group, STA_START_DISPLAY_BIT);
    }
    }
    
    

    函数 read_Smartconfig()是 4.7.4 有讲解,是用于读取 NVS 数据,读取的数据里有是否成功配对、wifi 的 SSID 和密码。
    显示任务专们用于显示屏控制,根据收到的事件去刷新不同的 LCD 区域,代码如下:

    //显示任务
    void  display_task(void *parm)
    {
    char lcd_buff[100]={0}; EventBits_t uxBits;
    
    //显示屏初始化以及显示相关的提示 Lcd_Init();
    Gui_DrawFont_GBK16(16,0,VIOLET,WHITE,(u8 *)"深圳亿研电子"); Gui_DrawFont_GBK16(32,20,BLUE,WHITE,(u8 *)"欢迎您");
    
    while(1) {
    //等待对应的事件发生
    uxBits = xEventGroupWaitBits(display_event_group, SMARTCONFIG_DISPLAY_BIT|STA_START_DIS PLAY_BIT|WIFI_CONNECTED_DISPLAY_BIT|DHT11_DISPLAY_BIT|ADC_DISPLAY_BIT,  true,  false, portMAX_DELAY);
    
    //开机进入 smartconfig
    if  (uxBits  & SMARTCONFIG_DISPLAY_BIT)
    .....
    
    //开机进入 STA 连接
    if  (uxBits  & STA_START_DISPLAY_BIT)
    .....
    
    //wifi 已连接
    if  (uxBits  & WIFI_CONNECTED_DISPLAY_BIT)
    .....
    
    //DHT11 显示
    if  (uxBits  & DHT11_DISPLAY_BIT)
    .....
    
    //ADC 显示
    if  (uxBits  & ADC_DISPLAY_BIT)
    .....
    }
    }
    
    

    传感器检测任务,用于 3 秒读一次 DHT11 数据,1 秒读一次 ADC 光照值。温度数据保存在变量 dht11_t,

    湿度数据保存在变量 dht11_h,光照的 ADC 值保存在 light_adc,光照的电压值保存在 light_mv 上,代码如下:

    //传感器数据采集任务
    void  sensor_check_task(void *parm)
    {
    int second_count=0; adc_Init();//adc 初始化
    
    while(1) {
    //DHT11 3 秒取一次数据 if((second_count%3)==0)
    {
    DHT11();//读取温湿度数据
    
    //如果读取数据不正确返回 250 if(wendu!=250)
    {
    dht11_t=wendu;//温度 dht11_h=shidu;//湿度
    
    //通过事件刷新显示
    xEventGroupSetBits(display_event_group, DHT11_DISPLAY_BIT);
    }
    }
    
    //光照采集 light_adc=adc1_get_voltage(ADC1_TEST_CHANNEL);//采集光照 ADC light_mv=(light_adc*1100)/4096;//转成电压值
    
    //通过事件刷新显示
    xEventGroupSetBits(display_event_group, ADC_DISPLAY_BIT);
    
    //延时 3 秒 vTaskDelay(100);
    if(second_count++>1000) second_count=0;
    
    

    (2) 启动 MQTT 任务
    不管是否启用了 smartconfig,当网络连接上之后,都会进入文件 app_smartConfig.c 里的 wifi 回调函数, 当 wifi 取得 IP 后,就启动 MQTT 任务,关键代码如下:

    //wifi 连接事件回调函数
    static esp_err_t smartconfig_event_handler(void *ctx, system_event_t *event)
    {
    ......
    case SYSTEM_EVENT_STA_GOT_IP://获取 IP ESP_LOGI(TAG1, "SYSTEM_EVENT_STA_GOT_IP");
    ......
    
    //启动 MQTT 服务
    extern void mqtt_app_start(void); mqtt_app_start();
    break;
    ......
    }
    
    void mqtt_app_start(void)
    {
    mqtt_event_group  =  xEventGroupCreate(); xTaskCreate(mqtt_task,  "mqtt_task",  4096,  NULL,  3, NULL);
    }
    
    

    (3) MQTT 任务
    MQTT 任务通过三步完成 MQTT 的连接,通过 MQTT 的事件回调函数,去检测 MQTT 是否连接上,是 否断开连接,是否收到订阅消息。

    //mqtt 初始化
    void mqtt_task(void *parm)
    {
    //第一步:配置 MQTT 参数 esp_mqtt_client_config_t mqtt_cfg = {
    .host = "183.230.40.39",	//MQTT 服务器 IP
    .port=6002,	//端口
    .event_handle = mqtt_event_handler, //MQTT 事件
    .username = "269223",	//用户名
    .password = "mfyIRyFEGojbzzwExjHrEAHLMXg=", //密码
    .client_id= "541022266",
    };
    
    ......
    vTaskDelay(300);
    
    //第二步:MQTT 初始化
    mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
    //第三步:MQTT 启动 esp_mqtt_client_start(mqtt_client);
    //等 mqtt 连上
    xEventGroupWaitBits(mqtt_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
    
    vTaskDelete(NULL);
    }
    
    

    我们的这个实验是使用移动 onenet MQTT 平台做实验的,IP 和端口号是不用修改的,用户名、密码 和 client_id 有一个文档专们说明,文档位于目录:
    在这里插入图片描述

    移动 onenet MQTT 平台的三个参数,对应关系如下图:
    在这里插入图片描述
    在这里插入图片描述

    (4) MQTT 的事件回调函数
    在回调函数里,我们关心两种事件,第一种 MQTT 连接成功事件(MQTT_EVENT_CONNECTED):收到 这个事件表求成功连接 MQTT 服务器, 我们就可以周期发送数据了; 第二种 MQTT 收到数据事件
    (MQTT_EVENT_DATA):通过对收到的主题和数据分析,可以对开发板做相应的操作,如我们代码里的点 灯;

    //MQTT 事件回调函数
    static  esp_err_t  mqtt_event_handler(esp_mqtt_event_handle_t event)
    {
    esp_mqtt_client_handle_t client =  event->client; int msg_id;
    
    switch  (event->event_id) {
    case MQTT_EVENT_CONNECTED://MQTT 连上事件 ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
    
    mqtt_connected=true;//连接上标志 xEventGroupSetBits(mqtt_event_group, CONNECTED_BIT);
    //创建任务用于周期发数据
    xTaskCreate(mqtt_SendData, "mqtt_SendData", 4096, NULL, 3, NULL); break;
    case MQTT_EVENT_DISCONNECTED://MQTT 断开连接事件 ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
    
    mqtt_connected=false; xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT); break;
    
    case  MQTT_EVENT_SUBSCRIBED://MQTT 发送订阅事件
    ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); msg_id  =  esp_mqtt_client_publish(client,  "/topic/qos0", "订阅成功
    ",  0,  0, 0);
    ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); 
    case  MQTT_EVENT_UNSUBSCRIBED://MQTT 取消订阅事件
    ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); break;
    case  MQTT_EVENT_PUBLISHED://MQTT 发布事件
    ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); break;
    case MQTT_EVENT_DATA://MQTT 接受数据事件 ESP_LOGI(TAG, "MQTT_EVENT_DATA");
    printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);	//主题 printf("DATA=%.*s\r\n", event->data_len, event->data);		//内容
    
    //控制 LED 灯
    if(event->data_len==2)
    {
    if(strncmp(event->data, "R1",2)==0)//开红灯
    {
    led_red(LED_ON);
    }
    
    

    (5) 周期发送 MQTT 数据任务
    通过这个任务,3 秒上传一次开发板的温度、湿度和光照 ADC 值,使用函数 mqtt_publishToOnenet()上 传数据。

    void  mqtt_SendData(void *parm)
    {
    while(1) {
    
    //只有连接上才发数据 if(mqtt_connected){
    mqtt_publishToOnenet(dht11_t,dht11_h,light_adc);
    }
    //延时三秒 vTaskDelay(300);
    }
    }
    
    /打包 JSON 数据
    unsigned  char  OneNet_FillBuf(char  *buf,int  t,  int  h,  int l)
    {
    char text[50];
    
    memset(text,  0, sizeof(text));
    
    strcpy(buf, "{");
    
    //温度
    memset(text, 0, sizeof(text)); sprintf(text, "\"temp1\":%d", t); strcat(buf, text);
    
    //湿度
    memset(text, 0, sizeof(text)); strcat(buf, ",");
    sprintf(text, "\"hum2\":%d", h); strcat(buf, text);
    
    //光照
    memset(text, 0, sizeof(text)); strcat(buf, ",");
    sprintf(text, "\"light\":%d", l); strcat(buf, text);
    
    strcat(buf, "}");
    memset(text, 0, sizeof(text)); return strlen(buf);
    
    }
    
    //数据上传 onenet
    void  mqtt_publishToOnenet(int  temp,  int  hum,  int light)
    {
    int msg_id;
    char buf[128]={0}; short  body_len  = 0;
    
    body_len  =  OneNet_FillBuf(&buf[3],  temp, hum, light);	//获取当前需要发送的数据流的总长度 buf[0]  = 3;
    buf[1] = body_len >>  8; buf[2]  =  body_len  & 0xFF;
    
    //数据上传服务器
    msg_id = esp_mqtt_client_publish(mqtt_client, "$dp", buf, body_len+3, 1, 0); ESP_LOGI(TAG,  "mqtt_publishToOnenet  successful,  msg_id=%d", msg_id);
    }
     
    

    4.10.5. 实验过程

    做这个实验的前提条件,必须接以下文档的方法先申请 onenet 帐号和创建设备:
    在这里插入图片描述

    当创建在设备后,按下图修改 MQTT 的初始化参数:
    在这里插入图片描述

    当修改了代码里的这三个参数后,就可以编绎代码,并下载到开发板上了。配置下载串口、波特率、 编绎和程序下载的详细过程请往回看 3.1.4,在这个实验里都是一笔带过。
    (1) 把开发板通过 USB 线接到电脑上,通过设备管理器查看生成的串口。开发板在我们演示电脑上生 成的是 COM3。
    (2) 在 menuconfig 菜单里配置下载程序串口。提供的例程配置的串口是 COM3,波特率为 921600。
    (3) 通过 make all 编绎工程。
    (4) 当编绎通过之后,使用命令 make flash 把程序下载到开发板上。或者参考 2.3.2 节,使用工具 下载。
    (5) 使用串口工具打开开发板生成的串口,默认的波特率是 115200。 串口工具在目录:.\开发软件\串口工具-sscom32.rar。
    (6) 打开按下开发板的复位键,让程序运行起来。第一次启动开发板上应该是红灯亮起,此时需要按 照 4.3.5 里的手机一键配置 smartconfig,配置 ESP32 的 wifi 名字和密码。如果开发板的蓝灯亮 起表示 wifi 已经正确连接,显示屏显示如下:

    注意:连接的 wifi 一定要能上网的,否则无法连接外网的 onenet 服务器 注意:连接的 wifi 一定要能上网的,否则无法连接外网的 onenet 服务器 注意:连接的 wifi 一定要能上网的,否则无法连接外网的 onenet 服务器

    (7) Smartconfig 配置后,打开 onenet 查看设备,正确情况下处于在线状态。
    在这里插入图片描述

    (8) 点击设备右边的“数据流”,可以看到开发板上传的数据。
    在这里插入图片描述

    (9) 下发命令控制开发板。 分别下发命令“A1”、“A0”、“R1”和“R0”观察彩灯的变化。
    在这里插入图片描述
    在这里插入图片描述

    (10)实验过程中,观察串口工具的输出。
    (11)在 MQTT 接入成功后,可以增加消息订阅、通过按键发布消息,和其他的开发板,如我们店里的 ESP8266 开发板、NB 开发板通信,实在不行可以使用提供的 PC 模拟器和 ESP32 通信。

    最后推荐一款开发套件,可以手淘扫码查看。
    在这里插入图片描述

    展开全文
  • ESP32 MQTT库 特征 基于: : 支持基于TCP的MQTT,具有mbedtls的SSL,基于Websocket的MQTT,基于Websocket Secure的MQTT 易于设置URI 多个实例(一个应用程序中有多个客户端) 支持订阅,发布,身份验证,将消息...
  • 此篇博客用来记录使用 mqtt.fx 创建本地 mqtt 服务器测试 ESP32 mqtt_tcp 例程 的全部流程,首先您需要准备以下环境: 下载 mqtt.fx 安装配置 ESP-IDF 环境 一块 ESP32 开发板 注:此次测试的 ESP-IDF 版本为 c...

    此篇博客用来记录使用 mqtt.fx 创建本地 mqtt 服务器测试 ESP32 mqtt_tcp 例程 的全部流程,首先您需要准备以下环境:

    注:此次测试的 ESP-IDF 版本为 c9646ff0beffc86d2c6d1bfbad34da16e328e0e3 (HEAD, tag: v4.3)。

    上述环境准备完成后,即可开始 ESP32 mqtt_tcp 例程 测试。

    1 通过 mqtt.fx 生成 mqtt broker 并订阅主题

    首先我们通过 ifconfig 指令查询本机 IP,如下:
    在这里插入图片描述
    可看到 IP 为 192.168.1.31。打开 mqtt.fx ,点击设置图标,在弹出来的 Edit Connection Profiles 界面里设置 Broker Address 为上述查询到的本机 IP 192.168.1.31,如下:
    在这里插入图片描述
    配置完成后点击上图右下角的 OK 选项,然后点击主页的 Connect,此时可以点击 Connect 下方横栏里的 Subscribe 里输入订阅主题,输入完成后点击 Subscribe。通过查看 mqtt_tcp 例程 里的代码:

    msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
    

    可以发现 ESP32 向 /topic/qos1 这个主题 publish 了 data_3 这段数据。在 mqtt.fx 里操作如下:
    在这里插入图片描述

    2 ESP32 开启 mqtt 并给主题发布消息

    终端进入到 mqtt_tcp 例程 目录下,配置好 Wi-Fi SSID 、 PASSWORD 和 mqtt Broker URL,此时的 URL 里的 IP 为上述查询并填入 mqtt.fx 的本机 IP 地址 192.168.1.31,如下:
    在这里插入图片描述
    在这里插入图片描述

    注:此时 ESP32 连接的 Wi-Fi 路由器需要与电脑 mqtt.fx 连接的一致。

    配置完成后,将 mqtt_tcp 例程编译烧写至 ESP32,可以从 ESP32 log 和 mqtt.fx 中观察到对应的 mqtt 消息已经被成功的 publish 和 subscribe。如下:

    • ESP32 端
      在这里插入图片描述

    • mqtt.fx 端
      在这里插入图片描述
      本次指南到此已结束,相关进阶 mqtt.fx 对应的 mqtt 操作后续可自行进一步探索。

    展开全文
  • 使用ssl连接腾讯MQTT服务器,使用了cert验证,可根据自己需要编写回调函数,操作lcd或者其他的硬件,注释比较少,功能完全没问题,不适合新手阅读,适合对框架有一定了解的人使用。
  • ESP32 MQTT的DEMO

    2019-05-08 15:57:13
    该工程实现了MQTT,订阅消息,发布消息的功能。DEMO工程。
  • 我们将在树莓派上设置服务器,并在esp 32上创建一个mqtt客户端。 视频演示 截图 材料需求 库文件 MQTT客户端应用程序 备注:视频中仅简单演示了如何在Raspberry Pi上通过Shell安装Mosquitto,如何下载Sketch到ESP...

    我们来看看最著名的物联网协议:MQTT。我们将在树莓派上设置服务器,并在esp 32上创建一个mqtt客户端。

    视频演示

    截图

    材料需求

    • 库文件
    • MQTT客户端应用程序

    备注:视频中仅简单演示了如何在Raspberry Pi上通过Shell安装Mosquitto,如何下载Sketch到ESP32,并通过MQTT客户端应用程序与Raspberry Pi和ESP32通讯。重点是视频中提到了一种MQTT应用程序。

    文本教程

    如何在Raspberry Pi上安装Mosquitto代理

    本指南说明了如何在Raspberry Pi板上安装用于MQTT通信的Mosquitto代理。

    代理主要负责接收所有消息,过滤消息,确定对它感兴趣的人,然后将消息发布到所有订阅的客户端。

    安装代理

    打开一个新的Raspberry Pi终端窗口:

    要安装Mosquitto Broker,请输入以下命令:

    pi@raspberry:~ $ sudo apt update
    pi@raspberry:~ $ sudo apt install -y mosquitto mosquitto-clients
    

    您必须输入Y,然后按Enter确认安装。要使Mosquitto在启动时自动启动,请输入:

    pi@raspberry:~ $ sudo systemctl enable mosquitto.service
    

    测试安装

    发送命令:

    pi@raspberry:~ $ mosquitto -v
    

    这将返回Raspberry Pi当前正在运行的Mosquitto版本。它应该是1.4.X或更高版本。

    注意:有时命令mosquitto -v会提示警告消息,提示“错误:地址已在使用中”。该警告消息表示您的Mosquitto Broker已在运行,所以不必担心。

    Raspberry Pi IP地址

    要在以后的项目中使用Mosquitto代理,您需要Raspberry Pi IP地址。要检索您的Raspberry Pi IP地址,请在“终端”窗口中键入下一个命令:

    pi@raspberry:~ $ hostname -I
    

    在我们的例子中,Raspberry Pi的IP地址是192.168.1.144。保存您的Raspberry Pi IP地址,因为在以后的项目中将需要它。

    测试Mosquitto代理和MQTT客户端

    参阅http://viadean.com/mqtt_client_esp32_raspberry_pi.html

    展开全文
  • 文章目录MQTT协议一,客户端二,服务端三,消息服务质量四,主题五,MQTT控制报文5.1 固定报头5.2 可变报头5.3 有效载荷5.4 控制报文类型5.4.1 连接报文5.4.2 发布publish5.4.3 订阅主题subscribe六,安全ESP-MQTT ...

    MQTT协议

    MQTT协议是一个应用层协议,他要求使用的传输层协议能提供有序的,可靠的双向字节流传输服务。

    MQTT协议通信对象分为客户端和服务端,数据的传输以消息为单位,每个消息包含主题,消息服务质量和有效数据。消息的发送和接收都需要依赖主题:A订阅主题T1,B订阅主题T2,A想发送消息给B,就需要将消息发送到主题T2。

    一,客户端

    通信双方的身份。mqtt通信双方都是客户端,消息传递是以订阅主题的形式。

    • 发布消息到服务端以转发到其他客户端
    • 订阅主题以接收其他客户端的消息
    • 发起连接/断开

    二,服务端

    作为客户端与客户端之间通信的中介。

    • 接收客户端发布的消息
    • 接收客户端的连接
    • 转发消息给特定的客户端
    • 接收客户端的订阅主题请求

    三,消息服务质量

    消息服务质量决定了一个MQTT报文的消息应如何处理。

    • qos0:客户端仅讲报文发送一次,服务端不需要应答,报文是否送达不保证。
    • qos1:客户端发送报文,服务端接收到后必须应答,超时重发。
    • qos2:客户端发送报文,服务端接收到后应答,客户端再次发送一个release报文,服务端发送该报文到指定主题下的客户端,并应答。

    qos0-qos2,服务的质量逐步提高。qos2能使客户端对报文的发送有全局的掌控。qos0很不负责任,嫁出去的女儿泼出去的水,不管了。qos1还行。

    四,主题

    MQTT主题是一个字符串,由服务端维护。客户端通过在服务端订阅主题,可接收来自该主题的消息。客户端可向该主题发送消息,所有订阅该主题的客户端都会受到该消息。实现的方式是:客户端向服务端发送带主题的消息到服务端,由服务端将消息转发给订阅该主题的客户端,所以服务端地位重要。

    MQTT主题支持分级,如/Home/BathRoom/Mirror,/Home/LivingRoom/Tv,是同一等级下的主题。

    主题也支持通配符#,发送消息到主题 /Home/# 则BathRoom和LivingRoom主题下的客户端都会收到消息。

    主题也支持单层通配符+,/Home/+ 则BathRoom和LivingRoom主题下的客户端会受到消息,但/Home/BathRoom/Mirror和/Home/LivingRoom/Tv 不会收到消息,这点需要跟#区别。

    五,MQTT控制报文

    MQTT协议依靠MQTT控制报文来通信
    在这里插入图片描述

    5.1 固定报头

    表示控制报文的类型,报文的一些标志位(包括消息服务质量),以及报文剩余的字节长度

    5.2 可变报头

    可变报头的内容跟报文类型有关。

    包含报文标识符,一个16bit的数据,用于唯一的标记此次通信的报文。当客户端处理完当前报文后,标识符可释放重用。qos0的消息不需要标识符,因为不需要服务端的应答。

    5.3 有效载荷

    前面都是协议规定必须的,有效载荷是真正的用户数据。不同类型的报文,有效载荷里的数据不同。

    5.4 控制报文类型

    不同类型的报文,其不同点在于可变报头及有效载荷。就以这两部分看看主要的报文:

    5.4.1 连接报文
    • 可变报头:包含 “使用传输层协议名”(TCP),MQTT协议等级(3.1.1),连接标志,保持连接。

    连接标志指示有效载荷部分的内容

    保持连接MQTT客户端需要在一个时间内给服务端发送心跳报文,服务端也要在规定时间内应答。由此判断通信双方是否在线。

    • 有效载荷

    由连接标志指示其内容,出现的顺序为:**客户端标识符,遗嘱主题,遗嘱消息,**用户名,密码。

    客户端标志:字符串,用于唯一标志一个客户端。

    遗嘱是一种错误补救方式,当客户端以异常方式断开连接时,服务端长时间未能联系到客户端,则服务端将该客户端的遗嘱消息发布到遗嘱主题。

    用户名和密码:字符串,用于识别客户端是否合法。

    5.4.2 发布publish
    • 固定报头:
      在这里插入图片描述
      DUP重发标志,是否是一个重发的报文,qos0大咩。

    RETAIN:保留标志位。若为1,服务端需要在内存中保留该消息。

    • 可变报头:主题及报文标识符
    • 有效载荷:应用数据,一般是json字符串。
    5.4.3 订阅主题subscribe

    订阅多个主题

    • 有效载荷:包含一个主题过滤器表示客户端要订阅的主题,消息服务质量qos。主题过滤器是一个字符串,后面跟着一个字节的消息服务质量,组成一组,一个订阅报文可包含多组这样的东西,来支持订阅多个主题。

    六,安全

    安全的实现主要依赖于传输层协议,推进TLS协议服务端使用8883端口。

    轻量加密AES

    ESP-MQTT API 指南

    概括

    ESP-MQTT是一个MQTT协议客户端的应用程序

    一,特性

    • 支持多种传输层协议如:TCP,SSL,Websocket,wws.
    • 使用url建立连接
    • 允许一个应用中多个客户端
    • 支持订阅,发布,认证,遗嘱,保活和3个消息质量

    二,应用示例

    三,初始化配置

    3.1 URI

    • 当前支持mqtt,mqtts,ws,wss方式

    • mqtt 使用tcp例子:

      • mqtt://mqtt.eclipse.org: MQTT over TCP, default port 1883
      • mqtt://mqtt.eclipse.org:1884 MQTT over TCP, port 1884
      • mqtt://username:password@mqtt.eclipse.org:1884 MQTT over TCP, port 1884, with username and password
    • MQTT over SSL samples:

      • mqtts://mqtt.eclipse.org: MQTT over SSL, port 8883
      • mqtts://mqtt.eclipse.org:8884: MQTT over SSL, port 8884
    • MQTT over Websocket samples:

      • ws://mqtt.eclipse.org:80/mqtt
    • MQTT over Websocket Secure samples:

      • wss://mqtt.eclipse.org:443/mqtt
    • 最小配置:

      const esp_mqtt_client_config_t mqtt_cfg = {
          .uri = "mqtt://mqtt.eclipse.org",
          // .user_context = (void *)your_context
      };
      esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
      
      //注册回调函数
      esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
      esp_mqtt_client_start(client);
      
    • 注意,默认mqtt客户端使用事件句柄来处理mqtt的事件,如连接,订阅,发布等等。

    3.2 SSL

    3.3 遗嘱

    MQTT支持使用遗嘱消息,当客户端意外断开连接时,遗嘱消息被服务端发送并用于通知其他客户端。在 esp_mqtt_client_config_t 中可配置遗嘱消息:

    • lwt_topic :指向遗嘱消息的主题
    • lwt_msg:指向遗嘱消息
    • lwt_msg_len:消息有效载荷长度
    • lwt_qos:消息服务质量
    • lwt_retain:是否保留

    3.4 其他配置参数

    • disable_clean_session:默认清除会话,对于连接消息,该参数关闭清除会话标志
    • keepalive:保活时间,默认120s
    • disable_auto_reconnect:关闭自动重连
    • user_context:本地参数,用于传递到事件处理句柄
    • task_prio:mqtt任务等级,默认5
    • task_stack:mqtt堆栈默认6144 bytes,menuconfig可配置
    • buffer_size:接收和缓存的长度,默认1024 bytes
    • username:连接到broker的用户名(服务器)
    • password:连接到broker的密码(服务器)
    • client_id:指向客户端id,一般是一个唯一的字符串,可从broker中获取
    • host:MQTT broker的ip地址,域名。设置了url会重写该参数
    • port:MQTT broker的端口。设置了url会重写该参数
    • transport:设置传输协议。设置了url会重写该参数
    • refresh_connection_after_ms:在多少时间(ms)后刷新连接
    • event_handle:处理mqtt事件的回调函数
    • event_loop_handle:mqtt事件组库

    更多esp_mqtt_client_config_t的选项,请参考下面API:

    3.5 项目配置菜单来配置mqtt

    通过idf.py menuconfig项目配置菜单来配置mqtt,在Component config -> ESP-MQTT Configuration

    下面的设置是可行的:

    3.6 事件

    mqtt主要围绕以下事件进行数据的处理:

    • MQTT_EVENT_BEFORE_CONNECT:客户端初始化完成并开始连接到broker
    • MQTT_EVENT_CONNECTED:客户端成功与broker建立连接,客户端准备好接收发送数据
    • MQTT_EVENT_DISCONNECTED:客户端由于无法接收或者发送消息而断开连接
    • MQTT_EVENT_SUBSCRIBED:broker 确认客户端的订阅请求。保留订阅消息的id
    • MQTT_EVENT_UNSUBSCRIBED:broker确认了客户端的取消订阅消息。保留取消订阅消息的id
    • MQTT_EVENT_PUBLISHED:broker确认了用户发布的消息。仅对qos为1和2的消息有效,保留发布消息的id
    • MQTT_EVENT_DATA:客户端已接收到一个发布的消息。event data包括:消息id,主题名称,数据及数据长度。若数据长度超过buffer大小,则多个MQTT_EVENT_DATA事件会被触发,*current_data_offset*total_data_len用于保持对数据的追踪。在此可将数据读到缓存中。
    • MQTT_EVENT_ERROR:客户端遇到错误。esp_mqtt_error_type_t from error_handle in the event data 可用于判断是哪个类型的错误。

    四,API参考

    esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config)

    根据配置创建mqtt 客户端句柄。

    esp_err_t esp_mqtt_client_set_uri(esp_mqtt_client_handle_t client, const char *uri);

    设置mqtt连接的url,这个函数通常会重写esp_mqtt_client_init里的配置。

    esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client);

    开启mqtt客户端

    esp_err_t esp_mqtt_client_reconnect(esp_mqtt_client_handle_t client);

    用于强制重新连接

    esp_err_t esp_mqtt_client_disconnect(esp_mqtt_client_handle_t client);

    用于强制从broker中断开连接

    esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client);

    停止mqtt客户端任务,不能再event handle中调用。

    int esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos);

    客户端订阅指向服务质量的主题。

    • 客户端必须已经连接,该API可被用户任务或mqtt event 回调函数调用。该API使用信号量,所以可能导致一段时间的阻塞。

    • 返回:消息id

    int esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic);

    取消订阅指定主题

    • 客户端必须连接
    • 线程安全。参考上面
    • 返回:消息id

    int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain);

    客户端发布消息到broker

    • 该API可能会阻塞几秒钟(由于网络,数据长度问题)
    • 客户端不必连接
    • 线程安全
    • 返回:消息id

    参数:

    • client:客户端句柄
    • topic:主题字符串
    • data:有效载荷字符串
    • len:有效载荷字符串长度
    • qos:消息服务质量
    • retain:保留消息标志

    esp_err_t esp_mqtt_client_destroy(esp_mqtt_client_handle_t client);

    销毁mqtt客户端,不能再mqtt回调函数中调用

    esp_err_t esp_mqtt_set_config(esp_mqtt_client_handle_t client, const esp_mqtt_client_config_t *config);

    设置配置结构体,通常用于更新mqtt配置,再连接之前的回调事件中。

    esp_err_t esp_mqtt_client_register_event(esp_mqtt_client_handle_t client, esp_mqtt_event_id_t event, esp_event_handler_t event_handler, void* event_handler_arg);

    注册mqtt事件

    参数:

    • client:

    • event:事件类型

    • event_handler:事件处理回调函数

    • event_handler_arg:事件处理回调函数传入参数

    int esp_mqtt_client_get_outbox_size(esp_mqtt_client_handle_t client);

    获取邮箱大小

    六,示例

    在这里插入图片描述

    展开全文
  • <div><p>Hi I have weird problem with my ESP32. Every 10-15 days it disconnected from MQTT broker and can not connect without reset by button or unplug electricity. It is same for all my ESP32 but ESP...
  • Esp32 mqtt over websocket?

    2020-12-25 23:57:41
    <div><p>Hi is there any way your code connect mqtt over "...<p>https://github.com/espressif/arduino-esp32/issues/3639</p><p>该提问来源于开源项目:marvinroger/async-mqtt-client</p></div>
  • esp32 mqtt接入百度云点亮led

    千次阅读 2020-04-22 10:05:39
    esp32配置mqtt前言获取代码idf4.0版本mqtt流程编译 前言 首先先获取esp32mqtt的相关代码,使用idf编译esp32的相关代码我已经放到了github上esp32配网连接mqtt代码,代码支持一键配网,密码保存到flash,上点自动从...
  • static void mqtt_app_start(void) { mqtt_client =... ESP_ERROR_CHECK(esp_mqtt_client_start(mqtt_client)); //启动客户端,连接服务器 vTaskDelay(1000 / portTICK_PERIOD_MS); }
  • 关于如何在Windows下设置mqtt服务器请移步上一篇博文:python MQTT服务通信 环境准备: ...esp32连接的网络和运行mosqutto服务程序的电脑处在同一个网段 arduino代码 /********* @author: Wenqi
  • 系列文章: 【玩转ESP32】1、开发环境搭建 【玩转ESP32】2、开发参考资料 【玩转ESP32】3、点亮LED,Blink,blink,blink 【玩转ESP32】4、ESP32驱动DHT11 ...【玩转ESP32】9、ESP32 作为TCP客户端连接服务器(非

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,385
精华内容 1,754
关键字:

esp32mqtt