首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让编码器与两个库协同工作?

如何让编码器与两个库协同工作?
EN

Stack Overflow用户
提问于 2020-11-20 16:15:44
回答 1查看 51关注 0票数 0

首先,我想说我对c++非常陌生,这就是为什么我在ESP32上使用Arduino内核和库,我想为下面将要看到的垃圾箱火灾道歉。

简单地制作一个带有按钮和编码器的自定义键盘。启动时,从两种模式中选择一种:漂白键盘或midi控制面。

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

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

提前谢谢你。

代码语言:javascript
复制
#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
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-11-22 18:07:51

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

避免这样做:

代码语言:javascript
复制
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;

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

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

代码语言:javascript
复制
// 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上的神奇tutorial。这样,您将枚举您的状态并根据用户的选择或硬件输入触发操作或事件,而不会阻塞代码流。

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

我怀疑这是一个冲突中断的问题。

我完全同意这一点。如果你正在使用这个库,有一个宏可以救你的命:

代码语言:javascript
复制
#define ENCODER_DO_NOT_USE_INTERRUPTS

在库的存储库中的this示例中使用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64925949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档