CD4066 - Quad Analog Switch

By barber408
// CD4066B — Quad Bilateral Analog Switch (stable version)

// ---- Tunables ----
const float RON   = 2.0;       // on resistance
const float ROFF  = 1e8;         // off resistance (use 1e8 for solver stability)
const float RLEAK = 1e9;         // tiny bleeder to VSS per terminal
const float TH_LO = 0.4;        // Schmitt low threshold (fraction of VDD)
const float TH_HI = 0.8;        // Schmitt high threshold

static bool en1=false, en2=false, en3=false, en4=false;

void setup() {
    chipName("CD4066B");

    // Use INPUT for pass-through analog terminals (passive)
    pin(1,  "1Y",  INPUT);
    pin(2,  "1Z",  INPUT);
    pin(3,  "1EN", INPUT);

    pin(4,  "2EN", INPUT);
    pin(5,  "2Z",  INPUT);
    pin(6,  "2Y",  INPUT);

    pin(7,  "VSS", GROUND);

    pin(8,  "3Y",  INPUT);
    pin(9,  "3Z",  INPUT);
    pin(10, "3EN", INPUT);

    pin(11, "4EN", INPUT);
    pin(12, "4Z",  INPUT);
    pin(13, "4Y",  INPUT);

    pin(14, "VDD", POWER);

    // Main controllable paths (must be NON_LINEAR so we can vary later)
    resistance(1,  2,  ROFF, NON_LINEAR);   // 1Y–1Z
    resistance(6,  5,  ROFF, NON_LINEAR);   // 2Y–2Z
    resistance(8,  9,  ROFF, NON_LINEAR);   // 3Y–3Z
    resistance(13, 12, ROFF, NON_LINEAR);   // 4Y–4Z

    // Tiny bleeders to VSS (LINEAR) to prevent floating-node explosions
    resistance(1,  7,  RLEAK);
    resistance(2,  7,  RLEAK);
    resistance(5,  7,  RLEAK);
    resistance(6,  7,  RLEAK);
    resistance(8,  7,  RLEAK);
    resistance(9,  7,  RLEAK);
    resistance(12, 7,  RLEAK);
    resistance(13, 7,  RLEAK);
}

// Simple Schmitt trigger vs VDD
static bool schmitt(bool last, float vin, float vdd) {
    float hi = TH_HI * vdd;
    float lo = TH_LO * vdd;
    return last ? (vin > lo) : (vin >= hi);
}

void loop() {
    float vdd = analogRead(14);
    if (vdd < 0.01) vdd = 5.0; // guard if VDD left unconnected in a test

    // Read enables
    float e1 = analogRead(3);
    float e2 = analogRead(4);
    float e3 = analogRead(10);
    float e4 = analogRead(11);

    // Update latches
    en1 = schmitt(en1, e1, vdd);
    en2 = schmitt(en2, e2, vdd);
    en3 = schmitt(en3, e3, vdd);
    en4 = schmitt(en4, e4, vdd);

    // Apply the switch states
    resistance(1,  2,  en1 ? RON : ROFF);
    resistance(6,  5,  en2 ? RON : ROFF);
    resistance(8,  9,  en3 ? RON : ROFF);
    resistance(13, 12, en4 ? RON : ROFF);
}