Enginursday: Detecting Knob Changes

A look into how to decide when a knob has moved, so that your program can take an action.

I make a lot of projects that tend to fit the same formula. The project has a microcontroller; some core function the object is to perform; and knobs, LEDs, buttons and other UI elements. When it comes to writing the software for said project, I always need the same thing from the UI elements. When an input changes, my program must do something in response.

This "Enginursday" focuses on how to detect a deliberate change in a knob position while rejecting noise. I've made a Processing sketch that displays the parameters of the detection system live, which helps me feel the knob response while testing the UI --- and is also a nice way to demonstrate what these essential filters do to the signal being processed.

I demonstrate:

  • Simple thisState lastState comparison -- snippet
  • Masking LSBs -- snippet
  • Arithmetic range, or threshold -- snippet
  • Hysteretic behavior -- snippet
  • Windowed behavior -- snippet
  • Averaged, windowed behavior

Have a look at the video and read on for more information!



The code and resources here aren't intended to be something you can just grab off the shelf and use; it's a work in progress, and I generally do it for "fun." But I do want to talk about a few things.

The Knob Box

The knob box is a Proto Pedal with Teensy 3.2 and Teensy Audio board installed and the addition of a TeensyView screen for debugging.

The Processing Sketch

Ok, ok, so you got me. There's text on the OLED screen, so it can't be the same sketch I show in the video. What's actually going on is that the box is packetizing data from a structure, then serializing it as 7-bit ASCII and shipping it out the USB serial interface.

On the other end, the Processing sketch parses the serial stream, decodes back to binary and builds a structure that Java can understand.

The graphical elements are truly a kludge of operations that uses some custom fonts, builds the seven-segment look and draws the graph items. It's been customized for each of the examples, and can be found in the associated "Graphic X" folders within the DynamicGraph repository.

The ACTUAL Implementation of the Knobs

In the video I hold up a book, Design Patterns: Elements of Reusable Object-Oriented Software (ISBN-13: 978-0201633610). As a hardware guy, this book is very difficult for me to wrap my head around, but has helped immensely with coming up with a scheme that solves a problem of divergent libraries. I was able to create a system that fits my needs. I call it uCModules.

The goals for the library:

  • Have abstract logic components that define behavior
  • Have abstract hardware components to communicate with hardware
  • Be extendable from the user code space without modifying libraries

The complexity increase of using design patterns has so far paid off. As an example, I've added a new hardware interface, which connects knob inputs to ADCs through analog muxes, to give me 64 ADCs while using only four physical channels and scanning. All of this is done without modifying the library itself. Also, for this post I needed to add getters to the logic so I could get the internal data, which is normally private. Again this was done without touching the library source.

If you'd like more information, there are class diagrams available, as well as an API reference. While you're free to poke around, It is still a work in progress! I'm currently looking for a better way to document it, as well as making a timing scheme that isn't convoluted --- or better yet, using an RTOS.

Happy filtering,
Marshall