Welcome to the CircuitPython Show. I'm your host, Paul Cutler. This episode I welcome
John Romkey. John is a computer scientist, software architect, and long-time internet
engineer who's been building and breaking networks since the early days of TCP/IP. John
demonstrated one of the earliest Internet of Things devices, the Internet Toaster, controlled
via SNMP in 1993 along with Simon Hackett. John currently works with microcontrollers,
sensors, home automation, and full stack systems,
with occasional detours into PCB design and development.
John currently works with microcontrollers, sensors,
home automation, and full stack systems,
with occasional detours into PCB design and development.
He enjoys programming in CircuitPython, Python, Ruby, C,
and C++, and working with Docker
and similar technologies for backend work.
John, welcome to the show.
- Hi, thank you very much.
I'm very happy to be here.
Thanks for inviting me.
- How did you first get started
with computers and electronics?
- When I was a teenager, I got bitten by a radioactive chip.
No, I was a really bored teenager in rural Maine
in the late '70s, and the kind of thing
that you would do at that point,
some of us, the nerds, would hang out at Radio Shack.
And Radio Shack in those days, when it existed,
that was like the golden age of Radio Shack.
And there was like, it was like electronics.
It was almost like you walked into a 70s version
of Adafruit in a store in a mall.
I had a lot of exposure to electronics there
and components and early personal computers.
We were not a well-off family,
but somehow my father managed to afford a TRS-80 for me.
And that pretty much changed my life.
And so between that and the access to electronics
at Radio Shack, that kinda got me into that.
At the time, we didn't have,
if you wanted to program, write programs on a TRS-80,
you wrote programs in Assembler,
which was, or BASIC, I'm sorry, BASIC,
which was not a lot better than Assembler, really.
And it was very, very low resource machine.
Like your baseline TRS-80 would have 4K
memory. So, you know, going from there to like decades later and writing software for
Arduinos and ESP 32s, it really takes me back there. Although we have such better tools
for working in software these days, you know, and CircuitPython is a great example of that.
CircuitPython, you couldn't even have imagined something like CircuitPython back then. But
hung out at Radio Shack.
- How did you discover CircuitPython?
- I mean, through Adafruit.
I got involved in doing work with ESP32s,
or the ESP8266 at first,
and looking for resources and looking for more hardware
to work with, Adafruit was right there.
And Adafruit does such an amazing job
at fostering community,
and also doing open-source hardware and software,
which is very important to me.
I was very drawn to Adafruit.
Anyway, if you spend any time poking around Adafruit
and looking at what Adafruit offers,
Adafruit's put so much resources into CircuitPython.
And I've done a lot of work writing C software.
And I love C.
C is better than programming in Assembler,
but it's like right next to it, really.
And it's so easy to shoot yourself in the foot in C.
You just like misjudge the length of your array
and suddenly you've written over your stack
and what happens when you return, who knows?
And your program just explodes in new and exciting ways,
which are really difficult to debug
'cause you're not on a full-fledged computer,
you're on some tiny microcontroller.
And CircuitPython just protects you from all of that.
and lets you write code in a civilized way.
For all the power that C gives you,
when you start just manipulating strings,
you're in a world of hurt,
and especially on these kinds of microcontrollers.
And if you're doing anything,
like say you're doing a web server,
which you can totally do in C, in Arduino,
on an ESP32, or anyway, if you're doing that,
you're doing a lot of string manipulation,
And this is just not something that C is very inviting to
or supportive of.
C++, better.
But CircuitPython's just got your back.
CircuitPython just makes it really easy,
especially since CircuitPython started supporting
f-strings in Python,
where you can just interpolate values in it.
It's just, it's so much more relaxing to program
in CircuitPython than it is in C.
I know that some people get uptight
about the overhead of CircuitPython.
You know, CircuitPython has less memory available.
CircuitPython is interpreted,
it's much slower doing some operations than C is.
It's actually shockingly fast for some things.
But I think they lose track of the fact
that your average program just doesn't need
that level of performance.
Yeah, if you're writing something on an ESP32,
I keep coming back to that
because that's the chip that I use the most.
But if you're writing something on an ESP32
that's very graphics intensive,
like maybe you're writing some game or something
that really pushes what you can do on an ESP32,
then sure, you're probably not gonna write that
in CircuitPython.
But most people just write code that's like a simple loop
and it's just reading some sensors
or controlling some servos or something like that,
or serving a webpage,
and it's actually not even touching,
getting close to the limits of the ESP32.
And CircuitPython is great for that.
There's plenty of capacity, plenty of resources.
And anyway, it's a great tool for a lot of applications.
- Speaking of tools, you've written a tool
for CircuitPython called circremote.
Tell me more about it and how it works.
- circremote basically will send a chunk of code
to CircuitPython, either over a serial port over USB,
or if you have a device, which I believe only ESP32s
do this currently, a device that supports the web workflow
so that you could connect to it over Wi-Fi or Ethernet.
If you have that kind of device,
then it can do it over the network.
So it doesn't have to be directly connected
to your computer.
So I do a lot of work with sensors
and I've been building some of my own PCBs with sensors.
Adafruits are fine,
but sometimes I just want something a little different.
Also, it's fun, honestly.
It's just fun, and it's a nice stretch.
There's a lot of stuff that I end up running frequently,
like an IDC scanner,
because most of the sensors that I connect are over IDC.
I'm using STEM-QT for the hardware connection,
which is awesome.
It makes prototyping so quick and easy.
But I am so tired of finding the IDC scanner code
for CircuitPython and copying and pasting it in.
And so I figured I'll write a utility
that will just keep track of this for me
and then send it to the device,
whether it's over Wi-Fi or whether it's over USB.
And once I started doing that,
having drivers for the different kinds of chips that I use
was the next step to do.
And so I decided to, of course,
make it way more complicated
and add way more functionality to it,
and just came up with this general concept of a command,
which is the code that you send over
and let it organize the commands and keep track of them,
added the ability to have multiple paths
to search for the commands.
So it comes with,
I think there's over a hundred things built in currently,
And they're not all things for sensors.
There are a lot of sensors it supports,
like temperature sensors, light sensors, things like that.
But also there are some utilities,
like list the files that are on the flash drive.
One of the utilities that I added enables web workflow.
And so it takes the credentials for your Wi-Fi
and the other information that you need
to set up web workflow,
and then just creates the settings.toml file on the device.
Another one just resets it.
You know, I got tired of typing import microcontroller,
microcontroller reset.
Another one puts it in UF2 bootloader mode.
Another one can just display the contents of an arbitrary file on it.
Oh, this is one, this is one that I really enjoyed and it's a little OCD.
Like I use a Mac and I love, I love Apple mostly until they release major
operating system updates and break everything.
But one of the things they do when a Mac is writing to a flash drive
with a DOS file system on it, like CircuitPython very reasonably uses,
it's the right choice.
One of the things they do is they just put all this trash on the drive,
all these random little files,
and these are keeping track of Mac-specific metadata
or indexing for Spotlight, which is the Mac's search system.
And it turns out Apple's not the only one.
Windows does something similar.
I use an editor that I would never recommend
that anybody use called Emacs, which is ancient.
I've used it for decades.
It's basically built into my fingers at this point.
And it's very hard for me to switch to a different editor.
Emacs leaves trash all over the place.
It leaves copies of files and checkpoints
of files and things.
And so this doesn't really take up all that much space
because most of these files are tiny.
But there's just all this crap on your drive,
on your CircuitPython drive.
There's a utility to remove the crap, it decraps it.
I think it's actually called clean, not decrap,
although that might've been a better choice for the name.
So anyway, the point is there's a bunch of utilities there too
and at this point I'm using it on an almost daily basis.
There's stuff that I'm doing all the time.
I've actually have, in my office,
I have a LED matrix sign that I've built using
Adafruit's matrix portal S3.
That's another project that someday I'll try to get
to a point where it's actually really releasable
so that other people could use it.
But one of the things with it is it's quite bright
and at night I would like to turn it off
and I haven't actually added an off function to it yet.
So what I do right now is I have a thing that runs
every night on my Mac, which just uses Cirq Remote
in an automated way to poke the sign
and just, I added a stop command.
And all that does is it's just a loop
that's like while true, pass.
And then in the morning, I have another one
that does a reset to it.
And so the sign goes off at night
and it comes back on in the morning and I'm happy
and I didn't actually have to fix the code
and the sign to do the right thing.
So it's been really helpful to me
and I hope it's something that may be helpful
to other folks too.
- You'll be happy to know that you're not
the only Emacs user.
todbot is a big Emacs user as well.
- Yes, I'm not the final Emacs user in the world.
Sometimes people ask me like, "What editor do you use?
"I wanna use the editor you use."
And I'm like, "No, no, you do not wanna use
"the editor that I use.
"You should use something modern.
"You should probably use VS Code or something like that.
Don't do that to yourself.
Cirq Remote supports dozens of sensors.
I plugged in a DPS 310 barometric and temperature sensor, ran Cirq Remote /dev/ttty/dps310
and it installed the dependencies.
And then I ran it again, and it spit out the temperature, pressure and altitude settings without me having to write any code.
How are you able to support so many sensors in Cirq Remote?
I cheated.
So it's not really a cheat, but some people think it is.
I actually had an AI write most of Cirq Remote and I have no illusions about this.
I've been writing software since the late seventies.
I've been pretty dubious about LLMs writing code.
They've come a long way since just, you know, a year ago, even six months ago.
I have to say that the rate of improvement and progress in LLMs is just stunning compared
to other things that I've seen over the course of my life.
So I could write most of Cirq Remote myself.
I kind of didn't feel like it, and I was curious to do an experiment.
The one part that I would have had some trouble with would have been the web workflow.
to the device over serial over USB, not a big deal. The web workflow uses web sockets and I
know how web sockets work and I've worked with them a bunch, but I've never programmed them in
Python. And so just to be clear for folks, Cirq Remote itself is a CPython program. It's a Python
program that runs on a Mac, on Linux, on Windows. Cirq Remote itself doesn't run on the device and
isn't CircuitPython. What it does, though, is have a library of commands written in CircuitPython,
which it then sends to the device. So we've kind of got these two dialects of Python going on there,
but Cirq Remote doesn't execute the CircuitPython itself. So I decided, why not take a shot at this?
Let's see what happens if I try to have an LLM write this for me. And at that time, I have a
a good friend, Elena Hardy, who has been doing a lot of work
using Cursor.
And Cursor is a front end that works with VS Code.
And it turns out there's a GC-EMACS compatibility
mode for VS Code.
And it actually is really good.
And so that worked really nicely for me.
Thank you, whoever wrote that.
I am so grateful to you, or your AI,
or whatever wrote that for you.
And so Cursor can work with a variety of backend LLMs, and I've been having it use Claude.
I think it was on Claude SONNET 4 when I did this.
And you'll get different results depending on which LLM, which model, language model
you're using.
So I basically gave it a set of instructions, and I tried to be really clear, and I tried
to not give it too much up front.
And I don't think this counts as vibe coding.
Cause I wasn't really just like throwing stuff at it and like, Hey, how about if
we do this, how about if we do that?
It was more like, I want this, I want this, I want this file location.
I want it organized like this.
It was a spec that I gave it and it worked.
It was shockingly good.
It wrote the code to send the code to it.
One of the things that makes this work
is CircuitPython supports this thing called raw REPL mode.
And so this is something where it
does no interpretation of what you're sending it
as you send it.
And then you send a terminator.
And that's when it goes and it actually processes the code.
And this makes it so much easier to automate sending code
to it to execute.
And Cirq Remote is not the only program that does this.
There are other programs that use it this way as well.
I think Fani does and probably Moo and a few other things.
So that was great.
So then I tossed in having it work with the web workflow
and I had to intervene in a couple of places there.
It didn't get the correct URL for the device.
I had to look that up and I couldn't get it to work though.
And it was having a bunch of issues with it
and I got frustrated.
And so I have done WebSocket programming in Ruby.
And so I basically just went and said,
okay, just rewrite it in Ruby for me.
And it rewrote it in Ruby in one shot.
It just, it did it.
And the WebSocket code in Ruby worked.
And so that was amazing.
And so I lived with that for a few days.
And then I thought,
how much is the CircuitPython community gonna love me
if I give them a utility that's written in Ruby?
And I figured not at all.
And so then I decided, let's just take another leap
and have it translate this Ruby program
that now works back to Python.
And it did it in one shot
and it worked the first time I tried it,
which just blew me away.
That was really, really wild.
So that's been really positive.
The negative to it has been that when things go wrong,
they can go really wrong.
And because I didn't write the code,
I'm not familiar with it in the way that I would be.
And it can be really tough to debug.
And when the LLM, the LLM is more than happy
to go deep, deep down a rabbit hole
trying to debug something.
But it's not very good at declaring defeat
and realizing that you need to back up
and take a new approach.
I have to do that.
And so one of the things I learned really quickly
was not only did I have to recognize
when we were totally going in the wrong direction,
which is fine, but also it can be tough
to unravel what it's done in going in that direction.
So I just get, you know, like 99% of the rest of the world.
And you definitely need to have really good
hygiene with this.
It's easier to just throw away the work
that's been being done and go back to where you started
when you started to debug this,
than it is to get the LLM to reliably
go back to a checkpoint.
Now, it's quite possible that Cursor's pretty good at this
and it's not something I know how to do in it.
Cursor's got a ton of stuff that it does
that I'm not an expert cursor user by any means.
So there may be expert cursor users,
like my friend Elena, who will listen to this
and roll her eyes and be like,
"I told you how to do this," and she probably did.
That's some experience with that.
So I also, you know, I wanted to support
lots and lots of sensors and other devices,
so I told Cursor to look at Adafruit's store
and see what Adafruit sells and write commands for those.
And that was partly really successful.
It was great at scanning what Adafruit had available
and it was great at organizing that.
And the thing with Python versus CircuitPython
is there's a lot of Python code on the internet
and there's a lot less CircuitPython code.
And they look really similar
because they are really similar.
And so the training, the base of code in CircuitPython
for the language models to be trained on is much smaller.
And so it doesn't do as good of a job
with generating CircuitPython code.
And sometimes it gets confused.
And especially things for accessing the file system
is different in CircuitPython versus Python,
which is totally reasonable, not a complaint at all.
It's actually just totally impressive
everything that CircuitPython does.
But so I found that the LLM would frequently
get confused about that.
And it would still hallucinate things that are not there.
Mostly it did a really good job at figuring out
the Adafruit libraries to use for the devices.
Occasionally, I think once or twice,
it hallucinated a library name that didn't exist.
But mostly it did a good job with that.
I had to manually intervene and fix things much more often
with the CircuitPython code than with the Python code.
I also, at one point, it had a sort of systematic error
that it had done across most of the commands.
And so I actually was able to tell it how to fix that
and then have it apply that to all the commands,
which was a huge time saver.
I figured out the fix, it did the work.
And that was pretty good, I liked that.
Yeah.
- That's pretty neat.
- You do a lot of work with sensors,
both for yourself and for your community.
How are you using sensors in your community?
- I am trying to do some projects to do sort of,
I guess one word for it, one phrase for it
is citizen science, so that people can have sensor networks,
or communities can have sensor networks in them
to track things like air quality, or noise pollution,
or light pollution or things like that.
Air quality is such a big, difficult question
because we tend to focus on one or two things
for air quality.
We have the AQI calculation,
which is really a synthetic number.
And it tends to focus on particulate pollution,
which is a big deal.
But also there's a ton of other things,
like respiratory irritants, gases like formaldehyde.
I live in Portland, in North Portland,
and there was an incident with a factory
on the sort of not real residential part of North Portland,
but which has been fined multiple times
for releasing formaldehyde.
And so I'd love for folks who are interested in doing this
to be able to have cheap devices
that they can put on a public sensor network
that could monitor for stuff like this.
And so that's kind of a passion of mine.
I work with a local hacker space, PDX hacker space,
and folks there help with this.
And some of us are working on projects like that.
Also like CO2 monitoring, CO2 monitoring.
Like CO2 can build up in a closed environment,
like an office space or home,
but also it got used as a proxy for airflow
during the pandemic.
A lot of people were getting CO2 monitors
with the idea that if CO2 levels went up,
then the possibility of COVID,
the virus in the air went up as well,
because that's a sign that air exchange isn't happening.
And so they were less concerned about the CO2
than they were just about fresh air, which is fair.
And so a bunch of folks at the hackerspace
were very interested in that.
One friend, Darcy Neal, is building personal CO2 monitors.
And so we've collaborated on some hardware there.
There's a commercial device called Purple Air,
which does something similar.
It's an air quality monitoring device,
very focused on particulate matter,
and they have air quality maps
that they generate from their data.
I'd like to generalize that.
I'm fine with commercial products.
You know, there's a lot to be said for just buying it,
having it be supported, that's great.
But I also like lower cost things available to hobbyists
or DIY people, maker spaces, things like that.
And so the hardware that I've been designing
and the software that I've built is all open source.
I got kind of waylaid by the tariff situation.
There's a board that I was doing a lot of work on
and got a final iteration of it in last spring
before the tariffs hit,
but they really jacked up the cost on doing everything.
And I'm happy to, I'd love to build things in the US,
but there's no options to do that.
the businesses just simply don't exist at this time.
There's a really great place in China called JLCPCB,
and a lot of folks use them.
And they have, it's just like it's so easy to work with them.
You upload your designs through their web interface,
you walk through it, and you get the order set right there.
It takes minutes.
And there's just nothing comparable to that in the US.
And also what I found trying to price things,
it's the factories in the US that do circuit board assembly,
they wanna do hundreds of thousands of boards,
which is fair, I don't begrudge them that,
I don't blame them, I would much prefer to deal
with large commercial orders
than individual hobbyists as well.
But it's just like, they don't wanna talk to you
if you wanna do 10 boards, and that's fine,
that's totally fair.
So there's simply no alternative available at this time.
And I know a lot of hobbyists and makers
got really, had a really hard time with this.
So I'm getting, you know, now that things have stabilized
even though it costs a lot more,
it's still orders of magnitude cheaper
to do it through China.
And so I'm trying to get back to that now
and just, you know, hopefully don't get hit
with a thousand dollar tariff or broker fee
or something like that for $100 worth of PCBs,
but we'll see how it goes.
- That's pretty neat.
Last question I ask each guest,
you're going to start a new project or prototype,
which board do you reach for?
- That's a great question.
And it would really depend a lot on the project.
So like I have these LED matrix signs
that are using Adafruit's matrix portal S3.
And if I were doing an LED matrix,
that is absolutely the board I would go for.
That's just really well thought out, well designed,
and actually impressively cheap for what it does board.
If I were going for just a more general purpose,
so almost everything I do is ESP32 based
because I always want connectivity.
But if I were going for just a more general purpose
board with connectivity,
Adafruit's feathers are great.
The board that I'm designing, it's just called sensor,
which is, you know, but it's got connectors on it
to hook up some more specific things like a particle sensor,
which needs a weird little ribbon cable connector.
Adafruit sells a version of that,
but I like having it directly on the board
because almost all the instances of this
that I'm going to put together are gonna need that.
So, you know, it's not very satisfying,
but I might go for my own board.
But Adafruit in general, like the feather boards are great.
For just general purpose boards,
unexpected maker, makes some really, really nice hardware.
A lot of emphasis on low power,
low overhead in the power
if you want to use a battery with it.
So I often look at his boards too.
So those are both really great choices, yeah.
- Yeah, those are great choices.
John, thanks so much for coming on the show.
- Thanks very much for having me.
This was a lot of fun.
- Thank you for listening to the CircuitPython Show.
For show notes and transcripts,
visit www.circuitpythonshow.com.
And if you're enjoying the show,
do me a favor and share a review
on your favorite podcast app.
It really helps.
Until next time, stay positive.