Issue with project - TPIC6C595N odd behaviour...

I am currently trying to get my binary clock I designed working.

It uses TPIC6C595N shift registers (4x daisy chained) and some LED bar graphs with an ATMEGA328p-pu and a DS1307 RTC to control the timings.

There appears to be an issue with the wiring/code (unsure which) that is causing 2 LEDs to light instead of just one.

VIDEO: When the "Day" LED comes on (4th along), one of the "Minutes" LEDs also lights up...Youtube Video of issue.

I am running a simple sketch that loads a bit in and then the code just toggles the SERCLK and RCLK pins to shift the bit along the registers.

The code seems to work fine till it gets to the third/fourth register where 2 LEDs light up. I have checked continuity between pins with my multi meter and there seems to be no "short" between them.

The code just runs my function "register_wave()" that is meant to just have each individual pin turned on in sequence order.

#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
#define ser 2
#define rclk 11
#define srclk 12
#define clr 13
#define led 4

void setup() {
  // put your setup code here, to run once:
  pinMode(led, OUTPUT);
  Wire.begin();
  delay(100);
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0x7);
  Wire.write(0b00010000);  // Turn on heartbeat
  Wire.endTransmission();
  digitalWrite(clr, 1);
}


void loop() {


  leds_clr();
  //wave(5);
  // put your main code here, to run repeatedly:
  digitalWrite(led, 1);
register_wave();
digitalWrite(led, 1);



}

void wave(unsigned int timing) {
  for (byte i = 0; i < 32; i++) {
    digitalWrite(ser, 1);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(srclk, 0);
    digitalWrite(rclk, 0);
    delay(timing);
  }
  for (byte i = 0; i < 32; i++) {
    digitalWrite(ser, 0);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(srclk, 0);
    digitalWrite(rclk, 0);
    delay(timing);
  }

}

void disply(unsigned long data) {
  byte b4 = data;
  byte b3 = data >> 8;
  byte b2 = data >> 16;
  byte b1 = data >> 24;

  byte mask = 0b10000000;

  while (mask) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b1);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);
    
    mask = mask >> 1;

  }
  mask = 0b10000000;

  while (mask) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b2);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);
    
    mask = mask >> 1;
  }
  mask = 0b10000000;
  while (mask) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b3);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);
    
    mask = mask >> 1;
  }
  mask = 0b10000000;
  while (mask>1) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b4);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);
    
    mask = mask >> 1;
  }



}

void register_wave(){
  leds_clr();
  digitalWrite(ser,1);
  digitalWrite(srclk,1);
  digitalWrite(srclk,0);
  digitalWrite(ser,0);
  
  for (byte i = 0; i<32;i++){
  digitalWrite(rclk,1);
  
  digitalWrite(rclk,0);

  digitalWrite(srclk,1);

  digitalWrite(srclk,0);
  delay(250);  
  }
  leds_clr();
}

void leds_clr() {
  digitalWrite(clr, 0);
  digitalWrite(clr, 1);
}

My schematic and PCB design are here. I have circled the LEDs/connections that seem to be "crossed"...

Full Res
Full Res

Thanks for any help!

If there are no wiring issues, and I don't see any in the schematic, that can only mean a coding issue.
Simplify your code to just walk a 1 thru each output and make sure all are turning in where they are supposed to.
Send out 4 bytes at a time, with just 1 bit, and see what you can find.
Send the data from an array even:

byte testArray[] = {
0x00,0x00,0x00,0x01,
0x00,0x00,0x00,0x02,
0x00,0x00,0x00,0x04,
0x00,0x00,0x00,0x08,
etc for all 32 outputs
0x40,0x00,0x00,0x00,
0x80,0x00,0x00,0x00,
};

Too bad you didn't use SPI.transfer to send the data out, that's what I use for shift registers.
But you didn't, so:

for (x=0; x<128; x=x+4){
digitalWrite (ssPin, LOW);
shiftOut (dataPin, clockPin, MSBFIRST, testArray[x+0];
shiftOut (dataPin, clockPin, MSBFIRST, testArray[x+1];
shiftOut (dataPin, clockPin, MSBFIRST, testArray[x+2];
shiftOut (dataPin, clockPin, MSBFIRST, testArray[x+3];
digitalWrite (ssPin, HIGH);
delay(2000); // visually confirm correct setment is lit
}

I think I am already using probably the most basic form?

void loop() {
  register_wave();
}

void register_wave() {
  leds_clr();
  digitalWrite(ser, 1);    // Put in a "1"
  digitalWrite(srclk, 1);
  digitalWrite(srclk, 0);
  digitalWrite(ser, 0);

  for (byte i = 0; i < 31; i++) {
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);             //All 0s for the next 31 bits.
    digitalWrite(srclk, 1);
    digitalWrite(srclk, 0);
    delay(250);
  }
  leds_clr();
}

void leds_clr() {
  digitalWrite(clr, 0);
  digitalWrite(clr, 1);
}

There is always that ghosting of the LED at the same point. Also occurs when I use the "disply" function:

void disply(unsigned long data) {
  byte b4 = data;
  byte b3 = data >> 8;
  byte b2 = data >> 16;
  byte b1 = data >> 24;

  byte mask = 0b10000000;

  while (mask) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b1);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);

    mask = mask >> 1;

  }
  mask = 0b10000000;

  while (mask) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b2);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);

    mask = mask >> 1;
  }
  mask = 0b10000000;
  while (mask) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b3);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);

    mask = mask >> 1;
  }
  mask = 0b10000000;
  while (mask > 1) {
    digitalWrite(srclk, 0);
    digitalWrite(ser, mask & b4);
    digitalWrite(srclk, 1);
    digitalWrite(rclk, 1);
    digitalWrite(rclk, 0);

    mask = mask >> 1;
  }
}

Is there a known issue with the TPIC6C595Ns or other registers "carrying out" incorrectly if damaged/faulty? It is just the LEDs the light as a pair are basically the last output of the 3rd register and the first output of the fourth register.

So like some form of "leaky" path?

I have soldered up a new board in case of any hardware issues and I am getting the same bug.

I can only assume this is a software issue...or a PCB design issue. Been at this for a good 6 hours again today with no luck...

Your code for the soft SPI out is a little screwy. You toggle the latch clock(RCK) on each bit with the data clock(SRCK) still high.

Normally the latch clock is set LOW (data clock also at start) to begin sending data so the output pins won't toggle as data moves thru.

For each bit set the value on the data pin then strobe the data clock (HIGH then LOW).

After all the bits are sent then enable the data to be seen at the outputs by setting the latch clock HIGH.

Did you try the shiftOut example? That's pretty basic.

justone:
Your code for the soft SPI out is a little screwy. You toggle the latch clock(RCK) on each bit with the data clock(SRCK) still high.

Normally the latch clock is set LOW (data clock also at start) to begin sending data so the output pins won't toggle as data moves thru.

For each bit set the value on the data pin then strobe the data clock (HIGH then LOW).

After all the bits are sent then enable the data to be seen at the outputs by setting the latch clock HIGH.

Thanks, think my understanding of RCLK was a bit off. I thought the RCLK was a clock to shift bits through an internal register...didn't know it was a simple "reveal bits".

But the problem still persists with this function I have written:

void reg_wave2(int timing, byte pos) {
  leds_clr();
  digitalWrite(ser, 1);    // Put in a "1"
  digitalWrite(srclk, 1);
  digitalWrite(ser, 0);
  digitalWrite(srclk, 0);

  for (byte i = 0; i < pos; i++) { // Toggle SRCLK line "pos" positions...
    digitalWrite(srclk, 1);
    digitalWrite(srclk, 0);
  }
  digitalWrite(rclk, 1);         // reveal the bits on the LEDs for "timing" ms.
  delay(timing);
  digitalWrite(rclk, 0);
}

In my main I used:

void loop() {
  for (byte pos = 0; pos < 31; pos++) {
    reg_wave2(100, pos);
  }
}

The single bit still cycles round as expected untill it lights the "Minutes 6" LED which causes an LED on the Day LEDs to light...
The same I circled in the schematics.

I will try the "shiftout" as well and come back.
I have placed de-coupling capacitors near all ICs and have electrolytics of different capacities to try absorb any possible "spikes" or noise...so I can only assume my PCB design/schematic are sound...

CrossRoads:
Did you try the shiftOut example? That's pretty basic.

I have now tried to implement this method and also experience the same bug. As soon as the "day 4 " led lights, the minutes 6 (next one over after the carry in the 3rd register).

byte testArray[]={
  0b00000000,0b00000000,0b00000000,0b00000001,
  0b00000000,0b00000000,0b00000000,0b00000010,
  0b00000000,0b00000000,0b00000000,0b00000100,
  0b00000000,0b00000000,0b00000000,0b00001000,
  0b00000000,0b00000000,0b00000000,0b00010000,
  0b00000000,0b00000000,0b00000000,0b00100000,
  0b00000000,0b00000000,0b00000000,0b01000000,
  0b00000000,0b00000000,0b00000000,0b10000000,
  0b00000000,0b00000000,0b00000001,0b00000000,
  0b00000000,0b00000000,0b00000010,0b00000000,
  0b00000000,0b00000000,0b00000100,0b00000000,
  0b00000000,0b00000000,0b00001000,0b00000000,
  0b00000000,0b00000000,0b00010000,0b00000000,
  0b00000000,0b00000000,0b00100000,0b00000000,
  0b00000000,0b00000000,0b01000000,0b00000000,
  0b00000000,0b00000000,0b10000000,0b00000000,
  0b00000000,0b00000001,0b00000000,0b00000000,
  0b00000000,0b00000010,0b00000000,0b00000000,
  0b00000000,0b00000100,0b00000000,0b00000000,
  0b00000000,0b00001000,0b00000000,0b00000000,
  0b00000000,0b00010000,0b00000000,0b00000000,
  0b00000000,0b00100000,0b00000000,0b00000000,
  0b00000000,0b01000000,0b00000000,0b00000000,
  0b00000000,0b10000000,0b00000000,0b00000000,
  0b00000001,0b00000000,0b00000000,0b00000000,
  0b00000010,0b00000000,0b00000000,0b00000000,
  0b00000100,0b00000000,0b00000000,0b00000000,
  0b00001000,0b00000000,0b00000000,0b00000000,
  0b00010000,0b00000000,0b00000000,0b00000000,
  0b00100000,0b00000000,0b00000000,0b00000000,
  0b01000000,0b00000000,0b00000000,0b00000000,
  0b10000000,0b00000000,0b00000000,0b00000000,
};
void loop() {
  shiftout();
}
void shiftout() {

  byte dataPin = ser;
  byte clockPin = srclk;
  byte ssPin = rclk;
  for (byte x = 0; x < 128; x = x + 4) {
    digitalWrite (ssPin, LOW);
    shiftOut (dataPin, clockPin, MSBFIRST, testArray[x + 0]);
    shiftOut (dataPin, clockPin, MSBFIRST, testArray[x + 1]);
    shiftOut (dataPin, clockPin, MSBFIRST, testArray[x + 2]);
    shiftOut (dataPin, clockPin, MSBFIRST, testArray[x + 3]);
    digitalWrite (ssPin, HIGH);
    delay(500); // visually confirm correct setment is lit
  }
}

I believe you have interchanged the clock pin and the latch pin (datasheet names RCK and SRCK respectively)

void shiftout() {

 byte dataPin = ser;
 byte clockPin = srclk;
 byte ssPin = rclk;
 for (byte x = 0; x < 128; x = x + 4) {
   digitalWrite (ssPin, LOW);  // this should be the latch - physical pin 15 on TPIC6C565 / datasheet name SRCK
   shiftOut (dataPin, clockPin, MSBFIRST, testArray[x + 0]); // clockPin should be physical pin 10 on TPIC6C565 / datasheet name RCK 
 . . . 
}