// CD74HC4067
// 16-Channel Analog Multiplexer
// Demultiplexing not implemented for this simulation.
// https://www.ti.com/lit/ds/symlink/cd74hc4067.pdf

#include <Adafruit_NeoPixel.h>

#define E1 21
#define S01 7
#define S11 8
#define S21 9
#define S31 3
#define COM1 A3

#define E2 22
#define S02 4
#define S12 5
#define S22 6
#define S32 2
#define COM2 A4

#define NP_PIN A1
#define NUMPIXELS 32

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NP_PIN, NEO_GRB + NEO_KHZ800);

const uint8_t controlPins1[] = { S01, S11, S21, S31 };
const uint8_t controlPins2[] = { S02, S12, S22, S32 };

float readMux1(uint8_t channel)
{
  digitalWrite(E1, HIGH);  // Disable chip before changing channel.
  delay(1);
  for(int8_t i = 3; i >= 0; i--)
  {
    int8_t b =  (channel >> i) & 1;
    digitalWrite(controlPins1[i], b);
  }
  digitalWrite(E1, LOW);  // Enable chip after changing channel.
  delay(1);
  return analogRead(COM1);
}

float readMux2(uint8_t channel)
{
  digitalWrite(E2, HIGH);  // Disable chip before changing channel.
  delay(1);
  for(int8_t i = 3; i >= 0; i--)
  {
    int8_t b =  (channel >> i) & 1;
    digitalWrite(controlPins2[i], b);
  }
  digitalWrite(E2, LOW);  // Enable chip after changing channel.
  delay(1);
  return analogRead(COM2);
}

void setup()
{
  Serial.begin(115200);
  pinMode(S01, OUTPUT);
  pinMode(S11, OUTPUT);
  pinMode(S21, OUTPUT);
  pinMode(S31, OUTPUT);
  pinMode(S02, OUTPUT);
  pinMode(S12, OUTPUT);
  pinMode(S22, OUTPUT);
  pinMode(S32, OUTPUT);
  pixels.begin();
}

void loop()
{
  pixels.clear();
  for(uint8_t i = 0; i < 16; i++)
  {
    float f1 = readMux1(i);
    pixels.setPixelColor(i, pixels.Color(0, f1 / 4095.0 * 255.0, 0));
    float f2 = readMux2(i);
    pixels.setPixelColor(i+16, pixels.Color(0, f2 / 4095.0 * 255.0, 0));
  }
  pixels.show();
}
CD74HC4067Breakout
CD74HC4067Breakout