How to extend the inputs and outputs of any microcontroller.

This project uses two key ICs: the 74HC4051 analog multiplexer/demultiplexer and the 74HC165 shift register. It controls an 8-button input system and a PWM-controlled LED system. The 74HC165 shift register reads up to 8 buttonswith just a few GPIO pins. The 74HC4051 multiplexer controls 8 LEDs with one PWM pin. It scans buttons, updates LEDs, and sets their brightness. When a button is pressed, the LED toggles between ON (full brightness) and OFF using an XOR operation. The PWM pin (D9) controls LED brightness, saving microcontroller resources. The system runs in a loop, checking for button presses and updating LEDs. This method reduces pins needed while maintaining control over inputs and outputs.

CODE:

// File: combined_74hc4051_74hc165_shared_d5.ino

// 74HC4051 pins
#define A 2
#define B 3
#define C 4
#define PWM_PIN 9

// 74HC165 pins
#define SH_LD 5   // Shared Shift/Load Bar pin
#define CLK 6     // Clock pin
#define SO 7      // Serial Output pin

// Brightness levels
#define LED_ON 255
#define LED_OFF 0

// Store LED states (ON/OFF)
byte ledStates = 0;

void setup() {
  // 74HC4051 control pins
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);

  // PWM output pin
  pinMode(PWM_PIN, OUTPUT);

  // 74HC165 control pins
  pinMode(SH_LD, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(SO, INPUT);

  Serial.begin(9600);
}

void loop() {
  // Read button states from 74HC165
  byte buttonStates = readShiftRegister();

  // Loop through each button/LED
  for (int i = 0; i < 8; i++) {
    // Check if button is pressed
    if ((buttonStates >> i) & 0x01) {
      // Toggle LED state
      ledStates ^= (1 << i); // XOR to toggle the bit
    }

    // Set the brightness for the corresponding LED
    selectChannel(i);
    if ((ledStates >> i) & 0x01) {
      analogWrite(PWM_PIN, LED_ON);
    } else {
      analogWrite(PWM_PIN, LED_OFF);
    }
    delay(30);
  }

  //delay(50); // Small delay for stability
}

// Function to read the shift register
byte readShiftRegister() {
  // Load parallel data into shift register
  digitalWrite(SH_LD, LOW);  // Activate parallel load
  delayMicroseconds(5);      // Wait for data to load
  digitalWrite(SH_LD, HIGH); // Set to shift mode

  byte data = 0;

  // Shift out the bits one by one
  for (int i = 0; i < 8; i++) {
    digitalWrite(CLK, LOW); // Pulse the clock to shift data
    delayMicroseconds(5);
    data |= (digitalRead(SO) << (7 - i)); // Read the SO pin and store the bit
    digitalWrite(CLK, HIGH);
  }

  return data;
}

// Function to select the active channel on the 74HC4051
void selectChannel(int channel) {
  digitalWrite(A, channel & 0x01);
  digitalWrite(B, (channel >> 1) & 0x01);
  digitalWrite(C, (channel >> 2) & 0x01);
}


Schematic:

Proteus screenshot of the shifter, the multiplexer and the arduino uno

Pin connection table:

For the 74HC165
pin connections to the 74HC165

For the 74HC4051

Pin connections to the 74HC4051

Working Principle

  1. Button State Reading (74HC165):

    • The Arduino loads parallel data from 8-button inputs into the 74HC165 shift register.
    • It then shifts out the data serially, reading each button state one by one.
    • If a button is pressed, its corresponding bit is set in the buttonStates variable.
  2. LED Control (74HC4051):

    • The system loops through all 8 LEDs, using the 74HC4051 multiplexer to select which LED to control.
    • If the corresponding button is pressed, it toggles the LED ON/OFF using an XOR operation.
    • The LED brightness is set using PWM on pin D9, meaning the LED is either fully ON (255) or OFF (0).
  3. Efficient GPIO Usage:

    • Instead of using 16 separate GPIO pins, the project uses just 6 digital pins for controlling 8 buttons and 8 LEDs.
    • The 74HC165 shift register allows reading multiple inputs through a single data pin.
    • The 74HC4051 multiplexer enables control of multiple LEDs using a single PWM pin.

This design is perfect for projects needing efficient input reading and output control with minimal pin usage.

Comments