tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.27k stars 140 forks source link

Пример CCIncrementDecrementButtons.ino #988

Closed Alexandr010360 closed 10 months ago

Alexandr010360 commented 10 months ago

Hello! Thank you for the amazing library with which I can create my own MIDI system project for the accordion! But I ran into one problem! I need a midi channel volume control function using two buttons, as shown in the CCIncrementDecrementButtons example.ino Pressing the minus button gives a result of one and pressing the plus button gives a maximum value of 127. There are no intermediate values! Everything works fine with the encoder class, but not with the buttons! I can't understand the reason! Please help me!`

include // Include the Control Surface library

// Instantiate a MIDI over USB interface. USBMIDI_Interface midi;

// Instantiate a CCIncrementDecrementButtons object CCIncrementDecrementButtons buttons { {2, 3}, // Button pins: 2 increments, 3 decrements {MIDI_CC::Channel_Volume, CHANNEL_3}, };

void setup() { // Use the Mackie Control protocol for sending relative MIDI CC messages. RelativeCCSender::setMode(TWOS_COMPLEMENT);

Control_Surface.begin(); // Initialize Control Surface Serial.begin(57600); }

void loop() { Control_Surface.loop(); // Update the control surface }`

tttapa commented 10 months ago

Hi, please open one discussion per issue.

The CCIncrementDecrementButtons class is intended for use with relative controls. A value of 1 should be interpreted as +1 and a value of 127 as -1. See relativeCCmode for details.

If you want the buttons to send absolute values, you'll need to keep track of the absolute value somehow. I'd recommend having a look at the Custom-MIDI-Output-Element.ino example. You can use the implementation of MIDIIncrementDecrementButtons as inspiration.

Alexandr010360 commented 10 months ago

Good afternoon! Thanks for the advice! I'll try to figure it out using other examples...

Alexandr010360 commented 10 months ago

Hello! Could you add an example sketch of how to use buttons to send absolute values, as is done in the example with an absolute encoder? I can't do anything with the implementation of MIDIIncrementDecrementButtons...

Alexandr010360 commented 10 months ago

При компиляции пишет ошибку exit status 1 invalid use of template-name 'CS::MIDIIncrementDecrementButtons' without an argument list

laps78 commented 10 months ago

Александр010360, у вас синтаксическая ошибка в коде - вызов сущности (метода?) без обязательных аргументов. КурИте документацию. Возможно, вы считаете, что ошибка не в Вашем коде, а в коде библиотеки?

tttapa commented 10 months ago

You could do something like this:

#include <Control_Surface.h>

BEGIN_CS_NAMESPACE

class CCAbsoluteIncrDecrButtons : public MIDIOutputElement {
 public:
  CCAbsoluteIncrDecrButtons(const AH::IncrementDecrementButtons &buttons,
                            MIDIAddress address, uint8_t initial_value = 0,
                            uint8_t multiplier = 1)
    : buttons(buttons), address(address), initial_value(initial_value),
      multiplier(multiplier) {}

 public:
  // Initialize: enable the pull-up resistors for the buttons
  // This method is called once by `Control_Surface.begin()`.
  void begin() final override { buttons.begin(); }

  // Update: read the buttons and send MIDI messages when appropriate.
  // This method is called continuously by `Control_Surface.loop()`.
  void update() final override {
    using IncrDecrButtons = AH::IncrementDecrementButtons;
    switch (buttons.update()) {
        case IncrDecrButtons::Nothing: break;
        case IncrDecrButtons::IncrementShort: // fallthrough
        case IncrDecrButtons::IncrementLong:  // fallthrough
        case IncrDecrButtons::IncrementHold:
            if (value <= 0x7F - multiplier) {
              value += multiplier;
              Control_Surface.sendControlChange(address, value);
            }
            break;
        case IncrDecrButtons::DecrementShort: // fallthrough
        case IncrDecrButtons::DecrementLong:  // fallthrough
        case IncrDecrButtons::DecrementHold:
            if (value >= multiplier) {
              value -= multiplier;
              Control_Surface.sendControlChange(address, value);
            }
            break;
        case IncrDecrButtons::Reset:
            if (value != initial_value) {
              value = initial_value;
              Control_Surface.sendControlChange(address, value);
            }
            break;
        default: break;
    }
  }

 private:
  AH::IncrementDecrementButtons buttons;
  const MIDIAddress address;
  const uint8_t initial_value;
  const uint8_t multiplier;
  uint8_t value = initial_value;
};

END_CS_NAMESPACE

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //

// Instantiate a MIDI over USB interface.
USBMIDI_Interface midi;

// Instantiate a CCAbsoluteIncrDecrButtons object
CCAbsoluteIncrDecrButtons buttons {
  {2, 3},                  // Push buttons on pins 2 and 3
  MIDI_CC::Channel_Volume, // Controller
  0x40,                    // Initial value
};

void setup() {
  Control_Surface.begin(); // Initialize Control Surface (calls buttons.begin())
}

void loop() {
  Control_Surface.loop(); // Update the Control Surface (calls buttons.update())
}
Alexandr010360 commented 10 months ago

Александр010360, у вас синтаксическая ошибка в коде - вызов сущности (метода?) без дополнительных аргументов. КурИте документацию. Возможно, вы считаете, что ошибка не в вашем коде, а в кодовой библиотеке?

Нет я не считаю что ошибка в библиотеке! Для моего случая нет готового кода из коробки! Для отправки абсолютных значений нужно самому написать соответствующий код. Или создать свой класс. Есть примеры и инструкции как расширить библиотеку. В чём я сейчас и разбираюсь. Но у меня недостаточно опыта для этого. Нужно время чтобы разобраться. Поэтому и попросил помощи у автора библиотеки Петера П.

laps78 commented 10 months ago

Александр010360, у вас синтаксическая ошибка в коде - вызов сущности (метода?) без дополнительных аргументов. КурИте документацию. Возможно, вы считаете, что ошибка не в вашем коде, а в кодовой библиотеке?

Нет я не считаю что ошибка в библиотеке! Для моего случая нет готового кода из коробки! Для отправки абсолютных значений нужно самому написать соответствующий код. Или создать свой класс. Есть примеры и инструкции как расширить библиотеку. В чём я сейчас и разбираюсь. Но у меня недостаточно опыта для этого. Нужно время чтобы разобраться. Поэтому и попросил помощи у автора библиотеки Петера П.

Александр, Ваша позиция ясна. Насколько я понимаю, библиотека это не Фреймворк. Т. е. Вы пишете свой проект и можете взять уже написанный код из библиотеки, чтобы не изобретать велосипед. С фреймворком иначе - Вы берете Фреймворк, а затем в его окружении пишете свой код. Это я к чему?

Следует ли @tttapa (busy) расширять код библиотеки под Ваши задачи - большой философский вопрос. Больше кода => больше багов => сложнее поддержка.

Этот раздел (issues) - для того, чтобы @username сферический в вакууме мог сообщить о баге в коде. Т.е. "issues" != "support".

Исходя из выше изложенного, настоятельно рекомендую самому разобраться в синтаксисе wiring/C, документации к библиотеке или найти профессионального разработчика, который решит задачу.

Следует также сказать спасибо(вы уже) @tttapa за то, что не нужно глубоко погружаться в спецификации MIDI и т.п.

С наилучшими пожеланиями творческих успехов!

Alexandr010360 commented 10 months ago

Peter P. Thank you very much! Everything worked out! You are a genius! I just had to tweak something in the code. For some reason, in the latest release of the library, it does not see the full name of sendControlChange. I had to change it to the abbreviated sendCC. And I also added an additional channel in my code. And I don't need a multiplier. This switching speed is also acceptable.`

include

BEGIN_CS_NAMESPACE

class CCAbsoluteIncrDecrButtons : public MIDIOutputElement { public: CCAbsoluteIncrDecrButtons(const AH::IncrementDecrementButtons &buttons, MIDIAddress address, uint8_t initial_value = 0, uint8_t multiplier = 1) : buttons(buttons), address(address), initial_value(initial_value), multiplier(multiplier) {}

public: // Initialize: enable the pull-up resistors for the buttons // This method is called once by Control_Surface.begin(). void begin() final override { buttons.begin(); }

// Update: read the buttons and send MIDI messages when appropriate. // This method is called continuously by Control_Surface.loop(). void update() final override { using IncrDecrButtons = AH::IncrementDecrementButtons; switch (buttons.update()) { case IncrDecrButtons::Nothing: break; case IncrDecrButtons::IncrementShort: // fallthrough case IncrDecrButtons::IncrementLong: // fallthrough case IncrDecrButtons::IncrementHold: if (value <= 0x7F - multiplier) { value += multiplier; Control_Surface. sendCC(address, value); } break; case IncrDecrButtons::DecrementShort: // fallthrough case IncrDecrButtons::DecrementLong: // fallthrough case IncrDecrButtons::DecrementHold: if (value >= multiplier) { value -= multiplier; Control_Surface. sendCC(address, value); } break; case IncrDecrButtons::Reset: if (value != initial_value) { value = initial_value; Control_Surface. sendCC(address, value); } break; default: break; } }

private: AH::IncrementDecrementButtons buttons; const MIDIAddress address; const uint8_t initial_value; const uint8_t multiplier; uint8_t value = initial_value; };

END_CS_NAMESPACE

// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //

// Instantiate a MIDI over USB interface. USBMIDI_Interface midi;

// Instantiate a CCAbsoluteIncrDecrButtons object CCAbsoluteIncrDecrButtons buttons { {2, 3}, // Push buttons on pins 2 and 3 {MIDI_CC::Channel_Volume, CHANNEL_3}, // Controller // Initial value };

void setup() { Control_Surface.begin(); // Initialize Control Surface (calls buttons.begin()) Serial.begin(57600); }

void loop() { Control_Surface.loop(); // Update the Control Surface (calls buttons.update()) }

Alexandr010360 commented 10 months ago

Александр010360, у вас синтаксическая ошибка в коде - вызов сущности (метода?) без дополнительных аргументов. КурИте документацию. Возможно, вы считаете, что ошибка не в вашем коде, а в кодовой библиотеке?

Нет, я не считаю эту ошибку в библиотеке! В моем случае нет готового кода из коробки! Для вручения абсолютных оценок необходимо написать соответствующий код. Или создай свой класс. Существуют модели и разработки, связанные с развитием технологии. В чём я сейчас и разбираюсь. Но у меня недостаточно опыта для этого. Нужно время для выяснения. Поэтому и попросил помощи у автора библиотеки Петера П.

Александр, Ваша позиция ясна. Насколько я понимаю, библиотека это не Фреймворк. Т. е. Вы пишете свой проект и можете взять уже написанный код из библиотеки, чтобы не изобретать велосипед. С помощью Фреймворка иначе — вы берете Фреймворк, а затем в его рамках записываете свой код. Это я к чему?

ли@tttapa(занят) расширение кода библиотеки под Ваши задачи - большой философский вопрос. Больше кода => больше багов => сложнее поддержка.

Этот раздел (вопросы) - для того, чтобы @username сферический в вакууме мог сообщить о баге в коде. Т.е. "проблемы" != "поддержка".

Исходя из вышеизложенного, настоятельно рекомендуется разобраться в синтаксисе проводки/C, документации к библиотеке или найти профессионального разработчика, который решит задачу.

Также следует сказать спасибо(вы уже)@tttapaза то, что не нужно глубоко погружаться в особенности MIDI и т.п.

Сформулируйте пожелания творческих успехов!

Благодарю вас за пожелание и совет! Обязательно займусь углублённым изучением языка C++ Пока только учусь программировать в среде ардуино.