Skip to content

how can i use absolute encoders with mcp23017? #13

@JuanFCulliganpy

Description

@JuanFCulliganpy

Hi, im really new on that, and i will craft by myselft this project, and i need help, i found this code for a midi interface. i craft the circuit and put all together, encoder, mcp23017 and arduino pro micro. when i did an i2c test it said me that is 0x20 adress its ok for me. but when i try on my daw and try to map any knob i can move the knob, after 1s(i guess) it back to the original position. as i said before prograaming is not my force, but i really like to do this project. here is my code:

#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>;
using uint16 = uint16_t;

// 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 = 600, 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 encV {Wire, 0x20, 7};
// │ │ └─ Interrupt pin
// │ └────── Address offset
// └──────────── I²C interface

// Sends Pitch Bend messages
PBMCPEncoder pbencodersVOL[] {
{encV[0], MCU::VOLUME_1},
{encV[1], MCU::VOLUME_2},
{encV[2], MCU::VOLUME_3},
{encV[3], MCU::VOLUME_4},
{encV[4], MCU::VOLUME_5},
{encV[5], MCU::VOLUME_6},
{encV[6], MCU::VOLUME_7},
{encV[7], MCU::VOLUME_8},
};

// Create objects that receives Pitch Bend messages from DAW channels
PBValue enc_values[] = {
{MCU::VOLUME_1},
{MCU::VOLUME_2},
{MCU::VOLUME_3},
{MCU::VOLUME_4},
{MCU::VOLUME_5},
{MCU::VOLUME_6},
{MCU::VOLUME_7},
{MCU::VOLUME_8}
};

// Create some array to store encoder's position
uint16 prev_positions [8];
uint16 incoming_values [8];
uint16 new_positions [8];

void setup() {
Control_Surface.begin();
Wire.begin(); // Must be called before enc.begin()
Wire.setClock(800000);
encV.begin(); // Initialize the MCP23017
}

void loop() {
for (int i = 0; i < 8; i++) {
prev_positions[i] = pbencodersVOL[i].getValue();
}
static constexpr decltype(millis()) timeout = 1000;
static decltype(millis()) prev_enc_move_time = -timeout;

Control_Surface.loop();

for (int i = 0; i < 8; i++) {
new_positions[i] = pbencodersVOL[i].getValue();
incoming_values[i] = enc_values[i].getValue();
bool dirty = incoming_values[i] != new_positions[i];
// Keep track of when the user last moved the encoder.

if (new_positions[i] != prev_positions[i]) {
  prev_positions[i] = new_positions[i];
  prev_enc_move_time = millis();
}

// If the value last sent by the DAW is different from our local
// value, and if the user hasn't moved the encoder for a while,
// update our local encoder position value.
// Note: this assumes that the DAW always echoes back the value
//       it received.
else if (dirty && millis() - prev_enc_move_time >= timeout) {
  pbencodersVOL[i].setValue(incoming_values[i]);
  pbencodersVOL[i].forcedUpdate(); // send the new value to the DAW (optional)
}
encV.update(); 

}
}
i think its for the thing thats name PBMCPEncoder (i guess its pitchbend) but idk if it is.
If someone can helpme i will really apreciate that and of course when i finish my project, i share photos or videos.
thats for sure.
Thanks and keep safe.
Jose Franco

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions