We were wondering about how to bring a custom camera solution that would be affordable and easy to integrate into the more than 400,000 original Prusa printers we have already shipped worldwide. While we have other solutions in the works, we would like to highlight a great open-source solution that was made specifically for Prusa Connect by a member of our community, Miroslav Pivovarský – an ESP32-CAM module with custom firmware.
This affordable module has integrated flash LED and WiFi, and you can buy it pretty much anywhere, flash it with Miroslav’s firmware, and start using it right away. It is not particularly revolutionary, but it provides an easy, cheap, and most importantly, functional solution for remote camera monitoring of your printer.
Once you flash the firmware, the entire setup is a matter of a few clicks. After that, all you have to do is register the camera in Prusa Connect, copy over its access token, and in a few seconds you will see its first snapshot in your interface. Do not expect a 4K60 video stream though, with the current implementation, it sends an image every couple of seconds, but even that is more than enough to remotely check on your print. Or even to send the image into a neural network for automatic fail detection, as we teased in the Prusa Podcast episode about AI in 3D printing. And since the firmware features OTA updates, the functionality can be improved in the future.
Detailed instructions for the entire setup can be found in this PDF. You can also print a handy camera mount that can be attached to the frame of your 3D printer. It’s flexible, yet sturdy, and you can easily set the position of the camera on it. It was created by the great designer, Michal Fanta and you can download it for free from Printables, along with the case for the camera module.
And if you’re wondering what it takes to develop such a solution, including the web application interface, OTA firmware updates, and many other interesting things, let us give you the detailed story behind its development! 🙂
The Story Begins
Miroslav began to explain how the work on his camera solution started: “We had a couple of MK3S+ 3D printers at work, and they were connected to the network via a Raspberry Pi with running PrusaLink software.” PrusaLink lets you get advanced network functionality even on older 8-bit machines and it allows you to connect them to Prusa Connect. “I was using an older smartphone as a remote camera (a built-in feature in Prusa Connect), but I was also looking for something more compact. Ideally, a small camera that would be functional just by itself,” he added.
So, in the meantime, he began to analyze the inner workings of the system – particularly how the phone sends the image to Connect. It didn’t take long to modify the NodeJS script that manages image transfers, so it could obtain captured photos from a small Raspberry Pi Camera via the CSI bus.
Miroslav then uploaded the script to another Raspberry Pi, connected the camera to it, and executed the script to grab the picture from the camera and send it to Connect. However, there still was a downside: it required two RPi boards – one for managing the camera, the other for running PrusaLink. It worked, but as Miroslav said, it was far from ideal.
Camera attached to the Original Prusa MK4
As it often happens, a breakthrough came by sheer coincidence. “I was just cleaning my desk and drawers the other day because I have plenty of various Arduino modules and addons – and there it was! A small ESP32-CAM module.” Miroslav remembers. This cheap MCU (Micro Controller Unit) has its own ARM processor, large Flash memory, enough RAM, and also a Wi-Fi module. It was perfect! 🙂
Of course, the path to a working solution wasn’t completely straightforward. While it might have seemed that the basic Arduino IDE (the development environment) would be enough, it wasn’t exactly true. In the end, Miroslav created his own HTTP server to receive and save incoming images, just like Prusa Connect. With this server, he tested the first versions of his scripts – those that were already working on the Raspberry Pi.
It works on my Raspberry Pi!
The next step was pretty obvious – make the ESP32-CAM do the same job the Raspberry Pi does. It was necessary to understand how the camera module works and how to send photos not just over HTTP, but also via HTTPS, which Prusa Connect uses, and which is more complex to work with. However, after some research, obtaining and correctly setting up the necessary certificate, Miroslav successfully sent the correct data from the ESP32-CAM to the server and even to Prusa Connect! Everything seemed to be working just fine, but the first problems appeared right away.
One of the biggest issues was with the size and resolution of the sent image. The maximal resolution, that was sent without any problems, was 320×240 pixels, which isn’t particularly much. This limitation was caused by the ESP32-CAM module itself, in which the problem occurred, when the size of the file, sent via HTTPS was larger than 9kB. After some research and several attempts, Miroslav found out, that if he split the file into the 5kB fragments and sent them sequentially, everything works correctly. Although it would cause slightly slower uploads, it was an ideal solution, at least for the moment.
It was even enough to create a video stream for a local network. The original concern was the maximum framerate would be around 1FPS, but after some problem-solving, where the streaming caused various color artifacts and poor horizontal sync, the results showed 5-7FPS at a resolution of 1024×768, which was a great result 🙂. And the MCU should have the potential to get even more FPS and better resolution, so Miroslav keeps working on it.
Now, Miroslav had a simple, but functional software solution, which he immediately shared on GitHub and the Prusa forum, because he just wanted to be the first, who came up with this solution.
You can view the latest image from the camera in the Prusa Connect application
There were still many things to solve, for example, it wasn’t ideal that the whole MCU configuration is integrated into the source code – the token, fingerprint, WiFi SSID, camera setup, and more. This whole package is compiled and flashed into the MCU memory, without the possibility of any additional changes. So, Miroslav began to look for a solution in a field with which he had little experience – the web interface.
Although web development was not Miroslav’s main focus, he took to his idea with enthusiasm and after several evenings of programming he came up with a functional web application for camera configuration, which ran directly on the camera module. “It looked like it came straight from the 90s, but it worked, so I was okay with that.” Miroslav laughed.
One of the first versions of the camera web interface
On the rails of development
We also noticed his solution and liked it very much, so we contacted him via email and offered him cooperation with the development of it. “I was very pleasantly surprised by the offer and immediately agreed to it. Among other things, because I would like to contribute more to the open-source community,” Miroslav said.
After some discussion and code review, we came up with several ideas for improving the software and web interface, for example, the implementation of a more modern-looking user interface, etc. Miroslav took up all these points with enthusiasm and started working on them immediately. “The most challenging part of the whole project for me was the development of the web application itself,” said Miroslav. The website had to look good and modern, ideally in a Prusa design, while still fitting into the MCU’s limited Flash memory. On the other hand, after analyzing and reading several articles, he evaluated, that his current solution, involving a combination of HTML and JavaScript with jQuery is the right way to go.
Miroslav also took the opportunity to work with AI, which helped him in the creation of the site. For example, he advised and explained the individual components, what they are called, how to use them, etc. “It was funny. I tried to explain to the AI what I wanted, but I didn’t even know exactly what I wanted. I just knew what I wanted it to look like in the end,” Miroslav mentioned. He also admitted that even though the web interface could have been more optimal and nicer, he had a great time developing it and learned a lot of new things.
The need for configuration
Now, when the design of the web interface was pretty much finished, he started thinking about other features. For example, firmware updates should be possible via the web interface – the camera could check the latest firmware version and download it if needed, and everything should be as user-friendly as it could.
Current appearance of the camera web interface
Now it was time to deal with one of the very important things, which was the first launch and setup of the MCU. Miroslav came up with two different solutions, that can exist next to each other and everybody can choose the preferred way of camera initialization.
The first solution is the AP mode, where an access point with a specific SSID is created after switching on the MCU. The client can connect to the AP via WiFi and here he can set the login details of his wireless network and further configure the camera. To prevent unused APs from unnecessarily interfering with the 2.4GHz WiFi band (imagine having dozens of them turned on), if no device connects within five minutes of turning on the camera, the AP mode is automatically turned off.
Once your camera is set up, you can locate its administration in the network via the IP address, but this is not very convenient, especially if you don’t know the IP address and don’t have access to your router’s administration. To ease this, Miroslav also added the mDNS functionality to the camera software, which means you are able to access the device in your local network via a DNS record (you can think of it as a nickname), so you don’t need to know or remember its IP address. The mDNS record is configurable – for example, now it is http://prusa-esp32cam.local
However, the AP mode solution brought up a problem, because the web interface needs to work in offline mode, while the user is connecting to the camera in the AP mode. Because of this, it was necessary to store the jQuery library directly in the MCU’s source code. Fortunately, small and optimized jQuery libraries already exist for this purpose, although it still takes approximately 86kB of MCU’s Flash memory, and that’s quite a lot.
Another way to configure the camera was a serial communication interface, that users can use instead of AP mode if they can’t or don’t want to use it. Here, the user can set the WiFi credentials and the authorization token for the backend application, display the IP address of the camera in the network, or use other commands via the console.
The bigger it gets…
At this point, the project has grown quite a bit. Miroslav rewrote the website about 3-4 times because he always found something that could be done better. The first version of the code was written in C, so now he tried to rewrite everything in C++, which is still not completely done, but the code is being edited and improved part by part. Although the project has grown quite a bit, it started and continues as an Arduino project, so the community can easily edit the source code without having to use another dedicated IDE with a compiler.
Now it was time to figure out how to implement the OTA (over-the-air) firmware update. The current MCU version has 4MB of Flash memory, which means that only 1.9MB of Flash can be used for the whole application. If you wonder why, it’s because for the firmware update, the so-called “double banking” is used, which means that the memory is divided into two sectors (it’s actually more, but for the sake of simplicity, let’s say two). In one sector, there runs an up-to-date, valid application (we’ll call it sector A). In the other sector, there is an invalid, outdated application version (you guessed it, it’s sector B).
Camera system information, including OTA firmware update options
When the new firmware is downloaded, sector B (the invalid application) is overwritten. Then the integrity of the installed firmware is checked, and if everything is OK, the application in sector B is set as the active one. Thanks to this system, an OTA update never overwrites the currently running application.
Hardware limitations
In addition to various software problems, there were also a few problems with the hardware itself. Some of the test samples stopped sending photos, kept disconnecting from WiFi, rebooted, etc. “It was many different problems, but I was having fun solving them. It was very interesting to see how they are occurring and then come up with solutions to eliminate them,” Miroslav commented.
The biggest problem was caused by the design of the ESP32-CAM board. For example – since the processor has few pins and a relatively large number of peripherals, the designer used the pin for lightning the LED also as one of the pins for communication with the microSD card. This resulted in a problem with communication between the MCU and the microSD card when the LED was lit. This was solved by using the microSD card’s “one wire mode”, where data is read and written only through one digital input/output.
The much bigger problem is with the flash LED on the board – the designer connected this LED directly to 3.3V without a current-limiting resistor, which causes the current flowing through the LED to be too high and the diode will die after a certain time. On one board the LED went out after a month of flashing every 30 seconds. Miroslav came up with several solutions to this problem, including soldering a resistor between the collector of the transistor and the PCB, or using an external light source, switched by a relay, a MOSFET, or something similar. Some pieces of the board also heat pretty much, but it depends on the current batch. This issue is still being worked on, because several attempts like reducing the clock frequency of the processor were tried, but they did not bring much improvement.
The few possible solutions for the LED problem suggested by Miroslav
As you can see, there are still many things to solve and improve in this project. However, Miroslav still enjoys it and likes to work on it. What he enjoys most is finding out what can be done with a small, cheap camera module. He would like to work even more on multitasking, since everything runs simultaneously on only one processor core, although the processor has two cores (dual core). And there’s sure to be a bunch of other tweaks/improvements he’d like to add.
So, do not hesitate to try this interesting camera solution, and also please share any of your comments or questions with us and the author.
Happy printing!
I've been hoping for a more "official" implementation of a camera solution. Thanks!
I just bought 2 ESP32 cams about a month ago. This is perfect timing.
Got both working!
Help/KB article was removed?
This is great fun!
I have flashed a "Version 2" ESP32-CAM with a FT232 serial adaptor and it works fine.
There was a slight snag initially because there is a typo in the Mac/Linux flash command given in Miroslav's Github instructions which I have detailed there as an issue.
Great stuff to play with!
Got one of mine up and running today. Glad we are able to connect it to prusa connect. Now to come up with a direct connect option to the buddy board
Thanks for this – way better than using an old bulky phone. Now to order a second camera with a wider field of view to keep an eye on the spools.
Nice clear instructions too (as long as I actually followed them it all worked 😉
Thoughts so far:
Some browsers seem more friendly than others to the web interface; Safari is a reluctant partner, Firefox seems more friendly, Thorium also seems friendly – Chromium based.
An external antenna is very, very desirable. My signal strenth went from really good to quite poor after moving it to the adjoining room – just one breeze block wall & a pretty busy 2.4 GHz WiFi is a challenge for my router.
It would be really nice that the flash only worked when the printer is printing!
thx so much, this is really great and it works 🙂
If you look at the file names in the PDF document opposed to file names that you download from the Github you will see that they are different.
Rename the downloaded files to match the instructions and you will find that it installs much easier.
A VERY different housing for the ESP32-Cam:
https://www.printables.com/model/31668-cthulhu-idol-esp32cam/comments/1756296
🙂 Have fun!
Having issues if I set resolution higher than about 800×600. Refresh snapshot works OK right up to 1600×1200 so hardware is working.
On the Prusaconnect webpage I only get parts of images loaded, sometimes an image loads briefly then immediately disappears to a grey box.
Not an internet issue: I have 10ms ping, 923Mbps download 106Mbps upload here
For now I have adjusted the image quality down but it's a bit frustrating.
Yeah, same as jimwsmith mentioned.
I'm not happy with this solution. I appreciate the effort, but way easier and better quality with one of the supported online cameras.
I hope whatever solution Prusa come up with works on PrusaLink, not just PrusaConnect. I don't want a cloud solution, way too risky for something that can heat up and with motors.
I am going to try to get a AMB82-MINI to work. I have one, that's one of the reason also it has better picture quality and 5g wifi
I built an integrated camera, lighting and filtration solution for the Prusa MK4, which works with Home Assistant. It is fully open culture and free to use by anyone, and you can build it yourself.
Check it out at https://rudd-o.com/smk4e
I've been running one of my printers with this camera for a few weeks nog, and it works great, for what it's supposed to do.
I'm very impressed by the setup, it's amazing what a great UI has been released on a simple ESP32.
Now, for comparing apples and oranges: I monitor another printer using a Raspberry Pi running OctoPi and Obico. That's just another level; I won't be comparing the performance of a simple ESP32 Camera module with a camera hooked up to a Raspberry, but I would like to point out something els. The AI spoken about in the podcast….already exist. It's called Obico, and i've used it for years (and contributed to training the AI model). It's amazing how good the model is at detecting failures, and prevent spaghetti (it once started as The Spaghetti Detective).
If anyone from the Prusa Dev team is reading this: how about reaching out to Obico, and see if the two teams could join efforts? The ESP experiment show there's a relative easy way to capture images, Obico is very good at analyzing them and predicting failures.
I could imagine Prusa users buying credits, used to analyze their footage through the Obico model, but integrated into Prusa Connect. Could be a win for both parties!
What remains a challenge either way: how to get from this ESP experiment to a single-power solution, so each Prusa printer can be monitored by a simple ESP32-Cam that's powered from the main power source, instead of using two separate power supplies for each monitored printer?
Anyway, as I started, I'm very impressed with it so far and salut the developers who made this possible. It's amazing work!
This seems like a big step along the way to a practical and affordable camera solution for the MK4/Mk4S/Mini and XL printers.
I think for most folks this is going to be a tad "techy" to assemble and get working, but there are going to be quite a few that can handle it. It needs (not much) further development to dumb it down and make it suited to the mass market, and even inclusion as an accessory for the printers and available in an eShop package.
Bad points seem to be confined to how to power the device. Looks like you need a separate plug pack power supply. But maybe a missed opportunity if obtaining power from the USB port on the xBuddy Board, or a connection to the Enclosure LED/Fan power supply (many folks have this).
Very cool idea. I have been waiting for it. Question to the community: How do you "illuminate" the scene for the little cam? In an enclosure there are LED stripes, but w/o?
I’ve been struggling to set mine up. I don’t have a windows PC and trying to set it up with a MacBook Pro and it has been a headache trying to piece the information together.
Anybody could offer a step by step guide to setting it up on a MacBook Pro for a Prusa mini 😭
Today I completed step 12 of the manual successfully with no errors along the way.
After disconnecting the cam module from the PC and power it up with another power supply, it does not bring up a Wifi I could connect to. Anyone any idea how to check the camera module?
i have the same problem. any solutions?
i have tried everything i can come up with.
it connects in ap mode, then disconnect before i can set it up with wifi.
anyone have some tips?
After flashing, I plug the camera into power and am getting the camera flash flashing, and no wifi SSID from the camera.
Could someone confirm the URL to the firmware we should be using. The one that I think is right is V1.0.3 at https://github.com/prusa3d/Prusa-Firmware-ESP32-Cam/releases. I also tried the latest (V1.1.0) with the same results (but no flashing flash).
Thanks,
Mark
when i connect to the camera in ap mode, to set up everything, the wifi connects and disconnect every two seconds.
Got it working with the newest firmware… Apparently I had a bad device. Tried with a different one and it working fine.
i have the same problem on two devices, wifi just dissapear when i connect to it.
i will try to order a new device and see.
Tapping into the printer for power would be cool. Maybe from the USB-C port, or the connections used by the accelerometer or GPIO breakout board. Otherwise a nice workaround to fill the gap.