4 puntos por GN⁺ 2024-09-02 | 1 comentarios | Compartir por WhatsApp
  • SolarCamPi es una cámara solar off-grid que enciende y apaga una Raspberry Pi Zero 2 W solo cuando toma fotos, por lo que el tiempo de arranque determina la duración de la batería
  • Con Debian 12 arm64 Lite, midiendo /init.sh como el primer código en espacio de usuario, el arranque inicial consumía unos 12 segundos y 9.5 Ws
  • Al reducir HDMI, LED, HAT/PoE/LCD, la detección automática de cámara y pantalla, e initramfs, se eliminaron esperas y detecciones innecesarias, y la corriente bajó de 136.7 mA → 120.6 mA
  • Tras pasar a Buildroot 2024.02.1 y un kernel personalizado, se quitaron drivers, compresión, KASLR y algunas mitigaciones, llegando al programa en espacio de usuario de Linux en menos de 3.5 segundos
  • Al bajar el voltaje de entrada de 5.0 V a 3.6 V, la energía total se redujo de 1.754 Ws → 1.438 Ws, aunque queda validar estabilidad y confiabilidad porque opera fuera de especificación

Por qué SolarCamPi necesitaba reducir el tiempo de arranque

  • SolarCamPi es una cámara WiFi alimentada por energía solar que arranca periódicamente una Raspberry Pi Zero 2 W, toma una foto, la sube por WiFi a un servicio en la nube y luego se apaga de nuevo
  • En entornos con poca energía, como el invierno en Europa occidental, cada segundo que la Pi permanece encendida se convierte directamente en un costo energético
  • La conexión al servidor y la subida de fotos de la aplicación en espacio de usuario ya estaban optimizadas al máximo posible, y el circuito electrónico también estaba diseñado para reducir el consumo durante el reposo
  • Quedaban dos caminos de ahorro
    • Reducir el consumo de corriente
    • Reducir el tiempo de ejecución
  • Bajar solo la corriente no siempre trae beneficios
    • Si se desactiva CPU turbo y baja la corriente, pero aumenta el tiempo de ejecución, la energía total puede terminar siendo mayor
    • El objetivo es minimizar el área bajo la curva de corriente y tiempo

Equipo de medición y método de prueba

  • En la optimización de arranque en sistemas embebidos, es importante contar con herramientas que permitan verificar rápidamente la ejecución real tras cada cambio, reduciendo la extracción de la tarjeta SD y la manipulación de energía
  • El equipo usado fue el siguiente
  • Power Profiler Kit II alimenta el dispositivo bajo prueba mientras mide el consumo de energía en el tiempo junto con el estado de 8 entradas digitales
    • Se conectó un pin GPIO de la Raspberry Pi a una entrada digital
    • Como primera acción de la aplicación, se alterna el GPIO para medir el tiempo desde la aplicación de energía hasta la ejecución del código en espacio de usuario
  • USB-SD-Mux es un interposer que se coloca entre la tarjeta microSD y el dispositivo, permitiendo que la computadora tome la tarjeta, reescriba su contenido y se la devuelva al dispositivo
    • Elimina la tarea repetitiva de sacar la tarjeta, insertarla en un lector y volver a ponerla en el dispositivo
    • Con GPIO integrado también puede automatizar el reset o el control de energía del dispositivo bajo prueba
  • La consola USB-UART es necesaria para revisar el estado cuando el sistema se rompe, por ejemplo ante fallas de arranque o problemas de WiFi

Medición de arranque con Debian como referencia

  • Sobre una imagen limpia de Debian 12 bookworm arm64 Lite, se agregó init=/init.sh en /boot/firmware/cmdline.txt
  • Esta configuración hace que el kernel ejecute /init.sh como primer proceso en espacio de usuario antes que systemd
  • El init.sh de ejemplo alterna GPIO4 y luego continúa el arranque de systemd con exec /sbin/init
  • En la medición inicial, la entrada digital 0 pasa a low tras unos 12 segundos, confirmando la ejecución de init.sh
  • Este proceso de arranque usó un total de 1.90 coulomb
    • 1.9As * 5.0V = 9.5Ws
    • Una batería alcalina AA puede entregar alrededor de 13500 Ws de energía

Reducir el consumo de corriente

  • Al desactivar por completo el codificador HDMI, la corriente bajó de 136.7 mA a 122.6 mA
    • Como era necesario codificar datos de cámara, no se pudo apagar la GPU en sí
    • Si la aplicación no necesita cámara ni GPU, también se podría intentar desactivar la GPU
  • Solo desactivar el activity LED ahorró 2 mA, reduciendo la corriente de 122.6 mA a 120.6 mA
  • Si hay un LED de cámara, se puede desactivar
    • También se reduce la posibilidad de que el LED se refleje en la imagen
  • En la prueba de cambio de configuración turbo, la Pi en el estado modificado actual usaba 1.62 As
    • Al ejecutarla sin turbo forzado, usaba 1.58 As
    • Por razones desconocidas, al apagar el modo turbo/boost, el estado predeterminado de GPIO4 se invirtió, por lo que se cambió la polaridad en init.sh

Reducir el tiempo de arranque

  • La corriente se redujo alrededor de 13%, pero todavía pasaban unos 8 segundos antes de que apareciera la primera salida de Linux en la consola, y en ese tramo se consumía alrededor de 1 As
  • En la familia Raspberry Pi, la GPU se inicializa primero
    • La GPU busca bootcode.bin en la tarjeta SD
    • Pi 4 y posteriores usan EEPROM
  • Al activar BOOT_UART en bootcode.bin, se pueden ver logs UART detallados
    • Es necesario respaldar el bootcode.bin original, y el proceso de modificación es potencialmente destructivo
  • El bootloader espera una respuesta EDID para detectar automáticamente los parámetros de video del monitor HDMI conectado
    • Como no se usa HDMI, se hardcodeó la cadena EDID para evitar la detección
  • También se desactivó la detección de EEPROM I2C relacionada con HAT, ventilador PoE, LCD y pantalla táctil
    • Estas opciones esperan respuestas en el bus I2C, por lo que se pueden apagar si no son necesarias
  • La detección automática de cámaras y pantallas MIPI también consume tiempo
    • Como la cámara usada está fijada a una HQ Camera IMX477, se apagó con camera_auto_detect=0, display_auto_detect=0 y se cargó directamente dtoverlay=imx477
  • Con los cambios anteriores, el tiempo de arranque reportado internamente bajó de 5.38 segundos a 4.75 segundos, y al desactivar initramfs eliminando auto_initramfs=1 bajó hasta 4.47 segundos
  • El método sdtweak, que overclockea el periférico SD a 100 MHz, no produjo una diferencia medible en el rendimiento de arranque
    • Existe riesgo de corrupción de datos en accesos de escritura, por lo que no es deseable para dispositivos IoT remotos

Cuello de botella en la carga del kernel y migración a Buildroot

  • En este punto, la carga del kernel era una de las tareas más lentas
    • Cargar kernel8.img de 9,276,375 bytes tomaba alrededor de 1.54 segundos
    • La velocidad de transferencia era de unos 6 MiB/s
  • La carga del kernel la realiza la GPU, que usa el procesador interno propietario VideoCore IV
    • Es posible que el código del loader sea ineficiente o use configuraciones conservadoras, pero al ser una caja negra no fue posible ajustar registros o parámetros de forma útil
  • El overclock del core del procesador GPU era teóricamente posible y redujo el tiempo de carga del kernel en 20%
    • No se recomienda porque se desconocen efectos secundarios como la confiabilidad
  • El sistema se migró de Raspbian/Debian a una distribución personalizada basada en Buildroot 2024.02.1
    • Uso de toolchain aarch64 nativa
    • Se mantuvieron glibc y las herramientas userland de Raspberry Pi
  • En el kernel personalizado se eliminaron o redujeron los siguientes elementos
    • Soporte de sonido
    • La mayoría de drivers de dispositivos de bloque y sistemas de archivos, manteniendo solo SD/MMC y ext4
    • RAID, USB, HID, DVB
    • Soporte de video y framebuffer
    • Funciones avanzadas de red como túneles, bridging y firewall
    • Compresión Gzip del kernel y compresión de módulos
  • Mantener tanto el kernel como los módulos sin comprimir fue beneficioso desde el punto de vista de energía total, aunque la GPU tardara más en cargarlos
    • La descompresión Gzip consume mucha energía y en la práctica incluye una etapa adicional de reubicación
  • También se desactivó KASLR
    • KASLR aleatoriza la dirección de carga del kernel en memoria para dificultar la creación de exploits, pero requiere reubicar el kernel después de la carga por la GPU
    • En este caso de uso, la superficie de ataque de red es muy limitada y todo el software de la aplicación se ejecuta como root
    • También se desactivaron mitigaciones para vulnerabilidades de ejecución especulativa como Spectre
  • El tamaño resultante del kernel fue de 8.5 MiB sin comprimir, y el tamaño Gzip para comparación fue de 4.1 MiB
    • El kernel original de Raspbian era de 25 MiB sin comprimir y 8.9 MiB comprimido con Gzip

Resultado final y optimización del voltaje de entrada

  • Finalmente se llegó al programa en espacio de usuario de Linux en menos de 3.5 segundos
  • El tiempo usado dentro del kernel de Linux fue de unos 400 ms
  • El consumo total de energía fue de 0.364 As * 5.0 V = 1.82 Ws
    • Comparado con los 9.5 Ws para llegar a espacio de usuario en Debian stock, es aproximadamente una quinta parte
  • Tras la publicación, Graham Sutherland / Polynomial señaló que el regulador de la Pi Zero no es eficiente con entrada de 5.0 V
  • En el escenario de prueba y en el producto terminado fue posible bajar el voltaje de entrada hasta 4.0 V
    • 5.0 V: 350.94mAs * 5.0V = 1.754Ws
    • 4.0 V: 390.77mAs * 4.0V = 1.563Ws
    • 3.6 V: 399.60mAs * 3.6V = 1.438Ws
  • Al bajar el voltaje, aumentan los mC, es decir los mAs, por el incremento de corriente, pero la energía total baja de forma importante
  • Operar a 3.6 V redujo la energía en alrededor de 20% adicional al usar el regulador conmutado en un punto de operación más ideal, pero técnicamente queda fuera de especificación, por lo que aún se necesita más validación de estabilidad y confiabilidad

Configuración y código publicados

1 comentarios

 
GN⁺ 2024-09-02
Opiniones de Hacker News
  • La gestión de energía de la familia Raspberry Pi sin duda es uno de sus puntos débiles. Por eso me entusiasma la nueva Pico 2, porque parece que será más fácil entrar en estados de ahorro de energía relativamente profundos incluso sin hardware externo.
    Una vez hice una cámara para un uso similar con una Google Coral mini; la cámara no es tan buena como la HQ cam, pero con el RTC integrado soportaba muy fácilmente el modo de espera/despertar, así que era ideal para una app que toma fotos periódicamente. También tenía el rendimiento y los 2 GB de memoria suficientes para procesar imágenes de alta resolución.
    Es posible conectar físicamente la HQ camera, pero hasta donde sé no existe en Coral una canalización de software para gestionarla.
    El ecosistema de Raspberry Pi es mucho más maduro, y confío más en la disponibilidad futura de Raspberry Pi que en que Google siga suministrando la línea Coral. Aun así, sentí claramente lo útil que puede ser contar con buen soporte de energía en el hardware.
    Irónicamente, la siguiente versión de la cámara la hizo un proveedor externo con Raspberry Pi, y compensó el problema de energía poniendo una batería mucho más grande. Gracias a eso ahora tengo acumuladas 100 Coral dev mini y cámaras sin siquiera abrir, así que estoy en la situación de tener que encontrar una buena idea o venderlas.

    • La línea Coral me da la impresión de que ya está muerta o descontinuada. El sitio coral.ai tampoco parece haberse actualizado desde 2021, y el aviso de copyright dice 2020.
      Busqué "google coral twitter" para encontrar la cuenta oficial de Twitter, y fue desconcertante que el segundo resultado fuera tu tuit intentando vender 100 placas sobrantes.
    • Me parece interesante, porque siempre he usado las Pi solo conectadas a la pared. Me pregunto si el hardware de la Pi no puede hacer una optimización de energía como la de Coral, o si lo que falta es soporte de software para la gestión de energía en la Pi.
      Por lo que mencionas de gestionar la energía con hardware externo, parece que no es solo un problema de software.
    • Me pregunto si también miraste el hardware BeagleBone, que tiene dispositivos PRU para operación de bajo consumo. Las PRU pueden permanecer despiertas incluso mientras el sistema está dormido.
    • Me pregunto qué tipo de tarea hacen que no se pueda resolver con las cámaras comerciales actuales.
  • Si empaquetas la aplicación como un initramfs enlazado al kernel, en casos simples puedes reducir bastante el arranque porque ya no hace falta montar un sistema de archivos.
    En algunos casos, incluso algo como el init de BusyBox puede reemplazarse por un script bash sencillo que solo haga el arranque mínimo. También vale la pena considerar montar devtmpfs, proc, sysfs, etc., y, si es posible, deshacerse de glibc.
    Antes de enlazar el initramfs al kernel, conviene probar con chroot que estén todas las dependencias necesarias de la aplicación. Si corre dentro de chroot, el kernel también podrá ejecutarlo durante el arranque, y los ciclos de desarrollo se vuelven mucho más rápidos.
    Si desactivas los módulos del kernel y enlazas dentro del kernel solo las funciones necesarias, puedes reducir aún más el espacio y el tiempo de arranque. También vale la pena probar la compresión zstd en lugar de gzip.

    • Por el contrario, si la carga del kernel y del initramfs es lenta, puede ser más rápido arrancar con la imagen más pequeña que sea práctica y luego cargar el resto del software una vez iniciado el espacio de usuario.
      Esto aplica cuando las etapas tempranas del arranque no aprovechan suficiente el rendimiento del hardware, o cuando la imagen es grande y conviene hacer otras cosas en paralelo con la carga.
    • No necesariamente hace falta un script de shell para montar varios pseudosistemas de archivos. Puedes hacerlo directamente dentro de la aplicación.
      Entonces lo único que queda es un initramfs con un único binario enlazado estáticamente.
  • Hay otros dos buenos artículos sobre cómo reducir el tiempo de arranque de la Pi:
    https://www.furkantokac.com/rpi3-fast-boot-less-than-2-secon...
    http://himeshp.blogspot.com/2018/08/fast-boot-with-raspberry...
    Tomé estos dos artículos como referencia para hacer un marco de fotos digital con una Pi, y logré que arrancara muy rápido incluso hasta el navegador en modo kiosco. Si los requisitos son muy pocos, se pueden conseguir tiempos de arranque bastante impresionantes.

    • Al leer el primer artículo, parece que el artículo original también podría beneficiarse de usar start_cd.elf. Es un bootloader de tercera etapa sin el subsistema gráfico, y dice que mejora el tiempo de carga en 0,5 segundos.
    • Gracias por los enlaces. ¿De casualidad está publicado también el código de ese marco de fotos en modo kiosco?
  • La verdadera tragedia es que el código de GPU bootcode.bin es una caja negra propietaria y no hay código fuente.
    Es terrible que los proyectos de hacking y hobby tengan que cargar con una caja negra secreta y oculta que no se puede modificar.

    • El firmware de la Pi es ThreadX, que luego Microsoft adquirió y renombró como Azure RTOS.
      Ahora es software libre y de código abierto.
      https://www.theregister.com/2023/11/28/microsoft_opens_sourc...
      Eso no hace que todo el firmware de la Pi se vuelva automáticamente libre y de código abierto. No es un driver. Pero si quisieran, podrían hacerlo.
    • Me pregunto si, al publicar el código fuente de bootcode, se habilitarían modificaciones tan extremas que RPI ya no podría garantizar el funcionamiento normal. O tal vez tenga relación con la carga de drivers propietarios.
      Me da curiosidad qué habrá adentro que necesiten mantener cerrado.
  • Me gusta el artículo en general, pero no estoy seguro de esta parte
    Me refiero a la parte de que desactivar el turbo de la CPU para ahorrar un poco de consumo de corriente es una mala decisión, y que por el tiempo más lento se gasta más energía que si se termina rápido y se apaga
    En clases de ciencias de la computación aprendí que el consumo de energía es proporcional al cuadrado de la frecuencia de reloj. Es decir, si duplicas el reloj, la potencia se cuadruplica
    Entonces, para comprobar si el incremento cuadrático al subir el reloj es mayor que el producto del consumo fijo de energía que aparece al aumentar el tiempo de trabajo, creo que habría que medir la diferencia real de potencia
    Relacionado con eso, sería bueno que la CPU de la Pi ofreciera información detallada de consumo de energía que se pudiera derivar de la hoja de datos o exponer en tiempo real mediante registros

    • Esa explicación no es del todo correcta. La potencia de conmutación de un chip, excluyendo las fugas estáticas, es proporcional al cuadrado del voltaje multiplicado por la frecuencia
      La mayoría de los chips necesitan un voltaje más alto para alcanzar velocidades de reloj más altas, y de ahí viene la relación cuadrática
      Pero tengo entendido que la Raspberry Pi no tiene control dinámico de voltaje, así que si solo bajas el reloj sin bajar el voltaje, no creo que afecte el consumo total de energía de conmutación
    • Esta es una estrategia conocida de optimización de energía llamada race to idle. Funciona porque, además de la CPU, hay muchos periféricos que consumen energía y no se pueden apagar hasta que termine el trabajo de la CPU
      Claro que también hay un punto óptimo. Si haces demasiado overclock a la CPU, el rendimiento por watt cae tanto que el race to idle deja de funcionar
    • Es una buena regla empírica para cargas de trabajo continuas, pero no es toda la historia. Siempre hay cierto consumo estático de energía mientras los componentes estén encendidos
      Por eso los sistemas embebidos modernos a menudo usan estrategias de "race-to-sleep" o "race-to-halt": ejecutan la tarea muy rápido y luego apagan la mayoría de los componentes hasta que llegue el siguiente evento
    • Hay una sobrecarga de energía base que el dispositivo consume aunque no esté haciendo nada. Incluso en el benchmark se ve que al activar el turbo el consumo de corriente aumenta 10%, pero el tiempo de arranque baja 11%, lo que produce una diferencia pequeña pero medible en el uso total de energía
    • Muy interesante. Gracias por compartirlo
      Si hacer cierto cálculo en 1 segundo cuesta 1 J, por ejemplo 1 W a 1 GHz, supongo que en un modelo esférico perfecto de vaca, hacer el mismo cálculo en 0.5 segundos costaría 2 J. Porque a 2 GHz serían 4 W
      Pero eso solo considera el consumo de la CPU; si el sistema completo tiene un consumo fijo de 4 W, a 1 GHz serían 1 J de CPU más 4 J del sistema, 5 J en total, y a 2 GHz serían 2 J de CPU más 2 J del sistema, 4 J en total
      Si lo entendí bien, ¿eso significa que conviene usar turbo cuando el consumo del sistema completo es similar al consumo de la CPU en estado turbo, y si no, no?
  • Impresionante. Pero cada vez que leo algo así me acuerdo de cuando grabé el arranque de Plan 9 en una Pi Zero: https://taoofmac.com/space/blog/2020/09/02/1900#resurrecting
    El GIF es salida en tiempo real

    • Eso en sí está genial
      Pero otra cosa es si puede cargar los drivers de cámara y Wi‑Fi que necesita el proyecto original
  • Personalmente, los tiempos de arranque de las distribuciones Linux en general me parecen bastante decepcionantes, y en hardware tan débil el problema se vuelve mucho mayor
    Hice optimizaciones parecidas en una SBC MQ-Pro. También lo noto bastante en laptops. Las MacBook quizá sean la excepción, pero de todos modos es algo molesto

    • Depende mucho de cómo definas tiempo de arranque. Por ejemplo, Windows optimiza para el momento en que aparece la primera UI, pero después el resto sigue cargando y la PC, en la práctica, no se puede usar durante unos segundos
    • La M1 MacBook tarda varias veces más, en un solo dígito, en iniciar que mi PC de escritorio con Windows
      Una vez encendida, volver a iniciar sesión es instantáneo, pero reiniciar sí toma bastante tiempo
    • Linux también puede arrancar bastante rápido si lo configuras bien. Escribí sobre eso en [0]
      Pero las distribuciones, por motivos razonables, crean kernels e initramfs muy genéricos, y esa combinación no es especialmente rápida para arrancar
      [0]: https://blog.davidv.dev/posts/minimizing-linux-boot-times/
    • No sé cuánto pueden hacer las distribuciones en este punto. El tiempo de arranque en espacio de usuario muchas veces es despreciable
      Salvo configuraciones horribles, como que NetworkManager espere 90 segundos por una Wi‑Fi inexistente. Mi caja Linux tarda unos 4 segundos hasta graphical.target, y la mayor parte es por la conexión Wi‑Fi y ntpd, que en principio son opcionales
      Si de verdad quieres un arranque rápido, basta con tirar por la borda toda la capacidad de configuración dinámica como capas de compatibilidad del bootloader, abstracciones e initramfs. Pero entonces quedas a merced del proveedor de hardware, así que no vale la pena
    • Esa afirmación me resulta un poco rara. En mi caso, Linux arranca muy rápido incluso en máquinas viejas y con almacenamiento lento
      Por ejemplo, una MacBook Air 11 con Linux llega a la pantalla de login tan rápido que casi no alcanzo a ver los logs de arranque. Según systemd-analyze, tarda menos de 4 segundos hasta el graphical target
      La clave parecen ser dos cosas. No usar un entorno de escritorio; arrancar en modo texto y luego ejecutar startx cuando hace falta, o arrancar X con un gestor de login ligero (lightdm). Sin entorno de escritorio, la cantidad de servicios se reduce varias veces, a un solo dígito, y en hardware viejo baja mucho la presión de I/O durante el arranque. Incluso ejecutando X, el sistema arrancado queda por debajo de 200 MB
      La otra es que EFI stub puede mejorar la velocidad: https://wiki.archlinux.org/title/EFISTUB
  • Mi primera intuición fue si no se podría usar otro núcleo. ¿De verdad hace falta Linux para tomar una foto y enviarla a la nube?
    No soy del área de hardware, así que me da curiosidad cómo se podría completar esta tarea con el presupuesto mínimo. Fue un artículo interesante.

    • Yo también pensé lo mismo al principio.
      Tal vez sea solo porque ahora tengo dos ESP32-CAM sobre la mesa del comedor, pero me dio curiosidad cómo se compararía una configuración con ESP32-CAM. Probablemente solo sirva bien hasta imágenes de 2 megapíxeles, pero creo que tanto el tiempo de arranque como el consumo de energía serían casi un orden de magnitud menores.
      Si les interesa, aquí hay detalles: https://components101.com/modules/esp32-cam-camera-module
    • El problema es que este proyecto usa una cámara y una red inalámbrica, y ambas requieren drivers bastante complejos.
      En principio también sería posible hacerlo en bare metal, pero no es fácil hacer funcionar los periféricos necesarios.
  • Me preguntaba por qué el kernel personalizado apareció tan tarde. Si se quiere optimizar, ¿no se empieza con LFS o con una distribución basada en código fuente? Tampoco parece que las actualizaciones autónomas de software sean imprescindibles en un dispositivo así.
    También me pregunto si se puede optimizar EFI/BIOS en este tipo de dispositivos. Al menos en mi escritorio común con Arch Linux representa una parte considerable del tiempo de arranque.
    $ systemd-analyze
    Startup finished in 10.076s (firmware) + 1.339s (loader) + 1.569s (kernel) + 2.974s (initrd) + 3.894s (userspace) = 19.854s

    • Buildroot, que fue lo que usaron, es exactamente una herramienta para ese propósito. En Buildroot configuras tu propia "distribución" y a partir de ahí generas una única imagen de arranque.
      No conozco exactamente el hardware de Raspberry Pi, pero muchos otros SoC embebidos tienen un bootloader bastante mínimo que funciona con u-boot y normalmente es muy rápido. Sobre todo si configuras en 0 el retraso para esperar entrada del usuario.
    • En un entorno real, probablemente no querrías usar LFS siguiendo el manual del proyecto LFS. Hay que compilar demasiado GNU.
      Un kernel mínimo y un sistema con busybox es mucho menos doloroso, y Gentoo tampoco es una mala opción.
    • Gracias a esto me doy cuenta de que tengo que optimizar mi bootloader (systemd-boot) y de que mi firmware es sorprendentemente bueno.
      > systemd-analyze
      Startup finished in 3.259s (firmware) + 35.127s (loader) + 1.823s (kernel) + 2.927s (userspace) = 43.138s
  • 3.5 segundos es genial, pero si el escenario completo realmente consiste en conectarse a Wi-Fi cada pocos minutos para subir una imagen, ESP32 habría sido una opción mucho mejor en consumo de energía.
    Salvo que haga falta alguna función específica del módulo de cámara para Pi que no tengan las cámaras compatibles con ESP32-CAM.

    • ESP32 solo admite hasta 4 MB de PSRAM, mientras que una sola imagen fija de la RPi HQ Camera ya pesa 18 MB.
    • Podría recomendar un microcontrolador un poco más avanzado con interfaz MIPI CSI, pero por lo demás estoy de acuerdo.
      Parece demasiado trabajo para hacer algo que un microcontrolador puede hacer casi sin esfuerzo.