// How to Interface 74HC4067 16 channel multiplexer
// https://www.youtube.com/watch?v=E6gTHbI4cjI
// TECHOOL Lab
// https://www.youtube.com/watch?v=E6gTHbI4cjI
/*
# ---------------- Use to Enter in System
*----------------- Use to Stop 

Now if you want to see channel 15 performance then:
Press 15
then Press #
See performance on serial Monitor Or LCD
before you want to see other channel First exit from System Press *

Then Proceed as above mentioned steps
*/

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <Keypad.h>              // keypad Library
#include <CD74HC4067.h>         // 16 channel analog Mux Library (CD74HC4067)

#define R0 2                 //define Row 0 (R0) for Keypaad
#define R1 3                //define Row 1 (R1) for Keypaad
#define R2 4               //define Row 2 (R2) for Keypaad
#define R3 5              //define Row 3 (R3) for Keypaad

#define C0 6            //define Column 0 (C0) for Keypaad
#define C1 7           //define Column 1 (C1) for Keypaad
#define C2 8          //define Column 2 (C2) for Keypaad
#define C3 9         //define Column 3 (C3) for Keypaad

#define S0 10      //define Select 0 (S0) for MUX
#define S1 11     //define Select 1 (S1) for MUX
#define S2 12    //define Select 2 (S2) for MUX
#define S3 13   //define Select 3 (S3) for MUX


CD74HC4067 my_mux(S0, S1, S2, S3);  // create a new CD74HC4067 object with its four control pins

const int sensor_pin = A0; // select a pin to share with the 16 channels of the CD74HC4067
const int EN_pin = A1;  // define enable pin

const byte ROWS = 4;  // No of Rows of Keyapd
const byte COLS = 4;  // No of Column of Keyapd

const int min_value = 48;  // int value of char '0'
const int max_value = 57;  // int value of char '9'

//define the symbols on the buttons of the keypads
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

char customKey;

byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);  // initialize an instance of class NewKeypad

int Channel = 0;
int mode = 0;

void setup()
{
  pinMode(EN_pin, OUTPUT); // set the initial mode of the Enable pin.
  digitalWrite(EN_pin, HIGH);
  Serial.begin(9600);
  Serial.println("*****Enter Channel*****");
  lcd.init();
  lcd.backlight();
  lcd.setCursor(1, 0);
  lcd.print("Hello, Wokwi!");
}

void loop()
{
  customKey = customKeypad.getKey();   // Get Character from keypad
  
  if (customKey >= min_value && customKey <= max_value)
  {
    Channel = Channel * 10 + customKey - min_value;   // store channel value
  }
  
  else if ((customKey == '#' || mode == 1) && Channel <= 15)
  {
    digitalWrite(EN_pin, LOW);
    mode = 1;
    my_mux.channel(Channel);
    String val = "Channel " + String(Channel) + " Val: " + String(analogRead(sensor_pin));
    Serial.println(val);
    delay(300);
    
    if (customKey == '*')
    {
      reset_program();
    }
  }
  
  else if (Channel > 15)
  {
    Serial.print("\n");
    Serial.println("Please Enter Channel 0 to 15");
    reset_program();
  }
}

void reset_program()
{
  mode = 0;
  Channel = 0;
  digitalWrite(EN_pin, HIGH);
  Serial.print("\n");
  Serial.println("*****Enter Channel*****");
}