Odd compile error: "No such file or directory" cause: #include #define SOLVED

I have a very weird problem... I am working on a code (which has now become pretty heavy).
Taking out the debug stuff I have the following.

Sketch uses 19746 bytes (61%) of program storage space. Maximum is 32256 bytes.
Global variables use 1103 bytes (43%) of dynamic memory, leaving 1457 bytes for local variables. Maximum is 2560 bytes.

With the debug staff I get this:

Low memory available, stability problems may occur.
Sketch uses 22474 bytes (69%) of program storage space. Maximum is 32256 bytes.
Global variables use 2069 bytes (80%) of dynamic memory, leaving 491 bytes for local variables. Maximum is 2560 bytes.

I must say that I didn't pay to much attention at the memory used by my debugging part of the code, so I am planning to go though it. I started by creating two compile time condition rather than one

So I added #define DEBUG_BUTTONS at the beginning of the code with the intention to apply this to my button part of the code, which uses quite a lot of Serial.print stuff.
when I add this line #define DEBUG_BUTTONS I got a compiler error, so I removed the line and the compile error is still there. I wasn't sure whether I involuntary messed up some part of the code so I closed without saving - reopened and the code compile again.
tried again and it just keeps doing it!! just adding a precompile condition and I get the error (which seems quite unrelated to anything written in the error code as it sayd that it cannot find a library when thelibrary is there and it does compile if I close without saving and reopen the file...

this is the error:

E:\ARDUINO files\ARDUINO SKETCHBOOK FOLDER\INKH_DJ testing\COMPLETE_BUILT_v2_2\COMPLETE_BUILT_v2_2.ino:4:10: fatal error: Wire.h: No such file or directory
#include <LiquidCrystal_I2C.h>
^~~~~~~~
compilation terminated.
exit status 1

Compilation error: Wire.h: No such file or directory

I strongly suggest that you post your sketch.

I can do that but it's a huge file
I can upload the whole file

  1. Separate your "quote" at "I must say..."
  2. Change every "Serial.print("xyz");" to "Serial.print(F("xyz");"

A single post can contain 120,000 characters. If it is bigger, zip and attach.

COMPLETE_BUILT_v2_2.zip (10.9 KB)
here it is

  1. Change every "Serial.print("xyz");" to "Serial.print(F("xyz");"

That's what I started to do, but also wanted to separate the button stuff and I got this issue. I have to go though all the Serial.print bits, but this error make me think that there could be something I have to address?

Post your program as text in a < CODE > block... it should look like this...

void setup() {
  // 
}

void loop() {
 //
}

I think it might be easier for whoever reads it to use the file I have uploaded (sea above - ignore the silly message in the LCD section :joy:) as it is quite long, in the zip file you have all the separated tabs which make it much easier to read, but I can copy everything and paste it in one long text if needed. By the way I have am in the process of changing all the Serial.print stuff and I can see that it takes A LOT of memory much more than I thougth!!.
This is what I get after changing all the Serial.print statements:

Sketch uses 22828 bytes (70%) of program storage space. Maximum is 32256 bytes.
Global variables use 1105 bytes (43%) of dynamic memory, leaving 1455 bytes for local variables. Maximum is 2560 bytes.

I wander how much the Flash memory can cope with?
Also I have indulged with useless characters in the debug messages...

Post your code in a < CODE > block by starting a reply, click < CODE > and paste your code between the tick marks, over the words: ```type or paste code here```

#define DEBUG

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <light_CD74HC4067.h>
#include <INHK_Pot3.h>
#include "Adafruit_NeoTrellis.h"
#include <ShiftRegister74HC595.h>
#include <Encoder.h>

#define POTS_MIDI_CH 3                // midi channel to be used with POTENTIOMETERS and ENCODERS
#define LED_BUTTON_MIDI_CH 4          // midi channel to be used with BUTTONS and LEDS

#define MIDI_MSG_OFFSET 14            // global offset for midi  messages for all midi message (avoid first 14 numbers)
#define EXTRA_POT_MIDI_MSG_OFFSET 60  // global offset for midi CC for EXTRA POTS
#define LEFT_ENC_MIDI_MSG_OFFSET 70   // global offset for midi CC for left encoder
#define RIGHT_ENC_MIDI_MSG_OFFSET 80  // global offset for midi CC for right encoder

#define EXTRA_POT_NUM 3 // number of additional potentiometers (direct to board, not to mux)

// LCD OBJECTS////////////////////////////////////////////////////////////////////////////////////////////////////////////////

LiquidCrystal_I2C lcdLeft(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcdRight(0x26,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

// LED GLOBALS ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define NUM_LED 16

ShiftRegister74HC595<2> sr(4, 2, 3);  // shift register object, par: <number of shift registers> (data pin, clock pin, latch pin)

uint8_t extraLedR_pin= 22;            // additional led not wired to shift registers
uint8_t extraLedL_pin = 23;           // additional led not wired to shift registers

// POTS GLOBALS///////////////////////////////////////////////////////////////////////////////////////////////////////////////

// mux pots:
CD74HC4067 mux(17, 16, 15, 14);  // create a new CD74HC4067 object with its four select lines

const uint8_t signal_pin0 = A2; // Pin connected to Sig pin of CD74HC4067
const uint8_t signal_pin1 = A0; // Pin connected to Sig pin of CD74HC4067

int lastValues[32]; // Store the last values for each of the 32 potentiometers (16 per multiplexer)
const uint8_t changeThreshold = 2;  // General threshold to avoid jitter
const uint8_t edgeThreshold = 3;    // Stricter threshold near the edges (0 or 127)

// extra pots:
Potentiometer Pot[EXTRA_POT_NUM] = {(A8), (A9), (A10)}; // Creates a number (EXTRA_POT_NUM) of objects of Potentiometer class and passes the pin number as argument
int lastextraPotReading[EXTRA_POT_NUM]; // Variable to store the last readings for comparison

// BUTTON MULTIPLEXER GLOBAL///////////////////////////////////////////////////////////////////////////////////////////////////

const uint8_t muxPin1 = 18; // Signal pin of the first multiplexer
const uint8_t muxPin2 = 20; // Signal pin of the second multiplexer

const uint8_t s0 = 17;  // Select pins
const uint8_t s1 = 16;
const uint8_t s2 = 15;
const uint8_t s3 = 14;

const uint8_t numChannels = 16; // Number of channels per multiplexer

uint8_t buttonPState[2 * numChannels];                                // Last stable state of the button
uint8_t buttonCState[2 * numChannels];                                // button current state
unsigned long lastTimeButtonStateChanged[2 * numChannels] = {0};  // last time button state changed 
unsigned long debounceDuration = 20;                              // debounce time, increase if output flickers

// ENCODER GLOBALS //////////////////////////////////////////////////////////////

Encoder knobLeft(7, 8);
Encoder knobRight(10, 9);

long positionLeft  = -999;
long positionRight = -999;

uint8_t leftEncModeOffset = 0;
uint8_t rightEncModeOffset = 0;

// LCD GLOBALS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

enum lcdActiveMode{            // LCD display modes     
  normal,
  effects,
  scratch
}leftLCD_activeMode, rightLCD_activeMode;

// TRELLIS GLOBALS////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define TRELLIS1_MIDI_CH 1
#define TRELLIS2_MIDI_CH 2

Adafruit_NeoTrellis trellis1; // Instantiate NeoTrellis board - left trellis
Adafruit_NeoTrellis trellis2; // Instantiate NeoTrellis board - right trellis

unsigned long prevMillisTrellis1 = 0;  // Store the last time the first trellis was read
unsigned long prevMillisTrellis2 = 0;  // Store the last time the second trellis was read
#define INTERVAL 20                    // Interval to read the trellises (20 milliseconds)

uint8_t leftDeck = 0;
uint8_t leftPad;              // doesn't need to be initialized as it responds to switch position (button 14)
uint8_t offset_Trellis1 = 0;  // offset for the trellis modes ie. DECK A = 0, PAD A 16, DECK C = 32,  PAD C 48 
uint8_t rightDeck = 0;
uint8_t rightPad;             // doesn't need to be initialized as it responds to switch position (button 23)
uint8_t offset_Trellis2 = 0;  // offset for the trellis modes ie. DECK B = 0, DECK D = 16, PAD B 32, PAD B 48

enum TrellisMode {
  deck0,
  pad0,
  deck1,
  pad1
};
TrellisMode trellis1_activeMode;
TrellisMode trellis2_activeMode;

// Define a callback for key presses on the first board
TrellisCallback press1(keyEvent evt){
  if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
    usbMIDI.sendNoteOn(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis1, 127, TRELLIS1_MIDI_CH);
    // trellis1.pixels.setPixelColor(evt.bit.NUM, 255, 0, 0);    // set the keypad colour when button is pressed
    #ifdef DEBUG
      Serial.print(F("MIDI MSG: Note On\t")); Serial.print(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis1);
      Serial.print(F("\t CH"));Serial.println(TRELLIS1_MIDI_CH);
    #endif
  } else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
    // trellis1.pixels.setPixelColor(evt.bit.NUM, 0);            // set the keypad colour when button is released
    usbMIDI.sendNoteOff(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis1, 127, TRELLIS1_MIDI_CH);
    #ifdef DEBUG
      Serial.print(F("MIDI MSG: Note Off\t")); Serial.print(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis1);
      Serial.print(F("\t CH"));Serial.println(TRELLIS1_MIDI_CH);
    #endif
  }
  trellis1.pixels.show();
  return 0;
}

// Define a callback for key presses on the second board
TrellisCallback press2(keyEvent evt){
  if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
    usbMIDI.sendNoteOn(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis2, 127, TRELLIS2_MIDI_CH);
    // trellis2.pixels.setPixelColor(evt.bit.NUM, 0, 255, 0);     // set the keypad colour when button is pressed
    #ifdef DEBUG
      Serial.print(F("MIDI MSG: Note On\t")); Serial.print(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis2);
      Serial.print(F("\t CH"));Serial.println(TRELLIS2_MIDI_CH);
    #endif
  } else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
    // trellis2.pixels.setPixelColor(evt.bit.NUM, 0);             // set the keypad colour when button is released
    usbMIDI.sendNoteOff(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis2, 127, TRELLIS2_MIDI_CH);
    #ifdef DEBUG
      Serial.print(F("MIDI MSG: Note Off\t")); Serial.print(evt.bit.NUM + MIDI_MSG_OFFSET + offset_Trellis2);
      Serial.print(F("\t CH"));Serial.println(TRELLIS2_MIDI_CH);
    #endif
  }
  trellis2.pixels.show();
  return 0;
}


//SETUP AND LOOP /////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {

  Serial.begin(9600);
  initializeLEDS();
  initializeButtons();
  initializePots();
  initializeExtraPots();
  initilizeLCD();
  initializeTrellis();

  usbMIDI.setHandleNoteOff(OnNoteOff);
  usbMIDI.setHandleNoteOn(OnNoteOn);

  trellisModesSelection();                              //updates the trellis selection modes
  
  leftLCDmodeSpy();                                     // refresh mode LED
  rightLCDmodeSpy();
  #ifdef DEBUG
    Serial.println();
    Serial.println(F("SETUP COMPLETED"));
    Serial.println();
  #endif 
}

void loop() {
  
  readEncoders();     // Call the function that reads encoders 
  updatePots();       // Call the function that reads potentiometers attached to mux 
  updateExtraPots();  // Call the function that reads extra potentiometers (using pot3 library with smooth output)
  readButtons();      // Call the function that reads buttons and performs debugging
  readBothTrellis();        // Call the function that reads both trellis
  
  usbMIDI.read();

}


//LCD FUNCTIONS/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void initilizeLCD(){
  lcdLeft.init();                     // initialize the lcd 
  lcdLeft.init();
  
  lcdLeft.backlight();
  lcdLeft.setCursor(4,0);             // Print a message to the LCD.
  lcdLeft.print("INHK  DJ");
  lcdLeft.setCursor(1,1);
  lcdLeft.print("By A.Monderisi");

  lcdRight.init();                    // initialize the lcd 
  lcdRight.init();

  lcdRight.backlight();
  lcdRight.setCursor(4,0);            // Print a message to the LCD.
  lcdRight.print("INHK  DJ");
  lcdRight.setCursor(0,1);
  lcdRight.print("...I am so cool!");
}
//LED FUNCTIONS/////////////////////////////////////////////////////////////////////////////////////////////////

void initializeLEDS(){
  pinMode(extraLedR_pin, OUTPUT);
  pinMode(extraLedL_pin, OUTPUT);
  ledBlink();
  extraLedBlink();
  extraLedBlink();
  #ifdef DEBUG
    Serial.println();
    Serial.println(F("LEDs initialization completed!"));
    Serial.println();
  #endif
}

void ledBlink(){
    for (int i = 0; i < NUM_LED; i++) {
      sr.set(i, LOW); // set single pin HIGH
    }
    delay(250);

    for (int i = 0; i < NUM_LED; i++) {
      sr.set(i, HIGH); // set single pin HIGH
    }
    delay(250);
    for (int i = 0; i < NUM_LED; i++) {
      sr.set(i, LOW); // set single pin HIGH
    }
    delay(250);

    for (int i = 0; i < NUM_LED; i++) {
      sr.set(i, HIGH); // set single pin HIGH
    }
    delay(250);

    for (int i = 0; i < NUM_LED; i++) {
      sr.set(i, LOW); // set single pin HIGH
    }
    delay(250);

}

void extraLedBlink(){
  digitalWrite(extraLedR_pin, HIGH); // sets the digital pin 13 on
  digitalWrite(extraLedL_pin, HIGH); // sets the digital pin 13 ondelay(500);            // waits for a second
  delay(250);  
  digitalWrite(extraLedR_pin, LOW);  // sets the digital pin 13 off
  digitalWrite(extraLedL_pin, LOW);  // sets the digital pin 13 offdelay(500);            // waits for a second
  delay(250);            // waits for a second
}

//BUTTONS FUNCTIONS///////////////////////////////////////////////////////////////////////////////////////////////////////////



void initializeButtons() {

  #ifdef DEBUG
    Serial.println();
    Serial.println(F("Starting BUTTONS initialization..."));
    Serial.println();
  #endif

  // Set multiplexer control pins as outputs
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);

  // Set the multiplexer signal pins as input with internal pull-up resistor
  pinMode(muxPin1, INPUT_PULLUP);
  pinMode(muxPin2, INPUT_PULLUP);

  buttonsFirstReading();

  #ifdef DEBUG
    Serial.println();
    Serial.println(F("BUTTONS initialization completed!"));
    Serial.println();
  #endif

}

// Function to read from the correct multiplexer based on index (0-31)
int readMux(int index) {
  int controlPin[] = {s0, s1, s2, s3};
  int channel = index % numChannels;
  int muxPin = (index < numChannels) ? muxPin1 : muxPin2;

  // Set the control pins to select the correct channel
  for (int i = 0; i < 4; i++) {
    digitalWrite(controlPin[i], (channel & (1 << i)) ? HIGH : LOW);
  }

  // Read the digital value from the corresponding multiplexer signal pin
  return digitalRead(muxPin);
}

void readButtons() {
  for (int i = 0; i < 2 * numChannels; i++) {                               // Read all 32 channels (0-15 for muxPin1, 16-31 for muxPin2)

    buttonCState[i] = readMux(i);
    
    if((millis() - lastTimeButtonStateChanged[i]) >debounceDuration){
            
      if (buttonCState[i] != buttonPState[i]) {                             // Check if the button state has changed
        lastTimeButtonStateChanged[i] = millis();
        (buttonCState[i] == LOW) ? button_Pressed_Outcome(i) : button_Released_Outcome(i);
        buttonPState[i] = buttonCState[i];                                  // Update the last known button state
      }                              
    }
  }
}

void button_Pressed_Outcome(uint8_t index){
  #ifdef DEBUG
    Serial.print(F("button pressed: "));
    Serial.println(index);
    Serial.print("\t");
  #endif
  switch (index){
    case 3: 
      leftLCD_activeMode = normal; 
      #ifdef DEBUG
        Serial.println(F("***BUTTON NOT YET ASSIGNED***"));
      #endif
      break;

    case 4: 
      leftLCD_activeMode = effects; 
      #ifdef DEBUG
        Serial.println(F("***BUTTON NOT YET ASSIGNED***"));
      #endif
      break;

    case 10: 
      leftLCD_activeMode = scratch; 
      #ifdef DEBUG
        Serial.println(F("***BUTTON NOT YET ASSIGNED***"));
      #endif
      break; 

    case 21: 
      rightLCD_activeMode = normal; 
      #ifdef DEBUG
        Serial.println(F("***BUTTON NOT YET ASSIGNED***"));
      #endif
      break;

    case 31: 
      rightLCD_activeMode = effects; 
      #ifdef DEBUG
        Serial.println(F("***BUTTON NOT YET ASSIGNED***"));
      #endif
      break;

    case 30: 
      rightLCD_activeMode = scratch; 
      #ifdef DEBUG
        Serial.println(F("***BUTTON NOT YET ASSIGNED***"));
      #endif
      break; 

    case 14: 
      leftPad = 1;                                          //change left PAD status to active 
      trellisModesSelection();                              //updates the trellis selection modes
      leftLCDmodeSpy();                                     //update spy LED and print debug message
      trellis1.pixels.clear();                              // clear Trellis LEDs
      break; 

    case 12: 
      leftDeck = !leftDeck;                                 //invert active left DECK from A to C and viceversa
      trellisModesSelection();                              //updates the trellis selection modes
      leftLCDmodeSpy();                                     //update spy LED and print debug message
      trellis1.pixels.clear();                              // clear Trellis LEDs
      break;

    case 23: 
      rightPad = 0;                                         //change right PAD status to active (right and left pad are wired the opposite way, here 0 is active) 
      trellisModesSelection();                              //updates the trellis selection modes
      rightLCDmodeSpy();                                    //update spy LED and print debug message
      trellis2.pixels.clear();                              // clear Trellis LEDs
      break; 

    case 19: 
      rightDeck = !rightDeck;                               //invert active right DECK from B to D and viceversa
      trellisModesSelection();                              //updates the trellis selection modes
      rightLCDmodeSpy();                                    //update spy LED and print debug messageZ
      trellis2.pixels.clear();                              // clear Trellis LEDs
      break;

    #ifdef DEBUG
    case 11: Serial.println(F("left ENC button pressed")); break;
    case 18: Serial.println(F("right ENC button pressed")); break;
    #endif
    default: 
      usbMIDI.sendNoteOn(MIDI_MSG_OFFSET + index, 127, LED_BUTTON_MIDI_CH); 
      #ifdef DEBUG
        Serial.print(F("MIDI msg -> Note ON: ")); 
        Serial.print(MIDI_MSG_OFFSET + index);
        Serial.println(F("\t value: 127")); 
      #endif
      break;

  }
}

void button_Released_Outcome(uint8_t index){
  #ifdef DEBUG
    Serial.print(F("button released: "));
    Serial.print(index);
    Serial.print("\t");
  #endif
    switch (index){
    case 3: 
      #ifdef DEBUG
        Serial.println(F("BUTTON NOT YET ASSIGNED"));
      #endif
      break;

    case 4: 
      #ifdef DEBUG
        Serial.println(F("BUTTON NOT YET ASSIGNED"));
      #endif
      break;

    case 10: 
      #ifdef DEBUG
        Serial.println(F("BUTTON NOT YET ASSIGNED"));
      #endif
      break; 

    case 21: 
      #ifdef DEBUG
        Serial.println(F("BUTTON NOT YET ASSIGNED"));
      #endif
      break;

    case 31: 
      #ifdef DEBUG
        Serial.println(F("BUTTON NOT YET ASSIGNED"));
      #endif
      break;

    case 30: 
      #ifdef DEBUG
        Serial.println(F("BUTTON NOT YET ASSIGNED"));
      #endif
      break; 

    case 14: 
      leftPad = 0;                                          //change left PAD status to inactive 
      trellisModesSelection();                              //updates the trellis selection modes
      leftLCDmodeSpy();                                     //update spy LED and print debug message
      trellis1.pixels.clear();                              // clear Trellis LEDs
      break; 

    case 12: 
      #ifdef DEBUG
        Serial.println(F("Button for A/C selection"));
      #endif
      break;

    case 23: 
      rightPad = 1;                                         //change right PAD status to inactive         
      trellisModesSelection();                              //updates the trellis selection modes
      rightLCDmodeSpy();                                    //update spy LED and print debug message
      trellis2.pixels.clear();                              // clear Trellis LEDs
      break; 

    case 19: 
      #ifdef DEBUG
        Serial.println(F("Button for B/D selection"));
      #endif
      break;

    #ifdef DEBUG
    case 11: Serial.println(F("left ENC button released")); break;
    case 18: Serial.println(F("right ENC button released")); break;
    #endif
    default: 
      usbMIDI.sendNoteOff(MIDI_MSG_OFFSET + index, 127, LED_BUTTON_MIDI_CH); 
      #ifdef DEBUG
        Serial.print(F("MIDI-> Note OFF: ")); 
        Serial.print(MIDI_MSG_OFFSET + index);
        Serial.println(F("\t value: 127")); 
      #endif
      break;
  }
}

void buttonsFirstReading() {
  for (int i = 0; i < 2 * numChannels; i++) {                               // Read all 32 channels (0-15 for muxPin1, 16-31 for muxPin2)

    buttonCState[i] = readMux(i);
    #ifdef DEBUG
      Serial.print(F("Button n: ")); Serial.print(i);
      Serial.print(F("\t Value: ")); Serial.println(buttonCState[i]); 
    #endif
  }
}


//POTS FUNTIONS///////////////////////////////////////////////////////////////////////////////////////////////////////////////

void initializePots(){
  pinMode(signal_pin0, INPUT); // Set as input for reading through signal pin
  pinMode(signal_pin1, INPUT); // Set as input for reading through signal pin

  // Initialize lastValues to a value that will always trigger a change
  for (int i = 0; i < 32; i++) {
      lastValues[i] = -1;  // Use -1 as an initial value to ensure the first read triggers a MIDI message
  }
  #ifdef DEBUG
    Serial.println();
    Serial.println(F("MUX POTS initialization completed!"));
    Serial.println();
  #endif
}

void updatePots(){
  readMux(0, signal_pin0);  // Read from the first multiplexer
  readMux(1, signal_pin1);  // Read from the second multiplexer
}

void readMux(uint16_t num, uint8_t pin) {
  // Loop through channels 0 - 15
  for (int i = 0; i < 16; i++) {
      mux.channel(i);  // Select the channel on the multiplexer
      int val = (analogRead(pin) >> 3);  // Read analog value and scale it down (0-127 for MIDI)

      int index = i + num * 16;  // Calculate the index in the lastValues array

      // Force values close to 0 or 127 to be exactly 0 or 127
      if (val ==1) val = 0;         // Snap to 0 if the value is 1

      // Handle jitter at edges (near 0 or 127) with stricter threshold
      if ((val <= edgeThreshold && abs(val - lastValues[index]) >= edgeThreshold) || 
          (val >= 127 - edgeThreshold && abs(val - lastValues[index]) >= edgeThreshold) || 
          // For general case, use the standard threshold
          abs(val - lastValues[index]) >= changeThreshold) {
          
          usbMIDI.sendControlChange((MIDI_MSG_OFFSET + i + num * 16), val, POTS_MIDI_CH);  // Send MIDI message
          lastValues[index] = val;  // Update the stored value

          #ifdef DEBUG
              // Print only when the value changes significantly, showing mux, channel, and value
              Serial.print(F("Mux-"));
              Serial.print(num);     // Print which mux (0 or 1) this value is from
              Serial.print(F("\t| Ch-"));
              Serial.print(i);       // Print which channel in the mux
              Serial.print(F("\t| Val="));
              Serial.print(val);   // Print the new value
              Serial.print(F("\t| MIDI MSG= CH:"));
              Serial.print(POTS_MIDI_CH);   // Print the midi channel
              Serial.print(F("\t| cc:"));
              Serial.print(MIDI_MSG_OFFSET + i + num * 16);   // Print the midi cc 
              Serial.print(F("\t| value:"));
              Serial.println(val);
          #endif
      }
  }
}

//EXTRAPOTS FUNTIONS//////////////////////////////////////////////////////////////////////////////////////////////////////////

void initializeExtraPots(){

  // Initialize last readings
  for (int i = 0; i < EXTRA_POT_NUM; i++) {
    lastextraPotReading[i] = Pot[i].readValue();
  }

  #ifdef DEBUG  
    Serial.print(F("Number of EXTRA POTS found: "));
    Serial.println(Potentiometer::getCounter()); 
    Serial.println(F("EXTRA POTS initialization completed!"));
    Serial.println();
  #endif  

}

void updateExtraPots() {                                          // Update and print potentiometer readings if they have changed
  for (int i = 0; i < EXTRA_POT_NUM; i++) {
    int val = Pot[i].readValue();

    if (val != lastextraPotReading[i]) {         // Check if the current reading is different from the last reading
      usbMIDI.sendControlChange((EXTRA_POT_MIDI_MSG_OFFSET + i), val, POTS_MIDI_CH);  // Send M
      lastextraPotReading[i] = val;              // Update last reading

      #ifdef DEBUG
        Serial.print(F("Pot #")); Serial.print(i + 1); 
        Serial.write('\t');                                          
        Serial.print(val);
        Serial.write('\t'); 
        Serial.print(F("cc:"));
        Serial.print(EXTRA_POT_MIDI_MSG_OFFSET + i);
        Serial.write('\t'); 
        Serial.print(F("CH:")); 
        Serial.println(POTS_MIDI_CH);                                        
      #endif
    }
  }
}

//ENCODERS FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////////////////

void readEncoders(){

  long newLeft;
  newLeft = knobLeft.read();
    if (newLeft != positionLeft) {
    uint8_t val;
    val = (newLeft > positionLeft) ? 127 : 1;
    usbMIDI.sendControlChange((LEFT_ENC_MIDI_MSG_OFFSET + leftEncModeOffset), val, POTS_MIDI_CH);
    #ifdef DEBUG
    Serial.println();
      Serial.print(F("Left ENC position = "));
      Serial.println(newLeft);
    #endif
    positionLeft = newLeft;
    }

  long newRight;
  newRight = knobRight.read();
  if(newRight != positionRight){
    uint8_t val;
    val = (newRight > positionRight) ? 127 : 1;
    usbMIDI.sendControlChange((RIGHT_ENC_MIDI_MSG_OFFSET + rightEncModeOffset), val, POTS_MIDI_CH);
    #ifdef DEBUG
      Serial.print(F("Right ENC position = "));
      Serial.println(newRight);
      Serial.println();
    #endif
    positionRight = newRight;
  }
}

 
//TRELLIS FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////////////////

void initializeTrellis(){
  // Initialize the first NeoTrellis board
  if (!trellis1.begin(0x2E)) {  // Address for the first board
    #ifdef DEBUG
      Serial.println();
      Serial.println(F("Could not start trellis 1"));
    #endif
    while(1) delay(1);
  } else {
      #ifdef DEBUG
        Serial.println();
        Serial.println(F("Trellis 1 started"));
      #endif
  }

  // Initialize the second NeoTrellis board
  if (!trellis2.begin(0x2F)) {  // Address for the second board
    #ifdef DEBUG
      Serial.println();
      Serial.println(F("Could not start trellis 2"));
    #endif
    while(1) delay(1);
  } else {
      #ifdef DEBUG
        Serial.println();
        Serial.println(F("Trellis 2 started"));
        Serial.println();
      #endif
  }

  // Activate all keys and set callbacks for the first and second board
  for(int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++){
    trellis1.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
    trellis1.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
    trellis1.registerCallback(i, press1);
  }

  for(int i = 0; i < NEO_TRELLIS_NUM_KEYS; i++){
    trellis2.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
    trellis2.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
    trellis2.registerCallback(i, press2);
  }

  // Do a little animation to show we're on for the first and second board
  for (uint16_t i = 0; i < trellis1.pixels.numPixels(); i++) {
    trellis1.pixels.setPixelColor(i, Wheel(map(i, 0, trellis1.pixels.numPixels(), 0, 255)));
    trellis1.pixels.show();
    delay(25);
  }
  for (uint16_t i = 0; i < trellis1.pixels.numPixels(); i++) {
    trellis1.pixels.setPixelColor(i, 0x000000);
    trellis1.pixels.show();
    delay(25);
  }

  for (uint16_t i = 0; i < trellis2.pixels.numPixels(); i++) {
    trellis2.pixels.setPixelColor(i, Wheel(map(i, 0, trellis2.pixels.numPixels(), 0, 255)));
    trellis2.pixels.show();
    delay(25);
  }
  for (uint16_t i = 0; i < trellis2.pixels.numPixels(); i++) {
    trellis2.pixels.setPixelColor(i, 0x000000);
    trellis2.pixels.show();
    delay(25);
  }
}

void readBothTrellis(){
    unsigned long currentMillis = millis();                       // Get the current time   
    if (currentMillis - prevMillisTrellis1 >= INTERVAL) {         // Read from the first trellis board
        prevMillisTrellis1 = currentMillis;                       // Save the current time
        trellis1.read();                                          // Read and handle events from the first board
    }    
    if (currentMillis - prevMillisTrellis2 >= INTERVAL) {         // Read from the second trellis board
        prevMillisTrellis2 = currentMillis;                       // Save the current time
        trellis2.read();                                          // Read and handle events from the second board
    }
}


// CLOUR WHEEL: Input a value 0 to 255 to get a color value. The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
    return trellis1.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
    return trellis1.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
    WheelPos -= 170;
    return trellis1.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  return 0;
}

// ACTIVE TRELLIS SELECTION

void trellisModesSelection(){
  
  // left trellis:

  if (!leftDeck && !leftPad) {
    trellis1_activeMode = deck0;
    offset_Trellis1 = 0;
    // Serial.println("Deck A active");
  }
  if (!leftDeck && leftPad) {
    trellis1_activeMode = pad0;
    offset_Trellis1 = 16;
    // Serial.println("Pad A active");
  }
  if (leftDeck && !leftPad) {
    trellis1_activeMode = deck1;
    offset_Trellis1 = 32;
    // Serial.println("Deck C active");
  }
  if (leftDeck && leftPad) {
    trellis1_activeMode = pad1;
    offset_Trellis1 = 48;
    // Serial.println("Pad C active");
  }

    // right trellis:

  if (!rightDeck && !rightPad) {
    trellis2_activeMode = deck0;
    offset_Trellis2 = 0;
    // Serial.println("Deck A active");
  }
  if (!rightDeck && rightPad) {
    trellis2_activeMode = pad0;
    offset_Trellis2 = 16;
    // Serial.println("Pad A active");
  }
  if (rightDeck && !rightPad) {
    trellis2_activeMode = deck1;
    offset_Trellis2 = 32;
    // Serial.println("Deck C active");
  }
  if (rightDeck && rightPad) {
    trellis2_activeMode = pad1;
    offset_Trellis2 = 48;
    // Serial.println("Pad C active");
  }
}


// RECEIVING MIDI////////////////////////////////////////////////////////////////////////////////////////////////

void OnNoteOn(byte channel, byte note, byte velocity) {
  if(channel == TRELLIS1_MIDI_CH){
    int adjustedNote = note - MIDI_MSG_OFFSET; // this keeps into account that the note has been offset 
    uint32_t color = 0;  // Placeholder for the color to set

    // Determine the color based on the velocity value
    if (velocity < 10)                                // LED OFF
      color = (0);
    else if (velocity == 10)
      color = trellis1.pixels.Color(1, 1, 1);         // white dim
    else if (velocity == 11)
      color = trellis1.pixels.Color(85, 85, 85);   // white 
    else if (velocity == 12)
      color = trellis1.pixels.Color(2, 0, 0);         // red dim
    else if (velocity == 13)
      color = trellis1.pixels.Color(127, 0, 0);       // red bright
    else if (velocity == 14)
      color = trellis1.pixels.Color(0, 1, 0);         // green dim
    else if (velocity == 15)
      color = trellis1.pixels.Color(0, 127, 0);       //green bright
    else if (velocity == 16)
      color = trellis1.pixels.Color(0, 0, 7);         // blue dim
    else if (velocity == 17)
      color = trellis1.pixels.Color(0, 0, 127);       // blue bright
    else if (velocity == 18)
      color = trellis1.pixels.Color(2, 2, 0);         // yellow dim
    else if (velocity == 19)
      color = trellis1.pixels.Color(64, 64, 0);     // yellow bright
    else if (velocity == 20)
      color = trellis1.pixels.Color(5, 2, 0);         // Orange dim
    else if (velocity == 21)
      color = trellis1.pixels.Color(60, 12, 0);       // Orange bright
    else if (velocity == 22)
      color = trellis1.pixels.Color(0, 4, 1);         // Green Sea dim
    else if (velocity == 23)
      color = trellis1.pixels.Color(0, 127, 24);      // Green Sea bright
    else if (velocity == 24)
      color = trellis1.pixels.Color(0, 0, 2);         // Blue sky dim
    else if (velocity == 25)
      color = trellis1.pixels.Color(0, 127, 127);     // Blue sky bright
    else if (velocity == 26)
      color = trellis1.pixels.Color(1, 0, 1);         // Fuxia dim
    else if (velocity == 27)
      color = trellis1.pixels.Color(63, 0, 127);      // Fuxia bright
    else if (velocity > 27 && velocity <= 30) {
      color = trellis1.pixels.Color(0, 0, 0);           // LED off
    }
    else if (velocity >= 30 && velocity <= 40) {        // Green with varying brightness  
      int brightness = map(velocity, 30, 40, 0, 255);   // interpret velocity sent by traktor to determine color of pixel 
      color = trellis1.pixels.Color(0, brightness, 0);  // Green color 
    }
    else if (velocity > 40 && velocity <= 50) {
          int brightness = map(velocity, 40, 50, 0, 255);
      color = trellis1.pixels.Color(0, 0, brightness);  // Blue color
    }
    else if (velocity > 50 && velocity <= 55) {
      color = trellis1.pixels.Color(0, 0, 0);           // LED off
    }
    else if (velocity > 55 && velocity <= 65) {
      int brightness = map(velocity, 55, 65, 0, 255);
      color = trellis1.pixels.Color(brightness, 0, 0);  // Red color
    }
    else
    color = trellis1.pixels.Color(127, 127, 127);


    // Set the pixel color based on the active mode and adjusted note
    switch(trellis1_activeMode){
      case deck0:
        if(adjustedNote < 16) 
          trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), color); 
      break;
      case pad0:
        if((adjustedNote >= 16) && (adjustedNote < 32))  
          trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), color); 
      break;
      case deck1: 
        if((adjustedNote >= 32) && (adjustedNote < 48))   
          trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), color); 
      break;
      case pad1:
        if((adjustedNote >= 48) && (adjustedNote < 64))   
          trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), color); 
      break;
      default:
        return;
    }

    // Show the updated pixel colors
    trellis1.pixels.show();
  }

  if(channel == TRELLIS2_MIDI_CH) {
    int adjustedNote = note - MIDI_MSG_OFFSET; // this keeps into account that the note has been offset 
    uint32_t color = 0;  // Placeholder for the color to set

    // Determine the color based on the velocity value
    if (velocity < 10)                                // LED OFF
      color = (0);
    else if (velocity == 10)
      color = trellis2.pixels.Color(1, 1, 1);         // white dim
    else if (velocity == 11)
      color = trellis2.pixels.Color(85, 85, 85);   // white 
    else if (velocity == 12)
      color = trellis2.pixels.Color(2, 0, 0);         // red dim
    else if (velocity == 13)
      color = trellis2.pixels.Color(127, 0, 0);       // red bright
    else if (velocity == 14)
      color = trellis2.pixels.Color(0, 1, 0);         // green dim
    else if (velocity == 15)
      color = trellis2.pixels.Color(0, 127, 0);       // green bright
    else if (velocity == 16)
      color = trellis2.pixels.Color(0, 0, 7);         // blue dim
    else if (velocity == 17)
      color = trellis2.pixels.Color(0, 0, 127);       // blue bright
    else if (velocity == 18)
      color = trellis2.pixels.Color(2, 2, 0);         // yellow dim
    else if (velocity == 19)
      color = trellis2.pixels.Color(64, 64, 0);     // yellow bright  
    else if (velocity == 20)
      color = trellis2.pixels.Color(5, 2, 0);         // Orange dim
    else if (velocity == 21)
      color = trellis2.pixels.Color(60, 12, 0);       // Orange bright
    else if (velocity == 22)
      color = trellis2.pixels.Color(0, 4, 1);         // Green Sea dim
    else if (velocity == 23)
      color = trellis2.pixels.Color(0, 127, 24);      // Green Sea bright
    else if (velocity == 24)
      color = trellis2.pixels.Color(0, 0, 2);         // Blue sky dim
    else if (velocity == 25)
      color = trellis2.pixels.Color(0, 127, 127);     // Blue sky bright
    else if (velocity == 26)
      color = trellis2.pixels.Color(1, 0, 1);         // Fuxia dim
    else if (velocity == 27)
      color = trellis2.pixels.Color(63, 0, 127);      // Fuxia bright
    
    else if (velocity > 27 && velocity <= 30) {
      color = trellis2.pixels.Color(0, 0, 0);           // LED off
    }

    else if (velocity >= 30 && velocity <= 40) {        // Green with varying brightness  
      int brightness = map(velocity, 30, 40, 0, 255);   // interpret velocity sent by traktor to determine color of pixel 
      color = trellis2.pixels.Color(0, brightness, 0);  // Green color 
    }
    else if (velocity > 40 && velocity <= 50) {
      int brightness = map(velocity, 40, 50, 0, 255);
      color = trellis2.pixels.Color(0, 0, brightness);  // Blue color
    }
    else if (velocity > 50 && velocity <= 55) {
      color = trellis2.pixels.Color(0, 0, 0);           // LED off
    }
    else if (velocity > 55 && velocity <= 65) {
      int brightness = map(velocity, 55, 65, 0, 255);
      color = trellis2.pixels.Color(brightness, 0, 0);  // Red color
    }
    else
      color = trellis2.pixels.Color(127, 127, 127);

    // Set the pixel color based on the active mode and adjusted note
    switch(trellis2_activeMode) {
      case deck0:
        if(adjustedNote < 16) 
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), color); 
      break;
      case pad0:
        if((adjustedNote >= 16) && (adjustedNote < 32))  
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), color); 
      break;
      case deck1: 
        if((adjustedNote >= 32) && (adjustedNote < 48))   
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), color); 
      break;
      case pad1:
        if((adjustedNote >= 48) && (adjustedNote < 64))   
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), color); 
      break;
      default:
        return;
    }

    // Show the updated pixel colors
    trellis2.pixels.show();
  }


  if(channel == LED_BUTTON_MIDI_CH){
    switch(note){
      case 27: sr.set(0, HIGH); break;
      case 23: sr.set(1, HIGH); break;
      case 36: sr.set(2, HIGH); break;
      case 31: sr.set(3, HIGH); break;
      case 15: sr.set(4, HIGH); break;
      case 21: sr.set(5, HIGH); break;
      case 34: sr.set(6, HIGH); break;
      case 16: sr.set(7, HIGH); break;
      case 20: sr.set(8, HIGH); break;
      case 14: sr.set(9, HIGH); break;
      case 19: sr.set(10, HIGH); break;
      case 43: sr.set(11, HIGH); break;
      case 42: sr.set(12, HIGH); break;
      case 41: sr.set(13, HIGH); break;
      case 30: sr.set(14, HIGH); break;
      case 40: sr.set(15, HIGH); break;    
      default: 
        return;
    }
  }

}

void OnNoteOff(byte channel, byte note, byte velocity) {
  if(channel == TRELLIS1_MIDI_CH){
    int adjustedNote = note - MIDI_MSG_OFFSET; // this keeps into account that the note has been offset 
    switch(trellis1_activeMode){
      case deck0:
        if(adjustedNote < 16) 
        trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), 0, 0, 0); 
      break;
      case pad0:
        if((adjustedNote >= 16) && (adjustedNote < 32))  
        trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), 0, 0, 0); 
      break;
      case deck1: 
        if((adjustedNote >= 32) && (adjustedNote < 48))   
        trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), 0, 0, 0); 
      break;
      case pad1:
        if((adjustedNote >= 48) && (adjustedNote < 64))   
        trellis1.pixels.setPixelColor((adjustedNote - offset_Trellis1), 0, 0, 0); 
      break;
      default:
        return;
    }
  trellis1.pixels.show();  
  }

  if(channel == TRELLIS2_MIDI_CH){
    int adjustedNote = note - MIDI_MSG_OFFSET; // this keeps into account that the note has been offset 
    switch(trellis2_activeMode){
      case deck0:
        if(adjustedNote < 16) 
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), 0, 0, 0); 
      break;
      case pad0:
        if((adjustedNote >= 16) && (adjustedNote < 32))  
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), 0, 0, 0); 
      break;
      case deck1: 
        if((adjustedNote >= 32) && (adjustedNote < 48))   
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), 0, 0, 0); 
      break;
      case pad1:
        if((adjustedNote >= 48) && (adjustedNote < 64))   
          trellis2.pixels.setPixelColor((adjustedNote - offset_Trellis2), 0, 0, 0); 
      break;
      default:
        return;
    }
  trellis2.pixels.show();  
  }

  if(channel == LED_BUTTON_MIDI_CH){
    switch(note){
      case 27: sr.set(0, LOW); break;
      case 23: sr.set(1, LOW); break;
      case 36: sr.set(2, LOW); break;
      case 31: sr.set(3, LOW); break;
      case 15: sr.set(4, LOW); break;
      case 21: sr.set(5, LOW); break;
      case 34: sr.set(6, LOW); break;
      case 16: sr.set(7, LOW); break;
      case 20: sr.set(8, LOW); break;
      case 14: sr.set(9, LOW); break;
      case 19: sr.set(10, LOW); break;
      case 43: sr.set(11, LOW); break;
      case 42: sr.set(12, LOW); break;
      case 41: sr.set(13, LOW); break;
      case 30: sr.set(14, LOW); break;
      case 40: sr.set(15, LOW); break;    
      default: 
        return;
    }
  }

}


void leftLCDmodeSpy(){
 switch(trellis1_activeMode){
  case deck0:
    digitalWrite(extraLedL_pin, HIGH);
    offset_Trellis1 = 0;  // offset for the trellis modes ie. DECK A = 0, PAD A 16, DECK C = 32,  PAD C 48
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs 
    #ifdef DEBUG
      Serial.println(F("DECK A"));
    #endif
      break;
  case pad0: 
    digitalWrite(extraLedL_pin, HIGH); 
    offset_Trellis1 = 16;  // offset for the trellis modes ie. DECK A = 0, PAD A 16, DECK C = 32,  PAD C 48
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs
    #ifdef DEBUG
      Serial.println(F("PAD A"));
    #endif
      break;
  case deck1: 
    digitalWrite(extraLedL_pin, LOW); 
    offset_Trellis1 = 32;  // offset for the trellis modes ie. DECK A = 0, PAD A 16, DECK C = 32,  PAD C 48 
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs
    #ifdef DEBUG
      Serial.println(F("DECK C"));
    #endif
      break;
  case pad1:
    digitalWrite(extraLedL_pin, LOW);  
    offset_Trellis1 = 48;  // offset for the trellis modes ie. DECK A = 0, PAD A 16, DECK C = 32,  PAD C 48 
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs
    #ifdef DEBUG
      Serial.println(F("PAD  C"));
    #endif
      break;
  default:
  return;
 }
}


void rightLCDmodeSpy(){
 switch(trellis2_activeMode){
  case deck0:
    digitalWrite(extraLedR_pin, HIGH); 
    offset_Trellis2 = 0;  // offset for the trellis modes ie. DECK B = 0, PAD B 16, DECK D = 32, PAD B 48
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs
    #ifdef DEBUG
      Serial.println(F("DECK B"));
    #endif
      break;
  case pad0: 
    digitalWrite(extraLedR_pin, HIGH); 
    offset_Trellis2 = 16;  // offset for the trellis modes ie. DECK B = 0, PAD B 16, DECK D = 32, PAD B 48
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs
    #ifdef DEBUG
      Serial.println(F("PAD B"));
    #endif
      break;
  case deck1: 
    digitalWrite(extraLedR_pin, LOW); 
    offset_Trellis2 = 32;  // offset for the trellis modes ie. DECK B = 0, PAD B 16, DECK D = 32, PAD B 48
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs
    #ifdef DEBUG
      Serial.println(F("DECK D"));
    #endif
      break;
  case pad1:
    digitalWrite(extraLedR_pin, LOW);  
    offset_Trellis2 = 48;  // offset for the trellis modes ie. DECK B = 0, PAD B 16, DECK D = 32, PAD B 48
    usbMIDI.sendNoteOn(127, 127, LED_BUTTON_MIDI_CH);     // midi message to be assigned to Global - SendMonitorState in Traktor to refresh trellis LEDs
    #ifdef DEBUG
      Serial.println(F("PAD  D"));
    #endif
      break;
  default:
  return;
 }
}





The funny thing is that in order to post the code I copied all the single tabs in on efile and now the arduino IDE compile it without errors. Is this something that could be due to the file being split ? It's really odd. ... if I add this line at the beginning of the script:
"#define DEBUG_BUTTONS" in the file with separated tabs (the one posted above), it causes problems, the behaviour is so odd that the file will not compile even if I then delete the line, but it will if I undo until before writing the line :roll_eyes:.....

The compile error in post #1 says Wire.h does not exist, and it was called from LiquidCrystal_I2C.h (probably) in the library path with < these > and not locally with " these "

To be honest what puzzles me is why the same file compiled without error before adding the #define line and then does no longer compile after I included that line, and more than that, it still does not compile when I remove it again (by deleting that line), although it does when I "undo" it. So I am I am inclined to ignore what the error says, (but maybe I am wrong). If there was a problem finding the library I would have had the error even before adding the line. Also I don't get the error with this code when the file is not split into several tabs....

You got the answer in the preceding post.

Thanks, I am not sure I understood it though. . Specifically I don't understand how the library suddenly is not longer found just after adding a #define statement ...

Which board are you compiling for? Looks like a 32U4 based board.

At the moment I can't compile your sketch (zip) because I do not now which library you use for the MIDI; which MIDI library are you using?

To find out where it goes wrong when you add the #define, you need to look at the file that the IDE actually compiles. To do so,

  1. Enable verbose output during compilation under file/preferences in the IDE.
  2. Compile your sketch.
  3. Copy the output to a text editor (for easy searching).
  4. Search for ino.cpp; you will find a path like C:\Users\yourUsername\AppData\Local\Temp\arduino\sketches\06E41F9258254C620ED25ACBC423E62C\sketch\COMPLETE_BUILT_v2_2.ino.cpp
  5. Using file explorer, navigate to that file and open it with a text editor and inspect.

Before the actual compile the "IDE" combines all your ino files to one big file (the ino.cpp) and somewhere along the line it drops a stitch while doing that. This is a long (and I mean looooooooooooong) known issue, it does not happen often but it does happen at occasion.

1 Like

You are right, I forgot to specify this... you don't need a library it's a teensy2.0 board and you I had to install teensyduino. Then select Tools->USB Type in the IDE Tool menu.
https://www.pjrc.com/teensy/td_midi.html
the problem only arises with the file that I have uploaded. If you try to compile the "one tab" version that I paste in post #15 adding the #define line will not create any issue

Hi @fluxia. I think this is happening due to a bug in Arduino IDE:

Please try this:

  1. Select File > Save from the Arduino IDE menus.
  2. Attempt to compile the sketch again.

Does the sketch now compile successfully, without the unexpected "No such file or directory" error?

1 Like

Thanks I am gonna try and let you know! in the meantime I tried to do what suggesetd by @sterretje
this is the result:
when compiled succesfully (without the added line ie.
#define DEBUGBUTTONS
the files 3 files in the temp folder (Users\yourUsername\AppData\Local\Temp\arduino\sketches\06E41F9258254C620ED25ACBC423E62C\sketch. see pic below:
Capture3
when the line is added and file deos not compile I only get the first file "COMPLETE_BUILT_v2_2.ino.cpp" with th eadditional cpp.d and cpp.o files.

also the difference between the two "COMPLETE_BUILT_v2_2.ino.cpp" files is that the successful version has an additional part. @sterretje I suppose this is the stitch your are referring to (I am going to paste it below). I haven't tried the solution suggested by @ptillisch as yet and will update the post after I have done that.

this is the added "stitch":


// Define a callback for key presses on the first board
#line 116 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\COMPLETE_BUILT_v2_2.ino"
TrellisCallback press1(keyEvent evt);
#line 137 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\COMPLETE_BUILT_v2_2.ino"
TrellisCallback press2(keyEvent evt);
#line 4 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\B-SETUP_LOOP.ino"
void setup();
#line 28 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\B-SETUP_LOOP.ino"
void loop();
#line 4 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\C_LCD.ino"
void initilizeLCD();
#line 3 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\D_LEDS.ino"
void initializeLEDS();
#line 16 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\D_LEDS.ino"
void ledBlink();
#line 43 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\D_LEDS.ino"
void extraLedBlink();
#line 6 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\E_BUTTONS.ino"
void initializeButtons();
#line 35 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\E_BUTTONS.ino"
int readMux(int index);
#line 49 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\E_BUTTONS.ino"
void readButtons();
#line 65 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\E_BUTTONS.ino"
void button_Pressed_Outcome(uint8_t index);
#line 158 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\E_BUTTONS.ino"
void button_Released_Outcome(uint8_t index);
#line 242 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\E_BUTTONS.ino"
void buttonsFirstReading();
#line 4 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\F_POTENTIOMETERS.ino"
void initializePots();
#line 19 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\F_POTENTIOMETERS.ino"
void updatePots();
#line 24 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\F_POTENTIOMETERS.ino"
void readMux(uint16_t num, uint8_t pin);
#line 65 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\F_POTENTIOMETERS.ino"
void initializeExtraPots();
#line 81 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\F_POTENTIOMETERS.ino"
void updateExtraPots();
#line 4 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\G_ENCODERS.ino"
void readEncoders();
#line 4 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\H_TRELLIS.ino"
void initializeTrellis();
#line 71 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\H_TRELLIS.ino"
void readBothTrellis();
#line 85 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\H_TRELLIS.ino"
uint32_t Wheel(byte WheelPos);
#line 100 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\H_TRELLIS.ino"
void trellisModesSelection();
#line 3 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\I_RECEIVING_MIDI.ino"
void OnNoteOn(byte channel, byte note, byte velocity);
#line 213 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\I_RECEIVING_MIDI.ino"
void OnNoteOff(byte channel, byte note, byte velocity);
#line 2 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\L_Helper_funtions.ino"
void leftLCDmodeSpy();
#line 42 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\L_Helper_funtions.ino"
void rightLCDmodeSpy();
#line 116 "C:\\Users\\WEB\\Desktop\\COMPLETE_BUILT_v2_2\\COMPLETE_BUILT_v2_2.ino"

Not wanting to derail the topic but just trying to learn.

I think that @fluxia is using IDE 1.x (at least it was posted in the IDE 1.x category); does this bug in the CLI also affects IDE 1.x?