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.

Please add the code you are trying to use and put it in code tags. Copy and paste the error messages here and place them in code tags.

DO NOT post a screenshot or a picture of some text. A picture of text is useless. Copy and paste the text you want to show us directly into a post. Use code tags.

Sorry. My bad. Updated my first post.

That is a successful compile. There are some warnings, but no errors. Does the code not work when you upload it?

2 Likes

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:

Can you describe what the code is supposed to do and what happens instead? Get us up to speed on what you mean by "doesn't work".

It's probably not because of these warning. Most of those are from core code that works despite the warnings.

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!

Several people are trying to get at the actual symptom so they can try to help you. You have to try to understand how hard it is to troubleshoot a device that you can't see or touch. I'm going to try asking this question in a slightly different way and see if maybe it helps you get to the info they need.

How do you know they don't work? There was something you expected to see. What was it? There was something else that happened instead. What was it?

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.

Meaning what? What would happen if they did respond. How would you know they were responding? You seem to be running on the assumption that someone here knows what your contraption is supposed to do. You need to fill us in on that.

I could maybe start digging through the code and the link to try to figure out what this code is about, but really it seems like that should be on you since these are things you actually know.

When you set out to build this contraption, what did you have in mind? What is it? What does it do?

And most importantly, answer these questions as specifically as you can. These answers will actually help these people to help you and you'll get an answer:

For example: "I was expecting to see the color change from blue to red as I turned the encoder, but the color just stayed blue."

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.

Last try and then I'm out.

How would you know that you got a value? Would you see it somewhere? Is there some output?

This is like pulling teeth.

Let me ask one more time:

For example: "There's a big red 0 on the screen. I expected as I turned the knob to see it change to a different value but it just stayed 0."

Or maybe:
"I was expecting as I turned the knob for the music to get louder from my computer, but that didn't happen it just stayed the same volume"

You have to be our eyes and ears. You're the only one there with the actual thing.


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.

If the controller isn't attached then wouldn't this be as expected? That doesn't mean the encoders aren't working.

So I came in saying that the radio doesn't work. Oh and there's also this issue about the battery cable is missing, but I'm mostly just interested in why the radio doesn't work.