在环境搭建好之后,编译出工程 bin 文件,下一步便是烧录到开发板了
将开发板通过USB连接到虚拟机
ls /dev/tty* 看到有 /dev/ttyUSB0 即连接成功
但是在 idf.py -p /dev/ttyUSB0 flash 时却出错了
通过命令 ls -lh /dev/ttyUSB0
可知此时权限为 660
寻找解决方法后:
sudo chmod 777 /dev/ttyUSB0
再次执行
idf.py -p /dev/ttyUSB0 flash 成功
但是这种设置在重启后又得重新设置,
于是执行
sudo usermod -aG dialout usrname ,注销后重新登陆即可。
( 1. dialout 是串口设备所在的组
2. usrname为你想要使用 /dev/ttyUSB0 的用户名,可以使用 whoami 查看)
执行 sudo usermod -aG dialout usrname 前:
执行 sudo usermod -aG dialout usrname 后:
(1)
执行语句:esptool.py --port /dev/ttyUSB0 write_flash_status --non-volatile 0
再次flash解决
(2)
又一次遇到了相同的问题,使用方法(1)无法解决,
最终发现是买的flash大小不合适,更换flash解决
(note:想要4MBflash,淘宝直接搜索4Mflash,搜到的都是4Mb(512kB)的,)
虽然烧录不进,但是通过espefuse.py summary查看芯片信息正常
解决:后重新焊接了一次串口线和flash,问题解决,猜测应该是flash没焊接好.
2.1 头文件在 esp-idf/components/ 目录下
根据日志可知 nvs_flash.h 存在问题
在 esp-idf 文件夹下执行 :
find ./ -name nvs_flash.h
于是在 project_dir(项目目录)/main/ 下CMakeLists.txt文件中添加此文件路径
2.2 头文件在 esp-idf/examples/ 目录下 (未解决)
根据日志可知 protocol_examples_common.h 存在问题
在 esp-idf 文件夹下执行 :
find ./ -name protocol_examples_common.h
可知该文件位置 :examples/common_components/protocol…
于是打算搜索其他使用过该头文件的例程看配置:
找到 tcp_server 例程使用到了该头文件
并且尝试编译了 tcp_server例程发现编译成功,于是查找该例程配置:
打开该CMakeLists.txt文件:
发现此处正好有protocol_examples_common.h对应的路径,于是把该部分添加到了自己项目中对应的位置
再查看其他文件,发现并没有其他特别的地方
于是再次编译,结果发现还是报相同的错误
于是我很懵逼,不知道为什么例程不会报错,我编译就会报错。。。
后了解到该组件目录(examples/common_components/protocol_examples_common)
是为了简化例程代码才具有的,并不适合用于正式工程
于是就把该头文件注释掉了,再次编译发现编译通过了
( 发现自己的工程中以前使用到该头文件内容的代码早被注释掉,没有使用了,只是头文件没删掉,因此现在把头文件也去掉。
不过相同的代码之前在release_v4.3版本编译没事,这次把整个项目文件移植到stable_v4.4就出现这个问题,也没搞清楚怎么回事,只能在此稍做记录一下)
在项目中,需要使用到UART0来与MCU进行通信,配置好UART0后,发现通信过程中数据与自己代码传输的有些出入,TX发送了很多无关的数据,后来发现log等输出都是默认输出到UART0的,在查找相关资料后找到3个可以改动的地方如下:
我将上述三处地方都改动后再次用串口查看TX数据,发现数据正常了
此时
那么具体每个选项造成的影响呢?经过测试如下
4.1
4.2
测试发现数据正常,所以无用数据应该不是该处影响
4.3
此时发现uart0 可以看到日志打印,但由于配置了UART0用于通信,导致日志停止如下
查看串口数据:
在发送所需数据时前面多了很多其他数据,且在通信时TX不应发送数据时也会不断弹出大量数据
4.3
经仔细检查后发现,sdkconfig中CONFIG_CONSOLE_UART_NUM为0,所以日志依旧输出向串口0
手动改动sdkconfig CONFIG_CONSOLE_UART_NUM = 1后,再次编译又会变回0,于是找到menucinfig 定义文件添加上对串口号的选择项使我们在menuconfig中可以选择自定义串口号来改变CONFIG_CONSOLE_UART_NUM(文件位置:esp-idf/components/esp_common/Kconfig)
成功后 CONFIG_CONSOLE_UART_NUM变为1,在代码中对串口1初始化后,发现日志可以正常输出向串口1了,且串口0通信正常;之后尝试在代码中关闭了串口1初始化后,发现不能输出日志了。
note:需要有日志打印,TOP /Component config /Log output 处不能关闭
5.1 初始测试使用静态uri:(uri改变需要改代码)
esp_mqtt_client_config_t mqtt_cfg = { .uri = "xxxxxx"};
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);
成功初始化,没有问题,后想使用接收到的指定uri "yyyyyy"
5.2 使用动态uri:(uri改变不需要改代码,健壮性更好)
char mqtt_url[64] = {0};
get_info_from_nvs(mqtt_url); //将nvs中的uri放入mqtt_uri
esp_mqtt_client_config_t mqtt_cfg ;
mqtt_cfg.uri = mqtt_url;
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);
运行至 esp_mqtt_client_init(&mqtt_cfg)
报错如下:
进行修改:
esp_mqtt_client_config_t mqtt_cfg ;
改为->
esp_mqtt_client_config_t mqtt_cfg = {.uri = NULL,};
或者 esp_mqtt_client_config_t mqtt_cfg = {0};
修改后运行正常
使用 esp_mqtt_client_set_uri()也可以
char mqtt_url[64] = {0};
get_info_from_nvs(mqtt_url); //将nvs中的uri放入mqtt_uri
esp_mqtt_client_config_t mqtt_cfg = {.uri = NULL,};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_set_uri(client,mqtt_url);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
esp_mqtt_client_start(client);
note: 不能写为:esp_mqtt_client_config_t mqtt_cfg ;
正常sta模式配置:
void Wifi_init_sta(void)
{
//创建一个新的事件组
s_wifi_event_group = xEventGroupCreate();
//初始化tcp/ip协议栈(LwIP)
ESP_ERROR_CHECK(esp_netif_init());
//创建默认事件循环(初始化wifi事件处理)
ESP_ERROR_CHECK(esp_event_loop_create_default());
//创建有TCP/IP堆栈的默认网络接口实例绑定station
sta_netif = esp_netif_create_default_wifi_sta();
//初始化wifi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// esp_event_handler_instance_t instance_any_id;
// esp_event_handler_instance_t instance_got_ip;
//向默认循环注册一个事件处理程序实例
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip));
//wifi配置
wifi_config_t wifi_config = {
.sta = {
// .ssid = sta_addr,
// .password = sta_password,
/* Setting a password implies station will connect to all security modes including WEP/WPA.
* However these modes are deprecated and not advisable to be used. Incase your Access point
* doesn't support WPA2, these mode can be enabled by commenting below line */
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.capable = true,
.required = false
},
},
};
strcpy((char *)wifi_config.sta.ssid,ssid);
strcpy((char *)wifi_config.sta.password,password);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
//启动wifi
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_LOGI(TAG, "wifi_init_sta finished.");
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
if (bits & CONNECTED_BIT) {
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
ssid, password);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGE(TAG, "Failed to connect to SSID:%s, password:%s",
ssid, password);
} else {
ESP_LOGE(TAG, "UNEXPECTED EVENT");
}
/* The event will not be processed after unregister */
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
vEventGroupDelete(s_wifi_event_group);
}
正常ap模式配置:
void Wifi_init_sta(void)
{
uint8_t ApMac[6] = {0};
ESP_ERROR_CHECK(esp_netif_init()); //初始化tcp/ip协议栈(LwIP)
ESP_ERROR_CHECK(esp_event_loop_create_default()); //创建默认事件循环(初始化wifi事件处理)
esp_netif_create_default_wifi_ap(); 创建具有TCP / IP堆栈的默认网络接口实例绑定AP
//初始化wifi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
//将事件处理程序注册到系统事件循环(wifi事件族)
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
NULL));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
esp_wifi_get_mac( ESP_IF_WIFI_AP , ApMac );//获取DHCP分配的IP接口的mac
//wifi配置
wifi_config_t wifi_config = {
.ap = {
//.ssid = AP_ESP_WIFI_SSID,
//.ssid_len = strlen(AP_ESP_WIFI_SSID)+5,
.channel = AP_ESP_WIFI_CHANNEL,
.password = AP_ESP_WIFI_PASS,
.max_connection = AP_MAX_STA_CONN,
//.authmode = WIFI_AUTH_WPA_WPA2_PSK
.authmode = WIFI_AUTH_OPEN //wifi安全类型
},
};
sprintf((char *)wifi_config.ap.ssid,"%s_%02X%02X",AP_ESP_WIFI_SSID,ApMac[4],ApMac[5]);
if (strlen(AP_ESP_WIFI_PASS) == 0)
{
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
//启动wifi
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
wifi_config.ap.ssid, AP_ESP_WIFI_PASS, AP_ESP_WIFI_CHANNEL);
}
在sta模式时想要切换为ap模式而不重启:
首先将sta的一些wifi配置取消掉
esp_wifi_disconnect();
esp_wifi_stop();
esp_wifi_deinit();
//s_wifi_event_group = NULL;
按照 ap 模式进行配置
发现运行在 ESP_ERROR_CHECK(esp_event_loop_create_default()); 时报错重启
于是将ap配置的 ESP_ERROR_CHECK(esp_event_loop_create_default()) 删除,发现成功开启ap模式
note: 刚开始配置sta时也调用了esp_event_loop_create_default(),
可能
esp_wifi_disconnect();
esp_wifi_stop();
esp_wifi_deinit();
并不会取消esp_event_loop_create_default()操作,于是再次配置ap时又调用esp_event_loop_create_default()导致报错
7.1 出各种错重启,0xf,0x7,0x3等,烧录时有时也报错无法正常进行
经查,连接芯片的gnd引脚很多金属丝松动,只连上少许,使用新的导线重连gnd,问题解决
7.2 模组本来正常,在测试过程中出了问题,monitor也看不到日志了,于是重新烧录并查看日志,烧录成功后,monitor 发现找不到分区表一直重启
不知道是什么原因导致的,该怎么解决,可能是模组被玩坏了吧,只能换个模组了
发现模组出了问题后,每次烧录后日志也有些区别,但是应用程序都跑不起来
(这次出问题时,在模组串口与MCU通信时,额外加了个串口线连接电脑查看通信内容,可能是TX也接上了导致芯片烧了)
7.3 烧录成功后,报错重启(SPI_FAST_FLASH_BOOT)
该flash: 25L3206e(4MB) ,换成华邦 W25Q32BVSIG(4MB)
芯片控制继电器工作,当上电时继电器总会吸合,想让芯片启动时判断是否为上电启动,上电启动的话软件控制继电器断开,其他启动方式不做处理
根据重启日志进行查询
grep -nr POWERON …/esp-idf/
再次查询
grep -nr POWERON_RESET …/esp-idf/
。。。经过不断查找结果如下