/*74HC166 Shift Register Demonstration Read from (up to) 16 switches (2x74166) and display values on serial monitor */ // Define Connections to 74HC166 // Arduino UNO #define DATA 8 // Qh (13) #define LOAD 9 // SHLD (15) #define CLOCK 10 // CLK (7) //Debug //#define TRIGGER 11 // CRO Trigger input. Any convenient GPIO int cascade = 1; // Number of additional 74166 void setup() { // Setup Serial Monitor Serial.begin(115200); // Setup 74HC166 connections pinMode(LOAD, OUTPUT); pinMode(CLOCK, OUTPUT); pinMode(DATA, INPUT); //Debug for managing an oscilloscope //pinMode(TRIGGER, OUTPUT); digitalWrite(LOAD, HIGH); // Possibly not needed } void loop() { //Debug //digitalWrite(TRIGGER, HIGH); //digitalWrite(TRIGGER, LOW); byte input_0; byte input_1; // Clock Control. // Holding either of the clock inputs HIGH inhibits clock. // Holding either of the clock inputs LOW enables the other input as the clock. // Clocking occurs on the LOW to HIGH transition. // Clock Inhibit should be changed to HIGH only when clock is high. (Spurious pulse??) // Inhibit control is not required if the input is held LOW in hardware. // This codee assumes that inhibit will not be used. It is only provided to allow // for a free-running clock, which is not relevant when driven from a MCU. // Wait for output to go HIGH. Included for safety - may not be required. do { digitalWrite(CLOCK, HIGH); // Clock Pulse. digitalWrite(CLOCK, LOW); } while (digitalRead(DATA) == LOW); //wait for output to go HIGH digitalWrite(CLOCK, HIGH); // Clock // Write load pulse to LOAD pin digitalWrite(CLOCK, LOW); // Clock Pulse. digitalWrite(LOAD, LOW); // Parallel LOAD Mode // One clock tick to force load digitalWrite(CLOCK, HIGH); // LOAD complete digitalWrite(LOAD, HIGH); // Complete the loading // Get data from 74HC166 input_0 = 0; for (int i = 7; i >= 0; i--) { digitalWrite(CLOCK, LOW); delayMicroseconds(2); input_0 = input_0 | digitalRead(DATA) << i; digitalWrite(CLOCK, HIGH); delayMicroseconds(2); } // Debug. Delay to separate bytes for CRO display //delayMicroseconds(20); // Process an additional device if (cascade == 1) { input_1 = 0; for (int i = 7; i >= 0; i--) { digitalWrite(CLOCK, LOW); delayMicroseconds(2); input_1 = input_1 | digitalRead(DATA) << i; digitalWrite(CLOCK, HIGH); delayMicroseconds(2); } } // Add more devices here. // Print to serial monitor // Invert for convenience. input_0 = ~input_0; if (cascade == 1) input_1 = ~input_1; Serial.print("Pins: "); Serial.print(input_0, HEX); Serial.print(" "); Serial.print(input_0, BIN); if (cascade == 1) { Serial.print(" "); Serial.print(input_1, HEX); Serial.print(" "); Serial.print(input_1, BIN); } Serial.println(); delay(2000); }