乐鑫技术交流
直播中

邹俩珍

7年用户 1062经验值
私信 关注
[问答]

用按键来发布消息,AWS订阅消息,按键能用但就是在AWS平台上看不到信息,怎么解决?

以下是完整的代码,望各位大佬帮帮忙,实在是不懂了

static const char *TAG = "subpub";
static xQueueHandle gpio_evt_queue = NULL;
#define GPIO_INPUT_IO_Key     4
// 定义按下按钮枚举类型
typedef enum {
        KEY_SHORT_PRESS = 1,
        KEY_LONG_PRESS,
} alink_key_t;
esp_err_t alink_key_scan(TickType_t ticks_to_wait);
void key_trigger_Task(void *arg);
/* The examples use simple WiFi configuration that you can set via
   'make menuconfig'.

   If you'd rather not, just change the below entries to strings with
   the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD

/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
const int CONNECTED_BIT = BIT0;


/* CA Root certificate, device ("Thing") certificate and device
* ("Thing") key.

   Example can be configured one of two ways:

   "Embedded Certs" are loaded from files in "certs/" and embedded into the app binary.

   "Filesystem Certs" are loaded from the filesystem (SD card, etc.)

   See example README for more details.
*/
#if defined(CONFIG_EXAMPLE_EMBEDDED_CERTS)

extern const uint8_t aws_root_ca_pem_start[] asm("_binary_aws_root_ca_pem_start");
extern const uint8_t aws_root_ca_pem_end[] asm("_binary_aws_root_ca_pem_end");
extern const uint8_t certificate_pem_crt_start[] asm("_binary_certificate_pem_crt_start");
extern const uint8_t certificate_pem_crt_end[] asm("_binary_certificate_pem_crt_end");
extern const uint8_t private_pem_key_start[] asm("_binary_private_pem_key_start");
extern const uint8_t private_pem_key_end[] asm("_binary_private_pem_key_end");

#elif defined(CONFIG_EXAMPLE_FILESYSTEM_CERTS)

static const char * DEVICE_CERTIFICATE_PATH = CONFIG_EXAMPLE_CERTIFICATE_PATH;
static const char * DEVICE_PRIVATE_KEY_PATH = CONFIG_EXAMPLE_PRIVATE_KEY_PATH;
static const char * ROOT_CA_PATH = CONFIG_EXAMPLE_ROOT_CA_PATH;

#else
#error "Invalid method for loading certs"
#endif

/**
* @brief Default MQTT HOST URL is pulled from the aws_iot_config.h
*/
char HostAddress[255] = AWS_IOT_MQTT_HOST;

/**
* @brief Default MQTT port is pulled from the aws_iot_config.h
*/
uint32_t port = AWS_IOT_MQTT_PORT;


static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch(event->event_id) {
    case SYSTEM_EVENT_STA_START:
        esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        /* This is a workaround as ESP32 WiFi libs don't currently
           auto-reassociate. */
        esp_wifi_connect();
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        break;
    default:
        break;
    }
    return ESP_OK;
}

void iot_subscribe_callback_handler(AWS_IoT_Client *pClient, char *topicName, uint16_t topicNameLen,
                                    IoT_Publish_Message_Params *params, void *pData) {
    ESP_LOGI(TAG, "Subscribe callback");
    ESP_LOGI(TAG, "%.*st%.*s", topicNameLen, topicName, (int) params->payloadLen, (char *)params->payload);
}

void disconnectCallbackHandler(AWS_IoT_Client *pClient, void *data) {
    ESP_LOGW(TAG, "MQTT Disconnect");
    IoT_Error_t rc = FAILURE;

    if(NULL == pClient) {
        return;
    }

    if(aws_iot_is_autoreconnect_enabled(pClient)) {
        ESP_LOGI(TAG, "Auto Reconnect is enabled, Reconnecting attempt will start now");
    } else {
        ESP_LOGW(TAG, "Auto Reconnect not enabled. Starting manual reconnect...");
        rc = aws_iot_mqtt_attempt_reconnect(pClient);
        if(NETWORK_RECONNECTED == rc) {
            ESP_LOGW(TAG, "Manual Reconnect Successful");
        } else {
            ESP_LOGW(TAG, "Manual Reconnect Failed - %d", rc);
        }
    }
}
char cPayload[100];
AWS_IoT_Client client;
IoT_Error_t rc = FAILURE;
IoT_Publish_Message_Params paramsQOS1;
int flag =0;
void aws_iot_task(void *param) {
    int32_t i = 0;

    IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault;
    IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault;
    IoT_Publish_Message_Params paramsQOS0;

    ESP_LOGI(TAG, "AWS IoT SDK Version %d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);

    mqttInitParams.enableAutoReconnect = false; // We enable this later below
    mqttInitParams.pHostURL = HostAddress;
    mqttInitParams.port = port;

#if defined(CONFIG_EXAMPLE_EMBEDDED_CERTS)
    mqttInitParams.pRootCALocation = (const char *)aws_root_ca_pem_start;
    mqttInitParams.pDeviceCertLocation = (const char *)certificate_pem_crt_start;
    mqttInitParams.pDevicePrivateKeyLocation = (const char *)private_pem_key_start;

#elif defined(CONFIG_EXAMPLE_FILESYSTEM_CERTS)
    mqttInitParams.pRootCALocation = ROOT_CA_PATH;
    mqttInitParams.pDeviceCertLocation = DEVICE_CERTIFICATE_PATH;
    mqttInitParams.pDevicePrivateKeyLocation = DEVICE_PRIVATE_KEY_PATH;
#endif

    mqttInitParams.mqttCommandTimeout_ms = 20000;
    mqttInitParams.tlsHandshakeTimeout_ms = 5000;
    mqttInitParams.isSSLHostnameVerify = true;
    mqttInitParams.disconnectHandler = disconnectCallbackHandler;
    mqttInitParams.disconnectHandlerData = NULL;

#ifdef CONFIG_EXAMPLE_SDCARD_CERTS
    ESP_LOGI(TAG, "Mounting SD card...");
    sdmmc_host_t host = SDMMC_HOST_DEFAULT();
    sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
        .format_if_mount_failed = false,
        .max_files = 3,
    };
    sdmmc_card_t* card;
    esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "Failed to mount SD card VFAT filesystem. Error: %s", esp_err_to_name(ret));
        abort();
    }
#endif

    rc = aws_iot_mqtt_init(&client, &mqttInitParams);
    if(SUCCESS != rc) {
        ESP_LOGE(TAG, "aws_iot_mqtt_init returned error : %d ", rc);
        abort();
    }
    else if(SUCCESS == rc)
    {
        ESP_LOGE(TAG, "aws_iot_mqtt_init sucessful : %d ", rc);
    }

    /* Wait for WiFI to show as connected */
    xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
                        false, true, portMAX_DELAY);

    connectParams.keepAliveIntervalInSec = 10;
    connectParams.isCleanSession = true;
    connectParams.MQTTVersion = MQTT_3_1_1;
    /* Client ID is set in the menuconfig of the example */
    connectParams.pClientID = CONFIG_AWS_EXAMPLE_CLIENT_ID;
    connectParams.clientIDLen = (uint16_t) strlen(CONFIG_AWS_EXAMPLE_CLIENT_ID);
    connectParams.isWillMsgPresent = false;

    ESP_LOGI(TAG, "Connecting to AWS...");
    do {
        rc = aws_iot_mqtt_connect(&client, &connectParams);
        if(SUCCESS != rc) {
            ESP_LOGE(TAG, "Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port);
            vTaskDelay(1000 / portTICK_RATE_MS);
        }
    } while(SUCCESS != rc);

    /*
     * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
     *  #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
     *  #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
     */
    rc = aws_iot_mqtt_autoreconnect_set_status(&client, true);
    if(SUCCESS != rc) {
        ESP_LOGE(TAG, "Unable to set Auto Reconnect to true - %d", rc);
        abort();
    }

    const char *TOPIC = "esp32/topic";
    const int TOPIC_LEN = strlen(TOPIC);

    ESP_LOGI(TAG, "Subscribing...");
    rc = aws_iot_mqtt_subscribe(&client, TOPIC, TOPIC_LEN, QOS0, iot_subscribe_callback_handler, NULL);
    if(SUCCESS != rc) {
        ESP_LOGE(TAG, "Error subscribing : %d ", rc);
        abort();
    }
    sprintf(cPayload, "%s : %d ", "hello from SDK", i);

    paramsQOS0.qos = QOS0;
    paramsQOS0.payload = (void *) cPayload;
    paramsQOS0.isRetained = 0;
    while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc)) {

        //Max time the yield function will wait for read messages
        rc = aws_iot_mqtt_yield(&client, 100);
        if(NETWORK_ATTEMPTING_RECONNECT == rc) {
            // If the client is attempting to reconnect we will skip the rest of the loop.
            continue;
        }
       // ESP_LOGI(TAG, "Stack remaining for task '%s' is %d bytes", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL));
      //  vTaskDelay(1000 / portTICK_RATE_MS);
        //sprintf(cPayload, "%s", "{"message": "123456789876543210"}");
       // paramsQOS1.payloadLen = strlen(cPayload);
       // rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, ¶msQOS1);
       // if (rc == MQTT_REQUEST_TIMEOUT_ERROR)
       // {
           // ESP_LOGW(TAG, "QOS1 publish ack not received.");
       //   //  rc = SUCCESS;
       // }
    }

    ESP_LOGE(TAG, "An error occurred in the main loop.");
    abort();
}
// GPIO中断处理函数
void IRAM_ATTR gpio_isr_handler(void *arg) {
        uint32_t gpio_num = (uint32_t) arg;
        xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
// 按键GPIO初始化
void KeyInit(uint32_t key_gpio_pin) {
        //配置GPIO结构体
        gpio_config_t io_conf;
        io_conf.intr_type = GPIO_INTR_ANYEDGE;                // 下降沿和上升沿触发中断
        io_conf.pin_bit_mask = 1 << key_gpio_pin;        // 设置GPIO号
        io_conf.mode = GPIO_MODE_INPUT;                                // 模式输入
        io_conf.pull_up_en = GPIO_PULLUP_ENABLE;        // 端口上拉使能
        gpio_config(&io_conf);

        // 设置GPIO中断类型
        gpio_set_intr_type(GPIO_INPUT_IO_Key, GPIO_INTR_ANYEDGE);// 下降沿和上升沿触发中断
        // 初始化GPIO事件队列
        gpio_evt_queue = xQueueCreate(2, sizeof(uint32_t));
        // 安装GPIO中断服务
        gpio_install_isr_service(0);
        // 添加GPIO中断事件回调函数
        gpio_isr_handler_add(key_gpio_pin, gpio_isr_handler, (void *) key_gpio_pin);
}

// 按键扫描函数,任务中调用
esp_err_t alink_key_scan(TickType_t ticks_to_wait)
{
        uint32_t io_num;
        BaseType_t press_key = pdFALSE;
        BaseType_t release_key = pdFALSE;
        int backup_time = 0;
        while (1) {
                // 接收从消息队列发来的消息
                xQueueReceive(gpio_evt_queue, &io_num, ticks_to_wait);
                if (gpio_get_level(io_num) == 0) {//当前低电平,记录下用户按下按键的时间点
                        press_key = pdTRUE;
                        backup_time = esp_timer_get_time();
                        //如果当前GPIO口的电平已经记录为按下,则开始减去上次按下按键的时间点
                } else if (press_key) {
                        //记录抬升时间点
                        release_key = pdTRUE;
                        backup_time = esp_timer_get_time() - backup_time;
                }
                //近当按下标志位和按键弹起标志位都为1时候,才执行回调
                if (press_key & release_key) {
                        press_key = pdFALSE;
                        release_key = pdFALSE;
                        //如果大于1s则回调长按,否则就短按回调
                        if (backup_time > 1000000) {
                                return KEY_LONG_PRESS;
                        } else {
                                return KEY_SHORT_PRESS;
                        }
                }
        }
}

// 按键中断任务
void key_trigger_Task(void *arg) {
    const char *TOPIC = "esp32/topic";
    const int TOPIC_LEN = strlen(TOPIC);
        esp_err_t ret = 0;
    paramsQOS1.qos = QOS1;
    paramsQOS1.payload = (void *) cPayload;
    paramsQOS1.isRetained = 0;
    printf("************Qos2:%srn",paramsQOS1.payload);
        KeyInit(GPIO_INPUT_IO_Key);
        while (1) {
                ret = alink_key_scan(portMAX_DELAY);
                if (ret == -1)
                        vTaskDelete(NULL);
                switch (ret) {
                case KEY_SHORT_PRESS:
                        ESP_LOGI(TAG,"Button Short Downrn");
             sprintf(cPayload, "%s", "{"message": "jhgfsytgsdewrhtgfyhrfcdf"}");

            paramsQOS1.payloadLen = strlen(cPayload);
            rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, ¶msQOS1);
            if (rc == MQTT_REQUEST_TIMEOUT_ERROR) {
                ESP_LOGW(TAG, "QOS1 publish ack not received.");
                rc = SUCCESS;
            }
                        break;
                case KEY_LONG_PRESS:
                        ESP_LOGI(TAG,"Button Long Downrn");
                        break;
                default:
                        break;
                }
        }
        vTaskDelete(NULL);
}

static void initialise_wifi(void)
{
    tcpip_adapter_init();
    wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_WIFI_SSID,
            .password = EXAMPLE_WIFI_PASS,
        },
    };
    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
}

void app_main()
{
    // Initialize NVS.
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK( err );

    initialise_wifi();
    xTaskCreatePinnedToCore(&key_trigger_Task, "key_trigger_Task", 1024 * 2, NULL, 4, NULL, 1);
    xTaskCreatePinnedToCore(&aws_iot_task, "aws_iot_task", 9216, NULL, 5, NULL, 1);
   
}

回帖(1)

朱小玲

2024-6-20 15:48:48
按键和AWS是两个任务,优先级一样,所以导致AWS收不到信息,修改优先级就行了
举报

更多回帖

发帖
×
20
完善资料,
赚取积分