Wio Terminal Accelerometer in CircuitPython

I’m exploring the Wio terminal so there may be other posts soon as I continue to tinker around with this cool board. I wasn’t finding a good example or tutorial on how to use the built-in LIS3DH accelerometer in CircuitPython, so I did some digging and got this to work:

import adafruit_lis3dh
import digitalio
import board
import busio
import time

int1 = digitalio.DigitalInOut(board.GYROSCOPE_INT)
i2c = busio.I2C(board.GYROSCOPE_SCL, board.GYROSCOPE_SDA)
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
lis3dh.range = adafruit_lis3dh.RANGE_8_G
for i in range(5):

This requires a library from the CircuitPython resources, I used Bundle for Version 7.x since that is what I have installed on my Wio Terminal. Once you have that bundle downloaded and unzipped, simply drag the adafruit_lis3dh.mpy file into a lib folder on your Wio drive (mine is called ARDUPY still, even though it is running CircuitPython):

Contents of the Wio drive

Notice that I have some extras from other tinkering, the adafruit_lis3dh.mpy file is the only lib file this example requires. If you are curious about the CMUTypewriter-Regular-70.bdf file, feel free to grab it, and check out adafruit tutorial for how to use bitmapped fonts. I converted a LaTeX font file that I had on my computer to bitmap by following a related adafruit tutorial Custom Fonts for CircuitPython Displays. I like this better than the American Typewriter font, and with the large size, it makes a very readable display (note: only three lines with 7-8 characters each fit on the screen, so it’s not appropriate for all uses).

A huge thanks to Adafruit for all sorts of contributions to the maker landscape. CircuitPython is an awesome way to interact with microcontrollers, and buying adafruit hardware and other products from the shop is a great way to support this work!

Within the Sand

This piece was originally published by Artists Repertory Theatre for their Fresh Eyes series. Thank you to the entire company for allowing me into their rehearsal and production process, the experience was incredible and I am honored to be able to reflect on this powerful show. La Ruta runs through Dec. 1, 2019.


Sand spreads an applied force through chains formed by neighbor grains pushing on one another. To create this image, a force is applied from above. The force chains appear bright in this model and larger forces are indicated by brighter beads. Photo credit: Karen Daniels, NCSU Physics

On the set of La Ruta, the sand encroaches from every side, a symbol of the constant, surrounding fear of daily life for the women of Juarez. “… the only thing between our beds and the desert is a thin layer of concrete.” The piles of sand in the blazing sun set the landscape, and the production’s use of sand as both a character and a set piece gives life to the desert and the monsters it hides.

Even in the field of physics, sand remains somewhat mysterious. Granular materials, such as sand, are hard to categorize; they behave like a liquid in certain ways, and like a solid in others. Sand can support objects that rest on it, but it will also move freely to fill whatever space is available. Piles of sand can support very heavy loads: we are able to walk, drive, even build on it, but sand is also delicate enough to shift in the wind, drifting around corners or slipping through cracks in a wall.

Imagine stepping down onto a small pile of sand, if you could zoom in on the sand grains under your foot, you would see that the force you apply is carried through the grains in a number of force chains. These chains are formed when grains are near enough to push on each other; one grain pushing on the next, and it in turn pushing on the next grain down the chain. We can visualize force chains in a lab by using models of sand where each sand grain is represented by a small plastic disc. These discs are made from a material that will change from opaque to clear when squeezed. By stacking many of these discs in a thin layer, we see force chains appear as a connected string of bright discs; illuminated because they are experiencing an applied force. The image above shows the chains that occur when a force is applied to the top layer of discs. The bright lines show how each grain in a chain is carrying part of the load. The structures that emerge are organic, resembling tree roots or branches. Forces split apart and sometimes rejoin later as they find a unique path through the sand grains.

Looking closely at the image, we see that forces are distributed through sand in a very uneven way. Some individual grains bear most of the pressure, while others, even the grains close by, are spared from feeling any force at all. Sand is indiscriminate in how the load is carried—unfair in some ways, certainly unequal. The women of La Ruta, grains of sand feeling forces from all sides, also bear the weight in unequal ways. Some crushed by grief, barely surviving, and others seemingly unaffected by the surrounding forces.

Another observation from the plastic sand model teaches us that moving the point where the force is applied can completely rearrange the force chains, and scramble how they connect. Grains that felt nothing before may quickly find themselves bearing the majority of the force. Subtle changes from the outside have the power to completely rearrange how it feels to be in the midst of the sand, just as is the case for the characters in La Ruta.

To close with a positive aspect of this metaphor, consider how force chains give sand its incredible strength: the ability to support any weight laid upon it. By supporting one another, and organizing themselves to share the burden, individual sand grains collectively grant sand the ability to withstand incredible pressure. Unlike other solid objects, each grain of sand maintains its identity and independence, granting the whole collective the ability to move and re-shape when given the opportunity and space to do so.

Driven by the Wind

This piece was originally published by Artists Repertory Theatre for their Fresh Eyes series. Thank you to the entire company for allowing me into their rehearsal and production process, the experience was incredible and I am honored to be able to reflect on this powerful show. La Ruta runs through Dec. 1, 2019.

Attending the table reading of La Ruta was a powerful experience, and there are many vivid scenes that linger in my mind. One scene in particular resonates with me for a variety of reasons. Though the stage direction was just read aloud, I could clearly picture the on-stage implementation of the scene. We hear the howling sound of wind blowing in the desert, and gradually a rhythm emerges that ultimately evolves into a song.

When I signed-on for Fresh Eyes, I assured ART that I would leave physics out of it. I lied.

The sound of howling wind is one we all know, and we are familiar with the noises it elicits when whipping around buildings, through narrow cracks in old walls, or past bending trees in the forest. We also know the sounds that come from blowing across the mouth of a bottle or jug. What determines the sound that is excited by the blowing wind? Does the wind itself decide if the sound will be pleasant? Musical? Annoying? Painful?

All sounds—the wind, a strum of a guitar, a woman’s scream—consist of vibrations, or oscillations of a specific frequency, that begin in a material and are carried through the air to our ears. The wind includes an enormous range of these oscillations which are each individually small but spread over a full spectrum of frequencies, from the highest squeal of a mosquito to the lowest rumble of thunder. Carrying all of these frequencies within it, the wind will inevitably match the natural oscillation of whatever object it blows past. If that object is an open jug, we hear the frequency of the jug; just as if we had blown on it ourselves.

Every object, based on its size, shape, and material, has specific frequencies that will resonate. You can find these frequencies for instruments by plucking a string, tapping a drum, blowing between two reeds or over the mouthpiece of a flute. The same is true for many objects: a wine glass will ring out when gently tapped. A guitar is meticulously designed to resonate at the frequencies (i.e., notes) that have been deemed musical by Western civilization. In the hands of a skilled musician, the instrument generates beautiful phrases or melodic ideas with vibration. While a guitar will still resonate when left out in the wind, it is now at the mercy of the wind. The open strings, not tuned to a particular chord, will all vibrate when driven by the wind and so the sound will fall somewhere between melodic and dissonant.

This is true for anything. The structures we leave out in the wind, intentionally designed or not, will be driven by the wind. They may resonate musically, or they may resonate with painful discord, sounding more evil than melodic.

In La Ruta, we hear the wind of capitalism as it blows across border, a force applied indiscriminately around the world. Whether it excites harmony or discord as it passes is determined by the structures—size, shape, material—that it blows past. The structure of human nature, when blown by strong winds, can resonate with either good or evil and the stronger the wind, the louder the sound.

Striking broken systems, unpaved streets, dark corners, and corrupt officials, the wind stirs up the worst aspects of human nature. This is how we find the characters of La Ruta, struggling against the wind and buffeted by the constant fear it stirs.

Not all wind excites the sounds of evil, however. When blowing past the right combinations of strings, pipes, and tubes, beautiful music fills the air. It is therefore our responsibility to construct the musical structures of society, systems that are ready to be driven by the force of the wind, and excited toward good instead of evil. These empowered instruments are built through strong infrastructure: just courts, lawful police, well-lit streets, and clean water. They are also built with the right combination of social and political strength, and supported by the collective voices ready to speak out for one another.

La Ruta presents the story of many strong women, facing the powerful winds with little in the way of protective structure. Instead, they create their own, and use it to rise above the fear and grief that define their lives.

Glowforge Aluminum Instrument Panel

I spent some time with the glowforge to test settings for engraving our instrument panels. This is powder-coated aluminum from Hammond. The cases are used in a variety of our projects, but despite cutting holes on the CNC, we haven’t ventured into CNC routing labels and have relied on our tape-based label-maker. It does ok, but laser-engraved labels really up the look. With some time to kill, I ran a few tests on the inside of one panel. The end result is to run with 1000 speed, 50% power, 340 lines-per-inch, and 0.15″ focus height. Continue reading

Pluto SDR (ADALM-PLUTO from Analog Devices)

I picked up an ADALM PLUTO from Analog Devices; a very powerful Software Defined Radio (SDR) for only $99. The cost is low as is the documentation. Many links on Analog site are broken, and to their credit, there are a few comments that “people found these instructions hard to follow, so we are revising them.”

That’s good, but in the meantime, here are the instructions that finally worked for me: at John’s Musings

Bio-Rad Ciphergen PBS-II back to life

That’s a mouthful, but it’s an instrument, for science and stuff. I got a used one from eBay last week, and finally have it set up to where I can actually talk to it over the crude computer interface, it’s been a fun process. I’ll back up: this thing is an analytical instrument from the early 2000s. It is designed to measure the distribution of mass in a sample (such as as a sample of proteins from tissue cells). It does this by blasting the sample with a pulsed UV laser (337 nm, nitrogen), accelerating the charged particles (ions) across a high voltage, and measuring the time it takes them to reach an ion detector a few feet away. The distribution of arrival times is therefore a distribution of charge-mass ratios (a spectrum).

Long story short, it has a whole lot of good physics equipment in it, even if it doesn’t do it’s biology thing very well anymore (though it might…  I don’t have a good sample to test it on). I bought it for the parts, and want to see what it can do. This is an outline of the steps I took to get it working. While it may not apply to anyone else, the tricks are generally useful for hacking on vintage instruments.

This machine originally came with a PC for control, and it communicates via GPIB port. This is not always my favorite platform to work with, but it is here to stay (at least it was in 2000).

I have a prologix USB-GPIB so my first try was to set that up with the machine. It took a while (and a few passes through the manuals) to find the note that the PBSii defaults to address 8. Once that was set correctly, it responded to *idn? with Stanford Research Systems,TOF200,ver045 which was a bit surprising. It turns out SRS was working on a time-of-flight mass spectrometer (similar to this) at that time, and must have been selling time-of-flight boards for OEM use. I pulled out the TOF board to take a look, and noticed that it connects to the master box via a cable labeled “SPI”. Despite being an actual protocol, I think this refers to “Serial Port Interface” as the manual has that phrase in a few locations (but no real information beyond the name). There are a few GPIB commands listed in the service manual, things like how to read and set various registers, but nothing very high-level (the design relies on the software for all of that). I didn’t try those commands right away because without knowing what they did… I’d risk setting the machine into some odd state or enabling a subsystem that I shouldn’t.


The SRS time-of-flight controller embedded in this instrument. GPIB chip (NAT9914) hiding under the top left ribbon cable.

Talking over GPIB was encouraging, but I still had no control over the vacuum system (or any readings from the gauges and various system status indicators). When it powers on, I could hear valves snapping open (or shut) and the pumps would start up; it clearly had a turn-on sequence and everything at least appeared to be working at this point.

After a few emails to the company, including an initial response to the effect of “that machine has been unsupported for over a decade,” I was sent a zip of the original software utilities. Lesson 1: the sooner you can get to an engineer in the company, the better. Find someone like you who enjoys diving in and isn’t afraid of the hardware-software boundary. Unfortunately, the software didn’t see my USB interface as a GPIB (why would it, its just a serial port). I couldn’t yet use the utility software. Sure, there may be some way to trick it into sending GPIB to the serial port, but a more direct route would be to revive some appropriate-era hardware.

The next step was to track down a PC with a GPIB card capable of running the windows utilities. They were written for Win2000 so I figured anything from NT to XP should work… and maybe even later. I borrowed a dusty XP machine from a colleague’s lab for some debugging. In that era of windows, there is an option for “Remote Desktop” which is nice, so I can check on things from outside the lab. Lesson 2: if you don’t want to be stuck in the same room as the machine for a week, set up VNC, remote desktop, or some other way to remotely check in on it

Fortunately everything fired up without a hitch, and the utility software started reporting status and accepting commands. At first, it reported the MAG gauge (high-vacuum gauge) at 0 volts, and turbo pump speed as LOW. Additionally, the backing valve was showing OPEN even though all valves were listed as commanded CLOSED. This was concerning, but not surprising given that it’s probably been sitting for at least a couple years. I cycled the power and the next time around both gauges were alive, and the turbo pump spun up to report OK. In retrospect, I should have followed the shutdown routine to make sure valves were properly closed and the turbopump was allowed to spin down before anything was vented. It seems to have defaulted ok, and the turbopump took a long (quiet) time to spin down. A good sign given the fact that turbos can be seriously damaged if vented too quickly.

Screen Shot 2018-10-21 at 12.18.58 PM

A screenshot of the utility software reporting the current status.

Now I’m at the hurry-up-and-wait stage of pumping down to 1e-6 Torr at which point I can fire up the high voltage and laser systems. I’ve only worked with a handful of vacuum systems (back in grad school) but I did remember that it’s useful to have a reference pumpdown curve… so I started charting away. This is where Remote Desktop really helps. I’d log in every so often to peek at the reported pressure. After 12 hours, it’s gone from roughing to 5e-6 Torr. The operating target is 1e-6, so we still have a ways to go. The flight tube had been open to atmosphere for who knows how long, so I suspect a bake-out is in order, and likely a replacement seal or two (rubber o-rings have a limited lifespan, especially in surplus storage warehouses).

Overall, it’s pretty cool to have something like this come to life even just to this level. At the very least, I got an operational high-vacuum system for $750 plus freight. Lesson 3: a lot of instrumentation is built from generally-useful parts. Such instruments become useless to the intended users even if only one tiny part stops working. Even worse, they become obsolete only through lack of software support. eBay is your friend, but you may have to battle your business office… mine requires personal payment and will only reimburse after equipment arrives on campus.

I owe a shout-out to Erik Sanchez from PSU who tipped me off on this amazing used-equipment find and sent me many helpful documents. Also thanks to Windell Oskay for a helpful conversation as I was starting out. He spent time as a hardware engineer at SRS, and gave me some insight on their hardware implementation of GPIB (using the NAT9914 chip).

Update: After about 48 hours, it wasn’t going below 3e-6 Torr so I started through the various seals and valves. There are several, all too specific to worry about here, but I cleaned the main sample seal o-ring with isopropyl alcohol, and cleaned out the two valves that vent the flight tube to higher pressures (one to atmosphere, one to the backing pressure). At this point, 12-hours later, it’s down to 1.2e-6 (closer!). I’ll give it a day, and see how it looks. Bottom line, the turbopump seems to be in working order (knock on wood) despite me absent-mindedly venting to atmosphere for a few seconds (doh!).

Projects I’d Love to Do

I’ve neglected this site for a bit, and will try to revive it by dumping the contents of my growing list of things I’d love to do if I could make 24 more hours in the day. Why share this? Because if someone else out there wants to work on one of these too, then that serves as extra motivation for me. Also, putting it out in the universe makes it a bit more real than if it sits in my head all the time. I’ll probably revise and will hopefully provide updates as warranted. These are not things that have to be done for the sake of humanity, or things that would even merit a paper or other substantial scholarship (which is probably why they keep getting pushed further down my list). That doesn’t mean they aren’t worth doing. Some lean toward personal projects, others are obviously aligned with my work. Here goes, in total random order:

  • Build a spatial light modulator from an old projector. Note: this has been done before, but I want one, and it sounds like a really fun project that touches on re-use, optics, electronics, and hacking (four of my favorite things!)
  • Directly image the output of a parametric down conversation crystal. Sure, we’ve seen pictures and this isn’t really new knowledge, but I think it really helps students understand what’s going on if you can watch it live. There are a lot of tricks to get this to work, but doing it on the cheap and easy would be sweet.
  • Demonstrate laser-to-RF mediated by at atomic medium. It’s all just E/M radiation, there has to be a fun demo in here somewhere. Are there four-wave mixing transitions that would generate RF that you could tune a radio to? I’ve yet to check this, but it would be cool if it worked.
  • Get my HAM license. I’ve studied up and everything, but just need to get to an exam session and do it.
  • 3D-print a working external cavity diode laser. I have some partial designs, just need to print and test the darn thing.
  • Part out an old argon laser system. I salvaged a laser slit lamp system from our college of optometry. It has all sorts of fun electronics, lasers, optics, and other parts. It doesn’t work anymore, but lots of it’s parts surely do.
  • Other stuff… to be added when I think of it, I’m sure it’s in my head somewhere.

In the meantime, feel free to comment on any of this. If you’d also like to work on something here, let me know.


This is a very cool visualization, and I will continue to play around and explore various parts of the country. One thing I noticed immediately, due to where I live, was an interesting consequence of the algorithm. According to the model, there are several very large buildings nearby (see the outskirts of Forest Grove in the picture).Screen Shot 2018-10-12 at 5.30.04 PM

There is one cluster in the lower left (near Ritchey Rd) and another in the upper right near Schefflin. These are not really buildings, they are hoop-houses. Structures made of only plastic sheets and a few metal pipes. You could argue this is nit-picking, and I’m fine with that characterization. But I’d love to press the issue and ask what would it take to train a neural network better… so it knows the difference between what you and I would call a building, and what merely looks like a building from space.

To be more clear, here is a picture of the Ritchey Rd area:

And a full-zoom of the satellite image, corresponding to the top left (northwest) portion of the nursery (the NYT article doesn’t zoom in from here):

Screen Shot 2018-10-12 at 5.37.37 PM

Clearly these are structures, but what would be the next step in developing the algorithm to know they aren’t actually buildings (or do you define them as such?). Certainly including some nurseries in the training set would be a first step.

Python with a Cocoa GUI on macOS

I finally had a chance to try writing a native Cocoa interface in python. My test project was based on a post by Adam Wisneiwski (though I had to use the cached google version due to a bad gateway error). In that post, Adam laid out the process to put together a basic python app that uses a native cocoa GUI created in Xcode. Given the updates to Xcode, and the fact that I’m using anaconda python, I figured I’d repost my process, with the modifications I made to get it to work in case it is useful for anyone else (and so I can remember how I got it to work).

First, some background: I have anaconda python installed in my home directory, so I had to add some packages so python can connect with the Mac Cocoa framework. If you are just running vanilla python that comes with your Mac, then you shouldn’t need to add anything. Test your setup by trying to import Cocoa in python. In my case, that didn’t work until I installed two packages:
pip install pyobjc-core
pip install pyobjc-framework-cocoa

I didn’t find these with conda on conda-forge so it was a job for pip. Once these are installed, you should be able to import Cocoa and import Foundation in python. Next, it’s time to check for py2app. This step was new to me (I haven’t used py2app before), but I figured it would work best to have this installed in the python environment I plan to use, so once again, let pip do the work: pip install py2app. After that, you should be able to run py2applet on the command line and it will return a default help message. We’ll use this utility to create a setup.py file for the application, and bundle it.

First, put the following application code into a file named SimpleXibDemo.py:

from Cocoa import *
from Foundation import NSObject

class SimpleXibDemoController(NSWindowController):
    counterTextField = objc.IBOutlet()

    def windowDidLoad(self):

        # Start the counter
        self.count = 0

    def increment_(self, sender):
        self.count += 1

    def decrement_(self, sender):
        self.count -= 1

    def updateDisplay(self):

if __name__ == "__main__":
    app = NSApplication.sharedApplication()

    # Initiate the contrller with a XIB
    viewController = SimpleXibDemoController.alloc().initWithWindowNibName_("SimpleXibDemo")

    # Show the window

    # Bring app to top

    from PyObjCTools import AppHelper

Next, we can start to package this app by creating a setup.py file using py2applet:

py2applet --make-setup SimpleXibDemo.py

Notice that you call this with the name of the python application file. The setup.py file generated should look like:

This is a setup.py script generated by py2applet

    python setup.py py2app

from setuptools import setup

APP = ['SimpleXibDemo.py']

    options={'py2app': OPTIONS},

You’ll want to associate the application with an xib file (i.e. the GUI side of things). Just add the filename (although we haven’t made the actual file yet):

DATA_FILES = ['SimpleXibDemo.xib']

Just be sure to name your XIB file accordingly when the time comes (that step is coming soon).

Now it’s time to fire up Xcode. I’m using Xcode 8, on macOS Sierra, things should be similar on earlier versions, but Xcode has evolved a bit over the years. I still have the Welcome widget enabled on Xcode, so the quickest way to get what I wanted was to “create a new Xcode project”, and choose “cross-platform” and “Empty”. We don’t need much in this project, but make sure to save it in the same folder where you created setup.py and SimpleXibDemo.py.

Next, create a new xib file for the app window. The menu path is File→New→File… and under macOS in the User Interface category pick Window. For a filename, type in SimpleXibDemo and it should add the .xib extension. Next, add your .py file to the listing for Xcode: File→Add files to “Project”… Select your file SimpleXibDemo.py. If you open this file in Xcode, you’ll see some decorators that let Xcode know how you will interface with it: @objc.IBAction indicates a function that you want to receive an action. You’ll also notice that the python script instantiates an outlet for the interface and calls it counterTextField: counterTextField = objc.IBOutlet() This will be the recipient of actions within the script.

To lay out the GUI, drag three buttons onto the window from the Object Library (lower right side by default). You can change the text that appears on the button by double clicking.

Next, we’ll associate the quit button with the terminate action. Ctrl-drag from the button over to the FirstResponder. In the pulldown, choose terminate, this will associate the quit button with ending the program.

Next, we have to associate the window with the python class that it represents, and link the buttons to the appropriate IBActions. Note that it is important the class specified in the File’s Owner matches the python class in the .py file. In the code above, that is SimpleXibDemoController so click on the top icon to the left of the workspace (File’s Owner) and then choose the Identity Inspector (likely the third-from-left in the right-side pane). Enter the class name in the top field (Class). This associates the window with the class that will handle actions. Finally, Ctrl-drag from the “-” button to the File’s Owner and select the decrement action. Do the same from the “+” button but pick the increment action. This connects the two buttons to the corresponding class functions.



Finally (as shown below), add a label to the center of the window and ctrl-drag from the File’s Owner to the label. In the pulldown, choose counterTextField (which should be the only option). This links the label in the GUI to the counterTextField in the python code.


Save the .xib file and we’re ready to build the app. From the command line, run:

python setup.py py2app -A

You can then run it from the command line as: ./dist/SimpleXibDemo.app/Contents/MacOS/SimpleXibDemo

Note: it may not work just yet. I had to change the setup.py file to point to the right python executable (this comes from using a local anaconda python instead of the built-in Framework python).

This is a setup.py script generated by py2applet

    python setup.py py2app

from setuptools import setup

APP = ['SimpleXibDemo.py']
DATA_FILES = ['SimpleXibDemo.xib']

OPTIONS = {'argv_emulation': True,
           'plist': {
               'PyRuntimeLocations': [

    options={'py2app': OPTIONS},

Where I added the plist to the OPTIONS variable and made sure to provide the path to libpython3.6m.dylib (select the path to the dylib that matches your runtime python version). If you use anaconda, then it should be similar to the path above though your username is probably different.

With this change, run
python setup.py py2app -A
once more, and then try the app again:

I’m pretty new to all this, but feel free to let me know if you have trouble getting it to work and I’ll do my best to help.