Enginursday: I <3 Python!


Python is amazing.

For those who don’t already know, Python is a cross-platform high-level scripting language. It’s designed from the ground up to be extremely easy to use, with a “batteries included” philosophy – almost everything you need to do almost anything is included in the basic distribution.

The strong cross-platform support is another good feature of Python – it’s relatively easy to write a program in Python that “just works” across Linux, MacOS or Windows. Even more wonderful is the fact that the Python interpreter has been cross-compiled over to run on many embedded platforms, which means that all the power of Python is available for boards like the pcDuino, Raspberry Pi, and BeagleBone Black.

Ever since I started dabbling with Python four or five years ago, it’s become a part of my daily life in several ways. Here I’ll present a brief summary of two problems I’ve attacked with Python, to give you some idea of how useful it can be in real practice.

Caveat: I’m not going to claim any tremendous skill at writing Python code; I’m taking a calculated risk in exposing my amateurish code to the world to show people who don’t know much about Python just how easy it is to get some pretty great results. Also, please don’t let’s get into any flame wars about which language is better! I expect that if I’d heard of, say, Ruby before Python, this tutorial might be about Ruby instead.

Real-life Resistor Divider Calculation

A common electrical engineering problem is the creation of a resistor divider. If you’re not familiar, a resistor divider allows you to take a known voltage (say, 5V) and generate a reference voltage at a second, lower voltage (say, 3.3V).

Resistor dividers happen all the time. While the math behind a resistor divider is easy (trivial, even), getting values for the two resistors that match the resistors you have on hand (or even the resistors which are available for purchase) becomes more difficult. I think, given the context of this post, you can probably guess what’s coming.

alt text

Above is a screenshot of the command line (a GUI would be an unnecessary complication) output of my script. I asked for a 5V to 3.3V divider, using the values specified in SFE.txt (which is a file I created from our MRP system – using ANOTHER Python scrip t– of stocked SparkFun resistor values). The result is a list of five possible solutions, delivered in order from smallest nominal error to largest nominal error. It also gives the output impedance of the divider; that can be very important, depending on what you plan to use the divider for.

You can find the source for this in my personal GitHub account.

Importing SVG into EAGLE

Another thing we run across is a desire to get fancy with our PCB designs. This can be for board shapes, silkscreen, logos, or whatever. EAGLE is pretty limited when it comes to editing shapes; you can have anything you want as long as it’s a straight line, ellipse, or section of an ellipse.

EAGLE, of course, has a powerful built-in scripting language (ULP) which is C-ish, but I have very little enthusiasm for learning new programming languages which aren’t portable. My solution to the problem was to learn about the SVG file format, as supported by Inkscape, and implement a simple Python script that can pull shapes out of an SVG file and generate a script for EAGLE that will draw the shape in EAGLE.

alt text

Here’s the result. The script has its limitations: it only works on paths, it only works on ungrouped objects in the top layer, and it doesn’t deal well with negative space. Within those constraints, however, it does a pretty decent job.

It generates both filled polygons and lines; layer is determined by the red channel of the stroke, thickness by the weight of the line, and fill by, well, fill of the path object.

I’ve noticed that it behaves poorly on files imported from Illustrator, but on Inkscape native drawings, it works a treat! It’s available on my GitHub page as well, and the SVG file I used above is there, too, just to provide a known good.

Other Fun Stuff

I’ve done lots of other fun things with Python that I’m not going to share here: data scrapers from our MRP system, a bot that watches for comments on our website and alerts me to certain things, and a “You’ve Got Mail!” light. The massive number of libraries which are available for Python make it very easy to get working applications banged together in no time at all.

A Note on Python Versions

The last thing I want to mention for the complete newb is Python’s versioning. Right now, there are two different branches of Python – 3.x and 2.x. Code written to work in 2.x (all mine was written in 2.7.3) will generally not run without modification in 3.x, and vice versa. Most libraries out there are written with 2.x support in mind, and won’t work properly for 3.x.

This is a bit of a problem; officially, 2.x is deprecated, 2.7.x is the only pre-3.x version still being worked on, and only bug fixing is happening – no new features will be added. Practically, the community hasn’t really embraced 3.x, and much (most?) of the examples and libraries that turn up when you ask Google for help with Python are 2.x compatible only.

My advice? Download the latest version of 2.7 for your platform and stick with that. The documentation on the python.org website is first rate, and their tutorial is a great step-by-step introduction for people who can program, but don’t know Python yet.

A Little Help?

One of the reasons I shared the two examples I did is because I know they could use some improvement. If you have an inclination, feel free to fork my repos and carry on improving them. At this point, they work well enough for me, most of the time, and I don’t have time to really push either of these programs ahead.


Comments 21 comments

  • The book, Think Python, is free.

  • Sorry, no comment. I just wanted to make your “You’ve got Comments!” alarm go off…. Childish, I know…

  • Heh, I wrote the same program a while ago (in C). Including the output impedance is a good idea, and something I didn’t do. My effort includes various resistor series, I should put the SparkFun ones in there too.

  • I take mild exception to the suggestion that the Python community “hasn’t embraced” Python3. Most of the really important third-party libraries have been migrated, but not all of them, and some are difficult ports. Any application that depends on a library that hasn’t been ported yet still needs the 2.x branch. It takes time to make these ports and many (if not most) of the developers are volunteers, so if it isn’t broken, they don’t want to fix it. I don’t blame them.

    I’ve been working with Python since 1998, and I’ve carefully watched as the (mostly scientific) libraries that I depend on have gradually become Python3-compatible. An interesting thing that I’ve noticed is that the Python community is unbelievably productive and creative now there are new and better alternatives for some of the grey-bearded 2.x libraries I used 4-5 years ago when I first developed some of my applications. When I begin work on the next version of my codes, I’ll refactor them to use the new libraries and Python3.

    None of this means I haven’t embraced Python3. I’m one guy, and I do this for fun and to make my own work more productive; I don’t sell code for a living. Rather than suggesting that Python3 is less than accepted, it’s probably more accurate to say that the Python community has been pretty tolerant of those of us lazy slobs that haven’t taken the time to port yet. Simply handling bug fixes and dealing with new versions of the underlying operating systems for 2.7 is a big job, and I’m grateful that the Python developers are still at it so long after the advent of Python3.

    When I compare the Python community to what happened to those of us who wrote large applications in Visual Basic 6 before Microsoft tossed the whole platform away for VB.Net, I am eternally happy that I moved away from proprietary language systems and started hacking Python. All I can say is that if you dabble in Python and you like it, get involved with the Python community. You’ll be glad you did!

  • I commend you for exposing your code to the public. Another nice thing about Python is that if your code is not “pythonic” you will usually hear about it, but from a bunch of folks who keep their flame-throwers set to somewhere around pilot-light.

    If you follow the scientific computing community, Python has taken over. SciPy.org will boggle the mind. Also medical imaging, massive networking simulations, you name it. The version problem is a real pain. The nicer graphics like tK is 3.5+ only IIRC.

    However, the ability to use GPIO in embedded Linux through /sysfs and other means is very cool and plenty fast for most needs. Love it.

  • Great article! I highly recommend messing around with Python some for all. I first made some very basic programs with it ~2 years ago, and even made a program that pressed the arrow keys for those Google Olympic doodles; ex. Hurdles.

    Then just this past summer I wrote a program that would mimic entering student usernames and info into the WPA2 Enterprise login system (imported data into arrays from CSV file and performed the necessary key strokes). The tech teacher at my high school liked it so much (partially cause he had to enter all 150+ new students every year manually), the school paid me for working on it. Also as a way of adding a GUI, i wrapped it up with a Just BASIC interface. So yea, just a little bit of knowledge in a cool language like this can help you out a lot.

    Now just need to learn multithreading stuff.

  • Python’s nice, but I kinda like being able to fix arguments to specific types sometimes (though being able to return any type is amazing actually) and the fact you can’t compile it to an .exe without having to export the whole interpreter in a .dll kinda mean I’m inclined to use C# a lot of the time. Sure, it’s great, easy and I use it loads, I just wish it could be a bit more like it’s counterparts…

    I think releasing your code is very kind of you :) I have a couple of modules up and opensource here if they’re any good to anyone. :)

  • I’ll put in my 2 cents for Python. My first language was C, and when I went to college and had to take an introductory programming course in Python. I thought that I would be making little command line programs and that the course might get to building a simple database program but nothing more. Little did I know that the we would be making 3D pictures and working with all sorts of graphical applications

    Once you have your data into Python through pySerial or something else, try matplotlib as a way to plot the data.

  • It’s still a slow interpreter, not suited to real time. :-(

    But within those limits it’s great :-)

    I like to think of Python as BASIC without the line numbers and REM statements

    • Depends on the platform. On 400MHz ARM9 you can toggle a GPIO bit at 100 KHz. No special tricks needed. For Interrupts response you have the lag of Linux in general or write handlers that do the job and set flags. ARM fast interrupt mode only takes a few cycles.

      • True, it may be fast enough for a particular application if the hardware platform makes up for the inefficiency of an interpreted language. A non-interpreted language will run even faster, though. Another concern is the behind-the-scenes stuff that happens in interpreters. The biggest for me is automatic garbage collection. That can really mess up a piece of hardware by exceeding its duty cycle rating.

        You’re right - the kernel is what sets the basic latency and determinism of the interrupts. In a poorly configured system it may swamp any interpreter slowness. But if the kernel is correctly set up and the platform’s fast enough, then Python is definitely suited to many applications that used to be considered hard real time. One just has to be careful.

  • Python is ideal for microcontroller projects involving serial communication - something that’s much harder to get off the ground in C/C++. I typically program only basic I/O into my Arduino’s and get the PC to do all the heavy lifting. I’m also stuck in 2.x land because the last good working version of PySerial module was compiled for 32-bit 2.7 Python. Many image processing plugins do not support 3.x code.

    Branching out of Python is a huge hassle considering that both, hardware and software coming out nowdays assumes 64-bit environment.

  • OH! One more hardware-related python tip – you can use python to play interactively with any hardware that has a serial port interface by downloading the pySerial add-on. It doesn’t come with the official python distribution.

    tonyv

    • YEA!!! and for those who never saw it, another awesome Sparkfun tutorial about Python over serial matched with a GPS Python + GPS.

      Also great for getting started in Python.

    • Thanks for mentioning this! Big oversight on my part…pySerial is a big part of what I do- obviously I do a lot of hardware interaction via Python and pySerial is just too easy to use.

      It’s really nice as a bridge between the small, cheap SBCs that are so popular these days and an Arduino- the Arduino is generally easier to use as a meatspace interface and the SBC with Python is generally easier to use as a bridge to the cloud.

  • Thanks for article. I agree that python is just a WONDERFUL gift to humanity. It is completely free and open source, and can even be incorporated into commercial products.

    Since this is a hardware-oriented site, I thought I would also make a plug for SWIG, which is a free tool that can generate a python-compatible wrapper for existing C or C++ DLLs. C is the defacto standard for hardware control since it is lean and mean and close to the machine, so most OEM hardware components out there have a C or C++ interface DLL (or at least source code) for programmatic control. If you have the *.h file for this code, then you can use SWIG to automatically generate a python interface (or perl, or java, or c#, or many other languages), and then play with the hardware interactively!.

    Finally, if you DO need a GUI, rather than a command-line interface, try wxPython rather than using the ancient TK libraries that come with the python distribution – you will be very glad you did.

    tonyv


This Week

This Month

Heartbleed

Happy Arduino Day!

SXSW Create 2014