从零在Linux(ubuntu)下,使用VScode+ESP32IDF+PlatformIO搭建开发环境
写在上面
ESP32的开发环境确实不友好,远不如STM32,在了解了几个的编译环境和方式后,我觉得这个方式是最简单便捷的,无需繁琐的命令配置,只须要认真阅读官方文档通常都能解决问题。
这儿有几个问题:
1).为何开发环境要使用Linux而不是Windows:
Linux下编译更快!速率在5-10倍以上
2).为何编译工具使用VScode而不是CMake等,虽然Eclipse也是可以的,并且我习惯了vs全家桶,就用vscode了。
主要是便捷,再加上本身对CMake、Makefile也不熟悉。
编译ESP32的工具介绍如图:
官方ESP-IDF编程手册文档:
3)为何要在Windows下使用虚拟机,而不是直接在化学机上运行一个Linux(Ubuntu)?
①主要是Windows下使用虚拟机可以在两个系统间便捷的复制代码、复制文字、移动文件等。
②还可以更便捷快速的创建系统的备份点和还原点。(须要安装VMwareTools)(不过文件类的还是建议使用FileZillaClient服务器-顾客端发送,这样会避开文件的错误传输)
1.首先要下载Ubuntu,建议在模拟器中食用;
模拟器就使用VMwareWorkstationPro就好。
Ubuntu可以在官网下载。
VMwareWorkstationPro也可以在官网下载。
2.安装好Ubuntu后要安装VScode
安装前要记得查看自己的Ubuntu是多少位的系统;
查看命令:getconfLONG_BIT
安装命令:sudodpkg-icode_1.32.3-1552606978_amd64.deb其中code_1.32.3-1552606978_amd64.deb为自己的安装包文件名
3.在VScode中安装插件
使用快捷键Ctrl+Shift+X打开扩充商店,之后在上面搜索须要安装的插件:
其中须要安装的有:
1)、C/C++,这个肯定是必须的。
2)、C/C++Snippets,即C/C++重用代码块。
3)、C/C++AdvancedLint,即C/C++静态检查。
4)、CodeRunner,即代码运行。
5)、IncludeAutoCompletelinux搭建网站环境,即手动头文件包含。
6、RainbowBrackets,彩虹花括弧,有助于阅读代码。
7)、OneDarkProVSCode的主题。
8)、GBKtoUTF8,将GBK转换为UTF8。
9、ARM,即支持ARM汇编句型高亮显示。
10)、Chinese(Simplified),即英文环境。
11)、vscode-iconsVSCode图标插件,主要是资源管理器下各个文件夹的图标。
12)、compareitlinux命令,比较插件,可以用于比较两个文件的差别。
13)、DeviceTree,设备树句型插件。
14)、TabNine,一款AI手动补全插件
最后进入题外话,安装ESP32IDF编译器/环境配置,点击安装即可。
安装帮助文档:
根据文档安装即可,过程中会出错和失败,此时断掉安装,再度打开ESPIDFSetup接着安装即可。须要注意的是:
1.在选择下载服务器的时侯要不要选择GitHub,要选择ESP官方的服务器,由于GitHub服务器太慢了,很大机率下载失败。
2.假如安装失败后再继续尝试的时侯,为了防止重复下载,所以在选择ESPIDE版本的时侯要选择用户本地的版本,这样会节约时间。
直至出现配置成功界面就可以了!
4.编译示例文件
这一步试了好久…(都怪自己没有好好看帮助文档)
1.一切安装好后,首先打开命令面板(快捷键Ctrl+Shift+P),步入ESP-IDF:showexamplesPrijects:
搜索到以下项后,再点击步入示例列表:
2.选择一个示例,之后选择一个工作目录。
3.接出来有3步须要执行:
1)打开命令面板,输入命令sdkconfigurationeditor
使用IDF的配置脚本进行默认配置,也可自行更改。
2)打开命令面板,输入命令addvscodeconfigurationfolder
添加IDF编译器在vscode中的配置文件,只需配置一次(更换项目后也不须要再配置)。
在vscode右下角提示框中有此信息表示正确配置。
3)打开命令面板,输入命令buildyourproject(快捷键为Ctrl+E松手再按下B)
进行编译,而且生成.bin文件。该文件在build目录下。
编译成功如下:
5.使用PlatformIO工具在Arduino平台快速开发(使用C++语言)
在扩充插件中搜索PlatformIO并安装
安装完毕后步入PlatformIO,安装自己须要的平台。
假如依照我的步骤安装,这个平台应当是早已有的,由于在第三步安装插件的时侯,我们早已使用ESP-IDF安装器安装过Espressif32平台了。
安装完后,步入插件新建一个项目
选择开发板机型和平台,可以使用Arduino平台。
Arduino平台的优势就是轮子多,便捷红旗linux系统,但他并不能作为开发者开发商业产品的专业平台,适宜自己做个小玩意儿啥的。
其实了,也可以使用乐鑫的平台操作都一样,疗效可以看第7部份。
新建完成后,就可以看见主函数了。之后可以打开PlatformIO的主页linux搭建网站环境,搜索一些示例代码,测试一下。随意搜索一个LED的就行。
点进去添加到自己的项目
选择版本和项目,点Add添加就可以了。
复制以下他的使用示例代码到main.cpp上面,值得一提的是,.cpp是使用的C++语言。
步入main.cpp点击编译,会提示8个错误,错误缘由是有函数未申明。
我们把他都申明下,或则直接把loo函数放到main.cpp的末尾,省的申明了。。。再度编译,就没有错误了。
接出来下载进开发板就可以了,下载之前要检测设备端口文件。我的是USB0,选择USB0就好了。
之后点击"->"下载。在下载的时侯要按住BOOT键,直至提示写入Flash为止。
到这儿就下载成功了。
6.使用PlatformIO:SerialMonitor作为并口输出端口,查看数据和复印信息。
可以看见端口显示了好多乱码,这是因为,Monitor默认码率是9600,我们把他改为115200就可以了。打开这个PlatformIO的配置文件,添加Monitor的码率速率为115200
monitor_speed=115200
再编译下载后就正常了,我加了一段复印的代码。
7.使用PlatformIO工具在乐鑫平台EspressifIoTDevelopmentFramework(IDF)开发(使用C语言)
优势:原生,专业,代码量小。最重要的是C语言、使用的官方原生库,愈发完整。但就是资料比较少,轮子少,须要自己造,能参考的就是官方解释器源码和官方指南。
(虽然Arduino是一种玩具或则爱好者类的开发,并不专业)
8.不使用PlatformIO,直接使用ESPIDF编译一个扫描附近WIFI的类库。
直接打开ESPIDF随意搜索一个类库,之后直接粘贴我下边的代码:
/* 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 tt%s", ap_info[i].ssid);
ESP_LOGI(TAG, "RSSI tt%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 tt%dn", 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();
}
编译一下:
在下载之前,须要设置一下下载形式Flashtype********重要!!!!!
之后就可以点击下载了,
下载完后,点击下载键左侧的Monitor终端(类似于并口助手)看一下疗效:
下边控制台(红色的)就是扫描到的WIFI名称。
9.建议
1.假如没有玩过Linux,可以先试一试Linux的环境,命令等。可以看一个正点原子的Linux开发手册文档,只须要看前四章即可,上面有详尽的安装VMware虚拟机、Ubuntu(Linux)、vscode教程。
B站也有,共有4期,把第一期看完就够了。
2.官方文档要仔细看!!!
10.官方文档
这儿贴几个官方文档地址:
1.(惟一一个英文文档,快速入门)
2.ESP-IDF官方库文件
3.Espressif官方全平台教程(6大平台)
4.Espressif官方扩充教程(这儿面虽然包含有5和6)
5.ESP-IDF官方安装文档
6.ESP-IDF官方使用文档
7.PlatformIO官方解释器(EspressifIoTDevelopmentFrameworkforEspressif32)(包含IDF类库和Arduino类库)
8.PlatformIO官方文档