CircuitPython: Programming Hardware in Python
github.com
github.com
I'd say the biggest pain points for me (unless I'm missing something/they've added more stuff recently) were created by the lack of support for what feel like production standards in software development. For example, the logging library is a toy, and unit testing is non-existent unless you isolate all your CircuitPython-specific code and run tests on your dev machine using CPython.
It was a nonprofit-style project without much wiggle room. We wanted to prove that an idea would or would not work in a small amount of time, which happily overlapped with the fact that the target environment for the device wouldn't require long periods of battery life. I'm happy to say that the project was a success so who knows, maybe one day we'll have someone port it to C and continue from there.
Sorry I can't be more specific.
I learned Python after I learned C, C++, Java, Scala, Rust and a few others. I fail to see my productivity going through the roof with Python. It's quite the opposite. Writing initial code is fast, but making it work well - not so much.
- you need every tiny bit of performance,
- you optimize for low executable size or low memory footprint (e.g ATTiny13)
- you have an exotic architecture that offers only a C compiler or ancient C++ compiler from 90s,
- you need to use C for other reasons like safety certification, e.g. MISRA C.
In all of these cases Python wouldn't work at all.
And in the others your can use modern C++ which can be just as productive as Python (in my case it is more productive, but I have probably spent more time with it than with Python, so I'm biased).
Twiddling GPIO pins and doing other bit gymnastics is a fair bit of simple sensor interface microcontroller projects, which is a large overlap with the target for CircuitPython.
I appreciate C and I’ve learned a lot of things like peripheral clock multipliers and all the work that has to be done before you can even jump to main. However, I set out to make an altimeter heh.
Edit: oh and with C, writing your own device driver for every single thing is a pit of a pita too. There are open source drivers for some breakouts but they all seem to require serious hand fitting.
Let's just find our own language each one and not bash others' choices, maybe?
> “Programming Hardware” the way it’s used here is pretty much the same as vanilla python
One can only hope so, since the project is a fork of MicroPython. Neither CPython or MicroPython are meant to be a long departure from Python itself.
Anyway, my first impression was same as parent's, write Python get hardware.
One does not "program hardware" except maybe in a CPLD. You cannot write code for a resistor or a tranzistor. You program maybe the microcontroller which is present on the board.
It almost does though. The name of the project has "circuit" in it (I guess because of Arduino applications or something?), and if you are confused why we're talking about circuits, well you can read on where the title goes on to double down on being about "programming hardware".
CPython IS the normal Python you get from python.org, It's only ever called CPython when discussing it in the context of other pythons like MicroPython, PyPy, Jython, etc.
class HalfAdder(Component):
def __init__(self, a, b, out=None, c=None):
super().__init__()
self.a = self.input(a)
self.b = self.input(b)
self.out = self.output(out)
self.c = self.output(c)
XOR(a=self.a, b=self.b, out=self.out)
AND(a=self.a, b=self.b, out=self.c)
having to declare each pin as input or output adds a lot of boilerplate; I was hoping to add a feature where input/output information could be declared using type annotations in the function signature itself. That would look something like: class HalfAdder(Component):
def __init__(self,
a: input,
b: input,
out:output = None,
c:output = None):
super().__init__()
XOR(a=self.a, b=self.b, out=self.out)
AND(a=self.a, b=self.b, out=self.c)
which I think is starting to look pretty Verilog-ish, while still staying Pythonic.My take on Micropython is that it is a small community with just a handful of long term dedicated contributors. It is a little rough around the edges, especially when you get into the details of board support other than the pyboard. For example I had issues with interrupts interacting with Python threads in the web sockets library. The documentation was flat out wrong and I had to figure things out on my own.
I ordered a couple accessory boards off Amazon, a high precision ADC and a real time clock. Both were fakes. They had swapped out chips with lower grade components. When I ordered from Adafruit I got the real things.
The big downside of the Circuit Python fork is that Adafruit deprecated their Micropython libraries for their boards. That seems like it will have long term impact to Micropython.
sort of off topic, but, I never buy anything from Amazon anymore unless it's a last resort. The convenience is no longer there if I end up having to send stuff back due to it being fake or damaged in shipping (particularly books that are put in large boxes with no packing material, which is sucky given Amazon used to be the primary way I'd buy books).
I'm excited to give MicroPython a try with the new Raspberry Pi 2040 microcontroller. I have a couple project ideas lined up and really looking forward to getting into this space a little as a hobby.
It doesn't even support interrupts.
Better use Micropython.
If you want to use F#, you might get lucky with Meadow boards, yet their focus is mostly getting C# to run on their runtime.
I.e. You write code in circuit python, and that same code will run on a little micro, and also a full blown Raspberry Pi.
This is apparently done at the expense of some prettiness.
[1] https://github.com/adafruit/circuitpython/commits/main [2] https://github.com/micropython/micropython/commits/master
The biggest difference is how they handle core modules... rather than having a per-port/board they have a common set of core modules. There are also a lot more of those modules and it seems to have a fairly robust set of hardware/boards that are supported.
I'll be the first to admit that I don't do a whole lot in either since the boards I work on are a bit resource constrained.
The other thing to note is that Adafruit is putting a ton of resources into CircuitPython, I see updates/improvements all the time from them in their git repo. The velocity in CircuitPython vs MicroPython appears to be significantly higher (and that by no means is a dig at MicroPython, I love their project and they have so much cool stuff going on).
[1] https://linux.conf.au/schedule/presentation/122/ [2] https://www.youtube.com/c/linuxconfau/featured
If scripting for microcontrollers become more mainstream, it can enable new applications and use cases that do not require a forced firmware re-flashing to change the code.
Instead of doubling down on MicroPython, Adafruit decided to fork it so they can have the right HALs. They should have made a library, contributed to MicroPython and grown the ecosystem.
Unrelated, I absolutely despise Adafruit customer service - they're demeaning and belittling. I wanted to return items because they were not as described in the pictures - their response was we don't guarantee that. OK. So, you buy stuff off of AliExpress and put a 3x markup and you can't guarantee your supply chain? I now buy all my electronics from DigiKey and Sparkfun.
Also, multi million could mean $2m/year which if you pay your employees well would translate to like 25 employees if you make no profits and only pay salaries.
Lastly, having bought loads of stuff from AliExpress and recently from AdaFruit, the latter absolutely has higher quality items. They are not simply reselling what’s available directly from China but are legitimately designing their own boards which are better thought out than the generic parts you can get for cheaper.
For most non-programmers (which is the target) support is much more important than issues with forks or OSS politics.
My experience is a counter example of your comment, "...instead of contributing to the greater success of the open source maker movement that enables their existence".
Their stuff works, is open, and when I used one of their LSM6DS dev boards on a 32-bit micro, it had an underflow bug; because that board and library was open-source, I could fix it the same afternoon I got the package. The fix was simple and obvious, they accepted my pull request, and now no one else has to waste that hour. That’s the power of open source to me.
I hold Adafruit and Limor in a positive light and think their “bloatware” is very effective in making electronics accessible to many more people than before, much the same as the $30 Arduino did for the $2 AVR. The ecosystem and accessibility matter.
I agree that they’re seeking success of Adafruit, and agree that’s not a bad thing, but I don’t see how they’re going closed. What is “closed” about their ecosystem? The article we’re discussing is about MIT-licensed software on their GitHub.
maybe an arduino board plus a raspberry pi?
Arduino's are lower-level C/C++ which may be a little more complex than CP, but have much broader library support (better intro to EE/embedded).
RPis are much higher level which could be programmed in any language (better intro to CS/Linux).
Version 2 called “Circuit Playground Express” is currently very popular. V1 is obsolete, and there’s a version 3 with Bluetooth. All of them are pre-built with sensors, RGB LEDs, and buttons. This removes a huge hurdle: no soldering required. (Soldering is a fun skill but so is baking bread and cross country hiking — most kids are usually 100% focused on making blinking lights and don’t want to do anything tangential.)
Right now, only version 2 is supported by http://makecode.adafruit.com. makecode is different to CircuitPython: you write your code in JavaScript either using a visual block language or directly in the online JS IDE — both of which are very high quality dev environments with excellent discoverability — and compile everything into a new .UF2 firmware for the device to load each time. The site provides an emulator which is another killer feature. You can go there right now and start programming a board.
CircuitPython on the other hand is itself a pre baked UF2 firmware with a Python interpreter built in. Because your dev tools (runtime, debugger) are now on the device you have less memory to play with and it’s less stable, in my experience. It’s also not immediately obvious how to get things done, compared with the makecode IDE.
With my teenage pupils it was only the makecode JS / block programming that lit up their eyes. The Python tools were too weird. Devices like this are about playfulness and doing weird stuff, and only tangentially about programming, I’ve found.
The killer feature of Circuit Playground was the v2/“Express” (CPE) board with its infrared transmit and receive functionality. Connectivity turns these things from toys into real hacking platforms. I spent the holidays making IR “WiFi” for a pool of 8 CPEs.
The v3 Bluetooth-enabled board sounds great but it won’t be as popular with my classes if it doesn’t support makecode (which it currently does not.)
Are the details of your classes online anywhere?
I let the kids riff, then review their project before showing them a new idea. It’s like they are learning a modern era computer game where there are no manuals, only self discovered game mechanics.
(CS classes have much more structure but are more niche and for the older pupils.)
For getting started fast I can't recommend MakeCode[2] enough. It's a web IDE with a compiler and device simulator for programming microcontrollers with blocks or JavaScript/Python.
That said, for more complex projects CircuitPython might be a better choice. There are tons of docs and lots of great examples. It re-runs your code every time you save so you get instant feedback. Also, the vscode-circuitpython[3] plugin has been really nice too.
[1]: https://www.adafruit.com/product/4333
[2]: https://maker.makecode.com
[3]: https://marketplace.visualstudio.com/items?itemName=joedeviv...
Their documentation is rather poor. Parameters to function/constructors are often left out, leaving you to go through the source to figure out how stuff works.
The standard modules can have different functions/variables between different boards. It makes sense since some boards have capabilities others don't. However there is no documentation on this.
Finally, in my opinion, some of the adafruit_* libraries are not well designed. There are many "kitchen sink" libraries that try to do everything. I also noticed that while they do appear to use pylint to enforce good standards, almost all source files have at least one check disabled...
I haven't touched any of the CircuitPython hardware libraries in... Well, something close to two years by now, I think. A lot has probably changed. Still, when I was last involved, placating pylint was consistently a hassle.
As I recall it squawks about things like identifiers that don't conform to snake_case. All well and good as a general stylistic suggestion, but not especially helpful when that's what the thing is called.
There may be some bad ideas lurking in places where those checks are disabled, but in general I blame no one for disabling one or more of its checks in service of greater readability or better code layout.
[0] https://circuitpython.readthedocs.io/en/latest/shared-bindin...
[0] https://www.dropbox.com/sh/l6tp9ym5nf8h5v9/AABC0Zd7_v4BWmBaZ...
It's probably more useful on microcontrollers with more than 32 kB of RAM.
Really fun in dev...really fun with my small test device. Then I loaded the config for a complicated I2C module and quickly blew out my memory. I was sad that I had to revert to more mundane means of I2C, but whatever.
A newer version of that same board has more memory. Perhaps it could support my mammoth I2C model.
It becomes very limiting for bigger embedded applications. Is the chip and are all peripherals supported? Probably not.