The overloading of potentiometers

Creating complex firmware for existing hardware is often complicated by unforseen ( or ignored by the hardware designer ) human-interface issues. One example of this situation comes up when a project requires more settings than there are physical controls for. Modern cameras provide examples of the problem, and also of its solution.

Consider the case of a camera with a touchscreen. Problem solved! The touchscreen provides the capability of having a given location on the screen provide control for many different things, each made available with a different screen display.

Some modern cameras, however, have a few buttons which could be called multipurpose. In one mode, a given button might be mapped to a different function than it is in another mode.

I’m currently working with the OpenEffects Project hardware, which sports 4 potentiometers. I want to experiment with quite a few different effects and explore their interactions with my electric violin. The number of parameters for these functions in total is about 40. I broke up the settings so that each effects module had its own settings mode. Its settings are displayed and can be changed while its mode is active.

Since this design overloads the potentiometers, I had to think long and hard about what should happen when the mode is changed, since the pot can’t move to reflect the ( different ) setting of the ( different ) parameter of the mode’s ( different ) effect module.

I chose to ignore each pot until it is moved, at which time the related effect module setting will ( unfortunately ) jump to the current pot setting.  (Note – consider using a rotary encoder rather than a pot in your designs!)

The need to ignore a pot when the mode changes brings up a *different* gotcha. Reading a voltage several times will often yield different values. This will cause the pot value to be perceived as changed. Rats. So I had to add a guard band around the current setting, considering any reading within the guard band to be unchanged.

I also added an EWMA smoothing algorithm  to minimize the required size of the guard band. The larger the guard band, the more one has to move the pot in order for the change to be noticed. The longer the averaging period, the more sluggishly the reaction to a change occurs and settles.

I  ended up by splitting the difference to balance rotational- and time- sluggishness. But it works!

Audio Effects Link Farm

As I develop firmware for the open effects box, and explore its musical possibilities, I will periodically update this page with interesting or important links.

Download Pure Data (Pd)
Pure Data tutorials – cheetomoskeeto
Pure Data cheat sheet
Chuck’s Github work on the OpenEffects box
Chuck’s PureData patches, including (in externals) the output~ abstraction

The OpenEffects Project – the source of the open effects boxes
The boxes are powered by Teensy microcontrollers from Paul Stoffregen
… and use the same chip found on the Teensy Audio Shield
A graphical web tool which generates the starting framework for Teensy audio effects

Other interesting links:

Onyx Ashanti – beatjazz performer with self-built audio processing
Gordon Reid’s Synth Secrets


Struggles with callbacks between c++ objects

In my plan to have an object for the open effects box as a whole, including the firmware and the overall structure of the user interface, and another to wrap the physical object including the pin assignments, switch handling, etc., I wanted to have the hardware wrapper able to call back to the overall object when a switch changes state or is held to auto-repeat. The callback cannot be a static function, as it needs to modify member variables.

While it is apparently possible for an object to set a callback to one of its own methods, that callback has to include some way to refer to the object itself, so that the object structure and variables are available. However, that requires the hardware wrapper’s setCallback method to know about the calling class. Thus the hardware wrapper class has to include the calling class’ header file; but the calling class has to include the hardware wrapper class’ header file, since it’s instantiating that class for part of its functionality.

Seems like an infinite loop of inclusion; this can be protected in the usual way, but I haven’t been able to make it work.

Thus I’m going to abandon this line of attack and send a bunch of pointers to the hardware wrapper so it can set flags “thisThingyHasChangedState” for the calling class to poll. Ugh.

Modular firmware for open-source audio effects box

I have been working, both for myself and for my UMass classes, with the Open Effects Project as instantiated by Øyvind Mjanger’s company OnkartGromt.
Being more of a software geek than a hardware geek, I started by writing code to exercise all the hardware stuff – switches, knobs, relays, and jacks. Having gotten this under my belt, I’m now refactoring the code into object-oriented modules to make it clearer and cleaner and just all-around easier to work with.

If you are a UMass Amherst EE or CSE student and want to work with audio effects, check out my course ECE297DP on the M5 web site!