Nos preguntábamos cómo aportar una solución de cámara personalizada que fuera asequible y fácil de integrar en las más de 400,000 impresoras Original Prusa que ya hemos enviado a todo el mundo. Un día nos encontramos con una gran solución de código abierto que se hizo específicamente para Prusa Connect por un miembro de nuestra comunidad, Miroslav Pivovarský – un módulo ESP32-CAM con firmware personalizado.

ESP32CAM

Este módulo económico tiene un flash LED integrado y WiFi, y se puede comprar en casi cualquier sitio, flashearlo con el firmware de Miroslav, y empezar a utilizarlo de inmediato. No es especialmente revolucionario, pero proporciona una solución fácil, barata y, lo que es más importante, funcional para la supervisión remota por cámara de tu impresora.

Una vez flasheado el firmware, toda la configuración es cuestión de unos pocos clics. Después de eso, todo lo que tienes que hacer es registrar la cámara en Prusa Connect, copiar tu token de acceso, y en pocos segundos verás su primera instantánea en tu interfaz. No esperes un flujo de vídeo 4K60, con la implementación actual, envía una imagen cada par de segundos, pero incluso eso es más que suficiente para comprobar a distancia tu impresión. O incluso para enviar la imagen a una red neuronal para la detección automática de fallos, como ya adelantamos en el episodio del Prusa Podcast sobre IA en la impresión 3D. Y como el firmware cuenta con actualizaciones OTA, la funcionalidad puede mejorarse en el futuro.

Encontrarás instrucciones detalladas para toda la instalación en nuestra página web de la PDF. También puedes imprimir un práctico soporte para la cámara que se puede fijar al marco de tu impresora 3D. Es flexible, pero resistente, y puedes fijar fácilmente la posición de la cámara en él. Fue creado por nuestro diseñador interno, Michal Fanta y puedes descargarlo gratis en Printables, junto con la carcasa para el módulo de la cámara.

Y si te estás preguntando qué se necesita para desarrollar una solución de este tipo, incluida la interfaz de aplicaciones web, las actualizaciones de firmware OTA y muchas otras cosas interesantes, ¡déjanos contarte la historia detallada de su desarrollo! 🙂

Comienza La Historia

Miroslav comenzó a explicar cómo empezó el trabajo en su solución de cámara: «Teníamos un par de impresoras 3D MK3S+ en el trabajo, y estaban conectadas a la red a través de una Raspberry Pi con software PrusaLink en ejecución». PrusaLink permite obtener una funcionalidad de red avanzada incluso en máquinas antiguas de 8 bits y permite conectarlas a Prusa Connect. «Estaba usando un smartphone antiguo como cámara remota (una función integrada en Prusa Connect), pero también buscaba algo más compacto. Lo ideal sería una cámara pequeña que fuera funcional por sí sola», añade.

Así que, mientras tanto, empezó a analizar el funcionamiento interno del sistema, en particular cómo envía el teléfono la imagen a Connect. No tardó mucho en modificar el script NodeJS que gestiona las transferencias de imágenes, de modo que pudiera obtener fotos capturadas de una pequeña cámara Raspberry Pi a través del bus CSI.

A continuación, Miroslav cargó el script en otra Raspberry Pi, conectó la cámara y ejecutó el script para obtener la imagen de la cámara y enviarla a Connect. Sin embargo, seguía habiendo un inconveniente: requería dos placas RPi – una para gestionar la cámara, la otra para ejecutar PrusaLink. Funcionó, pero como dijo Miroslav, estaba lejos de ser ideal.

Camera attached to Original Prusa MK4

Cámara acoplada a la Original Prusa MK4

Como sucede a menudo, un gran avance llegó por pura coincidencia. «El otro día estaba limpiando mi escritorio y mis cajones, porque tengo un montón de módulos y complementos de Arduino, ¡y ahí estaba! Un pequeño modulo ESP32-CAM» recuerda Miroslav. Esta MCU (Micro Controller Unit) barata tiene su propio procesador ARM, una gran memoria Flash, suficiente RAM y también un módulo Wi-Fi. ¡Era perfecto! 🙂

Por supuesto, el camino hacia una solución funcional no fue del todo sencillo. Aunque podría haber parecido que el IDE básico de Arduino (el entorno de desarrollo) sería suficiente, no fue exactamente así. Al final, Miroslav creó su propio servidor HTTP para recibir y guardar las imágenes entrantes, igual que Prusa Connect. Con este servidor, probó las primeras versiones de sus scripts, las que ya funcionaban en la Raspberry Pi.

¡Funciona en mi Raspberry Pi!

El siguiente paso era bastante obvio – hacer que la ESP32-CAM hiciera el mismo trabajo que la Raspberry Pi. Era necesario entender cómo funciona el módulo de la cámara y cómo enviar fotos no solo a través de HTTP, sino también a través de HTTPS, que utiliza Prusa Connect, y que es más complejo de trabajar. Sin embargo, después de investigar un poco, obtener y configurar correctamente el certificado necesario, Miroslav envió con éxito los datos correctos desde la ESP32-CAM al servidor ¡e incluso a Prusa Connect! Todo parecía funcionar bien, pero enseguida aparecieron los primeros problemas.

Uno de los mayores problemas era el tamaño y la resolución de la imagen enviada. La resolución máxima, que se envió sin problemas, fue de 320×240 píxeles, que no es mucho. Esta limitación fue causada por el propio módulo ESP32-CAM, en el que el problema se produjo, cuando el tamaño del archivo, enviado a través de HTTPS fue mayor que 9kB. Después de algunas investigaciones y varios intentos, Miroslav descubrió, que si dividía el archivo en fragmentos de 5kB y los enviaba secuencialmente, todo funcionaba correctamente. Aunque causaría subidas ligeramente más lentas, era una solución ideal, al menos por el momento.

Incluso fue suficiente para crear un flujo de vídeo para una red local. La preocupación original era que la velocidad de fotogramas máxima sería de alrededor de 1FPS, pero después de resolver algunos problemas, en los que el streaming causaba varios artefactos de color y una mala sincronización horizontal, los resultados mostraron 5-7FPS a una resolución de 1024×768, lo cual fue un gran resultado 🙂 . Y la MCU debería tener potencial para conseguir aún más FPS y mejor resolución, así que Miroslav sigue trabajando en ello.

Miroslav tenía una solución de software sencilla pero funcional, que compartió inmediatamente en GitHub y en el foro de Prusa, porque quería ser el primero en encontrarla.

Prusa Connect dashboard

Puedes ver la última imagen de la cámara en la aplicación de Prusa Connect

Aún quedaban muchas cosas por resolver, por ejemplo, no era ideal que toda la configuración de la MCU estuviera integrada en el código fuente: el token, la huella dactilar, el SSID WiFi, la configuración de la cámara y mucho más. Todo este paquete se compila y se flashea en la memoria del MCU, sin posibilidad de realizar cambios adicionales. Así que Miroslav empezó a buscar una solución en un campo con el que tenía poca experiencia – la interfaz web.

Aunque el desarrollo web no era lo que más le interesaba a Miroslav, se tomó su idea con entusiasmo y, tras varias tardes de programación, dio con una aplicación web funcional para la configuración de la cámara, que se ejecutaba directamente en el módulo de la cámara. “Parecía sacada directamente de los años 90, pero funcionaba, así que me pareció bien.” se ríe Miroslav.

La primera versión de la interfaz web de la cámara

Una de las primeras versiones de la interfaz web de la cámara

Sobre los raíles del desarrollo

También nos fijamos en su solución y nos gustó mucho, así que nos pusimos en contacto con él por correo electrónico y te ofreció colaborar en el desarrollo de la misma. “La oferta me sorprendió muy gratamente y acepté de inmediato. Entre otras cosas, porque me gustaría contribuir más a la comunidad de código abierto,” afirma Miroslav.

Tras debatir y revisar el código, se nos ocurrieron varias ideas para mejorar el software y la interfaz web, por ejemplo, la implementación de una interfaz de usuario de aspecto más moderno, etc. Miroslav asumió todos estos puntos con entusiasmo y empezó a trabajar en ellos inmediatamente. «Para mí, la parte más difícil de todo el proyecto fue el desarrollo de la propia aplicación web,» dice Miroslav. El sitio web tenía que tener un aspecto atractivo y moderno, idealmente con un diseño Prusa, y al mismo tiempo caber en la limitada memoria Flash de la MCU. Por otra parte, después de analizar y leer varios artículos, evaluó, que su solución actual, que implica una combinación de HTML y JavaScript con jQuery es el camino correcto a seguir.

Miroslav también aprovechó la oportunidad de trabajar con AI, que le ayudó en la creación del sitio. Por ejemplo, le asesoró y explicó los distintos componentes, cómo se llaman, cómo utilizarlos, etc. «Fue divertido. Intenté explicarle a la IA lo que quería, pero ni siquiera sabía exactamente lo que quería. Sólo sabía qué aspecto quería que tuviera al final», comentó Miroslav. También admitió que, aunque la interfaz web podría haber sido más óptima y agradable, tenía un me lo pasé muy bien desarrollándolo y aprendí muchas cosas nuevas.

La necesidad de configurarlo

Cuando el diseño de la interfaz web estaba prácticamente terminado, empezó a pensar en otras funciones. Por ejemplo, las actualizaciones de firmware deberían ser posibles a través de la interfaz web – la cámara podría comprobar la última versión del firmware y descargarla si fuera necesario, y todo debería ser lo más fácil de usar posible.

Current camera web interface

Aspecto actual de la interfaz web de la cámara

Ahora era el momento de ocuparse de una de las cosas muy importantes, que era la primera puesta en marcha y configuración de la MCU. Miroslav vino con dos soluciones diferentes, que pueden existir uno junto al otro y todo el mundo puede elegir la forma preferida de inicialización de la cámara.

La primera solución es el modo AP, en el que se crea un punto de acceso con un SSID específico tras encender la MCU. El cliente puede conectarse al AP a través de WiFi y aquí puede establecer los detalles de inicio de sesión de su red inalámbrica y seguir configurando la cámara. Para evitar que los AP no utilizados interfieran innecesariamente en la banda WiFi de 2,4 GHz (imagínese tener decenas de ellos encendidos), si ningún dispositivo se conecta en los cinco minutos siguientes al encendido de la cámara, el modo AP se desactiva automáticamente.

Una vez configurada tu cámara, puedes localizar su administración en la red a través de la dirección IP, pero esto no es muy cómodo, sobre todo si no conoces la dirección IP y no tienes acceso a la administración de tu router. Para facilitar esto, Miroslav también ha añadido la funcionalidad mDNS al software de la cámara, lo que significa que puedes acceder al dispositivo en tu red local a través de un registro DNS (puedes pensar en ello como un apodo), por lo que no necesitas saber o recordar su dirección IP. El registro mDNS es configurable – por ejemplo, ahora es http://prusa-esp32cam.local

Sin embargo, la solución del modo AP planteó un problema, ya que la interfaz web debe funcionar en modo sin conexión, mientras que el usuario se conecta a la cámara en el modo AP. Por ello, era necesario almacenar la biblioteca jQuery directamente en el código fuente de la MCU. Afortunadamente, ya existen librerías jQuery pequeñas y optimizadas para este propósito, aunque sigue ocupando aproximadamente 86kB de la memoria Flash del MCU, y eso es bastante.

El SSID de la cámara consta del prefijo ESP32_camera + ID, que son los tres primeros números del UID de la MCU. Por lo tanto, si alguien utiliza varios módulos -por ejemplo, para vigilar la granja-, con la ayuda de esta etiqueta podrá reconocer fácilmente cuál es cuál.

Otra forma de configurar la cámara era una interfaz de comunicación serie, que los usuarios pueden utilizar en lugar del modo AP si no pueden o no quieren utilizarlo. Aquí, el usuario puede establecer las credenciales WiFi y el token de autorización para la aplicación backend, mostrar la dirección IP de la cámara en la red o utilizar otros comandos a través de la consola.

Cuanto más crece…

A estas alturas, el proyecto ha crecido bastante. Miroslav reescribió el sitio web unas 3-4 veces porque siempre encontraba algo que se podía hacer mejor. La primera versión del código estaba escrita en C, así que ahora ha intentado reescribirlo todo en C++, lo que todavía no está hecho del todo, pero el código se está editando y mejorando parte por parte. Aunque el proyecto ha crecido bastante, comenzó y continúa como un proyecto Arduino, por lo que la comunidad puede editar fácilmente el código fuente sin tener que utilizar otro IDE dedicado con un compilador.

Ahora tocaba averiguar cómo implementar la actualización OTA (over-the-air) del firmware.. La versión actual del MCU tiene 4MB de memoria Flash, lo que significa que sólo se pueden utilizar 1,9MB de Flash para toda la aplicación. Si te preguntas por qué, es porque para la actualización del firmware se utiliza el llamado «double banking», que significa que la memoria se divide en dos sectores (en realidad son más, pero para simplificar, digamos dos). En un sector, se ejecuta una aplicación actualizada y válida (la llamaremos sector A). En el otro sector, hay una versión no válida y obsoleta de la aplicación (lo ha adivinado, es el sector B).

Camera system information with OTA

Información del sistema de la cámara, incluidas las opciones de actualización del firmware OTA

Cuando se descarga el nuevo firmware, se sobrescribe el sector B (la aplicación no válida). A continuación, se comprueba la integridad del firmware instalado y, si todo es correcto, la aplicación del sector B se establece como activa. Gracias a este sistema, una actualización OTA nunca sobrescribe la aplicación que se está ejecutando en ese momento.

Limitaciones de hardware

Además de varios problemas de software, también hubo algunos problemas con el propio hardware. Algunas de las muestras de prueba dejaron de enviar fotos, se desconectaban continuamente del WiFi, se reiniciaban, etc. «Fueron muchos problemas diferentes, pero me divertí resolviéndolos. Fue muy interesante ver cómo se producen y luego idear soluciones para eliminarlos», comentó Miroslav.

El mayor problema fue causado por el diseño de la placa ESP32-CAM. Por ejemplo – ya que el procesador tiene pocos pines y un número relativamente grande de periféricos, el diseñador utilizó el pin para encender el LED también como uno de los pines para la comunicación con la tarjeta microSD. Esto provocaba un problema de comunicación entre la MCU y la tarjeta microSD cuando el LED estaba encendido. Esto se solucionó utilizando el «modo de un solo cable» de la tarjeta microSD, en el que los datos se leen y escriben sólo a través de una entrada/salida digital.

El mayor problema es con el LED flash de la placa – el diseñador conectó este LED directamente a 3.3V sin una resistencia limitadora de corriente, lo que hace que la corriente que fluye a través del LED sea demasiado alta y el diodo morirá después de un cierto tiempo. En una placa el LED se apagó después de un mes de parpadear cada 30 segundos. A Miroslav se le ocurrió varias soluciones a este problema, incluyendo soldar una resistencia entre el colector del transistor y la placa, o usar una fuente de luz externa, conmutada por un relé, un MOSFET, o algo similar. Algunas piezas de la placa también se calientan bastante, pero depende del lote de corriente. Esta cuestión sigue trabajandose en ello, ya que se probaron varios intentos como reducir la frecuencia de reloj del procesador, pero no aportaron grandes mejoras.

Possible solutions to the LED problem

Las pocas soluciones posibles para el problema de los LED sugeridas por Miroslav

Como puedes ver, aún quedan muchas cosas por resolver y mejorar en este proyecto. Sin embargo, Miroslav todavía lo disfruta y le gusta trabajar en ello. Lo que más le gusta es descubrir qué se puede hacer con un módulo de cámara pequeño y barato. Le gustaría trabajar aún más en la multitarea, ya que todo se ejecuta simultáneamente en un solo núcleo del procesador, aunque éste tiene dos núcleos (dual core). Y seguro que hay un montón de otros ajustes/mejoras que le gustaría añadir.

Por lo tanto, no dude en probar esta interesante solución de cámara, y también por favor comparte cualquiera de tus comentarios o preguntas con nosotros y el autor. ¡Felices impresiones!