#include <Keypad.h>

#define ENC1_OUTA 9
#define ENC1_OUTB 10
#define ENC2_OUTA 11
#define ENC2_OUTB 12
#define ENC3_OUTA 13
#define ENC3_OUTB 14
#define ENC4_OUTA A5
#define ENC4_OUTB A6
#define ENC5_OUTA A8   // inverted encoders, thumb knob
#define ENC5_OUTB A7
#define ENC6_OUTA A10
#define ENC6_OUTB A9

int counter1 = 0;
int counter2 = 0;
int counter3 = 0;
int counter4 = 0;
int counter5 = 0;
int counter6 = 0;

int aState1;
int aLastState1;
int aState2;
int aLastState2;
int aState3;
int aLastState3;
int aState4;
int aLastState4;
int aState5;
int aLastState5;
int aState6;
int aLastState6;

const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', '4'},
  {'5', '6', '7', '8'},
  {'9', 'A', 'B', 'C'},
  {'D', 'E', 'S', 'I'}
};

byte colPins[ROWS] = {41, 43, 45, 47}; // Pins used for the rows of the keypad
byte rowPins[COLS] = {33, 35, 37, 39}; // Pins used for the columns of the keypad
// Initialise the Keypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

const int POT_1_PIN = A0;
const int POT_2_PIN = A1;
const int POT_3_PIN = A2;

int pot1Value = 0;
int pot2Value = 0;
int pot3Value = 0;

const int xPin = A3;  // X axis connected to analog pin A0
const int yPin = A4;  // Y axis connected to analog pin A1
int xValue = 0;       // variable to store the X axis value
int yValue = 0;       // variable to store the Y axis value

const int togglePin1 = 15; // toggle switch 1 is connected to pin 2
const int togglePin2 = 16; // toggle switch 2 is connected to pin 3

int toggleState1 = 0; // variable for storing the state of toggle switch 1
int toggleState2 = 0; // variable for storing the state of toggle switch 2

void setup() {
  pinMode(ENC1_OUTA, INPUT);
  pinMode(ENC1_OUTB, INPUT);
  pinMode(ENC2_OUTA, INPUT);
  pinMode(ENC2_OUTB, INPUT);
  pinMode(ENC3_OUTA, INPUT);
  pinMode(ENC3_OUTB, INPUT);
  pinMode(ENC4_OUTA, INPUT);
  pinMode(ENC4_OUTB, INPUT);
  pinMode(ENC5_OUTA, INPUT);
  pinMode(ENC5_OUTB, INPUT);
  pinMode(ENC6_OUTA, INPUT);
  pinMode(ENC6_OUTB, INPUT);

    pinMode(togglePin1, INPUT_PULLUP); 
  pinMode(togglePin2, INPUT_PULLUP); 
  Serial.begin(9600);

  aLastState1 = digitalRead(ENC1_OUTA);
  aLastState2 = digitalRead(ENC2_OUTA);
  aLastState3 = digitalRead(ENC3_OUTA);
  aLastState4 = digitalRead(ENC4_OUTA);
  aLastState5 = digitalRead(ENC5_OUTA);
  aLastState6 = digitalRead(ENC6_OUTA);
}

void loop() {
  aState1 = digitalRead(ENC1_OUTA);
  if (aState1 != aLastState1) {
    if (digitalRead(ENC1_OUTB) != aState1) {
      counter1++;
    } else {
      counter1--;
    }
    Serial.print("Encoder 1 Position: ");
    Serial.println(counter1);
  }
  aLastState1 = aState1;

  aState2 = digitalRead(ENC2_OUTA);
  if (aState2 != aLastState2) {
    if (digitalRead(ENC2_OUTB) != aState2) {
      counter2++;
    } else {
      counter2--;
    }
    Serial.print("Encoder 2 Position: ");
    Serial.println(counter2);
  }
  aLastState2 = aState2;

  aState3 = digitalRead(ENC3_OUTA);
  if (aState3 != aLastState3) {
    if (digitalRead(ENC3_OUTB) != aState3) {
      counter3++;
    } else {
      counter3--;
    }
    Serial.print("Encoder 3 Position: ");
    Serial.println(counter3);
  }
  aLastState3 = aState3;

  aState4 = digitalRead(ENC4_OUTA);
  if (aState4 != aLastState4) {
    if (digitalRead(ENC4_OUTB) != aState4) {
      counter4++;
    } else {
      counter4--;
    }
    Serial.print("Encoder 4 Position: ");
    Serial.println(counter4);
  }
  aLastState4 = aState4;

aState5 = digitalRead(ENC5_OUTA);
if (aState5 != aLastState5) {
if (digitalRead(ENC5_OUTB) != aState5) {
counter5++;
} else {
counter5--;
}
Serial.print("Encoder 5 Position: ");
Serial.println(counter5);
}
aLastState5 = aState5;

aState6 = digitalRead(ENC6_OUTA);
if (aState6 != aLastState6) {
if (digitalRead(ENC6_OUTB) != aState6) {
counter6++;
} else {
counter6--;
}
Serial.print("Encoder 6 Position: ");
Serial.println(counter6);
}
aLastState6 = aState6;

// Read the pushed button
  char button = customKeypad.getKey();

  if (button) {
    Serial.println(button);
  }

  int newPot1Value = analogRead(POT_1_PIN);
  int newPot2Value = analogRead(POT_2_PIN);
  int newPot3Value = analogRead(POT_3_PIN);

  if (newPot1Value != pot1Value) {
    Serial.print("Potentiometer 1: ");
    Serial.println(newPot1Value);
    pot1Value = newPot1Value;
  }

  if (newPot2Value != pot2Value) {
    Serial.print("Potentiometer 2: ");
    Serial.println(newPot2Value);
    pot2Value = newPot2Value;
  }

  if (newPot3Value != pot3Value) {
    Serial.print("Potentiometer 3: ");
    Serial.println(newPot3Value);
    pot3Value = newPot3Value;
  }

   // read the X axis value
  int newXValue = analogRead(xPin);
  if (newXValue != xValue) {
    xValue = newXValue;
    Serial.print("X axis value: ");
    Serial.println(xValue);
  }

  // read the Y axis value
  int newYValue = analogRead(yPin);
  if (newYValue != yValue) {
    yValue = newYValue;
    Serial.print("Y axis value: ");
    Serial.println(yValue);
  }

   int newToggleState1 = digitalRead(togglePin1); // read the state of toggle switch 1
  int newToggleState2 = digitalRead(togglePin2); // read the state of toggle switch 2

  if (newToggleState1 != toggleState1) { // if the state of toggle switch 1 has changed
    toggleState1 = newToggleState1; // update the state variable
    Serial.print("Toggle Switch 1: "); // print the switch name
    Serial.println(toggleState1); // print the new state value
  }

  if (newToggleState2 != toggleState2) { // if the state of toggle switch 2 has changed
    toggleState2 = newToggleState2; // update the state variable
    Serial.print("Toggle Switch 2: "); // print the switch name
    Serial.println(toggleState2); // print the new state value
  }
}