Skip to content

Commit ae69a4d

Browse files
authored
Merge pull request #15 from Koepel/master
Fix memory leak, add experimental setAll_P()
2 parents 9b2adde + 127d039 commit ae69a4d

3 files changed

Lines changed: 49 additions & 26 deletions

File tree

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ShiftRegister74HC595
2-
version=1.1
2+
version=1.2
33
author=Timo Denk (timodenk.com)
44
maintainer=Timo Denk (timodenk.com)
55
sentence=Simplifies usage of shift registers, designed for the 74HC595.

src/ShiftRegister74HC595.cpp

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,58 @@ ShiftRegister74HC595::ShiftRegister74HC595(int numberOfShiftRegisters, int seria
1414
{
1515
// set attributes
1616
_numberOfShiftRegisters = numberOfShiftRegisters;
17-
17+
1818
_clockPin = clockPin;
1919
_serialDataPin = serialDataPin;
2020
_latchPin = latchPin;
21-
21+
2222
// define pins as outputs
2323
pinMode(clockPin, OUTPUT);
2424
pinMode(serialDataPin, OUTPUT);
2525
pinMode(latchPin, OUTPUT);
26-
26+
2727
// set pins low
2828
digitalWrite(clockPin, LOW);
2929
digitalWrite(serialDataPin, LOW);
3030
digitalWrite(latchPin, LOW);
31-
31+
3232
// allocates the specified number of bytes and initializes them to zero
3333
_digitalValues = (uint8_t *)malloc(numberOfShiftRegisters * sizeof(uint8_t));
3434
memset(_digitalValues, 0, numberOfShiftRegisters * sizeof(uint8_t));
35-
36-
setAll(_digitalValues); // reset shift register
35+
36+
updateRegisters(); // reset shift register
37+
}
38+
39+
40+
// ShiftRegister74HC595 destructor
41+
// The memory allocated in the constructor is also released.
42+
ShiftRegister74HC595::~ShiftRegister74HC595()
43+
{
44+
free(_digitalValues);
3745
}
3846

3947

4048
// Set all pins of the shift registers at once.
4149
// digitalVAlues is a uint8_t array where the length is equal to the number of shift registers.
42-
void ShiftRegister74HC595::setAll(uint8_t * digitalValues)
50+
void ShiftRegister74HC595::setAll(const uint8_t * digitalValues)
4351
{
44-
int byte;
45-
46-
for (byte = _numberOfShiftRegisters - 1; byte >= 0; byte--) {
47-
shiftOut(_serialDataPin, _clockPin, MSBFIRST, digitalValues[byte]);
48-
}
49-
50-
_digitalValues = digitalValues;
51-
52-
digitalWrite(_latchPin, HIGH);
53-
digitalWrite(_latchPin, LOW);
52+
memcpy( _digitalValues, digitalValues, _numberOfShiftRegisters); // dest, src, size
53+
updateRegisters();
54+
}
55+
56+
57+
// Experimental
58+
// The same as setAll, but the data is located in PROGMEM
59+
// For example with:
60+
// const uint8_t myFlashData[] PROGMEM = { 0x0F, 0x81 };
61+
#ifdef __AVR__
62+
void ShiftRegister74HC595::setAll_P(const uint8_t * digitalValuesProgmem)
63+
{
64+
PGM_VOID_P p = reinterpret_cast<PGM_VOID_P>(digitalValuesProgmem);
65+
memcpy_P( _digitalValues, p, _numberOfShiftRegisters);
66+
updateRegisters();
5467
}
68+
#endif
5569

5670

5771
// Retrieve all states of the shift registers' output pins.
@@ -70,10 +84,17 @@ void ShiftRegister74HC595::set(int pin, uint8_t value)
7084
updateRegisters();
7185
}
7286

87+
7388
// Updates the shift register pins to the stored output values.
89+
// This is the function that actually writes data into the shift registers of the 74HC595
7490
void ShiftRegister74HC595::updateRegisters()
7591
{
76-
setAll(_digitalValues);
92+
for (int i = _numberOfShiftRegisters - 1; i >= 0; i--) {
93+
shiftOut(_serialDataPin, _clockPin, MSBFIRST, _digitalValues[i]);
94+
}
95+
96+
digitalWrite(_latchPin, HIGH);
97+
digitalWrite(_latchPin, LOW);
7798
}
7899

79100

@@ -101,20 +122,18 @@ uint8_t ShiftRegister74HC595::get(int pin)
101122
// Sets all pins of all shift registers to HIGH (1).
102123
void ShiftRegister74HC595::setAllHigh()
103124
{
104-
int i;
105-
for (i = 0; i < _numberOfShiftRegisters; i++) {
125+
for (int i = 0; i < _numberOfShiftRegisters; i++) {
106126
_digitalValues[i] = 255;
107127
}
108-
setAll(_digitalValues);
128+
updateRegisters();
109129
}
110130

111131

112132
// Sets all pins of all shift registers to LOW (0).
113133
void ShiftRegister74HC595::setAllLow()
114134
{
115-
int i;
116-
for (i = 0; i < _numberOfShiftRegisters; i++) {
135+
for (int i = 0; i < _numberOfShiftRegisters; i++) {
117136
_digitalValues[i] = 0;
118137
}
119-
setAll(_digitalValues);
138+
updateRegisters();
120139
}

src/ShiftRegister74HC595.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ class ShiftRegister74HC595
1414
{
1515
public:
1616
ShiftRegister74HC595(int numberOfShiftRegisters, int serialDataPin, int clockPin, int latchPin);
17-
void setAll(uint8_t * digitalValues);
17+
~ShiftRegister74HC595();
18+
void setAll(const uint8_t * digitalValues);
19+
#ifdef __AVR__
20+
void setAll_P(const uint8_t * digitalValuesProgmem); // Experimental, PROGMEM data
21+
#endif
1822
uint8_t * getAll();
1923
void set(int pin, uint8_t value);
2024
void setNoUpdate(int pin, uint8_t value);

0 commit comments

Comments
 (0)