ESP32固件开发开始

· 6min · Juicecat
Table of Contents

ESP32是一个小而便宜的SoC,具有本地WiFi和蓝牙(具有LE)功能。它们具有各种口味和尺寸,但通常它们看起来像这样(在我的手中以供大小参考):

1

我拥有的这个特定版本是我在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具有更大的社区。