The objective of this post is to explain how to connect the SN74HC595 8-bit shift register to an ESP8266 to control some LEDs.
Introduction
The objective of this post is to explain how to connect the SN74HC595 8-bit shift register to an ESP8266 to control some LEDs. The code to interface with the device is also explained.
We assume the use of the ESP8266 libraries for the Arduino IDE. You can check here how to configure the Arduino IDE to support the ESP8266.
Although this tutorial was tested using the SN74HC595 from Texas Instruments (datasheet here), it’s expected to work with versions of the 74HC595 from other manufacturers.
Hardware
The connection between the SN74HC595 is relatively simple and is shown in figure 1.
Figure 1 – Connection between the ESP8266 and the SN74HC595.
To keep the design simple, we are assuming that we just want to control 3 LEDs, but more could be used and the code that will be shown latter works for that situation. We are not specifying the values of resistors because they should be calculated accordingly to the current consumption of the LEDs used. There are plenty of tutorials and tools around the web on how to calculate those resistor values.
Just make sure you don’t exceed the maximum current of 35 mA per output pin and the maximum total current of 70 mA. You can check those values on the datasheet of the device.
In order to control the device, we just need 3 pins of the microcontroller. In this case, we use GPIO12 of the ESP8266 as the data pin, which is connected to the SER pin of the integrated circuit.
The shift register clock is controlled by GPIO15 and thus, is connected to the SRCLK pin. The transference of data between the shift register and the storage register of the SN75HC595 is controlled by GPIO13, which is connected to the RCLK pin.
The OE pin is directly connected to GND because we assume that we want pins QA to QH active all the time and SRCLR is connected to VCC because we assume that we don’t want to clear the shift register using a controllable signal.
Since we are not chaining multiple SN75HC595 ICs, the QH’ pin can be left unconnected.
Check my previous post for a more detailed explanation about each pin of the device and the internal working principle.
Important: If you are using a NodeMCU, don’t forget that the pin numbers in the board don’t map directly to the GPIOs of the ESP8266. As shown here, the mapping would be:
- GPIO15 – Pin D8
- GPIO13 – Pin D7
- GPIO12 – Pin D6
It’s important to refer that the pin ordering shown in figure 1 is not the physical one of the integrated circuit and is shown this way to simplify the schematic. The physical order of pins is shown in figure 2.
Figure 2 – Pin mapping of the 74HC595. Taken from [1].
Setup
As explained before, we will just need 3 pins of the ESP8266 to control the SN74HC595. So, we will start by declaring them as global variables and then initialize them as output pins in the setup function.
const int dataPin = 12; //Outputs the byte to transfer
const int loadPin = 13; //Controls the internal transference of data in SN74HC595 internal registers
const int clockPin = 15; //Generates the clock signal to control the transference of data
void setup() {
pinMode(dataPin, OUTPUT);
pinMode(loadPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
For this example, we don’t need to include any library.
Main loop
First of all, we will specify the variable with the data to transfer. Since we are working with separate bits, the easiest and less error prone approach is to specify the data bit by bit. So, we will declare the byte to transfer in binary format. Check here on how to specify variables in bases different from decimal. In this case, we will turn on the first LED.
byte data = B00000001;
Just take in consideration that we can specify the data in a numeric format and instead of a byte we can use an integer.
byte data = 2; //B00000010
int integerData = 3; //B00000011
If we want to follow this approach, we can use a binary to integer converter, such as the one shown here.
If we just want to turn on one LED at a time and we don’t want to worry about binary to decimal conversions, we can just use the bitWrite function. Essentially, it allows to set the value (HIGH or LOW) of a specific bit.
byte bitSpecified = 0;
int bitNumber = 2;
bitWrite(bitSpecified, bitNumber, HIGH);
In this case, we are writing the value HIGH (which corresponds to the value 1) in the third bit of the variable (the least significant bit is bit 0), which will correspond to B00000100.
After setting the data to transfer and before starting the actual communication, we will make sure that the load pin, which will trigger the transference of data between the internal registers of the integrated circuit, is in a LOW state. This way, we ensure that no transference will occur when we are sending the 8 bits from the microcontroller.
digitalWrite(loadPin, LOW);
Then, we will take care of the actual transference of data to the device. The simplest way of communicating with the shift register is using the shiftOut function from Arduino.
This function allows to shift a byte of data (8 bits) a bit at a time [2]. To achieve this, each bit (represented by a HIGH or LOW signal) is written in turn to a previously specified pin, after which a clock pin is is pulsed (taken HIGH then taken LOW) [2]. The clock pin is also specified in the code.
With this, we can easily implement the process of loading the 8 bits to the shift register of the SN74HC595, explained in the previous post. The function call is specified bellow.
shiftOut(dataPin, clockPin, MSBFIRST, data);
The first argument corresponds to the pin where we will be passing the data. Thus, it’s the digital pin of the microcontroller that will be connected to the SER pin of the integrated circuit.
The second argument corresponds to the pin of the microcontroller that will generate the clock signal to control the transference of data to the SN74HC595.
The third argument specifies which order to shift the bits. In this case, the value MSBFIRST indicates that it will start by the Most Significant Bit. Alternatively, we can pass the value LSBFIRST, which corresponds to Least Significant Bit First.
The fourth and final argument corresponds to the data byte we want to shift out.
After transferring the whole byte to the SN74HC595, we want to trigger the internal transference from the shift register of the integrated circuit to the storage register, to make the bits available in its output pins. To do so, we simply change the value of the load pin to HIGH.
digitalWrite(loadPin, HIGH);
Since the operation is started by a rising edge of this signal [1], we can then leave the pin in a HIGH state.
The final main loop function is specified bellow.
void loop() {
byte data = B00000001;
digitalWrite(loadPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, data);
digitalWrite(loadPin, HIGH);
delay(3000);
data = 2;
digitalWrite(loadPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, data);
digitalWrite(loadPin, HIGH);
delay(3000);
int integerData = 3;
digitalWrite(loadPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, integerData);
digitalWrite(loadPin, HIGH);
delay(3000);
byte bitSpecified = 0;
int bitNumber = 2;
bitWrite(bitSpecified, bitNumber, HIGH);
digitalWrite(loadPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, bitSpecified);
digitalWrite(loadPin, HIGH);
delay(3000);
data = 0;
digitalWrite(loadPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, data);
digitalWrite(loadPin, HIGH);
delay(3000);
}
In this final code, the sequence should be:
- First LED on (B00000001)
- Second LED on (B00000010)
- First and Second LEDs on (B00000011)
- Third LED on (B00000100)
- All LEDs off (B00000000)
You can check the final result in the video below.
Related Posts
- SN74HC595: Shift Register
- ESP8266: Connection to SN74HC595 via SPI
- ESP8266: Controlling chained SN74HC595 ICs
Resources
- Datasheet from Texas Instruments
- shiftOut function description
- bitWrite function description
- Implementation of shiftOut for the ESP8266 Arduino libraries
References
[1] http://www.ti.com/lit/ds/symlink/sn74hc595.pdf
[2] https://www.arduino.cc/en/Reference/ShiftOut
Technical details
- ESP8266 libraries: v2.3.0.
Pingback: ESP8266: Connection to SN74HC595 via SPI | techtutorialsx
Pingback: ESP8266: Connection to SN74HC595 via SPI | techtutorialsx
Pingback: ESP8266: Controlling chained SN74HC595 ICs | techtutorialsx
Pingback: ESP8266: Controlling chained SN74HC595 ICs | techtutorialsx
Pingback: SN74HC595: Shift Register | techtutorialsx
Pingback: SN74HC595: Shift Register | techtutorialsx
Pingback: ESP8266: Controlling a LED matrix with the 74HC595 ICs | techtutorialsx
Pingback: ESP8266: Controlling a LED matrix with the 74HC595 ICs | techtutorialsx