Com començar amb el desenvolupament del microprogramari ESP32

· 4min · Juicecat

Un ESP32 és un SoC petit i barat amb capacitats natives de WiFi i Bluetooth (amb LE). Tenen tots els sabors i mides, però normalment semblen una cosa així (a la meva mà per a referència de mida):

1

Aquesta versió específica que tinc és una imitació xinesa de this model que vaig trobar a aliexpress. Vaig comprar un paquet de 10 per uns 70 USD. Utilitza el xip ESP32-WROOM-32D i té un connector USB-C, així com un LED integrat fixat a GPIO-2 (etiquetat D2 a la placa). Això és molt útil per fer proves.

De totes maneres, quan escriu codi per a l'ESP32, hi ha 4 camins diferents que pots triar per baixar.

  1. Escriu codi C amb esp-idf
  2. Escriu codi micropython
  3. Escriu el codi C++ amb C externs i devolucions de trucada (també amb esp-idf)
  4. Escriu codi Arduino

L'objectiu d'aquest article és analitzar els punts forts i febles de cada mètode per decidir quin és el millor per a tu.

Estàndard C

Escriure en C és una gran opció per al desenvolupament de microprogramari en aquest xip. L'SDK, esp-idf, està ben documentat i robust. Escriure en C, però, significa gestió manual de la memòria, codi difícil de llegir i un paradigma de programació no objectiu. El que obteniu fer amb C és codi eficient i accés directe al maquinari. Aquí teniu un exemple senzill de parpelleig de tipus Hello-world utilitzant codi 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 és un port de CPython destinat a executar-se en SoC com ESP32. Penseu-hi com un subconjunt de Python 3 tradicional. Perquè això funcioni, haureu de flashejar un microprogramari Micropython proporcionat al xip, que us proporciona una REPL interactiva mitjançant una connexió UART. També és possible utilitzar una eina anomenada adafruit-ampy per copiar fitxers al sistema de fitxers perquè s'executin a l'arrencada del xip en lloc de generar simplement un REPL, però podeu fer la vostra pròpia investigació si ho voleu.

Tinc sentiments contradictoris a Micropython. D'una banda, és amb diferència (per a mi) la manera més senzilla de programar un ESP32 per fer tasques senzilles com fer peticions http. No obstant això, té un accés limitat al maquinari, depèn molt dels paquets preconstruïts i, a causa de la necessitat d'un intèrpret (el microprogramari Micropython), també és molt limitat en la mida dels programes i la memòria que té disponible.

Aquí teniu el mateix exemple de parpelleig, escrit en 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)

Com podeu veure, és increïblement senzill de llegir i entendre, cosa que el fa molt atractiu per als nous usuaris.

C++

Això és estrany. Com que C++ és un superconjunt de C per disseny, és possible escriure codi a C++ i fer-lo servir esp-idf de la mateixa manera que ho fa el C normal. Malauradament, hi ha algunes coses que cal tenir en compte.

  • La gestió dinàmica de la memòria C++ pot ser un inconvenient a causa dels recursos limitats a bord
  • Haureu d'utilitzar declaracions externes per integrar-vos amb esp-idf
  • Les coses es tornen complicades quan es barregen les dues llengües

Aquí teniu el mateix exemple de parpelleig, escrit a 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 és estrany i encara no ho entenc del tot. Arduino com a llenguatge és un embolcall i una capa d'abstracció posada sobre C. La gran part d'arduino són les seves extenses biblioteques i suport, a més de ser extremadament senzill. El nucli arduino proporciona gairebé totes les capacitats de esp-idf, amb la sintaxi agradable i fàcil de llegir d'arduino. Els inconvenients d'això són força abstractes i una mica polèmics. L'argument principal que he vist en contra de l'ús d'arduino per escriure codi ESP32 és que pot arribar a ser una càrrega quan s'escriu un codi extens, normalment girant al voltant d'un argument contra les funcions setup() i loop().

Aquí teniu el mateix exemple, però en arduino:

const int ledPin = 2;

void setup() {
  pinMode (ledPin, OUTPUT);
}

void loop() {
  digitalWrite (ledPin, HIGH);
  delay(1000);
  digitalWrite (ledPin, LOW);
  delay(1000);
}

TL;DR

  • Escriure en C és la manera viril i fresc de fer les coses", però és un mal de cul.
  • Escriure en C++ és el mateix que C, però per a persones que són "massa cool per a C normal".
  • Escriure en micropython és ideal per a projectes petit i senzill, com ara fer una sol·licitud HTTP ràpida.
  • Escriure en Arduino és principalment el mateix que C, però sense els aspectes viril i fresc, i és immensament més fàcil d'utilitzar i té una comunitat més gran.