Début avec ESP32 Firmware Development

· 4min · Juicecat

Un ESP32 est un SOC petit et bon marché avec des capacités WiFi et Bluetooth (avec LE). Ils viennent dans toutes les saveurs et tailles, mais généralement ils ressemblent à quelque chose comme ça (dans ma main pour référence de taille):

1

Cette version spécifique que j'ai est une imitation chinoise de this model que j'ai trouvée sur AliExpress. J'ai acheté un pack de 10 d'entre eux pour environ 70 USD. Il utilise la puce ESP32-WROOM-32D et dispose d'un connecteur USB-C ainsi qu'une LED intégrée épinglée à GPIO-2 (étiquetée D2 sur la carte). Ceci est très utile pour les tests.

Quoi qu'il en soit, lors de l'écriture de code pour l'ESP32, il y a 4 chemins distincts que vous pouvez choisir de suivre.

  1. Écrivez le code C en utilisant esp-idf
  2. Écrivez le code micropython
  3. Écrivez le code C++ avec C externes et rappels (également avec esp-idf)
  4. Écrivez le code Arduino

Le but de cet article est de passer en revue les forces et les faiblesses de chaque méthode pour décider ce qui peut être le mieux pour vous.

Standard C

L'écriture en C est une excellente option pour le développement du micrologiciel sur cette puce. Le SDK, esp-idf, est bien documenté et robuste. L'écriture en C signifie cependant la gestion de la mémoire manuelle, le code difficile à lire et un paradigme de programmation non objectif. Ce que vous obtenez avec C est un code efficace et un accès direct au matériel. Voici un exemple de clignotement de type Hello-World simple à l'aide du code 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 est un port de CPython destiné à être exécuté sur SOC comme ESP32. Pensez-y en quelque sorte comme un sous-ensemble de Python 3 traditionnel. Pour que cela fonctionne, vous devrez flasher un firmware micropython fourni sur la puce, qui vous fournit ensuite un REP interactif via une connexion UART. Il est également possible d'utiliser un outil appelé adafruit-ampy pour copier des fichiers sur le système de fichiers pour les faire s'exécuter sur Chip Boot au lieu de simplement engendrer un REPL, mais vous pouvez faire vos propres recherches à ce sujet si vous le souhaitez.

J'ai des sentiments mitigés sur Micropython. D'une part, c'est de loin (pour moi) le moyen le plus simple de programmer une ESP32 pour effectuer des tâches simples telles que faire des demandes HTTP. Cependant, il est limité dans l'accès matériel, très dépendante des packages prédéfinis, et en raison de la nécessité d'un interprète (le firmware MicropyThon), est également très limité dans la taille des programmes et de la mémoire dont il dispose.

Voici le même exemple de clignotement, écrit 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)

Comme vous pouvez le voir, il est incroyablement simple à lire et à comprendre, ce qui le rend très attrayant pour les nouveaux utilisateurs.

C++

C'est étrange. En raison de C++ étant un superset de C par conception, il est possible d'écrire du code dans C++ et de le faire utiliser esp-idf de la même manière que C normal. Malheureusement, il y a quelques choses à noter.

  • C++ La gestion dynamique de la mémoire peut être un inconvénient en raison des ressources limitées à bord
  • Vous devrez utiliser des instructions externes pour intégrer avec esp-idf
  • Les choses deviennent finnicky lors du mélange des deux langues

Voici le même exemple de clignotement, écrit en 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 est étrange, et je ne le comprends toujours pas complètement. Arduino en tant que langue est un wrapper et une couche d'abstraction mis sur C. La grande partie de Arduino est que ce sont de vastes bibliothèques et un soutien, ainsi que d'être extrêmement simple. Le noyau Arduino fournit presque toutes les capacités de esp-idf, avec la syntaxe agréable et facile à lire d'Arduino. Les inconvénients de cela sont assez abstraits et un peu controversés. L'argument principal que j'ai vu en utilisant Arduino pour écrire du code ESP32 est qu'il peut éventuellement devenir un fardeau lors de l'écriture de code étendu, tournant généralement autour d'un argument contre les fonctions setup() et loop().

Voici le même exemple, mais dans Arduino:

const int ledPin = 2;

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

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

TL; DR

  • L'écriture en C est la façon de faire viril et cool de faire les choses ", mais c'est une douleur dans le cul.
  • L'écriture en C++ est la même que C, mais pour les personnes qui sont "trop ​​cool pour le C normal".
  • L'écriture dans Micropython est idéale pour les projets petit et simple, comme faire une demande HTTP rapide.
  • L'écriture dans Arduino est principalement la même que C, mais sans les aspects viril et cool, et est extrêmement plus facile à utiliser plus a une communauté plus large.