Hi,
I have 8 rotary encoders connected to an Arduino Pro Micro via an MCP23017 and I am trying to control the volume of DAW tracks using the encoders instead of motorized faders since they are too expensive.
I took a cue from the examples in the CONTROL SURFACE library and wrote the code attached.
Currently, by mapping the Arduino as Mackie Control Universal in Reaper, I can control the track faders but there is a problem.
I create a new project, insert a track and by default it is at 0dB. When I increase the volume with the encoder, the level immediately jumps to -150dB (negative bottom end) and then rises again as I turn the encoder clockwise.
If I turn the encoder counterclockwise the volume decreases correctly.
However, if I change the volume using the daw's fader and then try to vary it again using the encoder, the starting level from which the variation begins is not the level set with the fader but is the old value set with the encoder.
This is probably due to the fact that I am using "absolute" and not relative encoders and so Arduino "remembers" the position of the encoder and uses it as the starting point with each movement.
Is it possible to make the behavior "relative" as in the case of changing the PAN of the tracks?
It is crucial for me that Arduino is mapped as an MCU in the DAW and not with generic MIDI controller.
Thanks! @PieterP
#include <Wire.h>
#include <Control_Surface.h>
#include <AH/Hardware/MCP23017Encoders.hpp>
// Type for the MCP23017 encoders (translates encoder pulses to position)
using WireType = decltype(Wire); // The type of I²C driver to use
using EncoderPositionType = uint8_t; // The type for saving encoder positions
using MCPEncoderType = MCP23017Encoders<WireType, EncoderPositionType>;
// Type for the MIDI encoders (translates position to MIDI messages)
struct PBMCPEncoder : GenericMIDIAbsoluteEncoder<MCPEncoderType::MCP23017Encoder, PitchBendSender<14>> {
PBMCPEncoder(MCPEncoderType::MCP23017Encoder enc, MIDIAddress address,
int16_t multiplier = 512, uint8_t pulsesPerStep = 4)
: GenericMIDIAbsoluteEncoder(std::move(enc), address, multiplier,
pulsesPerStep, {}) {}
};
/*
// Type for the MIDI encoders (translates position to MIDI messages)
struct PBMCPEncoder : GenericMIDIAbsoluteEncoder<MCPEncoderType::MCP23017Encoder,
PitchBendSender<14>> {
PBMCPEncoder(MCPEncoderType::MCP23017Encoder enc, MIDIAddress address,
int16_t multiplier = 512, uint8_t pulsesPerStep = 4)
: GenericMIDIAbsoluteEncoder(std::move(enc), address, multiplier,
pulsesPerStep, {}) {}
};
*/
USBMIDI_Interface midi;
//USBDebugMIDI_Interface midi;
// Create an object that manages the 8 encoders connected to the MCP23017.
MCPEncoderType encVOL {Wire, 0x27, 4};
// │ │ └─ Interrupt pin
// │ └────── Address offset
// └──────────── I²C interface
// Instantiate 8 MIDI rotary encoders.
PBMCPEncoder pbencodersVOL[] {
{ encVOL[0], MCU::VOLUME_1},
{ encVOL[1], MCU::VOLUME_2},
{ encVOL[2], MCU::VOLUME_3},
{ encVOL[3], MCU::VOLUME_4},
{ encVOL[4], MCU::VOLUME_5},
{ encVOL[5], MCU::VOLUME_6},
{ encVOL[6], MCU::VOLUME_7},
{ encVOL[7], MCU::VOLUME_8}
};
void setup() {
// RelativeCCSender::setMode(relativeCCmode::MACKIE_CONTROL_RELATIVE);
Control_Surface.begin();
Wire.begin(); // Must be called before enc.begin()
Wire.setClock(800000);
encVOL.begin(); // Initialize the MCP23017
}
void loop() {
Control_Surface.loop();
encVOL.update();
}