Problem with errors in the code

Hi, have bought a number of rotary encoders and pro micro cards. Trying to get this project's (GitHub - phcreery/Encoder2MIDI: Use arduino with Rotary Encoders to control Lightroom/MIDI software) code to work but I'm running into problems when checking the code. Is there anyone who can help me? Thanks!

#include <Wire.h>
//#include "Adafruit_MCP23017.h"  // https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
#include "MIDIUSB.h"

// #################### VARIABLES ####################

int maxBanks = 9;
bool debug = false;
bool debugAll = false;
//const int functionEnc = 9;


// #################### CONSTANTS ####################

// MCP23017 registers (everything except direction defaults to 0)

#define IODIRA   0x00   // IO direction  (0 = output, 1 = input (Default))
#define IODIRB   0x01
#define IOPOLA   0x02   // IO polarity   (0 = normal, 1 = inverse)
#define IOPOLB   0x03
#define GPINTENA 0x04   // Interrupt on change (0 = disable, 1 = enable)
#define GPINTENB 0x05
#define DEFVALA  0x06   // Default comparison for interrupt on change (interrupts on opposite)
#define DEFVALB  0x07`
#define INTCONA  0x08   // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
#define INTCONB  0x09
#define IOCON    0x0A   // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
//#define IOCON 0x0B  // same as 0x0A
#define GPPUA    0x0C   // Pull-up resistor (0 = disabled, 1 = enabled)
#define GPPUB    0x0D
#define INFTFA   0x0E   // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
#define INFTFB   0x0F
#define INTCAPA  0x10   // Interrupt capture (read only) : value of GPIO at time of last interrupt
#define INTCAPB  0x11
#define GPIOA    0x12   // Port value. Write to change, read to obtain value
#define GPIOB    0x13
#define OLLATA   0x14   // Output latch. Write to latch output.
#define OLLATB   0x15

#define addr0 0x20
#define addr1 0x21

unsigned long data[3][4];

int MCP = 0;
int Encoder = 0;
int Direction = 0;
int Bank = 1;

int encValArray[3] = {0,0,0};
int encCCWArray[3] = {2,1,1};
int encCWArray[3] = {1,1,2};

const int encCount = 9;                 // number of rotary encoders
const int encPins[encCount][2] = {
  {0,1},  //1
  {16,17},//2
  {18,19},//3
  {20,21},//4
  {22,23},//5
  {24,25},//6
  {26,27},//7
  {28,29},//8
  {30,31} //9
};
const int selectorEncoder = 7;

const int butCount = 9;            // number of buttons on mcp1d
const int butPins[butCount] = { 2,8,9,10,11,12,13,14,15 };

const int ledCount = 9;  
const int ledPins[ledCount] = { 9,10,16,14,15,18,19,20,21 };

byte arduinoIntPin0 = 0;                                                                // Interrupts from the MCP will be handled by this PIN on Arduino
byte arduinoIntPin1 = 7;

byte arduinoInterrupt0 = digitalPinToInterrupt(arduinoIntPin0);                         // ... and this interrupt vector
byte arduinoInterrupt1 = digitalPinToInterrupt(arduinoIntPin1);

volatile boolean awakenByInterrupt = false;

int led = 17;


//int debounce = 30;




// #################### TOOLS ####################

void expanderWriteBoth(const byte reg, const byte data, unsigned char addrX) {
  Wire.beginTransmission (addrX);
  Wire.write (reg);   //
  Wire.write (data);  // port A
  Wire.write (data);  // port B
  Wire.endTransmission ();
} 

unsigned int expanderRead(const byte reg, unsigned char addrX) {     // read a byte from the expander
  Wire.beginTransmission (addrX);
  Wire.write (reg);
  Wire.endTransmission ();
  Wire.requestFrom (addrX, 1);
  return Wire.read();
} 

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  //midiEventPacket_t noteOff = {0x08 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void sendMIDI(int Bank, int Encoder, int Direction) {
  if (debug == true){
    Serial.print("MIDI Data: B");
    Serial.print(Bank);
    Serial.print(" E");
    Serial.print(Encoder);
    Serial.print(" D");
    Serial.print(Direction);
    Serial.println();
  } else {
    controlChange(Bank, Encoder, Direction);
    MidiUSB.flush();
  }
}

void sendMIDIButton(int Bank, int Button){
  if (debug == false){
    noteOn(Bank, Button, 127);
    MidiUSB.flush();
    delay(50);
    noteOff(Bank, Button, 127);
    MidiUSB.flush();
  } else {
    Serial.print("Button: ");
    Serial.println(Button);
  }
}

void printBits2(long var) {
  for (unsigned long test = 0x80000000; test; test >>= 1) {
    if (test == 0x800000){Serial.print(" ");}
    if (test == 0x8000){Serial.print("  ");}
    if (test == 0x80){Serial.print(" ");}
    Serial.write(var  & test ? '1' : '0');
  }
}

void displayData(){

  unsigned long keyValue = data[0][3];
  unsigned long prevkeyValue = data[0][2];
  unsigned long changedkeyValue = data[1][3];
  unsigned long comparedkeyValue = data[2][3];

  Serial.println("DATA         MCP2b    MCP2a     MCP1b    MCP1a  ");
  Serial.print("keyvalue:   ");
  printBits2(keyValue);
  Serial.println();
  Serial.print("change:     "); 
  printBits2(changedkeyValue);
  Serial.println();
  Serial.print("comparison: ");
  printBits2(comparedkeyValue);
  Serial.println();


  for (int i = 0; i < 3; i++){ 
    for (int j = 0; j < 4; j++){ 
      Serial.print(data[i][j]);
    }
    Serial.println();
  }
}

void setled(int ledNumber){
  ledNumber = ledNumber - 1;
  if (debugAll == true){
    Serial.print("LED:");
    Serial.println(ledNumber);
  }
  for (int j = 0; j < ledCount; j++){ 
    digitalWrite(ledPins[j], LOW);
  }
  digitalWrite(ledPins[ledNumber], HIGH);
}


// ######################## SETUP ########################

unsigned char encPinsSetup() { // setup the encoders as inputs. 
  // expander configuration register
  expanderWriteBoth (IOCON, 0b01100000, addr0); // mirror interrupts, disable sequential mode
 
  // enable pull-up on switches
  expanderWriteBoth (GPPUA, 0xFF, addr0);   // pull-up resistor for switch - both ports

  // invert polarity
  expanderWriteBoth (IOPOLA, 0xFF, addr0);  // invert polarity of signal - both ports
  
  // enable all interrupts
  expanderWriteBoth (GPINTENA, 0xFF, addr0); // enable interrupts - both ports

  expanderRead(INTCAPA, addr0);
  expanderRead(INTCAPB, addr0);


  expanderWriteBoth (IOCON, 0b01100000, addr1); // mirror interrupts, disable sequential mode
 
  // enable pull-up on switches
  expanderWriteBoth (GPPUA, 0xFF, addr1);   // pull-up resistor for switch - both ports

  // invert polarity
  expanderWriteBoth (IOPOLA, 0xFF, addr1);  // invert polarity of signal - both ports
  
  // enable all interrupts
  expanderWriteBoth (GPINTENA, 0xFF, addr1); // enable interrupts - both ports

  expanderRead(INTCAPA, addr1);
  expanderRead(INTCAPB, addr1); 
}

void ledPinsSetup() {
  for (int j = 0; j < ledCount; j++){ 
    pinMode(ledPins[j], OUTPUT);
    digitalWrite(ledPins[j], LOW);
  }
}

void setup() {  
  Wire.begin ();  
  pinMode(arduinoIntPin0, INPUT);
  pinMode(arduinoIntPin1, INPUT);

  encPinsSetup();
  ledPinsSetup();
  setled(Bank);

  Serial.begin (115200);  //for debugging & MIDI
  
  //attachInterrupts();

  attachInterrupt(arduinoInterrupt0, intCallBack0, FALLING);                          // enable interrupts before going to sleep/wait
  attachInterrupt(arduinoInterrupt1, intCallBack1, FALLING);                          // And we setup a callback for the arduino INT handler.
}


// ######################## FUNCTIONS ########################

void intCallBack0() {
  if (awakenByInterrupt == false){    //only proceed if previous interrupt has finished processing
    awakenByInterrupt = true;
    //encSelect[0] = 0;
    MCP = 0;
  }
}
void intCallBack1() {
  if (awakenByInterrupt == false){    //only proceed if previous interrupt has finished processing
    awakenByInterrupt = true;
    //encSelect[0] = 1;
    MCP = 1;
  }
}

void detachInterrupts() {
  // disable interrupts while handling them.
  detachInterrupt(arduinoInterrupt0);
  detachInterrupt(arduinoInterrupt1);

  //delay(debounce);  // de-bounce before we re-enable interrupts

  //digitalWrite(led, !digitalRead(led));
}

void cleanInterrupts() {
  EIFR = 0x01;
  awakenByInterrupt = false;
}

void attachInterrupts() {
  attachInterrupt(arduinoInterrupt0, intCallBack0, FALLING);
  attachInterrupt(arduinoInterrupt1, intCallBack1, FALLING);
}

unsigned long getInteruptValue() {                   //Get pin from MCP that was interrupted 
  int addr;
  int encseladd;

  static unsigned long keyValue;
  static unsigned long prevkeyValue;
  static unsigned long changedkeyValue;

  if (MCP == 0){
    addr = addr0;
    encseladd=0;
  }  
  else if (MCP == 1){
    addr = addr1;
    encseladd=8;
  }
  keyValue = 0x00000000;
  if (expanderRead(INFTFA, addr))     // Read port values, as required. Note that this re-arms the interrupts.
    {
    keyValue &= 0xFF00;
    keyValue |= expanderRead(INTCAPA, addr);// << 8;    // read value at time of interrupt
    }
  if (expanderRead(INFTFB, addr))
    {
    keyValue &= 0x00FF;
    keyValue |= expanderRead(INTCAPB, addr) << 8;        // port B is in low-order byte
    }
  keyValue = keyValue << 16 * MCP;

  changedkeyValue = keyValue^prevkeyValue;

 /*
  if (debug == true){
    Serial.println("DATA         MCP2b    MCP2a     MCP1b    MCP1a  ");
    Serial.print("keyvalue:   ");
    printBits2(keyValue);
    Serial.println();
    Serial.print("change:     "); 
    printBits2(changedkeyValue);
    Serial.println();
    Serial.print("comparison: ");
    printBits2(keyValue&changedkeyValue);
    Serial.println();
  }
  */
  prevkeyValue = keyValue;

  return keyValue;
}

void appendtoData(unsigned long keyValue){           // appends keyvalue to data and returns inteerrupt pin value

  //keyValue = data[0];
  //changedkeyValue = data[1];
  //comparedkeyValue = data[2];

  static unsigned long keyValueArray[4];
  static unsigned long changedkeyValueArray[4];
  static unsigned long comparedkeyValueArray[4];
  static unsigned long prevkeyValue;

  //static int data[3][4];
  //int intpin;

  static unsigned long changedkeyValue;
  static unsigned long comparedkeyValue;

  changedkeyValue = keyValue^prevkeyValue;
  comparedkeyValue = keyValue&changedkeyValue;

  /*
  if (debug == true){
    Serial.println("DATA         MCP2b    MCP2a     MCP1b    MCP1a  ");
    Serial.print("keyvalue:   ");
    printBits2(keyValue);
    Serial.println();
    Serial.print("change:     "); 
    printBits2(changedkeyValue);
    Serial.println();
    Serial.print("comparison: ");
    printBits2(comparedkeyValue);
    Serial.println();
  }
  */
  /*
  if ((keyValue&changedkeyValue)%2 == 0) {                     //if pin number is even
    Serial.println("CW");
  } else {
    Serial.println("CCW");
  }
  */

  keyValueArray[0] = keyValueArray[1];
  keyValueArray[1] = keyValueArray[2];
  keyValueArray[2] = keyValueArray[3];
  keyValueArray[3] = keyValue;                            // shift array and append

  changedkeyValueArray[0] = changedkeyValueArray[1];
  changedkeyValueArray[1] = changedkeyValueArray[2];
  changedkeyValueArray[2] = changedkeyValueArray[3];                         //shift array and append
  changedkeyValueArray[3] = changedkeyValue;

  comparedkeyValueArray[0] = comparedkeyValueArray[1];
  comparedkeyValueArray[1] = comparedkeyValueArray[2];
  comparedkeyValueArray[2] = comparedkeyValueArray[3];
  comparedkeyValueArray[3] = comparedkeyValue;


  for (int i = 0; i < 4; i++){ 
    data[0][i] = keyValueArray[i];
  }
  for (int i = 0; i < 4; i++){ 
    data[1][i] = changedkeyValueArray[i];
  } 
  for (int i = 0; i < 4; i++){ 
    data[2][i] = comparedkeyValueArray[i];
  } 

  prevkeyValue = keyValue;
}

int decodeInterruptValue(){   //converts interrupt value to to pin numbers. returns -1 if value=0
  long changedkeyValue;
  int intpin;
  changedkeyValue = data[1][3];
  long one = 0x00000001;
  byte localpinNumber = 0;
  if (changedkeyValue != 0){                           // if there is a value attached to the interrupt
    for (localpinNumber = 0; localpinNumber < 32; localpinNumber++){
      if (changedkeyValue & (one << localpinNumber)) {          //bitwyse keyvalue == binary value of button
        intpin = localpinNumber;
        //if (debug == true){Serial.println(intpin);}
      }
    }
  } else {
    return -1;
  }

  return intpin;
}

int encoderNumber(int interruptPin){
  for (int i = 0; i < encCount; i++){ 
    for (int j = 0; j < 2; j++){ 
      if (encPins[i][j] == interruptPin){
        return i + 1;
      }
    }
  }
  return 0;
}

int buttonNumber(int interruptPin){
  for (int i = 0; i < butCount; i++){ 
    if (butPins[i] == interruptPin){
      return i + 1;
    }
  }
  return 0;
}

bool isSelector(int Encoder){
  if (Encoder == selectorEncoder){
    return true;
  } else {
    return false;
  }
  return false;
}

bool isButton(int interruptPin){
  for (int j = 0; j < butCount; j++){ 
    if (butPins[j] == interruptPin){
      return true;
    }
  }
  return false;
}

int encoderDirection(){          // 0 = null   1 = CW     -1 = CCW

  if ((data[2][2] == 0) && (data[2][3] == 0)){
    if (data[2][0] < data[2][1]){
      return 1;
    } else {
      return -1;
    }
  } else {
    //Serial.println("BAD READING");
    return 0;
  }
}


// ################# MAIN ########################

void loop() {
  if (awakenByInterrupt){
    detachInterrupts();
    unsigned long interruptValue = getInteruptValue();
    appendtoData(interruptValue);
    int interruptPin = decodeInterruptValue();
    int Encoder = encoderNumber(interruptPin);
    
    if (debugAll == true){displayData();}
    //Serial.println(Encoder);
    //Serial.println(encDirection);
    
    if (isButton(interruptPin) == true){  //if interrupt pin is not recognized as button pin
      int Button = buttonNumber(interruptPin);
      sendMIDIButton(Bank, Button);
    } else {
      int encDirection = encoderDirection();
      if ((encDirection != 0) && (Encoder != 0)) {
        if (isSelector(Encoder) == true){
          Bank = Bank + encDirection;
          if (Bank > maxBanks){
            Bank = maxBanks;
          }
          if (Bank < 1){
            Bank = 1;
          }
          setled(Bank);
          if (debug == true){
            Serial.print("Bank: ");
            Serial.println(Bank);
          }
        } else {
          sendMIDI(Bank, Encoder, ((encDirection-1)*-63)+1);  // converts: -1/1 -> 1/127
        }
      } else if (((encDirection = 0) && (Encoder != 0)) || ((encDirection != 0) && (Encoder = 0))){
        Serial.println("BAD READING");
      } else {
        //Serial.println("Skipping Check");
      }
    }



    cleanInterrupts();
    attachInterrupts();

  }
  //delay(50);                                //Maximum delay acceptable for normal and reactive encoder response time without loose events
}

Error message:




C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino: In function 'unsigned int expanderRead(byte, unsigned char)':
C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino:104:29: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
   Wire.requestFrom (addrX, 1);
                             ^
In file included from C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino:1:0:
C:\Users\Robin\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.5\libraries\Wire\src/Wire.h:68:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
     uint8_t requestFrom(int, int);
             ^~~~~~~~~~~
C:\Users\Robin\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.5\libraries\Wire\src/Wire.h:65:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
     uint8_t requestFrom(uint8_t, uint8_t);
             ^~~~~~~~~~~
C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino: In function 'void controlChange(byte, byte, byte)':
C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino:109:41: warning: narrowing conversion of '(int)(176 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
                                    ~~~~~^~~~~~~~~
C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino: In function 'void noteOn(byte, byte, byte)':
C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino:114:42: warning: narrowing conversion of '(int)(144 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
                                     ~~~~~^~~~~~~~~
C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino: In function 'void noteOff(byte, byte, byte)':
C:\Users\Robin\Desktop\Encoder2MIDI-master\LRC\LRC.ino:119:43: warning: narrowing conversion of '(int)(128 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
                                      ~~~~~^~~~~~~~~
Sketch uses 9938 bytes (34%) of program storage space. Maximum is 28672 bytes.
Global variables use 596 bytes (23%) of dynamic memory, leaving 1964 bytes for local variables. Maximum is 2560 bytes.

Sorry. My bad. Updated my first post.

Your first two warnings can be solved by casting the second argument of requestFrom() to a byte.

For the 'narrowing conversion' warning, the compiler will use integer maths. So e.g. 0x80 | channel results in an integer; casting the result of that calculation to a byte will solve that problem.

Further unsigned char encPinsSetup() does not return anything. So it should be encPinsSetup().

The compiler also complains about intpin

int decodeInterruptValue()
{  //converts interrupt value to to pin numbers. returns -1 if value=0
  long changedkeyValue;
  int intpin;
'intpin' may be used uninitialized

I would advise to initialise it to -1; in that case you can also get rid of the else in that function.

You have a similar problem with the below

unsigned long getInteruptValue()
{  //Get pin from MCP that was interrupted
  int addr;
'addr' may be used uninitialized

I think that I would default it to addr0 but not sure.

Lastly the compiler tells you that you have some variables that are unused; this might or might not pose a problem.

It looks like you did not get all warnings. To see all warnings, set 'Compiler warnings' to 'All' in file β†’ preferences.

Thank you for the help!

Here are the complete warnings.

C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino: In function 'unsigned int expanderRead(byte, unsigned char)':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:104:29: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
   Wire.requestFrom (addrX, 1);
                             ^
In file included from C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:1:0:
C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\libraries\Wire\src/Wire.h:68:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
     uint8_t requestFrom(int, int);
             ^~~~~~~~~~~
C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\libraries\Wire\src/Wire.h:65:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
     uint8_t requestFrom(uint8_t, uint8_t);
             ^~~~~~~~~~~
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino: In function 'void controlChange(byte, byte, byte)':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:109:41: warning: narrowing conversion of '(int)(176 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
                                    ~~~~~^~~~~~~~~
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino: In function 'void noteOn(byte, byte, byte)':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:114:42: warning: narrowing conversion of '(int)(144 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
                                     ~~~~~^~~~~~~~~
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino: In function 'void noteOff(byte, byte, byte)':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:119:43: warning: narrowing conversion of '(int)(128 | ((unsigned char)((int)channel)))' from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
   midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
                                      ~~~~~^~~~~~~~~
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino: In function 'void displayData()':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:164:17: warning: unused variable 'prevkeyValue' [-Wunused-variable]
   unsigned long prevkeyValue = data[0][2];
                 ^~~~~~~~~~~~
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino: In function 'unsigned char encPinsSetup()':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:233:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }
 ^
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino: In function 'long unsigned int getInteruptValue()':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:299:7: warning: variable 'encseladd' set but not used [-Wunused-but-set-variable]
   int encseladd;
       ^~~~~~~~~
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:303:24: warning: variable 'changedkeyValue' set but not used [-Wunused-but-set-variable]
   static unsigned long changedkeyValue;
                        ^~~~~~~~~~~~~~~
C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino\main.cpp: In function 'main':
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:451:5: warning: 'intpin' may be used uninitialized in this function [-Wmaybe-uninitialized]
     if (butPins[i] == interruptPin){
     ^
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:420:7: note: 'intpin' was declared here
   int intpin;
       ^
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:314:19: warning: 'addr' may be used uninitialized in this function [-Wmaybe-uninitialized]
   if (expanderRead(INFTFA, addr))     // Read port values, as required. Note that this re-arms the interrupts.
                   ^
C:\Users\Desktop\Aurdino\Encoder2MIDI-master\LRC\LRC.ino:298:7: note: 'addr' was declared here
   int addr;
       ^
Sketch uses 9938 bytes (34%) of program storage space. Maximum is 28672 bytes.
Global variables use 596 bytes (23%) of dynamic memory, leaving 1964 bytes for local variables. Maximum is 2560 bytes.

Fix them :wink: I've indicated how. If you have questions about the 'how', ask.

And you should answer @Delta_G's question "Does the code not work when you upload it?".

Sorry for the delay. No, the code doesn't work, tried setting everything up on a breadboard. I'd appreciate help with the "how" part. Because it's been a few years since I last sat with Arduino. :sweat_smile:

Sorry, the idea is Rotary Encoder/Button > MCP32017 I/O Expander > I2C > Arduino > MIDI signal over USB. But I don't get any function at all. The arduino still only shows up as a COM port in the device manager so I assume there is something wrong with the midi library?

Since the code is written in 2019, I tried downgrading the libraries to the same year but it didn't help.

What does that mean? Please explain what you expected to happen, and what happened instead.

This may be useful: Control Surface: MCP23017-RotaryEncoder-No-Interrupts.ino

Check the serial monitor to see if you get the expected MIDI messages, and then replace USBDebugMIDI_Interface by USBMIDI_Interface to make the Arduino show up as an actual MIDI device.

The rotary encoders do not work and no midi device in device manager.

No Midi message in serial monitor. Will try that PieterP, thanks!

I understand, I am grateful for your help and patience, I understand that it is not easy. I'm trying to get the rotary encoders to respond. But nothing happens, no indication of signals coming through. Nor in serial monitor. I have asked two programmers at work for help, but they are as confused as I am about the problem.

Okay, the idea of ​​this midi controller project is to control Adobe Lightroom via the Midi2LR plugin.

Have previously used this with ready-made midi controllers but wanted to build my own this time.

The idea is when you turn the encoders you should get a value between 0-127. That's the whole idea behind the project.

But it seems that windows 11 fails to identify the arduino as a midi controller, my amateur guess is that there is something wrong with the code. Maybe better to start from scratch and try to write something simple myself that works and then advance from there. I may have embarked on a too difficult project for my level of knowledge.


You would get a result like this when you turning each encoder but I get literally nothing.

I understand exactly what you mean, I work as a car mechanic and trying to troubleshoot a car over the phone is basically impossible.

I also don't think the encoders are the fault but where do I start? If I disconnect everything from the board apart from the usb cable, the arduino is still not found as a midi device in the device manager. Where should I start troubleshooting?

Update:
Sorry, did not see your 2:nd answer.

reinstalled the MIDIUSB library and manage to get the Arduino to show up as a MIDI device in the device manager. A step in the right direction. But still no Midi messages seem to go through. Will continue tomorrow. Now bedtime.

To test the encoders, use a simple program that does nothing but interface with the encoders, and prints current values on the serial monitor. Most, if not all of the encoder libraries have such an example.

That approach is the first and basic step to take with any sensor you connect to the Arduino.

Alternatively, but not as straightforward, you can add Serial.print() statements at the point where the encoders are read out, and see whether the printed values make sense.

I tried each KY-040 Encoder with this simple code and wiring and they all work as they should.

#define CLK_PIN 2
#define DT_PIN 3
#define SW_PIN 4
int position = 0;
int last_position = 0;
int n = 0;
bool taster = LOW;
bool last_taster = LOW;
void setup() {
pinMode(CLK_PIN, INPUT_PULLUP);
pinMode(DT_PIN, INPUT_PULLUP);
pinMode(SW_PIN, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
n = digitalRead(CLK_PIN);
taster = !digitalRead(SW_PIN);
if(taster != last_taster) {
Serial.print(position);
Serial.print("|");
Serial.println(taster);
delay(10);
last_taster = taster;
}

// one tab
if((last_position == 0) && (n == HIGH)) {
if(digitalRead(DT_PIN) == LOW) {
position++;
}
else {
position--;
}
Serial.print(position);
Serial.print("|");
Serial.println(taster);
}
last_position = n;
}

Great! The next step is to put Serial.print() statements in key places in your MIDI code, to see if variables are what you expect them to be.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.