Skip to content

Commit

Permalink
perf: optimize encoder scan and add support for hot swap
Browse files Browse the repository at this point in the history
  • Loading branch information
DriftKingTW committed Jan 22, 2023
1 parent 8445524 commit 8b0c335
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 74 deletions.
197 changes: 123 additions & 74 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
#include <main.hpp>

// Rotary Encoder Inputs
#define encoderPinA P5
#define encoderPinB P4
#define encoderSW P6

PCF8574 pcf8574(0x38);

int rotaryEncoderCounter = 0;
int rotaryEncoderCurrentStateCLK;
int rotaryEncoderLastStateCLK;
String rotaryEncoderCurrentDir = "";
unsigned long rotaryEncoderLastButtonPress = 0;

long unsigned int rotaryEncoderDebounce = 0;
bool rotaryEncoderChange = false;

RTC_DATA_ATTR unsigned int timeSinceBoot = 0;
RTC_DATA_ATTR bool bootWiFiMode = false;

Expand All @@ -24,11 +8,15 @@ U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0,
BleKeyboard bleKeyboard(BLE_NAME, AUTHOR);
TinyPICO tp = TinyPICO();

PCF8574 pcf8574RotaryExpansion(ENCODER_EXPANSION_ADDR);
bool isRotaryExpansionConnected = false;

TaskHandle_t TaskGeneralStatusCheck;
TaskHandle_t TaskLED;
TaskHandle_t TaskNetwork;
TaskHandle_t TaskScreen;
TaskHandle_t TaskEncoder;
TaskHandle_t TaskEncoderExpansion;
TaskHandle_t TaskI2CScanner;

// Stucture for key stroke
Key key1, key2, key3, key4, key5, key6, key7, key8, key9, key10, key11, key12,
Expand Down Expand Up @@ -117,18 +105,10 @@ void setup() {

printSpacer();

// Set encoder pins as inputs
pcf8574.encoder(encoderPinA, encoderPinB);
pcf8574.pinMode(encoderSW, INPUT_PULLUP);

pcf8574.setLatency(0);
// Start library
pcf8574.begin();
Serial.println("Starting Wire...");
Wire.begin();

rotaryEncoderDebounce = millis();

// Read the initial state of CLK
rotaryEncoderLastStateCLK = pcf8574.digitalRead(encoderPinA);
printSpacer();

Serial.println("Starting BLE work...");
bleKeyboard.begin();
Expand All @@ -139,6 +119,31 @@ void setup() {

printSpacer();

pcf8574RotaryExpansion.encoder(encoderPinA, encoderPinB);
pcf8574RotaryExpansion.pinMode(encoderSW, INPUT_PULLUP);
pcf8574RotaryExpansion.pinMode(expansionBtn1, INPUT_PULLUP);
pcf8574RotaryExpansion.pinMode(expansionBtn2, INPUT_PULLUP);
pcf8574RotaryExpansion.pinMode(expansionBtn3, INPUT_PULLUP);
pcf8574RotaryExpansion.setLatency(0);

if (pcf8574RotaryExpansion.begin()) {
Serial.println("Rotary Expansion Board initialized");
isRotaryExpansionConnected = true;
} else {
Serial.println("Rotary Expansion Board not found");
isRotaryExpansionConnected = false;
}

xTaskCreate(encoderTask, /* Task function. */
"Encoder Task", /* name of task. */
5000, /* Stack size of task */
NULL, /* parameter of the task */
2, /* priority of the task */
&TaskEncoderExpansion /* Task handle to keep track of created task */
);

printSpacer();

Serial.println("Loading SPIFFS...");
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
Expand Down Expand Up @@ -201,13 +206,14 @@ void setup() {
&TaskScreen, /* Task handle to keep track of created task */
0); /* pin task to core 0 */

xTaskCreate(encoderTask, /* Task function. */
"Encoder Task", /* name of task. */
5000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&TaskEncoder /* Task handle to keep track of created task */
); /* pin task to core 0 */
xTaskCreatePinnedToCore(
i2cScannerTask, /* Task function. */
"Screen Task", /* name of task. */
5000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&TaskI2CScanner, /* Task handle to keep track of created task */
0); /* pin task to core 0 */

printSpacer();

Expand Down Expand Up @@ -430,54 +436,97 @@ void screenTask(void *pvParameters) {
*
*/
void encoderTask(void *pvParameters) {
int value = 0;
bool btnState = false;
bool pinAState = false;
bool pinBState = false;
bool lastPinAState = false;
bool lastPinBState = false;
bool trigger = false;
unsigned long rotaryEncoderLastButtonPress = 0;
String direction = "";
byte btnArray[] = {encoderSW, expansionBtn1, expansionBtn2, expansionBtn3};

while (true) {
// Read the current state of CLK
rotaryEncoderCurrentStateCLK = pcf8574.digitalRead(encoderPinA);

// If last and current state of CLK are different, then pulse
// occurred React to only 1 state rotaryEncoderChange to avoid double
// count
if (rotaryEncoderCurrentStateCLK != rotaryEncoderLastStateCLK &&
rotaryEncoderCurrentStateCLK == HIGH) {
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (pcf8574.digitalRead(encoderPinB) != rotaryEncoderCurrentStateCLK) {
if (!(rotaryEncoderCurrentDir == "CCW" &&
millis() - rotaryEncoderDebounce < 50)) {
// Encoder is rotating CW so increment
rotaryEncoderCounter++;
rotaryEncoderCurrentDir = "CW";
rotaryEncoderDebounce = millis();
bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
if (isRotaryExpansionConnected) {
// Scan for rotary encoder
pinAState = pcf8574RotaryExpansion.digitalRead(encoderPinA);
pinBState = pcf8574RotaryExpansion.digitalRead(encoderPinB);
if (pinAState != lastPinAState || pinBState != lastPinBState) {
if (pinAState == true && pinBState == true) {
if (lastPinAState == false && lastPinBState == true) {
direction = "CCW";
} else if (lastPinAState == true &&
lastPinBState == false) {
direction = "CW";
}
trigger = true;
} else if (pinAState == false && pinBState == false) {
if (lastPinAState == false && lastPinBState == true) {
direction = "CW";
} else if (lastPinAState == true &&
lastPinBState == false) {
direction = "CCW";
}
trigger = true;
}
} else {
if (!(rotaryEncoderCurrentDir == "CW" &&
millis() - rotaryEncoderDebounce < 50)) {
rotaryEncoderCounter--;
rotaryEncoderCurrentDir = "CCW";
rotaryEncoderDebounce = millis();
bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
lastPinAState = pinAState;
lastPinBState = pinBState;
if (trigger) {
if (direction.equals("CW")) {
bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
} else if (direction.equals("CCW")) {
bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
}
trigger = false;
}
}
Serial.print("Direction: ");
Serial.print(rotaryEncoderCurrentDir);
Serial.print(" | Counter: ");
Serial.println(rotaryEncoderCounter);
}

// Remember last CLK state
rotaryEncoderLastStateCLK = rotaryEncoderCurrentStateCLK;
// Scan for button press
for (int i = 0; i < 4; i++) {
btnState = pcf8574RotaryExpansion.digitalRead(btnArray[i]);
if (btnState == LOW &&
millis() - rotaryEncoderLastButtonPress > 200) {
switch (btnArray[i]) {
case encoderSW:
bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);
break;
case expansionBtn1:
bleKeyboard.write(KEY_MEDIA_NEXT_TRACK);
break;
case expansionBtn2:
bleKeyboard.write(KEY_MEDIA_PREVIOUS_TRACK);
break;
case expansionBtn3:
bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);
break;
}
rotaryEncoderLastButtonPress = millis();
}
}
}

int btnState = pcf8574.digitalRead(encoderSW);
vTaskDelay(3 / portTICK_PERIOD_MS);
}
}

if (btnState == LOW) {
if (millis() - rotaryEncoderLastButtonPress > 50) {
Serial.println("Button pressed!");
bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);
void i2cScannerTask(void *pvParameters) {
while (true) {
byte error;
byte devices[1] = {ENCODER_EXPANSION_ADDR};
for (int i : devices) {
Wire.beginTransmission(devices[i]);
error = Wire.endTransmission();

if (devices[i] == ENCODER_EXPANSION_ADDR) {
if (error == 0)
isRotaryExpansionConnected = true;
else
isRotaryExpansionConnected = false;
}
rotaryEncoderLastButtonPress = millis();
}
vTaskDelay(2 / portTICK_PERIOD_MS);

vTaskDelay(100 / portTICK_PERIOD_MS);
}
}

Expand Down
15 changes: 15 additions & 0 deletions src/main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <U8g2lib.h>
#include <WebServer.h>
#include <WiFi.h>
#include <Wire.h>

#include <algorithm>
#include <animation.hpp>
Expand Down Expand Up @@ -36,6 +37,19 @@ using namespace std;
#define ROWS 5
#define COLS 7

// ====== Expansion Board Pin Definition ======

// Rotary Encoder Expansion Board
#define encoderPinA P5
#define encoderPinB P4
#define encoderSW P6
#define expansionBtn1 P0
#define expansionBtn2 P1
#define expansionBtn3 P2
#define ENCODER_EXPANSION_ADDR 0x38

// ====== End Expansion Board Pin Definition ======

struct Key {
uint8_t keyStroke;
bool state;
Expand All @@ -56,6 +70,7 @@ void generalTask(void *);
void networkTask(void *);
void screenTask(void *);
void ICACHE_RAM_ATTR encoderTask(void *);
void i2cScannerTask(void *);

// Keyboard
void initKeys();
Expand Down

0 comments on commit 8b0c335

Please sign in to comment.