v0.6.262
This commit is contained in:
@@ -45,5 +45,7 @@
|
|||||||
\
|
\
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||

|
\
|
||||||
|
\
|
||||||
|

|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ _\** GPIO 16 and 17 are used by PSRAM on the WROVER modules._
|
|||||||
---
|
---
|
||||||
## Dependencies
|
## Dependencies
|
||||||
#### Libraries:
|
#### Libraries:
|
||||||
**Library Manager**: Adafruit_GFX, Adafruit_ST7735\*, Adafruit_SSD1306\*, Adafruit_PCD8544\*, Adafruit_SH110X\*, Adafruit_SSD1327\*, Adafruit_ILI9341\*, Adafruit_SSD1305\*, (\* depending on display model), ESP32Encoder, OneButton, IRremoteESP8266, XPT2046_Touchscreen \
|
**Library Manager**: Adafruit_GFX, Adafruit_ST7735\*, Adafruit_SSD1306\*, Adafruit_PCD8544\*, Adafruit_SH110X\*, Adafruit_SSD1327\*, Adafruit_ILI9341\*, Adafruit_SSD1305\*, (\* depending on display model), OneButton, IRremoteESP8266, XPT2046_Touchscreen \
|
||||||
**Github**: [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer), [AsyncTCP](https://github.com/me-no-dev/AsyncTCP), [async-mqtt-client](https://github.com/marvinroger/async-mqtt-client)* \
|
**Github**: [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer), [AsyncTCP](https://github.com/me-no-dev/AsyncTCP), [async-mqtt-client](https://github.com/marvinroger/async-mqtt-client)* \
|
||||||
\* _if you need MQTT support_
|
\* _if you need MQTT support_
|
||||||
|
|
||||||
@@ -291,6 +291,12 @@ Work is in progress...
|
|||||||
|
|
||||||
---
|
---
|
||||||
## Version history
|
## Version history
|
||||||
|
#### v0.6.262
|
||||||
|
- change encoder library to [ai-esp32-rotary-encoder](https://github.com/igorantolic/ai-esp32-rotary-encoder) (injected to project)
|
||||||
|
- added new option VOL_ACCELERATION - volume adjustment acceleration by encoder (see [myoptions.h](exsamples/myoptions.h) for exsample)
|
||||||
|
- fixed connection error with http-stations on esp32-core v2.0.3
|
||||||
|
- fixed css errors (a [full update](#update-over-web-interface) is required)
|
||||||
|
|
||||||
#### v0.6.250
|
#### v0.6.250
|
||||||
- added update via web-interface \
|
- added update via web-interface \
|
||||||
**Attention! Full firmware with chip re-partitioning is required!** see [board setup example](#quick-start)
|
**Attention! Full firmware with chip re-partitioning is required!** see [board setup example](#quick-start)
|
||||||
|
|||||||
@@ -54,13 +54,15 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
//#define ENC2_BTNB 255 /* Encoder button */
|
//#define ENC2_BTNB 255 /* Encoder button */
|
||||||
//#define ENC2_BTNR 255 /* Right rotation */
|
//#define ENC2_BTNR 255 /* Right rotation */
|
||||||
//#define ENC2_INTERNALPULLUP true /* Enable the weak pull up resistors */
|
//#define ENC2_INTERNALPULLUP true /* Enable the weak pull up resistors */
|
||||||
//#define ENC2_HALFQUARD true /* Experiment with it */
|
//#define ENC2_HALFQUARD false /* (true, false, 255) Experiment with it */
|
||||||
/******************************************/
|
/******************************************/
|
||||||
|
|
||||||
/* BUTTONS */
|
/* BUTTONS */
|
||||||
//#define BTN_LEFT 255 /* VolDown, Prev */
|
//#define BTN_LEFT 255 /* VolDown, Prev */
|
||||||
//#define BTN_CENTER 255 /* Play, Stop, Show playlist */
|
//#define BTN_CENTER 255 /* Play, Stop, Show playlist */
|
||||||
//#define BTN_RIGHT 255 /* VolUp, Next */
|
//#define BTN_RIGHT 255 /* VolUp, Next */
|
||||||
|
//#define BTN_UP 255 /* Prev, Move Up */
|
||||||
|
//#define BTN_DOWN 255 /* Next, Move Down */
|
||||||
//#define BTN_INTERNALPULLUP true /* Enable the weak pull up resistors */
|
//#define BTN_INTERNALPULLUP true /* Enable the weak pull up resistors */
|
||||||
//#define BTN_LONGPRESS_LOOP_DELAY 200 /* Delay between calling DuringLongPress event */
|
//#define BTN_LONGPRESS_LOOP_DELAY 200 /* Delay between calling DuringLongPress event */
|
||||||
//#define BTN_CLICK_TICKS 300 /* Event Timing https://github.com/mathertel/OneButton#event-timing */
|
//#define BTN_CLICK_TICKS 300 /* Event Timing https://github.com/mathertel/OneButton#event-timing */
|
||||||
@@ -100,6 +102,7 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
//#define TFT_CONTRAST 55 /* Nokia 5110 contrast */
|
//#define TFT_CONTRAST 55 /* Nokia 5110 contrast */
|
||||||
//#define TFT_INVERT true /* Invert the display colors (usually true) */
|
//#define TFT_INVERT true /* Invert the display colors (usually true) */
|
||||||
//#define VOL_STEP 1 /* Volume control step */
|
//#define VOL_STEP 1 /* Volume control step */
|
||||||
|
//#define VOL_ACCELERATION 200 /* Encoder vol acceleration; 0 or 1 means disabled acceleration */
|
||||||
//#define MUTE_PIN 255 /* MUTE Pin */
|
//#define MUTE_PIN 255 /* MUTE Pin */
|
||||||
//#define MUTE_VAL HIGH /* Write this to MUTE_PIN when player is stopped */
|
//#define MUTE_VAL HIGH /* Write this to MUTE_PIN when player is stopped */
|
||||||
//#define PL_WITH_NUMBERS /* show the number of station in the playlist */
|
//#define PL_WITH_NUMBERS /* show the number of station in the playlist */
|
||||||
@@ -129,4 +132,9 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
//#define IR_CODE_NUM9 0xFF5AA5
|
//#define IR_CODE_NUM9 0xFF5AA5
|
||||||
//#define IR_CODE_HASH 0xFF52AD /* Toggle playlist mode */
|
//#define IR_CODE_HASH 0xFF52AD /* Toggle playlist mode */
|
||||||
//#define IR_CODE_AST 0xFF42BD /* Not used */
|
//#define IR_CODE_AST 0xFF42BD /* Not used */
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
BIN
images/img23.jpg
Normal file
BIN
images/img23.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
@@ -16,13 +16,28 @@ OneButton button[] {{BTN_LEFT, true, BTN_INTERNALPULLUP}, {BTN_CENTER, true, BTN
|
|||||||
constexpr uint8_t nrOfButtons = sizeof(button) / sizeof(button[0]);
|
constexpr uint8_t nrOfButtons = sizeof(button) / sizeof(button[0]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENC_HALFQUARD==false
|
||||||
|
#define ENCODER_STEPS 4
|
||||||
|
#elif ENC_HALFQUARD==true
|
||||||
|
#define ENCODER_STEPS 2
|
||||||
|
#elif ENC_HALFQUARD==255
|
||||||
|
#define ENCODER_STEPS 1
|
||||||
|
#endif
|
||||||
|
#if ENC2_HALFQUARD==false
|
||||||
|
#define ENCODER2_STEPS 4
|
||||||
|
#elif ENC2_HALFQUARD==true
|
||||||
|
#define ENCODER2_STEPS 2
|
||||||
|
#elif ENC2_HALFQUARD==255
|
||||||
|
#define ENCODER2_STEPS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (ENC_BTNL!=255 && ENC_BTNR!=255) || (ENC2_BTNL!=255 && ENC2_BTNR!=255)
|
#if (ENC_BTNL!=255 && ENC_BTNR!=255) || (ENC2_BTNL!=255 && ENC2_BTNR!=255)
|
||||||
#include <ESP32Encoder.h>
|
#include "src/yoEncoder/yoEncoder.h"
|
||||||
#if (ENC_BTNL!=255 && ENC_BTNR!=255)
|
#if (ENC_BTNL!=255 && ENC_BTNR!=255)
|
||||||
ESP32Encoder encoder;
|
yoEncoder encoder = yoEncoder(ENC_BTNL, ENC_BTNR, ENCODER_STEPS, ENC_INTERNALPULLUP);
|
||||||
#endif
|
#endif
|
||||||
#if (ENC2_BTNL!=255 && ENC2_BTNR!=255)
|
#if (ENC2_BTNL!=255 && ENC2_BTNR!=255)
|
||||||
ESP32Encoder encoder2;
|
yoEncoder encoder2 = yoEncoder(ENC2_BTNL, ENC2_BTNR, ENCODER2_STEPS, ENC2_INTERNALPULLUP);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -50,23 +65,34 @@ IRrecv irrecv(IR_PIN, kCaptureBufferSize, kTimeout, true);
|
|||||||
decode_results irResults;
|
decode_results irResults;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void initControls() {
|
|
||||||
#if ENC_BTNL!=255
|
#if ENC_BTNL!=255
|
||||||
encoder.useInternalWeakPullResistors = ENC_INTERNALPULLUP ? UP : DOWN;
|
void IRAM_ATTR readEncoderISR()
|
||||||
if (ENC_HALFQUARD) {
|
{
|
||||||
encoder.attachHalfQuad(ENC_BTNL, ENC_BTNR);
|
encoder.readEncoder_ISR();
|
||||||
} else {
|
|
||||||
encoder.attachFullQuad(ENC_BTNL, ENC_BTNR);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if ENC2_BTNL!=255
|
#if ENC2_BTNL!=255
|
||||||
encoder2.useInternalWeakPullResistors = ENC2_INTERNALPULLUP ? UP : DOWN;
|
void IRAM_ATTR readEncoder2ISR()
|
||||||
if (ENC2_HALFQUARD) {
|
{
|
||||||
encoder2.attachHalfQuad(ENC2_BTNL, ENC2_BTNR);
|
encoder2.readEncoder_ISR();
|
||||||
} else {
|
|
||||||
encoder2.attachFullQuad(ENC2_BTNL, ENC2_BTNR);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void initControls() {
|
||||||
|
|
||||||
|
#if ENC_BTNL!=255
|
||||||
|
encoder.begin();
|
||||||
|
encoder.setup(readEncoderISR);
|
||||||
|
encoder.setBoundaries(0, 254, true);
|
||||||
|
encoder.setAcceleration(VOL_ACCELERATION);
|
||||||
|
#endif
|
||||||
|
#if ENC2_BTNL!=255
|
||||||
|
encoder2.begin();
|
||||||
|
encoder2.setup(readEncoder2ISR);
|
||||||
|
encoder2.setBoundaries(0, 254, true);
|
||||||
|
encoder2.setAcceleration(VOL_ACCELERATION);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ISPUSHBUTTONS
|
#if ISPUSHBUTTONS
|
||||||
for (int i = 0; i < nrOfButtons; i++)
|
for (int i = 0; i < nrOfButtons; i++)
|
||||||
{
|
{
|
||||||
@@ -134,30 +160,28 @@ void loopControls() {
|
|||||||
|
|
||||||
#if ENC_BTNL!=255
|
#if ENC_BTNL!=255
|
||||||
void encoderLoop() {
|
void encoderLoop() {
|
||||||
long encNewPosition = encoder.getCount() / 2;
|
int8_t encoderDelta = encoder.encoderChanged();
|
||||||
if (encNewPosition != 0 && encNewPosition != encOldPosition) {
|
if (encoderDelta!=0)
|
||||||
encOldPosition = encNewPosition;
|
{
|
||||||
encoder.setCount(0);
|
controlsEvent(encoderDelta > 0, encoderDelta);
|
||||||
controlsEvent(encNewPosition > 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENC2_BTNL!=255
|
#if ENC2_BTNL!=255
|
||||||
void encoder2Loop() {
|
void encoder2Loop() {
|
||||||
long encNewPosition = encoder2.getCount() / 2;
|
int8_t encoderDelta = encoder2.encoderChanged();
|
||||||
if (encNewPosition != 0 && encNewPosition != enc2OldPosition) {
|
if (encoderDelta!=0)
|
||||||
enc2OldPosition = encNewPosition;
|
{
|
||||||
encoder2.setCount(0);
|
|
||||||
uint8_t bp = 2;
|
uint8_t bp = 2;
|
||||||
if (ENC2_BTNB != 255) {
|
if (ENC2_BTNB != 255) {
|
||||||
bp = digitalRead(ENC2_BTNB);
|
bp = digitalRead(ENC2_BTNB);
|
||||||
}
|
}
|
||||||
if (bp == HIGH && display.mode == PLAYER) {
|
if (bp == HIGH && display.mode == PLAYER) {
|
||||||
display.putRequest({NEWMODE, STATIONS});
|
display.putRequest({NEWMODE, STATIONS});
|
||||||
while(display.mode != STATIONS) {delay(5);}
|
while(display.mode != STATIONS) {delay(10);}
|
||||||
}
|
}
|
||||||
controlsEvent(encNewPosition > 0);
|
controlsEvent(encoderDelta > 0, encoderDelta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -474,15 +498,22 @@ void onBtnDuringLongPress(int id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void controlsEvent(bool toRight) {
|
void controlsEvent(bool toRight, int8_t volDelta) {
|
||||||
if (display.mode == NUMBERS) {
|
if (display.mode == NUMBERS) {
|
||||||
display.numOfNextStation = 0;
|
display.numOfNextStation = 0;
|
||||||
display.putRequest({NEWMODE, PLAYER});
|
display.putRequest({NEWMODE, PLAYER});
|
||||||
}
|
}
|
||||||
if (display.mode != STATIONS) {
|
if (display.mode != STATIONS) {
|
||||||
display.putRequest({NEWMODE, VOL});
|
display.putRequest({NEWMODE, VOL});
|
||||||
|
if(volDelta!=0){
|
||||||
|
int nv = config.store.volume+volDelta;
|
||||||
|
if(nv<0) nv=0;
|
||||||
|
if(nv>254) nv=254;
|
||||||
|
player.setVol((byte)nv, false);
|
||||||
|
}else{
|
||||||
player.stepVol(toRight);
|
player.stepVol(toRight);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (display.mode == STATIONS) {
|
if (display.mode == STATIONS) {
|
||||||
display.resetQueue();
|
display.resetQueue();
|
||||||
display.putRequest({DRAWPLAYLIST, toRight});
|
display.putRequest({DRAWPLAYLIST, toRight});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ void irLoop();
|
|||||||
void touchLoop();
|
void touchLoop();
|
||||||
void irNum(byte num);
|
void irNum(byte num);
|
||||||
void irBlink();
|
void irBlink();
|
||||||
void controlsEvent(bool toRight);
|
void controlsEvent(bool toRight, int8_t volDelta = 0);
|
||||||
|
|
||||||
void onBtnClick(int id);
|
void onBtnClick(int id);
|
||||||
void onBtnDoubleClick(int id);
|
void onBtnDoubleClick(int id);
|
||||||
|
|||||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
#ifndef options_h
|
#ifndef options_h
|
||||||
#define options_h
|
#define options_h
|
||||||
|
|
||||||
#define VERSION "0.6.250"
|
#define VERSION "0.6.262"
|
||||||
|
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
DO NOT EDIT THIS FILE.
|
DO NOT EDIT THIS FILE.
|
||||||
@@ -100,7 +100,7 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
#define ENC_INTERNALPULLUP true
|
#define ENC_INTERNALPULLUP true
|
||||||
#endif
|
#endif
|
||||||
#ifndef ENC_HALFQUARD
|
#ifndef ENC_HALFQUARD
|
||||||
#define ENC_HALFQUARD true
|
#define ENC_HALFQUARD false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ENC2_BTNL
|
#ifndef ENC2_BTNL
|
||||||
@@ -116,7 +116,7 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
#define ENC2_INTERNALPULLUP true
|
#define ENC2_INTERNALPULLUP true
|
||||||
#endif
|
#endif
|
||||||
#ifndef ENC2_HALFQUARD
|
#ifndef ENC2_HALFQUARD
|
||||||
#define ENC2_HALFQUARD true
|
#define ENC2_HALFQUARD false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BUTTONS */
|
/* BUTTONS */
|
||||||
@@ -197,6 +197,9 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
|||||||
#ifndef VOL_STEP
|
#ifndef VOL_STEP
|
||||||
#define VOL_STEP 1 // Encoder vol step
|
#define VOL_STEP 1 // Encoder vol step
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef VOL_ACCELERATION
|
||||||
|
#define VOL_ACCELERATION 200 // Encoder vol acceleration; 0 or 1 means disabled acceleration
|
||||||
|
#endif
|
||||||
#ifndef MUTE_PIN
|
#ifndef MUTE_PIN
|
||||||
#define MUTE_PIN 255 // MUTE Pin
|
#define MUTE_PIN 255 // MUTE Pin
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ esp_err_t Audio::I2Sstop(uint8_t i2s_num) {
|
|||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
esp_err_t Audio::i2s_mclk_pin_select(const uint8_t pin) {
|
esp_err_t Audio::i2s_mclk_pin_select(const uint8_t pin) {
|
||||||
if(pin != 0 && pin != 1 && pin != 3) {
|
if(pin != 0 && pin != 1 && pin != 3) {
|
||||||
ESP_LOGE(TAG, "Only support GPIO0/GPIO1/GPIO3, gpio_num:%d", pin);
|
//ESP_LOGE(TAG, "Only support GPIO0/GPIO1/GPIO3, gpio_num:%d", pin);
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
switch(pin){
|
switch(pin){
|
||||||
@@ -348,7 +348,7 @@ void Audio::httpPrint(const char* url) {
|
|||||||
strcat(resp, " HTTP/1.1\r\n");
|
strcat(resp, " HTTP/1.1\r\n");
|
||||||
strcat(resp, "Host: ");
|
strcat(resp, "Host: ");
|
||||||
strcat(resp, host);
|
strcat(resp, host);
|
||||||
strcat(resp, "\r\nUser-Agent: ESP32 audioI2S\r\n");
|
strcat(resp, "\r\nUser-Agent: Mozilla/5.0\r\n");
|
||||||
strcat(resp, "icy-metadata: 1\r\n");
|
strcat(resp, "icy-metadata: 1\r\n");
|
||||||
strcat(resp, "Accept-Encoding: identity\r\n");
|
strcat(resp, "Accept-Encoding: identity\r\n");
|
||||||
strcat(resp, "Connection: Keep-Alive\r\n\r\n");
|
strcat(resp, "Connection: Keep-Alive\r\n\r\n");
|
||||||
@@ -522,7 +522,7 @@ bool Audio::connecttohost(const char* host, const char* user, const char* pwd) {
|
|||||||
// strcat(resp, "Transfer-Encoding: \r\n"); // otherwise the server assumes gzip compression
|
// strcat(resp, "Transfer-Encoding: \r\n"); // otherwise the server assumes gzip compression
|
||||||
strcat(resp, "Connection: keep-alive\r\n\r\n");
|
strcat(resp, "Connection: keep-alive\r\n\r\n");
|
||||||
|
|
||||||
const uint32_t TIMEOUT_MS{350};
|
const uint32_t TIMEOUT_MS{3700};
|
||||||
uint32_t wtf;
|
uint32_t wtf;
|
||||||
if(m_f_ssl == false) {
|
if(m_f_ssl == false) {
|
||||||
uint32_t t = millis();
|
uint32_t t = millis();
|
||||||
|
|||||||
@@ -1640,7 +1640,7 @@ bool Audio::connecttohost(const char* host, const char* user, const char* pwd) {
|
|||||||
strcat(resp, "\r\n");
|
strcat(resp, "\r\n");
|
||||||
strcat(resp, "Connection: keep-alive\r\n\r\n");
|
strcat(resp, "Connection: keep-alive\r\n\r\n");
|
||||||
|
|
||||||
const uint32_t TIMEOUT_MS{350};
|
const uint32_t TIMEOUT_MS{3700};
|
||||||
uint32_t wtf;
|
uint32_t wtf;
|
||||||
if(m_f_ssl == false) {
|
if(m_f_ssl == false) {
|
||||||
uint32_t t = millis();
|
uint32_t t = millis();
|
||||||
|
|||||||
151
yoRadio/src/yoEncoder/yoEncoder.cpp
Normal file
151
yoRadio/src/yoEncoder/yoEncoder.cpp
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
// based on https://github.com/igorantolic/ai-esp32-rotary-encoder code
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
#define LOG_TAG "yoEncoder"
|
||||||
|
|
||||||
|
#include "yoEncoder.h"
|
||||||
|
|
||||||
|
void IRAM_ATTR yoEncoder::readEncoder_ISR()
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned long now = millis();
|
||||||
|
portENTER_CRITICAL_ISR(&(this->mux));
|
||||||
|
if (this->isEnabled)
|
||||||
|
{
|
||||||
|
// code from https://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino/
|
||||||
|
/**/
|
||||||
|
this->old_AB <<= 2; //remember previous state
|
||||||
|
|
||||||
|
int8_t ENC_PORT = ((digitalRead(this->encoderBPin)) ? (1 << 1) : 0) | ((digitalRead(this->encoderAPin)) ? (1 << 0) : 0);
|
||||||
|
|
||||||
|
this->old_AB |= (ENC_PORT & 0x03); //add current state
|
||||||
|
|
||||||
|
//this->encoder0Pos += ( this->enc_states[( this->old_AB & 0x0f )]);
|
||||||
|
int8_t currentDirection = (this->enc_states[(this->old_AB & 0x0f)]); //-1,0 or 1
|
||||||
|
|
||||||
|
if (currentDirection != 0)
|
||||||
|
{
|
||||||
|
long prevRotaryPosition = this->encoder0Pos / this->encoderSteps;
|
||||||
|
this->encoder0Pos += currentDirection;
|
||||||
|
long newRotaryPosition = this->encoder0Pos / this->encoderSteps;
|
||||||
|
|
||||||
|
if (newRotaryPosition != prevRotaryPosition && rotaryAccelerationCoef > 1)
|
||||||
|
{
|
||||||
|
//additional movements cause acceleration?
|
||||||
|
// at X ms, there should be no acceleration.
|
||||||
|
unsigned long accelerationLongCutoffMillis = 200;
|
||||||
|
// at Y ms, we want to have maximum acceleration
|
||||||
|
unsigned long accelerationShortCutffMillis = 4;
|
||||||
|
|
||||||
|
// compute linear acceleration
|
||||||
|
if (currentDirection == lastMovementDirection &&
|
||||||
|
currentDirection != 0 &&
|
||||||
|
lastMovementDirection != 0)
|
||||||
|
{
|
||||||
|
// ... but only of the direction of rotation matched and there
|
||||||
|
// actually was a previous rotation.
|
||||||
|
unsigned long millisAfterLastMotion = now - lastMovementAt;
|
||||||
|
|
||||||
|
if (millisAfterLastMotion < accelerationLongCutoffMillis)
|
||||||
|
{
|
||||||
|
if (millisAfterLastMotion < accelerationShortCutffMillis)
|
||||||
|
{
|
||||||
|
millisAfterLastMotion = accelerationShortCutffMillis; // limit to maximum acceleration
|
||||||
|
}
|
||||||
|
if (currentDirection > 0)
|
||||||
|
{
|
||||||
|
this->encoder0Pos += rotaryAccelerationCoef / millisAfterLastMotion;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->encoder0Pos -= rotaryAccelerationCoef / millisAfterLastMotion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->lastMovementAt = now;
|
||||||
|
this->lastMovementDirection = currentDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//respect limits
|
||||||
|
if (this->encoder0Pos > (this->_maxEncoderValue))
|
||||||
|
this->encoder0Pos = this->_circleValues ? this->_minEncoderValue : this->_maxEncoderValue;
|
||||||
|
if (this->encoder0Pos < (this->_minEncoderValue))
|
||||||
|
this->encoder0Pos = this->_circleValues ? this->_maxEncoderValue : this->_minEncoderValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL_ISR(&(this->mux));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
yoEncoder::yoEncoder(uint8_t encoder_APin, uint8_t encoder_BPin, uint8_t encoderSteps, bool internalPullup)
|
||||||
|
{
|
||||||
|
this->old_AB = 0;
|
||||||
|
|
||||||
|
this->encoderAPin = encoder_APin;
|
||||||
|
this->encoderBPin = encoder_BPin;
|
||||||
|
this->encoderSteps = encoderSteps;
|
||||||
|
|
||||||
|
pinMode(this->encoderAPin, internalPullup?INPUT_PULLUP:INPUT_PULLDOWN);
|
||||||
|
pinMode(this->encoderBPin, internalPullup?INPUT_PULLUP:INPUT_PULLDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void yoEncoder::setBoundaries(long minEncoderValue, long maxEncoderValue, bool circleValues)
|
||||||
|
{
|
||||||
|
this->_minEncoderValue = minEncoderValue * this->encoderSteps;
|
||||||
|
this->_maxEncoderValue = maxEncoderValue * this->encoderSteps;
|
||||||
|
|
||||||
|
this->_circleValues = circleValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
long yoEncoder::readEncoder()
|
||||||
|
{
|
||||||
|
return (this->encoder0Pos / this->encoderSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void yoEncoder::setEncoderValue(long newValue)
|
||||||
|
{
|
||||||
|
reset(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
long yoEncoder::encoderChanged()
|
||||||
|
{
|
||||||
|
long _encoder0Pos = readEncoder();
|
||||||
|
long encoder0Diff = _encoder0Pos - this->lastReadEncoder0Pos;
|
||||||
|
|
||||||
|
this->lastReadEncoder0Pos = _encoder0Pos;
|
||||||
|
|
||||||
|
return encoder0Diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void yoEncoder::setup(void (*ISR_callback)(void))
|
||||||
|
{
|
||||||
|
attachInterrupt(digitalPinToInterrupt(this->encoderAPin), ISR_callback, CHANGE);
|
||||||
|
attachInterrupt(digitalPinToInterrupt(this->encoderBPin), ISR_callback, CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void yoEncoder::begin()
|
||||||
|
{
|
||||||
|
this->lastReadEncoder0Pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void yoEncoder::reset(long newValue_)
|
||||||
|
{
|
||||||
|
newValue_ = newValue_ * this->encoderSteps;
|
||||||
|
this->encoder0Pos = newValue_;
|
||||||
|
this->lastReadEncoder0Pos = this->encoder0Pos;
|
||||||
|
if (this->encoder0Pos > this->_maxEncoderValue)
|
||||||
|
this->encoder0Pos = this->_circleValues ? this->_minEncoderValue : this->_maxEncoderValue;
|
||||||
|
if (this->encoder0Pos < this->_minEncoderValue)
|
||||||
|
this->encoder0Pos = this->_circleValues ? this->_maxEncoderValue : this->_minEncoderValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void yoEncoder::enable()
|
||||||
|
{
|
||||||
|
this->isEnabled = true;
|
||||||
|
}
|
||||||
|
void yoEncoder::disable()
|
||||||
|
{
|
||||||
|
this->isEnabled = false;
|
||||||
|
}
|
||||||
68
yoRadio/src/yoEncoder/yoEncoder.h
Normal file
68
yoRadio/src/yoEncoder/yoEncoder.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// yoEncoder.h
|
||||||
|
// based on https://github.com/igorantolic/ai-esp32-rotary-encoder code
|
||||||
|
|
||||||
|
#ifndef _YOENCODER_h
|
||||||
|
#define _YOENCODER_h
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
BUT_DOWN = 0,
|
||||||
|
BUT_PUSHED = 1,
|
||||||
|
BUT_UP = 2,
|
||||||
|
BUT_RELEASED = 3,
|
||||||
|
BUT_DISABLED = 99,
|
||||||
|
} ButtonState;
|
||||||
|
|
||||||
|
class yoEncoder
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
portMUX_TYPE buttonMux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
volatile long encoder0Pos = 0;
|
||||||
|
|
||||||
|
volatile int8_t lastMovementDirection = 0; //1 right; -1 left
|
||||||
|
volatile unsigned long lastMovementAt = 0;
|
||||||
|
unsigned long rotaryAccelerationCoef = 150;
|
||||||
|
|
||||||
|
bool _circleValues = false;
|
||||||
|
bool isEnabled = true;
|
||||||
|
|
||||||
|
uint8_t encoderAPin;
|
||||||
|
uint8_t encoderBPin;
|
||||||
|
long encoderSteps;
|
||||||
|
|
||||||
|
long _minEncoderValue = -1 << 15;
|
||||||
|
long _maxEncoderValue = 1 << 15;
|
||||||
|
|
||||||
|
uint8_t old_AB;
|
||||||
|
long lastReadEncoder0Pos;
|
||||||
|
|
||||||
|
int8_t enc_states[16] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
|
||||||
|
void (*ISR_callback)();
|
||||||
|
|
||||||
|
public:
|
||||||
|
yoEncoder(
|
||||||
|
uint8_t encoderAPin,
|
||||||
|
uint8_t encoderBPin,
|
||||||
|
uint8_t encoderSteps,
|
||||||
|
bool internalPullup = true);
|
||||||
|
void setBoundaries(long minValue = -100, long maxValue = 100, bool circleValues = false);
|
||||||
|
void IRAM_ATTR readEncoder_ISR();
|
||||||
|
|
||||||
|
void setup(void (*ISR_callback)(void));
|
||||||
|
void begin();
|
||||||
|
void reset(long newValue = 0);
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
long readEncoder();
|
||||||
|
void setEncoderValue(long newValue);
|
||||||
|
long encoderChanged();
|
||||||
|
|
||||||
|
unsigned long getAcceleration() { return this->rotaryAccelerationCoef; }
|
||||||
|
void setAcceleration(unsigned long acceleration) { this->rotaryAccelerationCoef = acceleration; }
|
||||||
|
void disableAcceleration() { setAcceleration(0); }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user