// 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 E  21
#define S0 18
#define S1 19
#define S2 22
#define S3 23
#define COM 34
#define NP_PIN 4
#define NUMPIXELS 16

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

const uint8_t controlPins[] = { S0, S1, S2, S3 };

float readMux(uint8_t channel)
{
  // digitalWrite(E, HIGH);  // Disable chip before changing channel.
  // delay(1);
  for(int8_t i = 3; i >= 0; i--)
  {
    int8_t b =  (channel >> i) & 1;
    digitalWrite(controlPins[i], b);
    // Serial.print(b);
  }
  // digitalWrite(E, LOW);  // Enable chip after changing channel.
  // delay(1);
  // Serial.print(": ");
  return analogRead(COM);
}

void setup()
{
  Serial.begin(115200);
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);

  pinMode(E, OUTPUT);
  digitalWrite(E, LOW);
  pixels.begin();
}

void loop()
{
  pixels.clear();
  for(uint8_t i = 0; i < 16; i++)
  {
    float f = readMux(i);
    pixels.setPixelColor(i, pixels.Color(0, f / 4095.0 * 255.0, 0));
    Serial.print(f); Serial.print("\t");
  }
  Serial.println();
  pixels.show();
}
CD74HC4067Breakout