Hello World!
blog for everything
EntriesAbout Me

ESP32 Media Knob

By bshabanov
Published in Electronics
March 01, 2021
1 min read

Story

Recently I have made the E-Paper dashboard display. The PCB was ordered from PCBWay, and as you may know, the minimal quantity you can order is 5pcs. In some cases, this may not be enough, and that is ok since you can order more, but in most cases, you end up with spare boards. In this project, I have managed to use one of that spare boards.

The E-Paper dashboard was based on the ESP32 module it has a LiPo charger and can be programmed directly from USB via FT232RL, so here I used it again but this time instead of WiFi connectivity, I use it as a BLE keyboard.

To be as simple as possible, I use a rotary encoder, and this pretty much shapes the project specification - a knob that controls volume, play, and pause.

To enable the keyboard, I use a library from GitHub The interface is almost identical to the Keyboard Interface from the Arduino library.

0x07
PCB for the encoder

For the rotary encoder, I put some capacitors for debouncing, but it didn’t work well(since is not an RC filter), so I decide to make a software debounce.

0x07
ESP32 Media Knob

First I attach an interrupt on FALING edge of pin A of the encoder.

attachInterrupt((ROTARY_A), rotary, FALLING);

Theoretically, this should be enough to know that the A is always in a LOW state, and we need to check only the B state. To determine the direction of rotation, I use a variable that whenever an interrupt is triggered it will either add or subtract from this variable.

int b = digitalRead(ROTARY_B);
int mod = delta > 90 ? 2 : 1;
if (b == LOW) {
    scala -= 1 * mod ;
} else if (b == HIGH) {
    scala += 1 * mod;
}

This greatly increases the performance of the encoder, because, for one loop cycle, the interrupt can be triggered many times. And if for example, you rotate the knob CW, the encoder will detect, let say - 3 times CW and one CCW signal. If the CCW signal is last, it will output CCW as the final direction. But if you represent CW as a positive number and CCW as negative, you can sum these numbers, and the final result should be the desired direction.

Also in the main loop, I made the direction detection with some tolerance of +-1.

if (scala > 1) {
    // CW Dircetion
    ...
} else if (scala < -1) {
    // CCW Dircetion
    ...
}

Basic code

#include <BleKeyboard.h>
BleKeyboard bleKeyboard("ESP32-MEDIA", "bshabanov", 100);

const int ROTARY_A = 17;
const int ROTARY_B = 18;
const int TOGGLE = 5;
const int debounceDelay = 10;
unsigned long riseDetectTime = 0;
unsigned long riseDetectTimeBTN = 0;

int scala = 0;
bool button = false;

void IRAM_ATTR rotary() {
  unsigned long delta = millis() - riseDetectTime;
  if (delta < debounceDelay) {
    return;
  }
  riseDetectTime = millis();
  int b = digitalRead(ROTARY_B);
  int mod = delta > 90 ? 2 : 1;
  if (b == LOW) {
    scala -= 1 * mod ;
  } else if (b == HIGH) {
    scala += 1 * mod;
  }
}

void IRAM_ATTR toggle() {
  if (millis() - riseDetectTimeBTN < debounceDelay) {
    return;
  }
  riseDetectTimeBTN = millis();
  button = true;
}


void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();

  pinMode(ROTARY_A, INPUT_PULLUP);
  pinMode(ROTARY_B, INPUT_PULLUP);
  pinMode(TOGGLE, INPUT_PULLUP);

  attachInterrupt((ROTARY_A), rotary, FALLING);
  attachInterrupt((TOGGLE), toggle, RISING);
}

void loop() {
  if (bleKeyboard.isConnected()) {
    if (button) {
      bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);
      bleKeyboard.release(KEY_MEDIA_PLAY_PAUSE);
      delay(100);
      button = false;
    }
    if (scala > 1) {
      bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
      bleKeyboard.release(KEY_MEDIA_VOLUME_UP);
      delay(100);
      scala = 1;
    } else if (scala < -1) {
      bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
      bleKeyboard.release(KEY_MEDIA_VOLUME_DOWN);
      delay(100);
      scala = -1;
    }
  }
}

Summary

ESP32 BLE media knob, built from reused PCB, and it can be powered from micro USB, and/or LiPo battery, and it has a software debounce for the rotary encoder.

0x07
ESP32 Media Knob


Tags

#esp32#Si7020#PCBWay#ble#rotary-encoder
Previous Article
E-Paper Dashboard

bshabanov

Discover the world

Categories

Code
Misc
Electronics

Related Posts

ESP32 Media Knob
March 01, 2021
1 min
0x48 0x65 0x6c 0x6c 0x6f 0x20 0x57 0x6f 0x72 0x6c 0x64 0x21
2021 and still discovering the world