SmartKnob firmware and software
Comments or questions are welcome! (Dropbox account required to sign into Paper)

Or, join the Discord for more lively discussion.

Dev Environment

SmartKnob uses PlatformIO to build the firmware. The recommended development environment is VS Code. Although the firmware uses some Arduino libraries/framework code, it cannot be developed using the Arduino IDE.

Getting started

💡Before we start, let’s set some expectations: the firmware currently only provides a basic framework for experimentation that allows haptic detent configuration and serial input/output as a demo, but doesn’t support any “real world” usage out of the box (i.e. there’s no MQTT, home assistant, macropad, or other features implemented — but reach out in Discord if you’d like to help contribute!).

Install PlatformIO extension in VS Code

From the extensions sidebar, install PlatformIO IDE

Open the source code

Use File→Open Folder, and select the root of the smartknob git repo.

If you haven’t already cloned the git repo, select the “Source Control” sidebar, “Clone Repository” and enter https://github.com/scottbez1/smartknob.git as the repository url. 

Select a location on your computer to store the code, Open it
Select “Yes, I trust the authors” (required for the PlatformIO extension to be able to run/compile code)

Upload firmware

From the PlatformIO sidebar, select “Upload and Monitor”
You should see a boot up message after upload. 

Calibration

Motor calibration
Motor calibration is REQUIRED for any haptic feedback to work correctly. It tunes the encoder to your specific motor’s magnet and coil orientation. To run calibration, type capital ‘C’ into the serial terminal at any time and then wait for the calibration procedure to complete — don’t touch the knob while calibration is running. The motor should spin smoothly for a bit, followed by a bunch of jerky movements in both directions. The calibration should be automatically saved to internal flash memory — look for Wrote <X> bytes and Success! messages

Strain calibration
The SmartKnob View uses analog strain gauges to measure presses on the knob. You’ll need to calibrate the thresholds based on the specific values you get from your strain gauges once assembled. To run calibration, type capital S into the serial terminal at any time and follow the prompts to complete calibration. Once this is done you should be able to press down on the knob to switch through demo modes, and the LEDs should react to the amount of pressure you apply.

You can find some additional configuration flags in the platformio.ini file, e.g. if you’d like to disable the strain gauge pressure sensitivity, or disable the VEML7700 ambient light sensor.

Modifying Firmware - Architecture Guide

If you’re interested in tweaking the firmware, start by reading through this quick high-level guide to the existing firmware to understand some of the key concepts, then I’d definitely recommend poking around the code and joining the discord to discuss!

Concepts

Config vs state
Config and State represent the key inputs/outputs to the SmartKnob.

“Config” is the specification of the desired configuration of the device. For example, the number of detents, or the strength/torque of detents. Config is pushed into the SmartKnob.

Config is idempotent (that is, applying the same config multiple times in a row doesn’t change the result). Config is always specified from outside the system, and shouldn’t internally change in response to the state of the system (however, an external controller may decide to change the configuration in response to changing state). [caveat: as of 2023-02-10, out of laziness and bad coding, the current position state is actually stored in a config data structure in motor_task.cpp. This should be fixed]

“State” is the representation of observable aspects of the system. For example, the current detent position (or sub-position). State is published by the SmartKnob.