Skip to content

Booster2ooo/stm32f103c8-usb-rotary-knob

Repository files navigation

Introduction

This project is meant to be a USB knob capable of sending user-defined keyboard combination based on rotary encoder(s) inputs.

This is my first baremetal (and C) project. I choose to work with the STM32F103C8T6 because, even if it's a bit outdate, it's still a very powerfull device at low cost.

Special thanks to sabu (email: sabu (at) serveur (dot) io) for his guidance, patience and help, this project wouldn't exist without him.

stm32f103c8-usb-rotary-knob picture

Project roadmap

[x] Handle hardware inputs

The first step of this project is to connect the rotary encoder(s) to the STM32F103C8T6 and to intercept the inputs.

There are two kinds of inputs to manage on the rotary encoder, the switch (RSW) and the rotation (RCLK/RDT).

The switch is handled with a GPIO EXTI, triggered both when rising and falling. The interupt starts a timer (TIM2) used to virtually debounce the switch state (virtual low pass filter).

The rotation is handled with two GPIO EXTI trigged both when rising and falling, one for the clock, the other for data. The state/direction is stabilized using an algo I found reading this article.

[x] FreeRTOS (threading)

To avoid blocking the main thread, I decided to use the FreeRTOS capabilities of the STM32F103C8T6.

The default task awaits for mails sent from the rotary encoder and behave accordingly.

[x] Composite USB: VCP + HID

CubeMX allows to easilly configure the device to USB Virtual Com Port mode but this is not enought.

The device should be recognized as both a VCP and an HID (keyboard) so it can:

  • send keyboard/media keys to the host when the user interacts
  • send logs to the host over COM
  • be reprogrammed by the user over COM without needing to recompile the firmware

[x] Programming key combos

The VCP interface should allow the user to program the key combination that are sent when the rotary is pressed, released, turned clockwiser or counter-clockwise.

It's done by sending a command over serial with the following format: [rotaryId][inputType][actionType][mediaAction/modifierKey][key1][key2][key3]

  • rotaryId: decimal interger representing the rotary index (1 to 5 depending on your initial configuration)
  • inputType: one letter (case insensitive) representing the input to listen for, can be:
    • P: button pressed
    • R: button released
    • C: rotary clockwise
    • X: rotary counterclockwise
  • actionType: one letter (case insensitive) representing the type of USB "action" taken after the input has been received, can be:
    • M: media mode
    • K: keyboard mode
  • (if media mode) mediaAction: hexadecimal interger (2 digits) representing the media code sent over USB after the input has been received. See mediakeyboard.h for the possible values.
  • (if keyboard mode) modifierKey/key1/key2/key3: hexadecimal intergers (4 x 2 digits) representing the keyboard keys sent over USB after the input has been received. See mediakeyboard.h for the possible values.

e.g.:

  • 1CM40<enter>: configures the rotary #1 to send VOL_UP when turned clockwise
  • 1CK014b0000<enter>: configured the rotary #1 to send CTRL + Page UP when turned clockwise

default is (conceptually, because it's configured straight away, not using COM commands):

  1PM00 // aka does nothing
  1RM00 // aka does nothing
  1CM40 // volume up when turned clockwise
  1XM80 // volume down when turned clockwise
  // ...  same for the other rotary encoders if any

[x] Save/load config to/from flash/eeprom

Once the rotary is programmed, the flash memory should be written for the configuration to be persistant when the device is unpluged/pluged again.

[ ] Make it right/make it fast

Once the proof of concept is done, the next steps are to review the code for design errors and performance improvments | "make it work, make it right make it fast" - Kent Beck

Links

Here are a few link to projects and articles that helped me during the process (aside from ST manuals):

About

USB knob using stm32f103c8t6 and rotary encoder(s)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published