ESP32的开发环境确实不友好,远不如STM32,在了解了几个的编译环境和方法后,我认为这个方法是最简单方便的,无需繁杂的命令配置,只需要认真阅读官方文档一般都能解决问题。
这里有几个问题:
1).为什么开发环境要使用Linux而不是Windows:
Linux下编译更快!速度在5-10倍以上
2).为什么编译工具使用VScode而不是CMake等,其实Eclipse也是可以的,但是我习惯了vs全家桶,就用vscode了。
主要是方便,再加上本身对CMake、Makefile也不熟悉。
编译ESP32的工具介绍如图:
官方ESP-IDF 编程指南文档:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/index.html
3)为什么要在Windows下使用虚拟机,而不是直接在物理机上运行一个Linux(Ubuntu)?
①主要是Windows下使用虚拟机可以在两个系统间方便的复制代码、复制文字、移动文件等。
②还可以更方便快速的创建系统的备份点和还原点。(需要安装VMware Tools)(不过文件类的还是建议使用 FileZilla Client 服务器-客户端发送,这样会避免文件的错误传输)
模拟器就使用VMware Workstation Pro就好。
Ubuntu可以在官网下载。https://ubuntu.com/#download
VMware Workstation Pro也可以在官网下载。https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html
安装前要记得查看自己的Ubuntu是多少位的系统;
查看命令:getconf LONG_BIT
安装命令:sudo dpkg -i code_1.32.3-1552606978_amd64.deb
其中code_1.32.3-1552606978_amd64.deb
为自己的安装包文件名
使用快捷键 Ctrl+Shift+X 打开扩展商店,然后在里面搜索需要安装的插件:
其中需要安装的有:
1)、 C/C++,这个肯定是必须的。
2)、 C/C++ Snippets,即 C/C++重用代码块。
3)、 C/C++ Advanced Lint,即 C/C++静态检测 。
4)、 Code Runner,即代码运行。
5)、 Include AutoComplete,即自动头文件包含。
6 、 Rainbow Brackets,彩虹花括号,有助于阅读代码。
7)、 One Dark Pro VSCode的主题。
8)、 GBKtoUTF8,将 GBK转换为 UTF8。
9 、 ARM,即支持 ARM汇编语法高亮显示。
10)、 Chinese(Simplified),即中文环境。
11)、 vscode-icons VSCode图标插件,主要是资源管理器下各个文件夹的图标。
12)、 compareit,比较插件,可以用于比较两个文件的差异。
13)、 DeviceTree,设备树语法插件。
14)、 TabNine,一款 AI自动补全 插件
最后步入正题,安装ESP32 IDF编译器/环境配置,点击安装即可。
安装帮助文档:https://github.com/espressif/vscode-esp-idf-extension/blob/master/docs/tutorial/install.md
按照文档安装即可,过程中会出错和失败,此时断开安装,再次打开ESP IDF Setup接着安装即可。需要注意的是:
1.在选择下载服务器的时候要不要选择GitHub,要选择ESP官方的服务器,因为GitHub服务器太慢了,很大几率下载失败。
2.如果安装失败后再继续尝试的时候,为了避免重复下载,所以在选择ESP IDE版本的时候要选择用户本地的版本,这样会节省时间。
直到出现配置成功界面就可以了!
这一步试了很久…(都怪自己没有好好看帮助文档)
1.一切安装好后,首先打开命令面板(快捷键 Ctrl+Shift+P),进入ESP-IDF:show examples Prijects:
搜索到以下项后,再点击进入示例列表:
2.选择一个示例,然后选择一个工作目录。
3.接下来有3步需要执行:
1)打开命令面板,输入命令sdk configuration editor
使用IDF的配置脚本进行默认配置,也可自行修改。
2)打开命令面板,输入命令add vscode configuration folder
添加IDF编译器在vscode中的配置文件,只需配置一次(更换项目后也不需要再配置)。
在vscode右下角提示框中有此信息表示正确配置。
3)打开命令面板,输入命令build your project
(快捷键为 Ctrl+E 松手 再按下B)
进行编译,并且生成.bin文件。该文件在build目录下。
编译成功如下:
在扩展插件中搜索PlatformIO并安装
安装完毕后进入PlatformIO,安装自己需要的平台。
如果按照我的步骤安装,这个平台应该是已经有的,因为在第三步安装插件的时候,我们已经使用ESP-IDF安装器安装过Espressif 32平台了。
安装完后,进入插件新建一个项目
选择开发板型号和平台,可以使用Arduino平台。
Arduino平台的优势就是轮子多,方便,但他并不能作为开发者开发商业产品的专业平台,适合自己做个小玩意啥的。
当然了,也可以使用乐鑫的平台操作都一样,效果可以看 第7部分。
新建完成后,就可以看到主函数了。然后可以打开PlatformIO的主页,搜索一些示例代码,测试一下。随便搜索一个LED的就行。
点进去添加到自己的项目
选择版本和项目,点Add添加就可以了。
复制以下他的使用示例代码到main.cpp里面,值得一提的是,.cpp是使用的C++语言。
进入main.cpp点击编译,会提示8个错误,错误原因是有函数未声明。
我们把他都声明下,或者直接把loo函数放在main.cpp的末尾,省的声明了。。。再次编译,就没有错误了。
接下来下载进开发板就可以了,下载之前要检查设备端口文件。我的是USB0,选择USB0就好了。
然后点击 " -> " 下载。在下载的时候要按住BOOT键,直到提示写入Flash为止。
到这里就下载成功了。
可以看到端口显示了很多乱码,这是由于,Monitor默认波特率是9600,我们把他改为115200就可以了。打开这个PlatformIO的配置文件,添加Monitor的波特率速度为115200
monitor_speed = 115200
再编译下载后就正常了,我加了一段打印的代码。
优势:原生,专业,代码量小。最重要的是C语言、使用的官方原生库,更加完整。但就是资料比较少,轮子少,需要自己造,能参考的就是官方例程源码和官方手册。
(毕竟Arduino是一种玩具或者爱好者类的开发,并不专业)
直接打开ESP IDF随便搜索一个例程,然后直接粘贴我下面的代码:
/* Scan Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
/*
This example shows how to scan for available set of APs.
*/
#include
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event.h"
#include "nvs_flash.h"
#define DEFAULT_SCAN_LIST_SIZE CONFIG_EXAMPLE_SCAN_LIST_SIZE
static const char *TAG = "scan";
static void print_auth_mode(int authmode)
{
switch (authmode) {
case WIFI_AUTH_OPEN:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_OPEN");
break;
case WIFI_AUTH_WEP:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WEP");
break;
case WIFI_AUTH_WPA_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_PSK");
break;
case WIFI_AUTH_WPA2_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_PSK");
break;
case WIFI_AUTH_WPA_WPA2_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_WPA2_PSK");
break;
case WIFI_AUTH_WPA2_ENTERPRISE:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_ENTERPRISE");
break;
case WIFI_AUTH_WPA3_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_PSK");
break;
case WIFI_AUTH_WPA2_WPA3_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_PSK");
break;
default:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_UNKNOWN");
break;
}
}
static void print_cipher_type(int pairwise_cipher, int group_cipher)
{
switch (pairwise_cipher) {
case WIFI_CIPHER_TYPE_NONE:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_NONE");
break;
case WIFI_CIPHER_TYPE_WEP40:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP40");
break;
case WIFI_CIPHER_TYPE_WEP104:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP104");
break;
case WIFI_CIPHER_TYPE_TKIP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP");
break;
case WIFI_CIPHER_TYPE_CCMP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_CCMP");
break;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
default:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
}
switch (group_cipher) {
case WIFI_CIPHER_TYPE_NONE:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_NONE");
break;
case WIFI_CIPHER_TYPE_WEP40:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP40");
break;
case WIFI_CIPHER_TYPE_WEP104:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP104");
break;
case WIFI_CIPHER_TYPE_TKIP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP");
break;
case WIFI_CIPHER_TYPE_CCMP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_CCMP");
break;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
default:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
}
}
/* Initialize Wi-Fi as sta and set scan method */
static void wifi_scan(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
uint16_t number = DEFAULT_SCAN_LIST_SIZE;
wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
uint16_t ap_count = 0;
memset(ap_info, 0, sizeof(ap_info));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
esp_wifi_scan_start(NULL, true);
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
ESP_LOGI(TAG, "Total APs scanned = %u", ap_count);
for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);
ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);
print_auth_mode(ap_info[i].authmode);
if (ap_info[i].authmode != WIFI_AUTH_WEP) {
print_cipher_type(ap_info[i].pairwise_cipher, ap_info[i].group_cipher);
}
ESP_LOGI(TAG, "Channel \t\t%d\n", ap_info[i].primary);
}
}
void app_main(void)
{
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
wifi_scan();
}
编译一下:
在下载之前,需要设置一下下载方式Flash type ********重要!!!!!
然后就可以点击下载了,
下载完后,点击下载键右边的Monitor终端(类似于串口助手)看一下效果:
下面控制台(绿色的)就是扫描到的WIFI名称。
1.如果没有玩过Linux,可以先试一试Linux的环境,命令等。可以看一个正点原子的Linux开发指南文档,只需要看前四章即可,里面有详细的安装VMware虚拟机、Ubuntu(Linux)、vscode教程。
B站也有,共有4期,把第一期看完就够了。
2.官方文档要仔细看!!!
这里贴几个官方文档地址:
1.ESP-IDF乐鑫编程指南(唯一一个中文文档,快速入门)
2.ESP-IDF官方库文件
3.Espressif官方全平台教程(6大平台)
4.Espressif官方扩展教程(这里面其实包含有5和6)
5.ESP-IDF官方安装文档
6.ESP-IDF官方使用文档
7.PlatformIO官方例程(Espressif IoT Development Framework for Espressif 32)(包含IDF例程和Arduino例程)
8.PlatformIO官方文档