Flux Capacitor - Shift Register Output pin Help

Hello all,
I’m new to coding and experimenting with shift registers, and yes, another noob trying to build a Flux Capacitor…

I used the wiring scheme from the ShiftOut article, and had daisy chained 2 shift registers, and ONLY wired up the outputs to form the “Y” in the flux capacitor. Used the code below and tweaked it a bit to get started. I was very excited to see the pattern working, how I wanted.

Here is the video of the CORRECT pattern: Fluxing (Correctly) - YouTube

But then I wired up a 3rd shift register so that I could get the rest of the LEDs wired up. (The outer 4 LEDs and the inner 3 LEDs). All of the outputs (a total of 19 LEDs), are wired in consecutive order of the 3 daisy-chained 74HC595’s.
So…
Register 1 - Q0 thru Q7 control the upper fork of the Y.
Register 2 - Q0 thru Q7 control the lower leg of the Y as well as the 4 outer LEDs
Register 3 - Q0 thru Q2 control the inner 3 LEDs, and the remaining are not wired

Here is the resulting video running the same code: Fluxing (IIncorrectly) - YouTube

As you can see the pattern I have is cycling through all the available inputs, when I only want the Y pattern to light.

Where I am stuck is, How do I kill the outputs for shift register #2 (Q4 - Q7) and shift register #3 (All outputs) while the pattern is running? I have searched all over and found several tutorials on controlling individual pins, and have tried uploading sample code to play with, but I just can’t seem to wrap my mind around isolating the pins. Everything I have tried just duplicates what the master register is doing. Maybe what I am trying to do isn’t possible with shift registers?

Here is the code that I started with, and please know that I am not trying to get anyone to write code for me, I just need advice on things that I should try and what I am missing.

Thanks!

nt dataPin = 8;        //Define which pins will be used for the Shift Register control
int latchPin = 9;
int clockPin = 10;

int seq[4] = {B10001000,B01000100,B00100010,B00010001};       //The byte sequence

void setup()
{
    pinMode(dataPin, OUTPUT);       //Configure each IO Pin
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
}

void loop()
{
    for (int n = 0; n < 4; n++)
    {
        digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq[n]);          //Send the data
        digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
        delay(150);
    }
}

I would suggest defining the pattern for all 3 bytes, and shift out 3 bytes at a time.
So 12 bytes in your array, read & shift out 2 3 at a time to make the 4 patterns.

Thank you CrossRoads. I think I’m on the right track with defining all the bytes (see below), but where I’m lost is how to shift them out 3 at a time. I don’t really understand the “For” command, and maybe that is where the problem is?

int dataPin = 8;        //Define which pins will be used for the Shift Register control
int latchPin = 9;
int clockPin = 10;

int seq[12] = {B10001000,B10000000,B00000000,B01000100,B01000000,B00000000,B00100010,B00100000,B00000000,B00010001,B00010000,B00000000};       //The byte sequence

void setup()
{
    pinMode(dataPin, OUTPUT);       //Configure each IO Pin
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
}

void loop()
{
    for (int n = 0; n < 3; n++)
    {
        digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq[n]);          //Send the data
        digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
        delay(150);
    }
}

Try this:

    for (int n = 0; n < 3; n++)
    {
        digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq[n]);          //Send the data
        shiftOut(dataPin, clockPin, MSBFIRST, seq[n]);          //Send the data
        shiftOut(dataPin, clockPin, MSBFIRST, seq[n]);          //Send the data
        digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
        delay(150);
    }

Thanks Paul. I did try that but no joy. I was up all last night til 2am trying different variations of that segment, but finally had to hang it up. I'll try some more later and report back.
Thanks again to you both for he pointers. It's got me moving in the right direction now.

I’m still not having any luck with this. I tried breaking the individual 3-Byte patterns into a total of4, and shifting them out one at a time, but still getting the same result (referenced in the 2nd video from my original post).

Paul RB, I found a thread where you helped someone with a similar issue

And I tried implementing that method, but just can’t seem how to figure out shifting the 24 bits down, so that they pass through all 3 registers, and display the correct LEDs to show up on each pattern.

Here is my re-worked code. Any pointers?

int dataPin = 8;        //Define which pins will be used for the Shift Register control
int latchPin = 9;
int clockPin = 10;

int seq1[3] = {B10001000,B10000000,B00000000};
int seq2[3] = {B01000100,B01000000,B00000000};
int seq3[3] = {B00100010,B00100000,B00000000};
int seq4[3] = {B00010001,B00010000,B00000000};       //The byte sequence

void setup()
{
    pinMode(dataPin, OUTPUT);       //Configure each IO Pin
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
}

void loop()
{
    for (int n = 0; n < 1; n++)
    {
        digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq1[n]);          //Send the data
        digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
        delay(125);
        
        digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq2[n]);          //Send the data
        digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
        delay(125);
        
        digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq3[n]);          //Send the data
        digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
        delay(125);
        
        digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
        shiftOut(dataPin, clockPin, MSBFIRST, seq4[n]);          //Send the data
        digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
        delay(125);
        
    }
}

I don't understand why it didn't work with my previous suggestion. I am going to need to see a schematic to figure out what's wrong. The schematic (rather unusually) needs to show which led is which on the flux capacitor PCB.

Paul, Thanks for your time. I know this is going to look like a mess. I did not include any ground wires, caps, resistors, supply and zero-V, etc since it is complicated enough trying to trace all the connections.

!(http://C:\Users\Hoffy\Documents\Flux Capacitor)

Here is also a “worded” schematic of what I’m trying to accomplish in a blinking inward to outward pattern on the “Y”, while cancelling out the inner 3 and outer 4 LEDs.

Register #1 Register #1
Pins Q0-Q3 start from top down Pins Q4-Q7 start from top down
X X
X X
X X
X X

X
X
X
X
Register #2
Pins Q0-Q3 start from bottom up

Register #2 (Pins Q4-Q7), thand Register #3 (all pins) are what I’m trying NOT to light up.

Here is the schemo. ,

!(http://C:\Users\Hoffy\Documents\Flux Capacitor\Fluc Capacitor_schem.jpg)

Ok. Thanks for drawing that, and especially for using the correct "schematic view" in Fritzing, which most users ignore.

Before we go further, are you sure that's correct? I notice that for Reg 1, the leds sequence is outwards with increasing pin number. But for Reg 2, the led sequence is inwards. I see this agrees with your text diagram.

Try this:

int dataPin = 8;        //Define which pins will be used for the Shift Register control
int latchPin = 9;
int clockPin = 10;

//                   Reg #1     Reg #2     Reg #3
//                  01234567   01234567   01234567
byte seq[4][3] = {{B10001000, B00010000, B00000000},
                  {B01000100, B00100000, B00000000},
                  {B00100010, B01000000, B00000000},
                  {B00010001, B10000000, B00000000}};       //The byte sequence

void setup() {
  pinMode(dataPin, OUTPUT);       //Configure each IO Pin
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
  for (int n = 0; n < 4; n++) {
    digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
    for (int i = 2; i >= 0; i--) {
      shiftOut(dataPin, clockPin, MSBFIRST, seq[n][i]);          //Send the data
    }
    digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
    delay(125);
  }
}

Hoffy84:
I did not include any ground wires, caps, resistors, supply and zero-V, etc since it is complicated enough trying to trace all the connections.

There are tricks you can use when drawing your schematic to keep it neat and readable:

  • Generally speaking, the layout of the schematic does not have to follow the layout of the actual circuit, where that would make the schematic unnecessarily complicated. In the case of your leds, the layout is very important, so you still want the physical layout to be represented in the schematic diagram. By contrast. for the caps, for example, everyone knows (or should know) that they should be physically close to the power pins of the chips, so on the schematic you can just put them in a bunch in a corner of the diagram.
  • There are special symbols for Vcc/5V and Ground/0V. You can put as many as these into the schematic as you like, for example one Vcc and one GND symbol per chip, placed right where they are needed, or one GND symbol per led, placed just by the cathode. Using these symbols, you don’t need to join up all the Vcc and GND points with wires.
  • You can give names to wires. Wires with the same name are assumed to be joined together, even if that is not shown on the schematic.

Have a look at this one of mine. I have used all 3 of the above tricks:

Wemos_GCLD_pcf8574.png

Here’s how I would do it.

// using this:
int seq[12] = {B10001000,B10000000,B00000000,B01000100,B01000000,B00000000,B00100010,B00100000,B00000000,B00010001,B00010000,B00000000};       //The byte sequence

void loop(){
for (byte x = 0; x<12; x=x+3){
digitalWrite (latchPin, LOW);
shiftOut (dataPin, clockPin, MSBFIRST, seq[x+0]); // bytes 0, 3, 6, 9
shiftOut (dataPin, clockPin, MSBFIRST, seq[x+1]); // bytes 1, 4, 7, 10
shiftOut (dataPin, clockPin, MSBFIRST, seq[x+2]); // bytes 2, 5, 8, 11
digitalWrite (latchPin, HIGH); // outputs change on this rising edge
delay (125);
}
}

Paul: That is wayyy prettier than mine!
Thank you for the tips. I'm going to want to redraw that again, anyway for my reference. That was my first time using Fritz. I couldn't believe how user-friendly it was.
Paul/Crossroads:
I'll check everything out when I get home tonight, and report back.
Much appreciated!

Okay, Here’s what happened…

Paul, I tried yours first but got the same result. (the video I referenced before). The “Y” pattern works exactly as it should, but the inner 3 and outer 4 LEDs still cycle along with everything.

CrossRoads, I think you meant for me to use the last sketch I wrote and overwrite the “void loop ()” with the one you wrote up, as well as the byte pattern. Tried that, but nothing lit up.

Could the problem be with how I have the 3 registers daisy-chained? I followed the ShiftOut tutorial wiring to the T, (of course the only alteration was removing the erroneous cap location , and placing the .01 caps to the VCC-Gnd pins of each register. The data pins are all joined, the STCP pins are all joined, & the SHCP pins are all joined.Could this be what’s causing the 2 downstream registers to act the same as the master?

I don’t know. I’m going to triple check all the wiring again, and let you know.

Thanks again for your help guys.

The data pins are all joined

Damn! Your schematic shows that and we all missed it. That's the problem. The regs are not daisy chained. Only the DS pin of reg#1 should be connected to the Arduino. Then the Q7' pin of reg#1 should be connected to DS of reg#2 and Q7' of reg#2 to DS of reg#3. Clock & latch pins are wired ok.

Oh my goodness. What a relief!! I rewired the data pins, tried all the codes and revisions that we all contributed; still no desired pattern :frowning:

HOWEVER! :). The LEDs are now behaving the way I expect them to. No duplicated register action. Whew!

I am on the right path now. Just need to play around with the code a bit and I will follow up with the results and new schematic for future prosper.

Thanks guys!!

All working now! PaulRB the code you posted works great. It took me a while to figure out why it wasn’t lighting correctly after I had rewired everything, and it turns out that I had to rearrange the bit patterns. For some reason all the registers are working reversely.

For instance, If I wanted all LEDs lit, you would think it would be like this:

B 1 1 1 1 1 1 1 1, B 1 1 1 1 1 1 1 1, B 1 1 1 00000

but instead, it’s:

B 1 1 1 1 1 1 1 1, B 1 1 1 1 1 1 1 1, B00000 1 1 1 (You can’t tell on the first 2 bytes, but the outputs are mirrored.)

Not a big deal really; just thought it was odd they work inverted.
I still don’t understand how the two “for” formulas work. More digging.

Here is the working code for the standard “fluxing” pattern…

int dataPin = 8;        //Define which pins will be used for the Shift Register control
int latchPin = 9;
int clockPin = 10;

//                   Reg #1     Reg #2     Reg #3
//                  01234567   01234567   01234567
byte seq[4][3] = {{B10001000, B00001000, B00000000},
                  {B01000100, B00000100, B00000000},
                  {B00100010, B00000010, B00000000},
                  {B00010001, B00000001, B00000000}};       //The byte sequence

void setup() {
  pinMode(dataPin, OUTPUT);       //Configure each IO Pin
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
  for (int n = 0; n < 4; n++) {
    digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
    for (int i = 2; i >= 0; i--) {
      shiftOut(dataPin, clockPin, MSBFIRST, seq[n][i]);          //Send the data
    }
    digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
    delay(125);
  }
}

And here is the working code for Ping-Pong effect!!

int dataPin = 8;        //Define which pins will be used for the Shift Register control
int latchPin = 9;
int clockPin = 10;

//                   Reg #1     Reg #2     Reg #3
//                  01234567   01234567   01234567
byte seq[6][3] = {{B10001000, B00001000, B00000000},
                  {B01000100, B00000100, B00000000},
                  {B00100010, B00000010, B00000000},
                  {B00010001, B00000001, B00000000},       //The byte sequence
                  {B00100010, B00000010, B00000000},
                  {B01000100, B00000100, B00000000}};
                 

void setup() {
  pinMode(dataPin, OUTPUT);       //Configure each IO Pin
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
  for (int n = 0; n < 6; n++) {
    digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
    for (int i = 2; i >= 0; i--) {
      shiftOut(dataPin, clockPin, MSBFIRST, seq[n][i]);          //Send the data
    }
    digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
    delay(125);
  }
}

For some reason all the registers are working reversely.

You could have fixed that by changing MSBFIRST to LSBFIRST.