Comenzando con el desarrollo del firmware ESP32
Table of Contents
Un ESP32 es un SoC pequeño y económico con capacidades nativas de WiFi y Bluetooth (con LE). Vienen en todos los sabores y tamaños, pero normalmente se ven así (en mi mano como referencia de tamaño):

Esta versión específica que tengo es una imitación china de this model que encontré en aliexpress. Compré un paquete de 10 por alrededor de ~70 USD. Utiliza el chip ESP32-WROOM-32D y tiene un conector USB-C, así como un LED integrado fijado a GPIO-2 (etiquetado como D2 en la placa). Esto es muy útil para realizar pruebas.
De todos modos, al escribir código para ESP32, hay 4 caminos distintos que puedes elegir seguir.
- Escriba código C usando
esp-idf - Escribe código Micropython.
- Escriba el código C++ con externos de C y devoluciones de llamada (también con
esp-idf) - Escribe código Arduino
El propósito de este artículo es repasar las fortalezas y debilidades de cada método para decidir cuál puede ser mejor para usted.
Estándar C
Escribir en C es una gran opción para el desarrollo de firmware en este chip. El SDK, esp-idf, está bien documentado y es sólido. Sin embargo, escribir en C significa gestión manual de la memoria, código difícil de leer y un paradigma de programación no objetivo. Lo que obtienes hacer con C es código eficiente y acceso directo al hardware. A continuación se muestra un ejemplo simple de parpadeo tipo "hola mundo" usando código 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);
}
}
Micropitón
Micropython es un puerto de CPython destinado a ejecutarse en SoC como ESP32. Piense en ello como un subconjunto del Python 3 tradicional. Para que esto funcione, necesitará instalar un firmware Micropython proporcionado en el chip, que luego le proporcionará un REPL interactivo a través de una conexión UART. También es posible usar una herramienta llamada adafruit-ampy para copiar archivos en el sistema de archivos para que se ejecuten en el arranque del chip en lugar de simplemente generar un REPL, pero puedes hacer tu propia investigación al respecto si lo deseas.
Tengo sentimientos encontrados sobre Micropython. Por un lado, es, con diferencia (para mí), la forma más sencilla de programar un ESP32 para realizar tareas sencillas como realizar solicitudes http. Sin embargo, tiene un acceso limitado al hardware, depende en gran medida de paquetes prediseñados y, debido a que necesita un intérprete (el firmware Micropython), también es muy limitado en el tamaño de los programas y la memoria que tiene disponible.
Aquí está el mismo ejemplo de parpadeo, escrito 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)
Como puede ver, es increíblemente sencillo de leer y comprender, lo que lo hace muy atractivo para los nuevos usuarios.
C++
Éste es extraño. Debido a que C++ es un superconjunto de C por diseño, es posible escribir código en C++ y hacer que use esp-idf de la misma manera que lo hace C normal. Lamentablemente, hay algunas cosas que conviene tener en cuenta.
- C++ la gestión dinámica de la memoria puede ser una desventaja debido a los recursos limitados a bordo
- Necesitará utilizar declaraciones externas para integrarse con
esp-idf - Las cosas se ponen complicadas al mezclar los dos idiomas.
Aquí está el mismo ejemplo de parpadeo, escrito 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 es extraño y todavía no lo entiendo del todo. Arduino como lenguaje es una capa contenedora y de abstracción colocada sobre C. Lo mejor de arduino es su amplia biblioteca y soporte, además de ser extremadamente simple. El núcleo arduino proporciona casi todas las capacidades de esp-idf, con la sintaxis agradable y fácil de leer de arduino. Las desventajas de esto son bastante abstractas y un poco polémicas. El principal argumento que he visto en contra del uso de arduino para escribir código ESP32 es que eventualmente puede convertirse en una carga al escribir código extenso, generalmente girando en torno a un argumento en contra de las funciones setup() y loop().
Aquí está el mismo ejemplo, pero 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
- Escribir en C es la forma varonil y Frío de hacer las cosas", pero es un dolor de cabeza.
- Escribir en C++ es lo mismo que C, pero para personas que son "demasiado geniales para C normal".
- Escribir en micropython es excelente para proyectos pequeño y sencillo, como realizar una solicitud HTTP rápida.
- Escribir en Arduino es básicamente lo mismo que C, pero sin los aspectos varonil y Frío, y es inmensamente más fácil de usar y además tiene una comunidad más grande.