繁体   English   中英

如何使编码器与两个库一起工作?

[英]How to make encoder work with two libraries?

首先,我想说我对 C++ 非常陌生,这就是我在 ESP32 上使用 Arduino 核心和库的原因,我想为您即将在下面看到的垃圾箱火灾道歉。

只需制作带有按钮和编码器的自定义键盘。 启动时,选择两种模式之一:blekeyboard 或 ble midi 控制界面。

该按钮可在两种模式下工作,但编码器仅在最后声明的模式下工作。 (因此在此脚本顺序中,模式 1 blekeyboard 中的编码器和按钮均有效,而模式 2 中只有按钮有效。)

我做错了什么,我能做什么? 欢迎任何有关问题或整体脚本的建议。

先感谢您。

#include <Arduino.h>

#include <BleKeyboard.h>
BleKeyboard bleKeyboard;

#define ESP32
#include <encoder.h>
#include <Control_Surface.h>
#include <MIDI_Interfaces/BluetoothMIDI_Interface.hpp>
BluetoothMIDI_Interface midi;

const int usermodebutton1 = 2;
const int usermodebutton2 = 0;
int usermode = 0;

// ---------------------- mode 2 MIDI Input Elements ------------------------ //

using namespace MIDI_Notes;
NoteButton csButton1 = {
    2,
    note(C, 4),
};
CCRotaryEncoder csEnc1 = {
    {26, 25},     // pins
    MCU::V_POT_1, // MIDI address (CC number + optional channel)
    1,            // optional multiplier if the control isn't fast enough
};

// -------------------------- mode 1 blekeyboard --------------------------- //

int kbutton1 = 2;
int kbutton1State;
int keyInterval = 400000;
Encoder kencoder1(25, 26);
int encInterval = 5000;
TickType_t currentTime;
TickType_t previousTime;
long enc1_oldPos = -999;

// ============================================================================= //

void setup()
{
    pinMode(usermodebutton1, INPUT_PULLUP);
    pinMode(usermodebutton2, INPUT_PULLUP);

    Serial.begin(115200);
    Serial.println("");
    Serial.println("select mode:");

    // ----------------------------------------------------------------------------- //

    while (true)
    {
        if (digitalRead(usermodebutton1) == LOW)
        {
            usermode = 1;
            Serial.println("mode 1 selected");
            break;
        }
        if (digitalRead(usermodebutton2) == LOW)
        {
            usermode = 2;
            Serial.println("mode 2 selected");
            break;
        }
        delay(1000);
    }

    // ----------------------------------------------------------------------------- //

    if (usermode == 1)
    {
        Serial.println("setup mode 1");
        Serial.println("Starting BLE work...");
        bleKeyboard.begin();
        pinMode(kbutton1, INPUT_PULLUP);
        previousTime = 0;
    }
    if (usermode == 2)
    {
        Serial.println("setup mode 2");
        Serial.println("Control Surface BLE starting...");
        RelativeCCSender::setMode(relativeCCmode::TWOS_COMPLEMENT);
        Control_Surface.begin(); // Initialize Control Surface
    }
}

// ============================================================================= //

void loop()
{
    while (usermode == 1)
    {
        while (bleKeyboard.isConnected())
        {
            // mode 1 encoders
            long enc1_newPos = kencoder1.read();
            currentTime = esp_timer_get_time();

            if (enc1_newPos < enc1_oldPos && currentTime - previousTime > encInterval)
            {
                enc1_oldPos = enc1_newPos;
                previousTime = currentTime;
                // bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
                Serial.print("enc1: ");
                Serial.println(enc1_newPos);
            }
            if (enc1_newPos > enc1_oldPos && currentTime - previousTime > encInterval)
            {
                enc1_oldPos = enc1_newPos;
                previousTime = currentTime;
                // bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
                Serial.print("enc1: ");
                Serial.println(enc1_newPos);
            }

            // mode 1 keys
            kbutton1State = digitalRead(kbutton1);
            if (kbutton1State == LOW && currentTime - previousTime > keyInterval)
            {
                previousTime = currentTime;
                Serial.println("button 1 pressed");
                bleKeyboard.print("1");
            }
        }
    }
    while (usermode == 2)
    {
        Control_Surface.loop(); // Refresh all elements
    }
}

首先,您的代码需要进行一般整理。 不要在#include 或#define 部分之后实例化对象。

避免这样做:

#include <BleKeyboard.h>
BleKeyboard bleKeyboard;

#include <MIDI_Interfaces/BluetoothMIDI_Interface.hpp>
BluetoothMIDI_Interface midi;

我通常将我的代码组织为:

// Include libraries
#include <lib1.h>
#include <lib2.h>
...

// Macros
#define SOMETHING_FUNNY value  // see the Macro name in capitals?
#define SOMETHING_USEFUL anothervalue
...

/*
* Variables Section.
* Also, I usually categorize my variables section by type: floats, integers, chars, etc. If I ever use booleans I pack them in a section called 'flags'. Also, if a boolean is used inside an interrupt it should be volatile
*/

Type var_name1 = initial_value;    // the initaliztion is optional
AnotherType var_name2;
...

// Object instantiation
ClassName object1;
AnotherClassName object2 = new AnotherClassName(constructor_parameters);
...

//Setup Function

void setup(){
// Serial Port initialization goes first
Serial.begin(baudrate);

// Initialization routines --> use functions! 

}

void loop(){
// Check for states of your FSM and call the respective function 
}

// Functions definitions

output type myFunction1(args){
// Routine
}

...

其次,您的代码对我大喊“有限状态机”,这基本上是您正在实现的,但不是以传统方式实现的。 请阅读 Nick Gammon 关于 FSM 的精彩教程 这样,您将根据用户的选择或硬件输入枚举您的状态并触发操作或事件,而不会阻塞代码流。

现在,我假设您已经从两个库中读取了 .cpp 文件并检查了它们之间是否没有冲突? 另外,您使用的是哪个encoder.h库? 看起来像 Paul Stoffregen 的图书馆,是吗? 我问是因为他的库在很大程度上基于中断,并且它是用一些 ASM 块编码的,这些块可能没有针对 ESP32 进行优化,但请不要引用我的话。 正如 enhzflep 所说:

我怀疑冲突中断有问题。

我对此完全同意。 如果您正在使用该库,则有一个宏可以挽救您的生命:

#define ENCODER_DO_NOT_USE_INTERRUPTS

这个例子中使用来自图书馆的 repo

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM