ESP32-IDF MQTT连接aws亚马逊云

1. 云端配置

  1. 登录AWS,地址: https://aws.amazon.com/

  2. 选择IOT core 服务

  3. 创建云端设备,点击连接一台设备 进行云端设备创建,按照流程创建云端设备,注意在创建过程中重要参数的保存

  1. 保存云端设备服务器域名地址,后续连接时有用!

  1. 填写设备名,并进入下一步

  1. 选择对应的平台及sdk,此处我选择linux及python,实际可根据个人情况修改   

 

  1. 下载对应设备的工具包,并存储好, 此包内内容是连接云端设备的唯一凭证

  1. 解压工具包,并运行里面的start.sh文件,进行测试

    运行前需要给予脚本可执行文件,输入以下指令:

    chmod +x start.sh
    ./start.sh
    

对应可以在网页看到由测试脚本上传上来的数据,如下图所示:


2. 设备端配置

  1. 拷贝ESP-IDF example目录下 ssl_mutual_auth 例程,ssl_mutual_auth

  2. 在终端输入 get_idf 配置 idf 环境

  1. 进入对应工程目录,输入 idf.py menuconfig 修改工程配置文件,配置wifi连接信息

    路径: -> Example Connection Configuration -> WiFi SSID / WiFi Password

    打开工程,替换证书文件,总共需要替换三个证书,替换的文件在刚刚下载的连接工具包中,对应关系如下:
    • client.crt 客户端证书,采用 xxx.cert.pem 替换
    • client.key 客户端秘钥,采用 xxx.private.key 替换
    • mosquitto.org.crt 服务端秘钥,采用 root-CA.crt 替换
  2. 修改程序 mqtt 客户端配置代码,配置代码修改注意两个重点,否则后续再连接时会连接失败

    • 修改 uri 参数,域名前面需要增加 mqtts:// 前缀
      • 域名地址为云端配置第四步时保存的域名地址
    • 需要增加 client_id 配置项内容
      • 此测试 client_id  ./start.h 脚本所使用的client_id
    const esp_mqtt_client_config_t mqtt_cfg = {
      .broker.address.uri = "mqtts://xxx(你自己的域名)xxx.amazonaws.com",
      .broker.verification.certificate = (const char *)server_cert_pem_start,
      .credentials = {
        .authentication = {
          .certificate = (const char *)client_cert_pem_start,
          .key = (const char *)client_key_pem_start,
        },
        .client_id = "basicPubSub",
      }
    };
    

  1. 修改订阅和发布消息主题,修改mqtt_event_handler() mqtt事件回调函数内容如下:

    /*
     * @brief Event handler registered to receive MQTT events
     *
     *  This function is called by the MQTT client event loop.
     *
     * @param handler_args user data registered to the event.
     * @param base Event base for the handler(always MQTT Base in this example).
     * @param event_id The id for the received event.
     * @param event_data The data for the event, esp_mqtt_event_handle_t.
     */
    static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
    {
        ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
        esp_mqtt_event_handle_t event = event_data;
        esp_mqtt_client_handle_t client = event->client;
        int msg_id;
        switch ((esp_mqtt_event_id_t)event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            msg_id = esp_mqtt_client_subscribe(client, "sdk/test/python", 0);
            ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
    
            // msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
            // ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
    
            // msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
            // ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;
    
        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            msg_id = esp_mqtt_client_publish(client, "sdk/test/python", "good morning", 0, 0, 0);
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_UNSUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED:
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA:
            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);
    
            msg_id = esp_mqtt_client_publish(client, "sdk/test/python", "good afternoon", 0, 0, 0);
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
                log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
                log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
                log_error_if_nonzero("captured as transport's socket errno",  event->error_handle->esp_transport_sock_errno);
                ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
    
            }
            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
        }
    }
    
  2. 编译烧录下载程序,在串口终端可以看到成功连接上服务器,并订阅了主题以及发布了消息,同时也接收到了对应主题返回的消息,由于这里测试发送和接收共用了同一个主题,所以接收到的数据我我们在代码里设置的发送数据内容。

    此外,我们在AWS网页上亦可看到我们上报的数据内容,如下所示:

  3. 注意使用ESP32连接AWS的时候,./start 脚本记得关闭,由于这两个设备使用的是同一个 client_id,因此会造成冲突,此处只是简单的测试演示,实际开发的时候,对应云平台要进行配置,每个设备有不同且唯一的client_id

3. 总结

以上便是使用ESP32 IDF开发方案连接AWS MQTT服务器的简单应用了,重点需要注意的是初始化mqtt_cfg结构体的时候对应的参数配置,以及需要增加 client_id 参数才能连接成功,原本的示例 demo 里面没有此项内容,这可能是大家连接不上的一个重要原因。


创作不易,转载请注明出处!

关注、点赞+收藏,可快速查收博主有关分享!


相关文章推荐: