用按键来发布消息,AWS订阅消息,按键能用,但就是在AWS平台上看不到信息,不知道是哪里出问题了

fst202130609
Posts: 171
Joined: Thu Sep 23, 2021 10:03 am

用按键来发布消息,AWS订阅消息,按键能用,但就是在AWS平台上看不到信息,不知道是哪里出问题了

Postby fst202130609 » Thu Oct 14, 2021 8:28 am

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

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, "%.*s\t%.*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, &paramsQOS1);
// 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:%s\r\n",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 Down\r\n");
sprintf(cPayload, "%s", "{\"message\": \"jhgfsytgsdewrhtgfyhrfcdf\"}");

paramsQOS1.payloadLen = strlen(cPayload);
rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS1);
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 Down\r\n");
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);

}

ESP_ICY
Posts: 404
Joined: Mon Aug 23, 2021 11:10 am

Re: 用按键来发布消息,AWS订阅消息,按键能用,但就是在AWS平台上看不到信息,不知道是哪里出问题了

Postby ESP_ICY » Fri Oct 15, 2021 2:23 am

可以提供下程序运行的log吗

fst202130609
Posts: 171
Joined: Thu Sep 23, 2021 10:03 am

Re: 用按键来发布消息,AWS订阅消息,按键能用,但就是在AWS平台上看不到信息,不知道是哪里出问题了

Postby fst202130609 » Fri Oct 15, 2021 6:00 am

已经解决了,按键和AWS是两个任务,优先级一样,所以导致AWS收不到信息,修改优先级就行了

Who is online

Users browsing this forum: No registered users and 47 guests