// 74HC4067 multiplexer demonstration for 16 buttons and 16 relays

// Control pins for 74HC4067 for buttons
#define btnMux_S0 7   // S0 pin (A)
#define btnMux_S1 6   // S1 pin (B)
#define btnMux_S2 5   // S2 pin (C)
#define btnMux_S3 4   // S3 pin (D)

// Control pins for 74HC4067 for relays
#define relayMux_S0 3   // S0 pin (A)
#define relayMux_S1 2   // S1 pin (B)
#define relayMux_S2 1   // S2 pin (C)
#define relayMux_S3 0   // S3 pin (D)

#define analogPin A0  // Analog pin connected to 74HC4067 Z pin for reading button states

byte btnControlPins[] = {
  B00000000, B10000000, B01000000, B11000000,
  B00100000, B10100000, B01100000, B11100000,
  B00010000, B10010000, B01010000, B11010000,
  B00110000, B10110000, B01110000, B11110000
};

byte relayControlPins[] = {
  B00000000, B10000000, B01000000, B11000000,
  B00100000, B10100000, B01100000, B11100000,
  B00010000, B10010000, B01010000, B11010000,
  B00110000, B10110000, B01110000, B11110000
};

byte btnValues[16] = {0};  // Holds button states read from 74HC4067
byte relayStates[16] = {0}; // Holds relay on/off states

void setup()
{
  Serial.begin(9600);

  // Set control pins as outputs
  pinMode(btnMux_S0, OUTPUT);
  pinMode(btnMux_S1, OUTPUT);
  pinMode(btnMux_S2, OUTPUT);
  pinMode(btnMux_S3, OUTPUT);

  pinMode(relayMux_S0, OUTPUT);
  pinMode(relayMux_S1, OUTPUT);
  pinMode(relayMux_S2, OUTPUT);
  pinMode(relayMux_S3, OUTPUT);

  // Initialize serial monitor and delay
  delay(1000);
}

void loop()
{
  // Read button states
  for (int i = 0; i < 16; i++) {
    setBtnPin(i); // Set pin on 74HC4067 for reading button state
    btnValues[i] = digitalRead(analogPin); // Read button state and store in array
  }

  // Display button states
  displayButtonStates();

  // Control relays based on button states (example)
  controlRelays();
}

void setBtnPin(int pin)
{
  digitalWrite(btnMux_S0, bitRead(btnControlPins[pin], 0));
  digitalWrite(btnMux_S1, bitRead(btnControlPins[pin], 1));
  digitalWrite(btnMux_S2, bitRead(btnControlPins[pin], 2));
  digitalWrite(btnMux_S3, bitRead(btnControlPins[pin], 3));
}

void setRelayPin(int pin)
{
  digitalWrite(relayMux_S0, bitRead(relayControlPins[pin], 0));
  digitalWrite(relayMux_S1, bitRead(relayControlPins[pin], 1));
  digitalWrite(relayMux_S2, bitRead(relayControlPins[pin], 2));
  digitalWrite(relayMux_S3, bitRead(relayControlPins[pin], 3));
}

void displayButtonStates()
{
  Serial.println("Button States:");
  Serial.println("=================");
  for (int i = 0; i < 16; i++) {
    Serial.print("Button ");
    Serial.print(i);
    Serial.print(": ");
    Serial.println(btnValues[i]);
  }
  Serial.println("=================");
  Serial.println();
}

void controlRelays()
{
  // Example: Control relays based on button states
  for (int i = 0; i < 16; i++) {
    if (btnValues[i] == HIGH) {
      // Turn on corresponding relay
      setRelayPin(i);
      digitalWrite(relayMux_S1, HIGH);
      relayStates[i] = 1;
    } else {
      // Turn off corresponding relay
      setRelayPin(i);
      digitalWrite(relayMux_S1, LOW);
      relayStates[i] = 0;
    }
    delay(100); // Delay for stability (adjust as necessary)
  }
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
NOCOMNCVCCGNDINLED1PWRRelay Module
relay1:VCC
relay1:GND
relay1:IN
relay1:NC
relay1:COM
relay1:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay2:VCC
relay2:GND
relay2:IN
relay2:NC
relay2:COM
relay2:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay3:VCC
relay3:GND
relay3:IN
relay3:NC
relay3:COM
relay3:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay4:VCC
relay4:GND
relay4:IN
relay4:NC
relay4:COM
relay4:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay5:VCC
relay5:GND
relay5:IN
relay5:NC
relay5:COM
relay5:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay6:VCC
relay6:GND
relay6:IN
relay6:NC
relay6:COM
relay6:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay7:VCC
relay7:GND
relay7:IN
relay7:NC
relay7:COM
relay7:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay8:VCC
relay8:GND
relay8:IN
relay8:NC
relay8:COM
relay8:NO
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
btn4:1.l
btn4:2.l
btn4:1.r
btn4:2.r
btn5:1.l
btn5:2.l
btn5:1.r
btn5:2.r
btn6:1.l
btn6:2.l
btn6:1.r
btn6:2.r
btn7:1.l
btn7:2.l
btn7:1.r
btn7:2.r
btn8:1.l
btn8:2.l
btn8:1.r
btn8:2.r
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
r4:1
r4:2
r5:1
r5:2
r6:1
r6:2
r7:1
r7:2
r8:1
r8:2
led1:A
led1:C
led2:A
led2:C
led3:A
led3:C
led4:A
led4:C
led5:A
led5:C
led6:A
led6:C
led7:A
led7:C
led8:A
led8:C
NOCOMNCVCCGNDINLED1PWRRelay Module
relay9:VCC
relay9:GND
relay9:IN
relay9:NC
relay9:COM
relay9:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay10:VCC
relay10:GND
relay10:IN
relay10:NC
relay10:COM
relay10:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay11:VCC
relay11:GND
relay11:IN
relay11:NC
relay11:COM
relay11:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay12:VCC
relay12:GND
relay12:IN
relay12:NC
relay12:COM
relay12:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay13:VCC
relay13:GND
relay13:IN
relay13:NC
relay13:COM
relay13:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay14:VCC
relay14:GND
relay14:IN
relay14:NC
relay14:COM
relay14:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay15:VCC
relay15:GND
relay15:IN
relay15:NC
relay15:COM
relay15:NO
NOCOMNCVCCGNDINLED1PWRRelay Module
relay16:VCC
relay16:GND
relay16:IN
relay16:NC
relay16:COM
relay16:NO
btn9:1.l
btn9:2.l
btn9:1.r
btn9:2.r
btn10:1.l
btn10:2.l
btn10:1.r
btn10:2.r
btn11:1.l
btn11:2.l
btn11:1.r
btn11:2.r
btn12:1.l
btn12:2.l
btn12:1.r
btn12:2.r
btn13:1.l
btn13:2.l
btn13:1.r
btn13:2.r
btn14:1.l
btn14:2.l
btn14:1.r
btn14:2.r
btn15:1.l
btn15:2.l
btn15:1.r
btn15:2.r
btn16:1.l
btn16:2.l
btn16:1.r
btn16:2.r
r9:1
r9:2
r10:1
r10:2
r11:1
r11:2
r12:1
r12:2
r13:1
r13:2
r14:1
r14:2
r15:1
r15:2
r16:1
r16:2
led9:A
led9:C
led10:A
led10:C
led11:A
led11:C
led12:A
led12:C
led13:A
led13:C
led14:A
led14:C
led15:A
led15:C
led16:A
led16:C
mux1:I15
mux1:I14
mux1:I13
mux1:I12
mux1:I11
mux1:I10
mux1:I9
mux1:I8
mux1:I7
mux1:I6
mux1:I5
mux1:I4
mux1:I3
mux1:I2
mux1:I1
mux1:I0
mux1:COM
mux1:S3
mux1:S2
mux1:S1
mux1:S0
mux1:EN
mux1:VCC
mux1:GND
mux2:I15
mux2:I14
mux2:I13
mux2:I12
mux2:I11
mux2:I10
mux2:I9
mux2:I8
mux2:I7
mux2:I6
mux2:I5
mux2:I4
mux2:I3
mux2:I2
mux2:I1
mux2:I0
mux2:COM
mux2:S3
mux2:S2
mux2:S1
mux2:S0
mux2:EN
mux2:VCC
mux2:GND