ESP32固件开发开始
Table of Contents
ESP32是一个小而便宜的SoC,具有本地WiFi和蓝牙(具有LE)功能。它们具有各种口味和尺寸,但通常它们看起来像这样(在我的手中以供大小参考):
我拥有的这个特定版本是我在aliexpress上发现的this model的中文仿制。我以约70美元的价格买了一包10包。它使用ESP32-WROOM-32D
芯片,并具有USB-C连接器以及固定在GPIO-2(板上的D2)的集成LED。这对于测试非常有用。
无论如何,在为ESP32编写代码时,您可以选择下降4个不同的路径。
1。使用esp-idf
编写C代码
2。编写微部代码
3。用C外部和回调写C++代码(也带有esp-idf
)
4。写arduino代码
本文的目的是解决每种方法的优势和劣势,以决定哪种最适合您。
###标准c
在C中写作是该芯片上固件开发的绝佳选择。 SDK,esp-idf,有充分的文献记载且鲁棒。然而,在C中写作意味着手动内存管理,难以读取代码以及非目标编程范式。您的做使用C获得的是有效的代码,并且可以直接访问硬件。这是一个简单的Hello-World类型闪烁示例,使用C代码:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "led_strip.h"
#include "sdkconfig.h"
static const char *TAG = "example";
#define BLINK_GPIO 2
static uint8_t s_led_state = 0;
static void blink_led(void) {
gpio_set_level(BLINK_GPIO, s_led_state);
}
static void configure_led(void) {
ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
gpio_reset_pin(BLINK_GPIO);
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
}
void app_main(void) {
configure_led();
while (1) {
ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
blink_led();
s_led_state = !s_led_state;
vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
}
}
Micropython
Micropython是Cpython的港口,本来可以在SOC上运行的ESP32。可以将其视为传统Python 3的子集。要使此功能正常,您需要将提供的微型固件刷到芯片上,然后通过UART连接为您提供交互式的替补。也可以使用一个称为adafruit-ampy
的工具将文件复制到文件系统上,以使它们在芯片启动下运行,而不是简单地将替补产卵,但是如果愿意,您可以对此进行研究。
我对Micropython有不同的感觉。一方面,到目前为止,这是(对我来说)编程ESP32来执行简单任务(例如制作HTTP请求)的最简单方法。但是,它在硬件访问中受到限制,高度依赖于预先构建的软件包,并且由于需要解释器(Micropopython固件),因此它可用的程序和内存的大小和内存的大小也非常有限。
这是用Micropython编写的相同眨眼示例:
import machine
import time
led = machine.Pin(2, machine.Pin.OUT)
while True:
led.value(1)
time.sleep(1)
led.value(0)
time.sleep(1)
如您所见,阅读和理解非常简单,这使其对新用户非常有吸引力。
C++
这是一个奇怪的人。由于C++是设计的超级c,因此可以在C++编写代码,并以与正常C相同的方式使用esp-idf
。不幸的是,应该注意一些事情。
- C++动态内存管理可能是一个缺点,因为船上资源有限
- 您需要使用外部语句与
esp-idf
集成 - 混合两种语言时的情况会变得芬兰语
这是用C++编写的相同眨眼示例:
#ifdef __cplusplus
extern "C" {
#endif
#include <esp_log.h>
#include <string>
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#ifdef __cplusplus
}
#endif
static char tag[] = "cpp_helloworld";
extern "C"
{
void app_main(void);
}
class Blink
{
public:
Blink(gpio_num_t blinkPin)
{
this->blinkPin = blinkPin;
gpio_pad_select_gpio(blinkPin);
gpio_set_direction(blinkPin, GPIO_MODE_OUTPUT);
}
void blinkTimes(int x)
{
ESP_LOGD(tag, "Blink Times %d", x);
int delayMs = 50;
int level = gpio_get_level(blinkPin);
gpio_set_level(blinkPin, 0);
vTaskDelay(1000 / delayMs);
for (int i = 0; i < x; i++)
{
gpio_set_level(blinkPin, 1);
vTaskDelay(1000 / delayMs);
gpio_set_level(blinkPin, 0);
vTaskDelay(1000 / delayMs);
}
gpio_set_level(blinkPin, level);
}
private:
gpio_num_t blinkPin = GPIO_NUM_2;
};
void app_main(void)
{
vTaskDelay(1);
Blink blink(GPIO_NUM_2);
blink.blinkTimes(5);
}
Arduino
Arduino很奇怪,我仍然不完全理解它。 Arduino作为一种语言是包装纸,并且是放在C上的抽象层。关于Arduino的重要部分是它的广泛库和支持,而且非常简单。 Arduino Core几乎提供了esp-idf
的所有功能,并具有易于阅读的Arduino语法。这是相当抽象的,有点有争议。我看到反对使用Arduino编写ESP32代码的主要参数是,在编写广泛的代码时,它最终可能会成为负担,通常围绕针对setup()
和loop()
功能的参数进行旋转。
这是同一个例子,但在Arduino中:
const int ledPin = 2;
void setup() {
pinMode (ledPin, OUTPUT);
}
void loop() {
digitalWrite (ledPin, HIGH);
delay(1000);
digitalWrite (ledPin, LOW);
delay(1000);
}
tl; dr
- 在c中写作是男子气概和凉爽的做事的方式”,但屁股很痛苦。
- 在C++中写作与C相同,但对于“对于正常C来说太酷”的人。
- 在Micropython中写作非常适合小而简单项目,例如提出快速的HTTP请求。
- 在Arduino中写作主要与C相同,但没有男子气概和凉爽的方面的内容,并且非常易于使用Plus Plus具有更大的社区。