Embedded Python: MicroPython Toolkits

Last time, I talked about how MicroPython is powerful and deserving of a place in your toolkit, and it made for a lively discussion. I’m glad to see that overall, MicroPython has indeed been getting the recognition it deserves – I’ve built a large number of wonderful projects with it, and so have people I’ve shown it to!

Sometimes I see newcomers dissatisfied with MicroPython, because the helper tools they initially pick don’t suit it well. For instance, they try and start out with a regular serial terminal application that doesn’t fit the MicroPython constraints, or a general IDE that requires a fair bit of clicking around every time you need to run your code. In particular, I’d make sure that you know your options no matter whether you prefer GUI or commandline – both have seriously nice tools for MicroPython use!

The main problem to be solved with MicroPython is that you have a single serial port that everything happens through – both file upload and also debugging. For ESP8266/32-based boards, it’s a physical serial port, and for chips like RP2040 and ESP32-S* where a hardware USB peripheral is available, it’s a virtual one – which makes things harder because the virtual port might get re-enumerated every now and then, possibly surprising your terminal application. If you want to upload a program of yours, you need to free up the serial port, and to see the program’s output, you will need to reopen that port immediately after – not a convenient thing to do if you’re using something like PuTTy.

So, using MicroPython-friendly software is a must for a comfortable hacking experience. What are your options?

Power Of Thonny And Friends

Whether you’re primarily a GUI user, or you’re teaching someone that is, Thonny is undoubtedly number one in MicroPython world – it’s an IDE developed with Python in mind, and it has seriously impressive MicroPython integrations. Your board’s terminal is being managed as if effortlessly in the background – just open your files in different tabs as you normally do, and press the Run button sometimes.

Expecting more? There is more – basically anything MicroPython adjacent you’d do from commandline, is present in Thonny in a comfortable way. For instance, are you working with an ESP32 board that doesn’t yet have a MicroPython image in its flash? Lucky you, there’s an esptool integration that lets you flash an image into your MCU through a dialog box. Want debugging? There’s single-step debugging that works in an intuitive user-friendly way – you’d find this pretty hard to happen from console apart from specially engineered print statements, but Thonny delivers.

Not looking to pick a new IDE? There are VSCode extensions. Arduino IDE more your jam? Yeah, well, remember how Arduino has a MicroPython IDE now? It’s decently usable, so if you got used to the Arduino keybindings, you might like it. More of a commandline user? You’ve got a good few options, then, and they are similarly powerful.

Mpremote And Ampy

Rather use the terminal? Maybe IDEs are too clunky for you and the terminal window’s cleanliness provides for a distraction-free environment you can only dream about, maybe it’s just the thing you’ve used your entire life, or maybe you’re even debugging a MicroPython device over an SSH connection? mpremote is the tool to save you.

mpremote is part of the MicroPython project, it’s developed alongside the project, and it’s got plenty of killer features to show for it. It includes an “inline” terminal emulator that lets you access REPL effortlessly to see your code’s results and interact with the variables afterwards, correctly managing things like Ctrl+C so you can interrupt your code if needed and still poke at its variables in the REPL. You can also explore the MicroPython filesystem Linux-style with ease, and, most importantly, you can mount your current directory up to it with mpremote mount, and mpremote will send files to your board as the on-MCU interpreter requests them.

Overall, mpremote offers a seriously comfortable environment for iterating on MicroPython code lightning quick. Without it, you would need to reopen the serial port each time you need to upload a new file – here, you can just chain a bunch of commands together and mpremote will dutifully do the serial port juggling needed to get you there.

In addition to that, you can see that mpremote is designed to help you with awkward-to-do things you didn’t know you needed to do. Need to sync your board’s RTC time with your computer’s time? That’s a mpremote rtc command away. Want to access the MicroPython package manager? That’s mpremote mip. Your board needs to switch into bootloader mode? No need to fiddle with buttons, just use mpremote bootloader. In short, mpremote is a MicroPython powerhouse for everyone who’s most comfortable in a terminal window.

There is an alternative here, too: ampy, a personal choice of mine, which I use combined with screen. Ampy is a tool initially designed by Adafruit, and it’s more barebones – I like it because I have control of what’s happening when I issue a command to a software, keeping my MicroPython devices in a known state at all times. On the other hand, it does require jugging the serial port on your own, so when I need to update my code, I exit screen, run the ampy command, then re-enter screen again. I regularly work with large MicroPython files that also import static library files that don’t change for months, however, so having control of the upload process seems to save me a fair bit of time.

There are caveats, of course – the major one is, when using screen in serial terminal mode, you need to press `Ctrl+A k y` (kill window) instead of `Ctrl+A d` to detach the screen session. If you do the detach instead, as you might be used to with screen, the serial port will remain open until you unplug the device or kill the screen process, and ampy will fail mysteriously.

Summary

I hope this toolkit overview helps you make sure you’re using exactly the kind of MicroPython environment that works for you – while compiling it, I’ve learned some nuances myself! Next time, we shall talk about CircuitPython – a MicroPython fork that has grown into a contender in the educational Python space, and how it is different from MicroPython in a number of crucial ways you deserve to know about.

23 thoughts on “Embedded Python: MicroPython Toolkits

    1. I too like rshell, as I can hop back and forth between file transfers and serial in one spot. And it’ll shell out to VIM (or maybe to my default editor, not sure) if I want to do a quick edit on a on-device file, without manually transferring it somewhere before and after.

      I didn’t realize it for a long time, but it’s possible to name your devices, so they’re not all just /pyboard/ in rshell.

      1. Didn’t know that, as cp to /pyboard works fine.

        I simply use Geany (a programming editor in Linux) on my workstation for code changes and use rshell for the transfer and test cycles. Some people seem to be comfortable with IDEs, but Python is so simple to use, a programming editor is all that is necessary (geany, kate, or notepad++ in Windoze). I usually use nano from the command-line on headless Linux systems (RPIs) when necessary, or vi in a pinch.

  1. Maybe µPy’s Unix port deserves a bit more popularity too. I’m using it more than the big original monster these days and that way I reduce confusion between very similar, but not completely identical dialects of the same language.

  2. I love python for non-time sensitive things. For things that need to happen as fast/soon as possible I go to C or C++.. but I wish I could write a python program then compile python to C or C++. Very wishful thinking and not feasible for a multitude of reasons… But it would certainly make things easier.

    1. So far most all of my projects have been doable in Python whether an RPI project and/or Pico/Metro projects. Nothing time critical enough to matter. Working on a tracked vehicle project right now and python moves the tracks and responds quickly enough (using an overkill RoboClaw ESC for motor controller).

      BTW C is the language that I used all the time for real-time programming in my career… And I am very fond of the language. But Python sure makes it easy(ier) for a lot of applications that don’t have time fixed constraints (to a point) and priorities!

      1. Sadly python (and micropython) is just too slow for microcontrollers + RF which has been the focus of my personal projects for a few years. Done a few other embedded projects in C.

        All of my work programming is either in VB or python, your typical reconciliations, data sorting, email generation, DB frontend (access backend) and so on. Things that can take as long as they take.

        1. Yep, use the right language for the job.

          The job I currently have (and will retire from) after leaving the real-time world, one of the first tasks in our area given to me was to write a new task scheduler, and replace all the batch files, excel/access applications (vb being the glue code) with Python scripts. It was a ‘very’ confusing hodgepodge set of applications! The host system is a 24x7x365 dual computer system that is getting data in from a lot of places, and then turning the various data into other data formats for other systems inside and outside the company to use (and many other tasks as well). Since Python can read/write Excel (and json, xml, csv, etc.) it was an excellent fit. Also Python can handle http, https (with certs), ftp, sftp, copy files, pop, smp, exchange, etc… When done, It really made the 24x7x365 process a very reliable system. We rarely have to touch it now. Took a year or two to finish the rewrite, but worth it. Oh and since it not compiled, the source is the run-time and can be changed on the fly as needed (say a URL changes). That said, at work, I work with c/c++ and Python mainly now. Some Perl and C# as needed.

    2. MicroPython makes it pretty easy to integrate small C modules. So you can keep the majority of your code in MicroPython where it’s easy/fast to write and then call out to C modules when you require performance. It works pretty well in practice!

  3. As i do not do PC programs a lot, i am not an expert on the issue, but Julia language programs can apparently be very fast. If speed is a necessity, then maybe take a look.

    For the little tools i need to do (speed is not a factor), i’ve chosen to learn Julia over Python cause of Python’s dumb whitespace crap + couple other things and the possibility of speed. I’ve only used Python on few occasions just because i’ve had to.

    But there is no microJulia, if that’s a requirement.

    1. I’ll take a look. As long as it isn’t super confusing like js I should be able to pick it up without too much trouble, but yeah I would be using it with a micro controller.

      That was mostly wishful thinking as I’m already 600 lines of C into my current project.

  4. I have just come across ViperIDE ( https://github.com/vshymanskyy/ViperIDE. ). I mainly use Thonny on PiPico and ESP32 and I am still just starting to Test ViperIDE. So far it seems a worthy competitor to Thonny. It is lightweight with nothing to install and runs in the browser. I has a very nice option to use bluetooth as your serial interface which is what attracted me to it.

  5. I’ve used Python a little on and off over the years, but always found it just a bit of a PITA enough to always be looking for something else.
    Currently, working on TinyGo which is expressive enough, with excellent goroutines and makes comparatively small-ish programs.
    Small, simple language with very decent speed.

  6. droidscript.org has just announced a new Micropython feature that let’s u easily program your RP2040 from an Android phone using a USB-C cable…with full REPL access too.

  7. Nowadays I tend to use SWD for flashing, but years ago when I still regularly used the serial port for that, I too had to deal with the abovementioned serial port juggling. At some point I got annoyed enough that I actually wrote a serial port muxer (using CUSE), so you can keep your minicom (or whatever you use to look at the serial output) open, and the flasher just borrows the serial port for a little while when you run it.

    It’s not the most beautiful thing in the world, and it’s definitely not perfect, but it worked for me, so just in case it’ll help someone else: https://github.com/alexer/serialmux (you give it a path to your serial port as the first argument – eg. “/dev/ttyS0” – and an alias to use for the newly created muxing serial port as the second argument – eg. “ttyS0mux” – and it’ll create the alias, which you then use instead of the original serial port path in the other programs – ie. the flasher and serial terminal. The last program to open the port always steals it from the previous one, and then gives it back when it closes)

Leave a Reply

Your email address will not be published. Required fields are marked *

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.