Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ sr.set(1, HIGH)
Please find the detailed **documentation** at https://timodenk.com/blog/shift-register-arduino-library/.

An **example** sketch can be found in this repository at [/examples/example/example.ino](https://github.com/Simsso/ShiftRegister74HC595/blob/master/examples/example/example.ino).



New:

to shift data via SPI define `SHIFT_REGISTER_USES_SPI_WITH_FREQUENCY 20000000UL` before you include ShiftRegister74HC595.h

Arduino UNO uses pin 13 for CLOCK and pin 11 for MOSI (data) - latch pin - configurable.
54 changes: 54 additions & 0 deletions examples/spi_example/example.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
ShiftRegister74HC595 - Library for simplified control of 74HC595 shift registers.
Developed and maintained by Timo Denk and contributers, since Nov 2014.
Additional information is available at https://timodenk.com/blog/shift-register-arduino-library/
Released into the public domain.
*/

// 20000000UL <- your chip speed. if arduino cant handle that, it will work at max it can. On uno up to 8mhz. 20000000UL means 20Mhz
// MOSI to shift register DATA pin, SCLK to CLock pin, Latch pin configurable
#define SHIFT_REGISTER_USES_SPI_WITH_FREQUENCY 20000000UL
#include <ShiftRegister74HC595.h>

// create a global shift register object
// parameters: <number of shift registers> (latch pin)
ShiftRegister74HC595<1> sr(7);

void setup() {
}

void loop() {

// setting all pins at the same time to either HIGH or LOW
sr.setAllHigh(); // set all pins HIGH
delay(500);

sr.setAllLow(); // set all pins LOW
delay(500);


// setting single pins
for (int i = 0; i < 8; i++) {

sr.set(i, HIGH); // set single pin HIGH
delay(250);
}


// set all pins at once
uint8_t pinValues[] = { B10101010 };
sr.setAll(pinValues);
delay(1000);


// read pin (zero based, i.e. 6th pin)
uint8_t stateOfPin5 = sr.get(5);
sr.set(6, stateOfPin5);


// set pins without immediate update
sr.setNoUpdate(0, HIGH);
sr.setNoUpdate(1, LOW);
// at this point of time, pin 0 and 1 did not change yet
sr.updateRegisters(); // update the pins to the set values
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ShiftRegister74HC595
version=1.3.1
version=1.3.2
author=Timo Denk (timodenk.com)
maintainer=Timo Denk (timodenk.com)
sentence=Simplifies usage of shift registers, designed for the 74HC595.
Expand Down
1 change: 1 addition & 0 deletions src/ShiftRegister74HC595.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@

#include <Arduino.h>
#include "ShiftRegister74HC595.h"

17 changes: 17 additions & 0 deletions src/ShiftRegister74HC595.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@

#include <Arduino.h>

#if defined(SHIFT_REGISTER_USES_SPI_WITH_FREQUENCY)
#include <SPI.h>
#endif

template<uint8_t Size>
class ShiftRegister74HC595
{
public:
#if !defined(SHIFT_REGISTER_USES_SPI_WITH_FREQUENCY)
ShiftRegister74HC595(const uint8_t serialDataPin, const uint8_t clockPin, const uint8_t latchPin);
#else
ShiftRegister74HC595(const uint8_t latchPin);
#endif

void setAll(const uint8_t * digitalValues);
#ifdef __AVR__
Expand All @@ -26,13 +34,22 @@ class ShiftRegister74HC595
void setAllLow();
void setAllHigh();
uint8_t get(const uint8_t pin);
void order(uint8_t o);

private:
#ifdef __AVR__
uint8_t bo = MSBFIRST;
#else
BitOrder bo = MSBFIRST;
#endif
uint8_t _clockPin;
uint8_t _serialDataPin;
uint8_t _latchPin;

uint8_t _digitalValues[Size];

uint8_t *_port;
uint8_t _pinMask;
};

#include "ShiftRegister74HC595.hpp"
68 changes: 66 additions & 2 deletions src/ShiftRegister74HC595.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
Released into the public domain.
*/


#if !defined(SHIFT_REGISTER_USES_SPI_WITH_FREQUENCY)

// ShiftRegister74HC595 constructor
// Size is the number of shiftregisters stacked in serial
template<uint8_t Size>
Expand All @@ -15,6 +18,8 @@ ShiftRegister74HC595<Size>::ShiftRegister74HC595(const uint8_t serialDataPin, co
_serialDataPin = serialDataPin;
_latchPin = latchPin;

bo = MSBFIRST;

// define pins as outputs
pinMode(clockPin, OUTPUT);
pinMode(serialDataPin, OUTPUT);
Expand All @@ -31,6 +36,40 @@ ShiftRegister74HC595<Size>::ShiftRegister74HC595(const uint8_t serialDataPin, co
updateRegisters(); // reset shift register
}

#else

// ShiftRegister74HC595 constructor
// Size is the number of shiftregisters stacked in serial
template<uint8_t Size>
ShiftRegister74HC595<Size>::ShiftRegister74HC595(const uint8_t latchPin)
{
_latchPin = latchPin;

#ifdef __AVR__
_pinMask = digitalPinToBitMask(latchPin);
_port = portOutputRegister(digitalPinToPort(latchPin));
#endif

bo = MSBFIRST;

// define pins as outputs
pinMode(latchPin, OUTPUT);

// set pins low
digitalWrite(latchPin, LOW);

// allocates the specified number of bytes and initializes them to zero
memset(_digitalValues, 0, Size * sizeof(uint8_t));

SPI.begin();
SPI.beginTransaction(SPISettings(SHIFT_REGISTER_USES_SPI_WITH_FREQUENCY, bo, SPI_MODE0));

updateRegisters(); // reset shift register
}


#endif

// Set all pins of the shift registers at once.
// digitalVAlues is a uint8_t array where the length is equal to the number of shift registers.
template<uint8_t Size>
Expand Down Expand Up @@ -71,19 +110,38 @@ void ShiftRegister74HC595<Size>::set(const uint8_t pin, const uint8_t value)
updateRegisters();
}


#if !defined(SHIFT_REGISTER_USES_SPI_WITH_FREQUENCY)
// Updates the shift register pins to the stored output values.
// This is the function that actually writes data into the shift registers of the 74HC595.
template<uint8_t Size>
void ShiftRegister74HC595<Size>::updateRegisters()
{
for (int i = Size - 1; i >= 0; i--) {
shiftOut(_serialDataPin, _clockPin, MSBFIRST, _digitalValues[i]);
shiftOut(_serialDataPin, _clockPin, bo, _digitalValues[i]);
}

digitalWrite(_latchPin, HIGH);
digitalWrite(_latchPin, LOW);
}

#else
// Updates the shift register pins to the stored output values.
// This is the function that actually writes data into the shift registers of the 74HC595.
template<uint8_t Size>
void ShiftRegister74HC595<Size>::updateRegisters()
{
for (int i = Size - 1; i >= 0; i--) {
SPI.transfer(_digitalValues[i]);
}
#ifdef __AVR__
*_port |= _pinMask;
*_port &= ~_pinMask;
#else
digitalWrite(_latchPin, HIGH);
digitalWrite(_latchPin, LOW);
#endif
}
#endif
// Equivalent to set(int pin, uint8_t value), except the physical shift register is not updated.
// Should be used in combination with updateRegisters().
template<uint8_t Size>
Expand Down Expand Up @@ -119,3 +177,9 @@ void ShiftRegister74HC595<Size>::setAllLow()
}
updateRegisters();
}

template<uint8_t Size>
void ShiftRegister74HC595<Size>::order(uint8_t o)
{
bo = o;
}