Skip to content

Commit

Permalink
Added Knob with rotary encoder
Browse files Browse the repository at this point in the history
  • Loading branch information
Lillifee committed Nov 20, 2020
1 parent 21a817b commit a963bcd
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 46 deletions.
69 changes: 29 additions & 40 deletions data/bundle.js

Large diffs are not rendered by default.

133 changes: 133 additions & 0 deletions lib/Knob/KnobHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#include "KnobHelper.h"
AiEsp32RotaryEncoder rotary = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN);

void KnobHelperClass::read() {
preferences.begin("knob", true);
host = preferences.getString("host");
port = preferences.getInt("port", 3333);
preferences.end();
}

void KnobHelperClass::write() {
preferences.begin("knob", false);
preferences.putString("host", host);
preferences.putInt("port", port);
preferences.end();
}

void KnobHelperClass::setup() {
unsigned long setupStartTime = millis();
Serial.println("Setup Knob helper");

read();

//we must initialize rorary encoder
rotary.begin();
rotary.setup([] { rotary.readEncoder_ISR(); });

rotary.setBoundaries(0, 100, false);
//optionally we can set boundaries and if values should cycle or not
// rotary.setBoundaries(0, 10, true); //minValue, maxValue, cycle values (when max go to min and vice versa)

setupDuration = millis() - setupStartTime;
Serial.print("Setup knob helper took ");
Serial.println(setupDuration);
}

void KnobHelperClass::loop() {
readValues();
sendValues();
}

void KnobHelperClass::sleep() {
}

void KnobHelperClass::readValues() {
// Serial.println("Read knob");
prevValue = value;
pressed = false;

//first lets handle rotary encoder button click
if (rotary.currentButtonState() == BUT_RELEASED) {
pressed = true;
Serial.println("Button Pressed");
}

//lets see if anything changed
//optionally we can ignore whenever there is no change
int16_t encoderDelta = rotary.encoderChanged();
if (encoderDelta == 0) return;

//if value is changed compared to our last read
if (encoderDelta != 0) {
//now we need current value

value = rotary.readEncoder();

//process new value. Here is simple output.
Serial.print("Value: ");
Serial.println(value);
}
}

void KnobHelperClass::sendValues() {
if (value == prevValue && !pressed) return;
if (host.length() == 0) return;
if (!WiFiHelper.connect()) return;
unsigned long requestStartTime = millis();

StaticJsonDocument<32> doc;

udp.beginPacket(host.c_str(), port);

doc["value"] = value;
doc["pressed"] = pressed;
serializeJson(doc, udp);

udp.println();
udp.endPacket();

requestDuration = millis() - requestStartTime;
Serial.print("Send UDP request ");
Serial.println(requestDuration);
}

void KnobHelperClass::server() {
Serial.println("Setup Knob server");

WebServerHelper.server.on("/api/knob", HTTP_GET, [this](AsyncWebServerRequest *request) {
int args = request->args();

if (args > 0) {
request->send(200, "text/plain", "message received");
Serial.println("Update knob settings");

if (request->hasArg("host")) host = request->arg("host");
if (request->hasArg("port")) port = request->arg("port").toInt();
// if (request->hasArg("duration")) duration = request->arg("duration").toInt();
// if (request->hasArg("threshold")) threshold = request->arg("threshold").toInt();

write();

} else {
AsyncJsonResponse *response = new AsyncJsonResponse();
response->addHeader("Server", "ESP Async Web Server");
JsonVariant &root = response->getRoot();

root["value"] = value;
root["setupDuration"] = setupDuration;
root["requestDuration"] = requestDuration;

root["host"] = host;
root["port"] = port;

// root["duration"] = duration;
// root["threshold"] = threshold;

response->setLength();
request->send(response);
}
});
}

KnobHelperClass KnobHelper;
61 changes: 61 additions & 0 deletions lib/Knob/KnobHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

#ifndef MpuHelper_h
#define MpuHelper_h

#include "AiEsp32RotaryEncoder.h"
#include "ArduinoJson.h"
#include "AsyncJson.h"
#include "I2Cdev.h"
#include "MPU6050.h"
#include "WebServerHelper.h"
#include "WiFiUdp.h"
#include "Wire.h"

/*
connecting Rotary encoder
CLK (A pin) - to any microcontroler intput pin with interrupt -> in this example pin 32
DT (B pin) - to any microcontroler intput pin with interrupt -> in this example pin 21
SW (button pin) - to any microcontroler intput pin -> in this example pin 25
VCC - to microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1) or in this example pin 25
GND - to microcontroler GND
*/
#define ROTARY_ENCODER_A_PIN 15
#define ROTARY_ENCODER_B_PIN 4
#define ROTARY_ENCODER_BUTTON_PIN 13
#define ROTARY_ENCODER_VCC_PIN -1 /*put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
#define ROTARY_ENCODER_TEST_LIMITS = 2;

class KnobHelperClass {
private:
WiFiUDP udp;
Preferences preferences;

String host;
int32_t port;

void read();
void write();

void readValues();
void sendValues();

unsigned long requestDuration;
unsigned long setupDuration;

int threshold;
int testlimits = 2;

public:
int16_t value;
int16_t prevValue;
bool pressed;

void setup();
void server();
void loop();
void sleep();
};

extern KnobHelperClass KnobHelper;

#endif
4 changes: 4 additions & 0 deletions lib/Knob/library.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "KnobHelper",
"version": "1.0.0"
}
15 changes: 9 additions & 6 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ board_build.partitions = partitions_custom.csv
;lib_deps = FS, ESP Async WebServer, ArduinoJson, ESPAsyncTCP, Update, MH-Z19, Adafruit BME680 Library

; ---- BSEC Software build flags with CO2 ----
src_filter = +<co2.cpp>
lib_deps = FS, ESP Async WebServer, ArduinoJson, ESPAsyncTCP, Update, MH-Z19, BSEC Software Library
build_flags =
-I .pio/libdeps/BSECSoftwareLibrary/src/bme680
-L .pio/libdeps/BSECSoftwareLibrary/src/esp32
-lalgobsec
; src_filter = +<co2.cpp>
; lib_deps = FS, ESP Async WebServer, ArduinoJson, ESPAsyncTCP, Update, MH-Z19, BSEC Software Library
; build_flags =
; -I .pio/libdeps/BSECSoftwareLibrary/src/bme680
; -L .pio/libdeps/BSECSoftwareLibrary/src/esp32
; -lalgobsec

; ---- Waveshare display ----
; src_filter = +<display.cpp>
; lib_deps = FS, ESP Async WebServer, ArduinoJson, ESPAsyncTCP, Update, GxEPD2, U8g2_for_Adafruit_GFX

; ---- Knob ----
src_filter = +<knob.cpp>
lib_deps = FS, ESP Async WebServer, ArduinoJson, ESPAsyncTCP, Update, igorantolic/Ai Esp32 Rotary Encoder @ ^1.0
54 changes: 54 additions & 0 deletions src/knob.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "KnobHelper.h"
#include "WebServerHelper.h"
#include "WifiHelper.h"

unsigned long sleepTime;
RTC_DATA_ATTR int bootCount = 0;

void deepSleep() {
WiFiHelper.sleep();
KnobHelper.sleep();

Serial.println("sleep");
esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);
esp_deep_sleep_start();
}

void setup() {
++bootCount;
setCpuFrequencyMhz(80);

Serial.begin(115200);
Serial.print("bootCount ");
Serial.println(String(bootCount));

WiFiHelper.setup();
KnobHelper.setup();

if (bootCount == 1) {
pinMode(LED_BUILTIN, OUTPUT);

WiFiHelper.server();
KnobHelper.server();

WebServerHelper.onSleep(deepSleep);
WebServerHelper.start();
} else if (!WiFiHelper.connect()) {
deepSleep();
}

sleepTime = millis() + 2000;
}

void loop() {
KnobHelper.loop();
delay(50);

if (bootCount != 1) {
if (KnobHelper.value != KnobHelper.prevValue)
sleepTime = millis() + 2000;

if (millis() >= sleepTime)
deepSleep();
}
}

0 comments on commit a963bcd

Please sign in to comment.