I have turn on 16 LEDs one by one using two 74HC595 shift register. I have some doubt regarding my code and need some help

I have written the following Arduino code to turn on LEDs one by one using a shift register. However, I have a few questions regarding the implementation and would appreciate any guidance or clarification. I am new to Arduino development.

Below is my code:

// ST_CP pin 12
const int latchPin = 8;
// SH_CP pin 11
const int clockPin = 12;
// DS pin 14
const int dataPin = 11;

void setup() {
  // Configure pins as outputs
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  for (int i = 0; i < 16; i++) {
    byte lowLED = lowByte(1 << i);
    byte highLED = highByte(1 << i);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, lowLED);
    shiftOut(dataPin, clockPin, LSBFIRST, highLED);
    digitalWrite(latchPin, HIGH);

    delay(1000);
  }
}

My Questions:

  1. Why is the shiftOut() function called twice — once for lowLED and once for highLED?
    I would like to understand the reasoning behind using two calls instead of a single one.
  2. Why are two separate byte variables (lowLED and highLED) used?
    Is it possible to achieve the same result using only a single variable?
  3. Can we use shiftOut(dataPin, clockPin, LSBFIRST, 0B0001000000000000); directly to control a specific LED?
    For example, if I want to turn on the 10th LED, can I shift out a 16-bit binary value like 0B0001000000000000 directly?

Thank you in advance for your assistance. I truly appreciate your support and look forward to your insights.

Welcome to the forum

You started a topic in the Uncategorised category of the forum when its description explicitly tells you not to

Your topic has been moved to a relevant category. Please be careful in future when deciding where to start new topics

Shifts out a byte of data

Answer for question 2: because that's how you wrote the code, didn't you?

If you want a single variable, try this:

// ST_CP pin 12
const int latchPin = 8;
// SH_CP pin 11
const int clockPin = 12;
// DS pin 14
const int dataPin = 11;

void setup() {
  // Configure pins as outputs
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  for (int i = 0; i < 16; i++) {
    uint16_t LED = 1 << i;

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, lowByte(LED));
    shiftOut(dataPin, clockPin, LSBFIRST, highByte(LED));
    digitalWrite(latchPin, HIGH);

    delay(1000);
  }
}

Yes, but not using shiftOut(), as already explained.

This code (untested) uses hardware SPI and can send all 16 bits in a single call.

With shiftOut(), you can use any pins you like, but with hardware SPI the pins are fixed and depend on the model of Arduino you are using. I have assumed you are using Uno R3 or similar Arduino based on ATMEGA328.

#include <SPI.h>

// ST_CP pin 12
const int latchPin = 10;
// SH_CP pin 11
const int clockPin = 13;
// DS pin 14
const int dataPin = 11;

void setup() {
  // Configure pins as outputs
  pinMode(latchPin, OUTPUT);
  SPI.begin();
  SPI.beginTransaction(SPISettings(10000000, LSBFIRST, SPI_MODE0));
}

void loop() {
  for (int i = 0; i < 16; i++) {
    uint16_t LED = 1 << i;

    digitalWrite(latchPin, LOW);
    SPI.transfer16(LED);
    digitalWrite(latchPin, HIGH);

    delay(1000);
  }
}

See this page for the pins to use for other models of Arduino:

https://docs.arduino.cc/language-reference/en/functions/communication/SPI/

Note that then the 74HC595 needs to be in series (daisy chained) , while the OP uses them in parallel (otherwise it would not work)

What makes you say that, @robtillaart ?

Oops, my mistake, saw things that were not in the code.
(FYI, a second datapin)

1 Like