Here is a script and instructions for using a ESP32Cam for snapping a series of shots when the arm sweeps to one end of the rail to compile later into a GIF, MP4, etc to post or share, BUT, only in linux :(
With just a simple microswitch (snagged from my defunct ender3) that is attached just above the swiper section of the X axis. There is a simple webserver in the script to "delete all" images, and a "delete all and reboot" with a directory listing on the page for when a print is done. Just pop out the Sdcard and pull off the images onto your desktop, etc. and edit, replace the sdcard back in the esp32cam and power cycle. I DID try to have it zip up and package all the images or allow the images in the directory be clicked on or downloaded and viewed, but that would eat up to many cycles and lag the monitoring of switch on GPIO13.
The ESP32 was NOT having it (not with micropython).
So I followed this diagram for wiring minus the resistor
Where I simply took a microswitch that was wired in a N.O. setup as a limit switch for an axis (x,y,x) from my old printer and placed 1 wire to GND and the other wire to GPIO13 from the switch. Dronebotworkshop.com has a really good write up already on how to use the esp32-cam with a shutter button here.
I wrote this in MicroPython and tried to keep it simple, since python (albeit 'micro') is a heavy workload already for a esp32 MCU.
sudo apt update
sudo apt install python3 python3-pip python3-venv
mkdir ~/esp32-cam-project
cd ~/esp32-cam-project
python3 -m venv esp32cam-env
source esp32cam-env/bin/activate
pip install adafruit-ampy esptool.py pyserial
FTDI to ESP32-CAM wiring:
FTDI TX → ESP32 RX (GPIO 3)
FTDI RX → ESP32 TX (GPIO 1)
FTDI GND → ESP32 GND
FTDI 5V → NOT CONNECTED (use external 5V power)
Additional connections for programming: GPIO 0 → GND (during programming only!) External 5V → ESP32 5V pin
I used the one with out bluetooth from this github repo or compile you own (not helping you there, compiling that was a pain without any success (for some reason))
wget https://github.com/lemariva/micropython-camera-driver/blob/master/firmware/micropython_v1.21.0_camera_no_ble.bin
esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash
esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 micropython_v1.21.0_camera_no_ble.bin
2. Connect GPIO 0 to 3.3V (or leave floating, works best, just incase you have to do it over again lol)
screen /dev/ttyUSB0 115200
MicroPython v1.xx.x on ESP32 module
Type "help()" for more information.
>>>
This part is optional, but should work
import camera
camera.init(0)
buf = camera.capture()
print("Camera works!", len(buf))
nano main.py
Replace you SSID and WIFI_PASSWORD
SSID = "YOUR_SSID"
PASSWORD = "YOU_WIFI_PASSWORD"
Also you can change the name of the camera to something else instead of Bambu-Camera, so you can see it on your wifi
DEVICE_NAME = "Bambu-Camera"
ADDED MORE SETTINGS
CAMERA_RESOLUTION = 10 # XGA (1024x768) is index 10
JPEG_QUALITY = 8
(sdcard was anonying for me)
SD_MOUNT_POINT = "/sd" PHOTO_FOLDER_NAME = "photos" LOG_FOLDER_NAME = "logs"
PHOTO_FOLDER = SD_MOUNT_POINT + "/" + PHOTO_FOLDER_NAME LOG_FOLDER = SD_MOUNT_POINT + "/" + LOG_FOLDER_NAME
shutter = machine.Pin(SHUTTER_PIN, machine.Pin.IN, machine.Pin.PULL_UP) picture_count = 0 last_shutter_state = None
(Then after you've updated you script then you need to "put" over main.py THEN boot.py once the esp32 resets boot.py will take over, its only there for 'rebooting' off the webpage)
ampy --port /dev/ttyUSB0 put main.py
ampy --port /dev/ttyUSB0 put boot.py
ampy --port /dev/ttyUSB0 ls
$ ampy --port /dev/ttyUSB0 ls
/boot.py
/main.py
Power cycle ESP32-CAM (disconnect/reconnect 5V) Monitor boot with serial monitor:
*NOTE: This part I was using two terminals and when I would unplug the FTDI it would free up the ttyUSB0 so I could watch the startup process when I power cycled the ESP32cam. In terminal 1 I would use ampy to flash the micropython firmware, and also push the main.py over.. and (after unplugging the FTDI) in terminal 2 I would use screen as a serial monitor. Sooo... my process was complicated, see below.
-
terminal 1 flash mircopython.bin to the esp32cam, when there was no errors cut off the 5v power to the esp32 and power it back on. Then flash main.py with ampy to side load the main.py onto the esp32cam module, unplug FDTI from the usb port and uplug 5v power from the cam.
-
switch to terminal 2, plug in the FDTI to the usb port, then plug the 5v back in to the camera module and run...
screen /dev/ttyUSB0 115200
watch the boot up of the esp32cam module for WIFI, button presses, errors, etc..
(screen commands are CTRL+A then K to kill the console session (not the esp32), but with boot.py running you will have to hit CTRL+C a few times to break the boot.py loop and set the esp32 to >>> for the micropython IDE, from there you can CTRL+a K and the screen session and use ampy to reupload another version of the main.py, if not you'll get a ttyUSB0 in use, etc...)
-
repeat if needed
-
no errors, then access web interface at the IP shown in serial monitor
(I seriouly never had any 'fun' with a esp32-cam (Ai-Thinker, etc) for me and linux it always felt like a chore LOL)
Troubleshooting If /dev/ttyUSB0 permission denied:
sudo usermod -a -G dialout $USER
Log out and log back in, or restart
Or temporary fix:
sudo chmod 666 /dev/ttyUSB0
If port not found:
Check available ports
ls /dev/ttyUSB*
Check if device detected
dmesg | grep tty
If upload fails:
Make sure GPIO 0 is NOT connected to GND during upload
Ensure stable 5V power supply
Try different USB cable/port
Quick Reference Commands
source esp32cam-env/bin/activate
esptool.py --port /dev/ttyUSB0 erase_flash # Erase
esptool.py --port /dev/ttyUSB0 write_flash 0x1000 firmware.bin # Flash
ampy --port /dev/ttyUSB0 put main.py # Upload code
ampy --port /dev/ttyUSB0 ls # List files
screen /dev/ttyUSB0 115200 # Serial monitor
Your complete workflow:
python3 -m venv esp32cam-env
source esp32cam-env/bin/activate
pip install adafruit-ampy esptool.py
Activate your programming session:
source esp32cam-env/bin/activate
esptool.py --port /dev/ttyUSB0 erase_flash
esptool.py --port /dev/ttyUSB0 write_flash 0x1000 firmware.bin
ampy --port /dev/ttyUSB0 put main.py
This gives you a clean, reproducible setup for programming your ESP32-CAM! CAKE! (no) After this........ you can then assemble your printed "Esp32-camera case", power it up and mount your microswitch above the swiper with paper clips, painters tape, gum.... i don't know mounting is your call with the switch, enjoy. lol
I did use this "poop catcher" and added a rectangle cube on the top (just extended the surface area).
BUT, mount the switch on the modified poop catcher, screw in first front screw and the second one, but tighten the first down to hold the switch on the catcher. clip the catcher onto the printhead and home your axis... then after homing move the printhead all the way "-X" as far as it can go, then slide the switch gently to the right till it clicks, and lock it in place with that second screw as a set screw.
There is only 1 hole in the catcher to hold the switch in place.

