论坛元老
 
- 积分
- 3129
- 金钱
- 3129
- 注册时间
- 2017-11-28
- 在线时间
- 234 小时
|
50金钱
前不久购买了正点原子ESP32BOX3小智学习开发板,在测试WiFi_MQTT例程时为了显示动态时间,增加了时间读取及显示功能,谁料到增加时间显示后,随机运行一段时间后会卡死,经调试定位在增加液晶显示时间这一行代码处。
例程包含主函数main.c,及lwip_demo.c和wifi_config.c
其中wifi_config.c主要进行wifi配网初始化等一系列联网操作。
lwip_demo.c main.c实现MQTT功能。
代码内容如下:(粘贴部分相关代码)
//1.wifi_config.c------------------------------------------------------------------------------------------------------
/**
****************************************************************************************************
* @file wifi_config.c
* @Author 正点原子团队(ALIENTEK)
* @version V1.0
* @date 2023-08-26
* @brief 网络连接配置
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
****************************************************************************************************
* @attention
*
* 实验平台:正点原子 ESP32-S3 开发板
* 在线视频:www.yuanzige.com
* 技术论坛:www.openedv.com
* 公司网址:www.alientek.com
* 购买地址 penedv.taobao.com
*
****************************************************************************************************
*/
#include "wifi_config.h"
/* 链接wifi名称 */
#define DEFAULT_SSID "ALIENTEK-YF"
/* wifi密码 */
#define DEFAULT_PWD "aa123456789"
/* 事件标志 */
static EventGroupHandle_t wifi_event;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
network_connet_info network_connet;
static const char *TAG = "static_ip";
char lcd_buff[100] = {0};
/* WIFI默认配置 */
#define WIFICONFIG() { \
.sta = { \
.ssid = DEFAULT_SSID, \
.password = DEFAULT_PWD, \
.threshold.authmode = WIFI_AUTH_WPA2_PSK, \
}, \
}
/**
* @brief 链接显示
* @param flag:2->链接;1->链接失败;0->再链接中
* @retval 无
*/
void connet_display(uint8_t flag)
{
if((flag & 0x80) == 0x80)
{
spilcd_fill(0,90,320,240,WHITE);
sprintf(lcd_buff, "ssid:%s",DEFAULT_SSID);
spilcd_show_string(0, 90, 240, 16, 16, lcd_buff, BLUE);
sprintf(lcd_buff, "psw:%s",DEFAULT_PWD);
spilcd_show_string(0, 110, 240, 16, 16, lcd_buff, BLUE);
}
else if ((flag & 0x04) == 0x04)
{
spilcd_show_string(0, 90, 240, 16, 16, "wifi connecting......", BLUE);
}
else if ((flag & 0x02) == 0x02)
{
spilcd_show_string(0, 90, 240, 16, 16, "wifi connecting fail", BLUE);
}
else if ((flag & 0x01) == 0x01)
{
spilcd_show_string(0, 150, 200, 16, 16, (char*)network_connet.ip_buf, MAGENTA);
}
network_connet.connet_state &= 0x00;
}
/**
* @brief WIFI链接糊掉函数
* @param arg:传入网卡控制块
* @param event_base:WIFI事件
* @param event_id:事件ID
* @param event_data:事件数据
* @retval 无
*/
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
static int s_retry_num = 0;
/* 扫描到要连接的WIFI事件 */
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{
network_connet.connet_state |= 0x04;
network_connet.fun(network_connet.connet_state);
esp_wifi_connect();
}
/* 连接WIFI事件 */
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED)
{
network_connet.connet_state |= 0x80;
network_connet.fun(network_connet.connet_state);
}
/* 连接WIFI失败事件 */
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
network_connet.connet_state |= 0x02;
/* 尝试连接 */
if (s_retry_num < 20)
{
esp_wifi_connect();
s_retry_num ++;
ESP_LOGI(TAG, "retry to connect to the AP");
}
else
{
xEventGroupSetBits(wifi_event, WIFI_FAIL_BIT);
network_connet.fun(network_connet.connet_state);
}
ESP_LOGI(TAG,"connect to the AP fail");
}
/* 工作站从连接的AP获得IP */
else if(event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
network_connet.connet_state |= 0x01;
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "static ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
sprintf(network_connet.ip_buf, "static ip:" IPSTR, IP2STR(&event->ip_info.ip));
network_connet.fun(network_connet.connet_state);
xEventGroupSetBits(wifi_event, WIFI_CONNECTED_BIT);
}
}
/**
* @brief WIFI初始化
* @param 无
* @retval 无
*/
void wifi_sta_init(void)
{
static esp_netif_t *sta_netif = NULL;
network_connet.connet_state = 0x00;
network_connet.fun = connet_display;
wifi_event= xEventGroupCreate(); /* 创建一个事件标志组 */
/* 网卡初始化 */
ESP_ERROR_CHECK(esp_netif_init());
/* 创建新的事件循环 */
ESP_ERROR_CHECK(esp_event_loop_create_default());
sta_netif= esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL) );
ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL) );
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
wifi_config_t wifi_config = WIFICONFIG();
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start());
/* 等待链接成功后、ip生成 */
EventBits_t bits = xEventGroupWaitBits( wifi_event,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* 判断连接事件 */
if (bits & WIFI_CONNECTED_BIT)
{
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
DEFAULT_SSID, DEFAULT_PWD);
}
else if (bits & WIFI_FAIL_BIT)
{
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
DEFAULT_SSID, DEFAULT_PWD);
}
else
{
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
vEventGroupDelete(wifi_event);
}
//2.lwip_demo.c------------------------------------------------------------------------------------------------------
/**
****************************************************************************************************
* @file udp.c
* @author 正点原子团队(ALIENTEK)
* @version V1.0
* @date 2023-08-26
* @brief LWIP实验
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
****************************************************************************************************
* @attention
*
* 实验平台:正点原子 ESP32-S3 开发板
* 在线视频:www.yuanzige.com
* 技术论坛:www.openedv.com
* 公司网址:www.alientek.com
* 购买地址 penedv.taobao.com
*
****************************************************************************************************
*/
#include "lwip_demo.h"
#include "esp_sntp.h"
#include "esp_netif_sntp.h"
#include <time.h>
#include <sys/time.h>
int g_publish_flag = 0;/* 发布成功标志位 */
static const char *TAG = "MQTT_EXAMPLE";
char g_lcd_buff[100] = {0};
/**
* @brief 错误日记
* @param message :错误消息
* @param error_code :错误码
* @retval 无
*/
static void log_error_if_nonzero(const char *message, int error_code)
{
if (error_code != 0)
{
ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
}
}
/**
* @brief 注册接收MQTT事件的事件处理程序
* @param handler_args:注册到事件的用户数据
* @param base :处理程序的事件库
* @param event_id :接收到的事件的id
* @param event_data :事件的数据
* @retval 无
*/
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=%" PRIi32 "", 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_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 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);
g_publish_flag = 1;
/* 订阅主题 */
msg_id = esp_mqtt_client_subscribe(client, DEVICE_SUBSCRIBE, 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
break;
case 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, "/topic/qos0", "data", 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: /* 接收数据事件 */
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
break;
case 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;
}
}
/**
* @brief lwip_demo进程
* @param 无
* @retval 无
*/
void lwip_demo(void)
{
time_t now;
struct tm timeinfo;
struct timeval tv_now;
char strftime_buf[64]={0};
char mqtt_publish_data[] = "alientek dnesp32s3 mqtt demo";
/* 设置客户端的信息量 */
esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.hostname = HOST_NAME, /* MQTT地址 */
.broker.address.port = HOST_PORT, /* MQTT端口号 */
.broker.address.transport = MQTT_TRANSPORT_OVER_TCP, /* TCP模式 */
.credentials.client_id = CLIENT_ID, /* 设备名称 */
.credentials.username = (char*)USER_NAME, /* 产品ID */
.credentials.authentication.password = PASSWORD, /* 计算出来的密码 */
};
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, NULL);
esp_mqtt_client_start(client);
//增加时间获取代码部分---------------------->>>-----------------------------------------
time(&now);//获取时间戳
setenv("TZ","CST-8",1); //设置时区(例如中国标准时间CST-8)
tzset();
// 配置 SNTP,使用默认 NTP 服务器
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org");
config.sync_cb = sntp_sync_time; // 注册同步回调函数
esp_netif_sntp_init(&config);
esp_netif_sntp_start();
if(esp_sntp_get_sync_status() == SNTP_SYNC_STATUS_COMPLETED) //检查是否同步成功
ESP_LOGI("SNTP-OK", "Check Time synchronized");
LEDB_OFF;
//-------------------------------------------<<<-----------------------------------------
while(1)
{
if (g_publish_flag == 1)
{
esp_mqtt_client_publish(client,DEVICE_PUBLISH,(char *)mqtt_publish_data,strlen(mqtt_publish_data),1,0);
//增加代码用于屏幕显示---------------------->>>-------------------------------------------
time(&now);//获取时间戳
localtime_r(&now,&timeinfo); //将时间戳转换为本地时间结构体
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d %H:%M:%S", &timeinfo);
ESP_LOGI("TIME","当前日期/时间:%s",strftime_buf);
lcd_show_string(0, 200, 200, 16, 16, (char*)strftime_buf, MAGENTA); //--->随机运行一段时间,此处容易死机
//-------------------------------------------<<<------------------------------------------
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
//3.main.c-------------------------------------------------------------------------------------------------------------
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_mac.h"
#include "my_spi.h"
#include "lcd.h"
#include "aw9523b.h"
#include "lwip_demo.h"
#include "wifi_config.h"
#include <stdio.h>
void app_main(void)
{
esp_err_t ret;
ret = nvs_flash_init(); /* 初始化NVS */
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ESP_ERROR_CHECK(nvs_flash_init());
}
my_spi_init(); /* SPI初始化 */
myiic_init(); /* IIC初始化 */
aw9523b_init(); /* 初始化按键 */
lcd_init(); /* LCD屏初始化 */
lcd_show_string(0, 0, 240, 32, 32, "ESP32-S3", RED);
lcd_show_string(0, 40, 240, 24, 24, "WiFi Aliyun Test", RED);
lcd_show_string(0, 70, 240, 16, 16, "ATOM@ALIENTEK", RED);
wifi_sta_init(); /* WiFi STA模式初始化 */
lwip_demo(); /* lwip测试代码 */
}
问题出现在lwip_demo.c代码中增加的实时时间显示。请见如上注释
多次调试定位,确认是液晶显示代码卡死,网上查询说是液晶显示通讯不能中断,可能与free_rtos有冲突。
也尝试通过新建显示任务将刷新时间的功能,通过消息队列将该功能作为单独任务,结果也是同样卡死在
lcd_show_string(0, 200, 200, 16, 16, (char*)strftime_buf, MAGENTA); //--->随机运行一段时间,此处容易死机
想请教一下,正点原子提供的液晶显示函数,难道就不能正常使用吗
|
|