Setting Up esptool in a Python Virtual Environment

I’m trying to get into the habit of asking ChatGPT to create a blog post each time I do something I want to remember (and perhaps tell others about). I did this today to get a device ready for my shutter controller….

So, you’ve got an ESP32, and you need to flash some firmware. The official tool for the job is esptool, but before you go installing things system-wide like a reckless cowboy, let’s do it properly—with a Python virtual environment.

Why? Because keeping things self-contained means no dependency nightmares down the line. Trust me, future-you will thank present-you for this.


Step 1: Install Python (If You Haven’t Already)

First, make sure you have Python installed:

python3 --version

If that spits out a version number, you’re good. If not, go install it from python.org.

On Windows, also make sure pip is installed:

python -m ensurepip --default-pip

Step 2: Create a Virtual Environment

Now, let’s create a virtual environment so we don’t clutter up our system’s Python installation:

python -m venv esptool-env

This makes a new folder called esptool-env, which holds its own little self-contained Python world.


Step 3: Activate the Virtual Environment

Before installing anything, you need to activate the virtual environment.

  • On Windows (Command Prompt or PowerShell):
    esptool-env\Scripts\activate
  • On macOS/Linux:
    source esptool-env/bin/activate

Your terminal should now show something like (esptool-env) at the beginning of the prompt, meaning you're inside the virtual environment.


Step 4: Install esptool

Now, install esptool inside your virtual environment:

pip install esptool

To check if it installed correctly, run:

esptool --version

✅ If you see a version number, you're all set!


Step 5: Using esptool (No .py Required!)

At this point, you might be tempted to type:

esptool.py chip_id

But stop right there! On Windows (and even some Linux/macOS systems), esptool installs as an executable, meaning you don’t need the .py suffix.

Instead, just run:

esptool chip_id

Much cleaner, right?


Step 6: What is firmware.bin?

When flashing an ESP32, you need a firmware file—usually named firmware.bin. This file contains the actual program that will run on the ESP32, including:
✅ The operating system (like MicroPython or an IoT framework)
Libraries and runtime components
✅ The main application code

Think of it as the brain of your ESP32—it tells the chip what to do when it powers on.

If you’re installing MicroPython, you’ll need to download the latest ESP32 firmware from the official site:

🔗 Download MicroPython Firmware

Make sure you get the correct version for your ESP32 model (ESP32, ESP32-C3, ESP32-S3, etc.).


Step 7: Flashing MicroPython to an ESP32

Once you have the firmware.bin file, you can flash it using esptool.

1️⃣ Erase the Existing Flash Memory

Before installing new firmware, it’s a good idea to wipe the existing flash:

esptool --port COM3 erase_flash

(Replace COM3 with your actual serial port. On Linux/macOS, it might be something like /dev/ttyUSB0.)

2️⃣ Flash the MicroPython Firmware

Now, install MicroPython by flashing the .bin file:

esptool --port COM3 --baud 460800 write_flash -z 0x1000 firmware.bin

🛠 Breaking this down:

  • --port COM3 → Specifies the serial port
  • --baud 460800 → Speeds up flashing (can be lowered if issues arise)
  • write_flash -z 0x1000 firmware.bin → Writes the firmware at the correct address (0x1000)

When it’s done, MicroPython is now installed! 🎉


Step 8: Connecting to MicroPython

Once the firmware is flashed, you can connect to the ESP32 using a serial terminal program:

1️⃣ Install a terminal program like PuTTY, screen, or minicom
2️⃣ Connect using the correct port and baud rate (115200 baud)
3️⃣ Press Enter, and you should see the MicroPython REPL (interactive shell)

Alternatively, use Thonny (a beginner-friendly Python IDE) to interact with MicroPython.


Step 9: Deactivating the Virtual Environment

When you're done, exit the virtual environment with:

deactivate

The next time you need to use esptool, just reactivate the environment and you’re good to go:

esptool-env\Scripts\activate  # Windows
source esptool-env/bin/activate  # macOS/Linux

Final Thoughts

By using a virtual environment, you've kept your system clean and organized—no global Python clutter, no version conflicts. And remember:

🔥 Just type esptool, no .py needed!
🔥 MicroPython firmware is just a .bin file that needs to be flashed to your ESP32!

Now, go forth and flash those ESP32s like a pro. 🚀

Remote Camera Control Fun at DDD North 2025

It would be lovely if it worked…

I want to take pictures of folks at my DDD North Session next month. And not just with any camera. I want to use my “self-fogging” Polaroid Camera. You’ll find out how to build your own if you come along. Snag is I don’t want to have to press the shutter button myself. I mean I could, but I really want to control the camera for a brief timed exposure (around half a second or so) for each shot and I’d love them all to be totally consistent.

I found a design for a remote controlled camera release which looked like a good starting point so last night I printed out the actuator and today I printed the box. I then put it all together, connected a microcontroller and fired it up.

It doesn’t work. Not a problem with the device itself, it can trigger the shutter on a lot of my cameras. But not on my “self-fogger”. The shutter on early Polaroid cameras is cocked as you press it. This makes the mechanism simpler and less prone to wear, but it means that you have to work quite hard to push the button down. Something which my little 9gm servo is just not equal to. So I’ve switched to a much beefier servo. We’ll see how it goes.

If you want to find out out how it all turns out, and maybe even get a ready fogged snap of yourself, make sure to sign up for DDD North on the 22nd February and come along to my session.

Adventures with old digital camera backs

Now that I’ve got a very old digital back for my very, very old camera I thought it was time to take some pictures with it. I’m a bit constrained, in that the camera has to be connected to the computer when I use it, but this is still much easier and cheaper than using film.

The digital back that I’m using has a sensor which is around the size of a 35mm frame. This means that I’m only capturing the centre of the picture, but I’m not unhappy with the results.

It’s been great fun walking around the house and taking pictures of stuff. It has allowed me to practice focusing and framing without spending a fortune on film. I’m really looking forward to taking some portraits with the setup. The absolute picture quality is pretty good. I know that modern cameras, and even phones, can produce images which seem sharper and brighter, but that’s not the point. I love the filmic quality of the results I get from this kit.

If you have an old computer (and you will need an old one - new ones are no good) that you can dedicate to the project and you happen to have an old film camera that will work with a digital back you should definitely have a go.

DeepSeek Ai

Well, it certainly passes my Ego test

There’s been a lot of chatter about this new AI called DeepSeek. I had a little go with it this afternoon. I gave it a programming problem and it acquitted itself quite well. I couldn’t distinguish the replies from the ones I got from ChatGPT, although it did stop talking to me after a couple of questions. They say that DeepSeek is smaller and more efficient and all the code is open source.

I can remember back to the time when it was really cool to have a computer of your own running at home. The way things are going, the next cool thing will be to have your own AI running at home.

We do live in interesting (and a bit scary) times.

Updating a Polaroid Wink Light

it is in good condition for its age

I’ve been messing around with Polaroid Land cameras for a while. Today I thought I’d do something with their flash lights. The Polaroid Wink light was created to add a bit of extra light to your pictures. If you buy a second hand Polaroid outfit you will frequently find one included in the package.

YOu can’t get 45 volt batteries any more. And this is a good thing.

Above you can see inside the light. The silver thing at the back is a capacitor which is charged up from the battery before the shot is taken. When the shutter is fired the charge in the capacitor is sent into the bulb producing a bright “wink” of light. The bulb in a wink light was made for use in cars which have a 12 volt power supply. The wink light sends 45 volts through the bulb making it get extra bright for a short time. If you want even more light you can plug a little holder into the side of a wink light which holds a “proper” flash bulb. These bulbs contain fine magnesium wire which burns with a really bright light - although you can only use each bulb once.

Anyhoo, I wanted to make the wink light actually do something. I had a number of ideas but in the end I decided to see if I could fit a standard G4 lighting led into the light. These use a 12 volt power supply. The most I could get from my batteries was 6 volts so I dug out a little voltage converter which steps this up to 12 volts.

The power switch is in the case at the bottom left hand side

Above you can see what I ended up with. There are two battery holders, each of which contains 2 AA batteries. They are connected via a switch to a “buck converter” which steps their 6 volts up to the 12 volts the bulb likes. I’m not planning on making the light switch on when the camera takes a picture. I’m a bit concerned that it might take too long for the circuit to fire up. Instead I’m going to leave the light on all the time while I take pictures. This also gives me a bit more light to focus with, which is nice.

Ready for action

Above you can see the light on the camera as it is meant to be used. The next step is to take some test pictures and get a feel for the exposure settings it needs. This was a fun way to spend a Sunday.

DDD North Schedule and Registration Now Available

I might bring the duck along if I can think of a reason to….

DDD North is an awesome conference hosted at Hull University on Saturday 22nd February. It’s been going for ages and is always wonderful. You can find the schedule here. And you can register for tree here. I’m on with all my toys in the first slot, 9:30 in Lecture Theatre A. I really like this timing, it means that I can get my session out of the way and then go and see lots of other stuff.

I look forward to seeing you there.

Plumbing the depths

I don’t usually wake up and think “Perhaps I’ll do some plumbing today”. But this morning the decision was taken out of my hands, what with the water cascading down the side of the house and all. I had a pretty good idea what the problem was, and a trip into the loft confirmed it. The float valve on the water tank had failed. The split pin that holds the ball cock had rusted through and the whole assembly had broken free, leading the valve to fill the tank forever. The good news was that the overflow was working perfectly, and all the excess water was being directed out of the house. The bad news was that I had to fix it.

I’ve been here before, around twenty years ago when pretty much the same thing happened. That time I didn’t have the luxury of a tap to turn off the water supply. Well, actually I did have a tap, it’s just that when I turned it the top came off in my hand. On that occasion (and I’m rather proud of this) I came home from work in my lunch hour, turned on all the cold-water taps, flushed the toilets and then managed to swap the broken assembly while the water pressure was reduced. I hardly made any mess. Then I ate a bag of crisps and went back to work. But of course, I was much younger then.

Today I turned the water off and then headed off to ToolStation to get a replacement (£7.98). Fun fact. If you search for ToolStation the first hit you get is for ScrewFix. And if you search for ScrewFix the first hit you get is ToolStation.

ScrewFix and ToolStation are competing building supply companies in the UK. In Hull their depots are actually next to each other. I have this idea that on Christmas Eve, when all is peace and goodwill, the staff from the two depots meet in the car park for a football match while someone plays the mouth organ and all talk is of “When will this war all be over….”. But I digress.

The fixing process was actually quite painless. Fortunately I’ve kept my big spanners. For me the worst part was seeing the corroded and aged part and remembering back to when I fitted it as a brand new shiny one. I don’t think I’ll be replacing this the next time it wears out.

Anyhoo, we now have running water in all the right places.

I found this awesome sticker on my toolbox…

Musical Meetup

I like a messy desk

We had a splendid meetup tonight. Sally from Drake Music came along to see what we get up to and we had Midi Cheeseboxes, a digital trombone, and a magical theramin. Brian had also brought along his lidar that can tell when you hold your hands above your head and the discussions were wide ranging, from “How do you hear a square wave?” to “What happens if you dream that you are lying awake at night?” and lots of places in-between

I’m not sure we found all (or indeed any) of the answers, but we are looking forward to having another go at the next meetup on February 5th at Hull Library Makerspace. You are welcome to come along. Ping me an email (meetups@robmiles.com) if you want me to add you to our mailing list.

Fujica Half

It is a stylish little camera

Half frame cameras are having a moment right now. The attraction of getting twice as many shots on your roll of 35mm film is hard to ignore. Pentax have recently launched a new half-frame camera and there are also cheaper (although rather expensive for what they are) half frame offerings out there too.

The Fujica Half dates from 1963. It is a quality lump of metal that looks the part and unlike the new cameras you can buy today it has shiny metal and proper heft. It is quite easy to use. You set the film speed on the back and it sorts out exposure (rather well in my experience) but you have to do the focusing yourself, adjusting the lens to the right distance. The film advance uses a neat little lever.

No batteries are required. The exposure meter uses a light powered selenium cell which lasts for ever, or until it breaks. If the camera has been kept in its case the cell will probably be OK, if not you can set everything manually which is a bit more of a faff, but not a stopper. The viewfinder is nice and bright, and it shows the shutter and aperture settings selected by the camera along with marks that help you frame close up subjects. You can use a flash with it, but you’ll have to plug it into the socket on the front and then set the aperture by hand. The frame counter is hidden on the bottom of the camera. It goes all the way up to 72 shots, which is what you would get from a 36 exposure film.

The camera takes pictures in portrait mode. If you have a film processed you’ll get two images per frame, which is rather nice. The lens is lovely and sharp and I really like the pictures it turns out.

These are two of the first pictures I took with the camera

The Exposure meter coped well with low light. I need to work on holding the camera straight,

I had to tip the camera on its side to take these pictures

The lens doesn’t flare too much

If you are thinking of getting into film photography you could do a lot worse than pick up one of these. And if you are already into photography it’s a nice thing to have around - and you can use the camera in full manual mode and set the shutter and aperture yourself if you want to get creative.

They seem to be nudging up in price at the moment (at least in terms of what folks are asking for them on ebay). If you see a tidy one with a working meter for less than the price of a video game I think it would be worth a punt.

Working with ChatGPT

I’ll let ChatGPT explain what I’ve been up to today:

  1. Context: We’re building a framework to store and load settings for a MIDI controller using CircuitPython on a Raspberry Pi PICO.

  2. Challenge: Lists of settings needed to handle both uniform and mixed object types while keeping the JSON output compact and memory-efficient.

  3. Solution: We dynamically added type information to list keys when uniform or to individual items when mixed, ensuring deserialization works flawlessly.

  4. Result: A smart, efficient system that elegantly handles nested settings and mixed data—perfect for the PICO’s constraints and your MIDI Cheesebox magic. 🎶🧀

Minolta Vectis-S1

The Minolta Vectis S-1 camera is not particularly pretty. But it is pretty cheap. I picked up the example above for less than ten pounds. It is cheap for two reasons:

  1. It uses a type of film which is no longer made.

  2. It probably won’t work when you get it.

The camera uses Advanced Photo System film which was launched in the 1990’s and abandoned in 2011. But this is not a huge problem, you can still get film cassettes for it, albeit ones which will be at least 13 years old. The system uses a very complicated film loading mechanism containing many whirring and clicking parts. The first example of this camera I got made a few unhappy sounds too, followed by total lockup. But the sample above was made of sterner stuff and seems to be able to load film and take photos OK. I got hold of some film and took some shots.

I’ve not made the holders that go on top of the film yet.

The system was designed so that the film stayed in the cassette at all times. The processing and printing machinery was clever enough to get the film out of the cassette, print the shots you wanted and then wind it back in again. Of course I don’t have any of that machinery, so instead I designed a little holder which I can load up with film for the scanner. I then pulled the film out of the cassette and cut it into lengths for scanning.

The negatives are 16mm high with a “widescreen” aspect ratio

The results are pretty respectable for a twenty year old camera using fifteen year old film. Above is one of the more interesting ones. There is plenty of detail and the image is sharp enough . The shadows are very grainy though, probably because of the age of the film.

I’m not sure if I’d use this camera and film combination for any pictures that I really care about (although the auto-focus and exposure seem to work well). But it is fun to get out and play with.

Phase One digital back success: return to the Mac

I think this has the appropriate level of recursion

I’m still not sure if anyone wants to hear about my travails getting digital back for my old camera. But things have gone so well today that I really want to tell everyone (or at least both of my readers) all about it.

Yesterday I discovered that it was all but impossible to get my recently acquired Phase One digital camera back (frog number two) working on a Windows machine. So today I went into the garage and dug out a venerable MacBook Pro that I’ve had for ages. I used it to write “Begin to Code C#” all those years ago. Just like me to write a book with that title on a machine with no # key on the keyboard. But I digress.

It turns out that things kept in the garage survive the experience. It booted up first time and I even remembered my password. It works a treat. In fact it works so well I got to wondering what new laptops do which made them worth the upgrade. Then I tried to pick it up, and I remembered.

I installed the appropriate version of Capture One, plugged the cable from the back into the firewire port on the side of the machine and lo and behold, it worked. It turns out that the FireWire port on a MacBook Pro (or at least this one) puts out enough current to power the back.

This was the first shot I took out of the window

I took a few pictures. It seems strange to be using a digital camera and still have to set the exposure. You configure the “film speed” of the back and then expose for that. But you have the advantage of seeing your shot straight after taking it. This gives you a proper “film” experience, just with really fast developing.

Capture One is an awesome program. I’m using version 6 from 2013. It runs fine on the MacBook. It is a professional tool, which means the learning curve is a bit steep, but it works a treat. I might try the newer versions (which might work on the Mac) but I’m not going to push my luck too far…

I now have a “portable” camera system, as long as I take along the Phase One back, MacBook and the cable that links them together. The resolution is not that great, but I don’t care. The pictures look really nice to me. And I’ve only had to kiss two frogs to get where I want to be.

Loft Computing

My loft is now officially the place that things to to break. As part of the “digital back kissing frogs project” today I had a need for a computer running Windows XP. “No problem” I thought. “I’ve got one in the loft”. Well, that was true - sort of. I have a computer up there which I last used around 20 years ago. Unfortunately it doesn’t work. I set it up in the loft and got the result you see above.

Once it got as far as the Windows XP loading screen before collapsing with the blue screen of death. So it is now staying in the loft pending a trip to the tip. This is probably a blessing in disguise though, as I’m not completely sure I remember the login password……

Taking Control of CircuitPython: Disabling and Restoring USB Mass Storage

Thanks to ChatGPT for help with this…

Ah, CircuitPython. A delightful platform that turns "playing with microcontrollers" into an accessible and joyful experience. But every so often, you hit a problem that makes you scratch your head and say, "Wait, what?" Today, we’re diving into one such scenario: disabling USB mass storage, and (more importantly) restoring it without bricking yourself into a corner. Let's dig in!

Why Disable USB Mass Storage?

Good question! CircuitPython presents itself to your computer as a USB drive (the iconic CIRCUITPY), which makes transferring code files a breeze. However, there are times when you need the microcontroller itself to have exclusive write access to the filesystem—perhaps to log data or update files without interference from your computer. For this, we can disable USB mass storage in the boot.py file.

But what happens if you decide, "No, wait, I do want my CIRCUITPY drive back?" Worry not! With the power of the REPL (and a pinch of Pythonic magic), you can re-enable mass storage mode. Let’s see how.

Step 1: Disabling USB Mass Storage

First, create a boot.py file with the following content:

import storage
import usb_cdc

# Disable USB mass storage
storage.disable_usb_drive()

# Keep USB REPL enabled to allow deploying files via REPL tools
usb_cdc.enable(console=True, data=True)

# Remount the filesystem so CircuitPython code can write to it
storage.remount("/", readonly=False)

When this code runs on boot, the CIRCUITPY drive will no longer appear on your computer. But don’t panic! Your device is still alive and kicking, and you can access it through the REPL (Read-Eval-Print Loop).

Important: The boot.py file runs before code.py, and it’s where you set up USB behavior. Always keep this distinction in mind.

Step 2: Accessing the REPL

Even with USB mass storage disabled, the REPL remains accessible via the USB serial interface. Here’s how to connect:

  1. Open a Serial Terminal: Use a tool like Mu Editor, Thonny, or even mpremote.

    • On Linux/macOS: Use screen (e.g., screen /dev/ttyACM0 115200).

    • On Windows: Use a terminal program like PuTTY.

  2. Press Enter: Once connected, hit Enter to activate the REPL.

  3. Start Typing Python Code: You’re now in the CircuitPython shell, ready to command your device!

Step 3: Restoring USB Mass Storage

From the REPL, you can modify or delete the offending boot.py file to restore USB mass storage functionality.

Here’s how to rename it (so you can keep it as a backup):

import os

# Rename boot.py to boot_backup.py
os.rename("boot.py", "boot_backup.py")

Alternatively, if you’re feeling bold, you can delete it entirely:

import os

# Delete boot.py
os.remove("boot.py")

Once you’ve made the change, reboot your device:

import microcontroller

# Reboot the board
microcontroller.reset()

And just like that, the CIRCUITPY drive will reappear! Congratulations, you’ve regained control.

Pro Tips

  1. Test Before You Commit: Before adding storage.disable_usb_drive() to your boot.py, ensure you’re comfortable using the REPL and os commands.

  2. Keep Backups Handy: Always back up critical files before experimenting. If you’re locked out, you’ll need to reflash CircuitPython to recover.

  3. Use Safe Mode: Double-press the reset button to enter safe mode, which bypasses boot.py and lets you recover from mistakes.

Wrapping Up

Disabling USB mass storage can seem scary at first, but with a bit of planning (and the magic of the REPL), it’s a totally reversible process. Now you can take full control of your CircuitPython projects without fear of getting stuck.

As always, happy hacking!

Bye Bye Froggie

It looks lovely, but it may never work again

There’s a little voice in my head telling me that nobody cares about my problems acquiring a digital back for my old film camera. I am choosing to ignore that voice.

The story so far:

Robert wants to be able to take digital pictures with his sixty year old film camera. So he has purchased a younger (by comparison - only twenty years old) digital back for the camera. Unfortunately, as can be the case with vintage electronics, the back has “forgotten” its software and needs to be returned to the mothership for reprogramming. In the last post on this matter Rob likened the process of getting a working device to “kissing frogs” and hoping that one of them will turn out to be a prince (or princess depending on taste). Now read on..

I’ve been told that it will cost 500 pounds (plus VAT and postage) to reprogram my broken digital back. I’m amazed that this is even possible, but it is more than I can afford to spend on this project and it might not fix the problem if something else is broken. So this back is now officially staying a frog. I’ve got another back on order which the seller is being very coy about actually sending to me. So I’m assuming that this one will definitely work….

In the meantime I’ve sent back the “frog” and been refunded. I’d like to give a special shout out to the folks at The Real Camera Company in Manchester who were great about the returns process, the Phase One technical support people and Andy at PearTree Photo who were all super helpful. The quest continues…