How to access 2nd shift register

I get that

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 160);
digitalWrite(latchPin, HIGH);

Will set the first registers pins to:
ON,OFF,ON,OFF,OFF,OFF,OFF,OFF

What I'm not getting through my thick cranium is how to get that into the 2nd register so I get something like:
OFF,OFF,OFF,OFF,OFF,OFF,OFF,OFF ON,OFF,ON,OFF,OFF,OFF,OFF,OFF

I've looked at a boatload of examples and the reference for shiftOut. Generally, I'll ask folks here for a nudge in the right direction and try to learn something as I figure it out on my own. But I'm just not getting it. (insert pulling hair out icon here)

Anyone care to explain what I need to do here?

the reference states:

Notes and Warnings

The dataPin and clockPin must already be configured as outputs by a call to pinMode().

shiftOut is currently written to output 1 byte (8 bits) so it requires a two step operation to output values larger than 255.

// Do this for MSBFIRST serial
int data = 500;
// shift out highbyte
shiftOut(dataPin, clock, MSBFIRST, (data >> 8));
// shift out lowbyte
shiftOut(dataPin, clock, MSBFIRST, data);

pretty clear I guess. Or in your case if you want to send hardcoded:

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 160);
digitalWrite(latchPin, HIGH);

noiasca:
the reference states:

Notes and Warnings

The dataPin and clockPin must already be configured as outputs by a call to pinMode().

shiftOut is currently written to output 1 byte (8 bits) so it requires a two step operation to output values larger than 255.

// Do this for MSBFIRST serial

int data = 500;
// shift out highbyte
shiftOut(dataPin, clock, MSBFIRST, (data >> 8));
// shift out lowbyte
shiftOut(dataPin, clock, MSBFIRST, data);





pretty clear I guess. Or in your case if you want to send hardcoded:



digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 0);
shiftOut(dataPin, clockPin, MSBFIRST, 160);
digitalWrite(latchPin, HIGH);

Well, dang. I guess I spent 3 hours chasing my tail. That is the first thing I tried (2 shiftOuts with first having the >> 8 )!! Apparently my noob butt has something else wrong in my sketch. I would post it up. But I'm no longer home and won't be for the week.

I think I may have over-complicated it right from the start. I'll probably file 13 it and start over and simplify it.

I really appreciate the help! Karma coming your way when I get home. Cell phone won't let me.

Well, it's bugging me. So I put together a simple code for testing when I get home.

const int latchPin = 3; //ST_CP of 74HC595 (12)
const int clockPin = 5; //SH_CP of 74HC595 (11)
const int dataPin = 4; //DS 0f 74HC595 (14)
const int stepsPerRevolution = 2048;

int forDataArray[4] = {160, 96, 80, 144}; //Clockwise
int revDataArray[4] = {144, 80, 96, 160}; //Reverse

void setup(){
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  }
  
void loop(){
    for ( int i = 0; i < stepsPerRevolution/4 ){
        for ( int e = 0;  e < 4; e++ ){
             digitalWrite(latchPin, LOW);
             shiftOut(dataPin, clockPin, MSBFIRST,  0 >> 8 );
             shiftOut(dataPin, clockPin, MSBFIRST, forDataArray[e]);
             digitalWrite(latchPin, HIGH);
             delay(5);
         }
     }
     delay(5000);
}

That should, if my thinking is correct, send to the registers something like the following. Where 1 is on and 0 is off.

00000000 10100000
00000000 01100000
00000000 01010000
00000000 10010000

And repeat that over and over. Right? Wrong?

Wrote it on a text editor on my phone. So, it may/may not compile.

Arduino shift out reference. If the upper sixteen bits are always zero I don't expect you'd have to shift them - zero shifted eight times or eight thousand times is still zero.

Speculation: The compiler may optimize away that construction anyway.

Thanks folks.

Not sure what I had jacked up in my original script. I started over and simplified other things somewhat.

Everything works as expected now.

Post the updated working code for the benefit of other beginners who might find this thread. We can also check it for you.

I will try to remember to do that when I make it home this weekend. I'm sure there are parts that could be coded better or by better means anyway.

I'll edit out code I have in there for other features I haven't received components for as yet. No sense in confusing folks for no reason. And those portions haven't been tested yet.

It sounds very much as if you need to put together a "travel kit". :roll_eyes:

Paul__B:
It sounds very much as if you need to put together a "travel kit". :roll_eyes:

I would. But I wouldn't want to do my job, if I did. LOL

I posted this a little while ago with a problem. I have since worked out what the issue was. Just me being dense and used the wrong numbers in my 3rd array.

Now it works as intended.

This uses two 74HC595 shift registers to run 3 stepper motor drivers (ULN2003). Could add a fourth if needed. This will later become part of a larger sketch to control an automatic fish feeder for my aquarium(s). For now, it just rotates each motor clockwise one full turn. And then counter-clockwise (anti-clockwise for some) one full turn.

const int latchPin = 3; //ST_CP of 74HC595 (12)
const int clockPin = 5; //SH_CP of 74HC595 (11)
const int dataPin = 4; //DS 0f 74HC595 (14)

unsigned long stepperSpeedFast = 5; //Lower is faster. 5 is probably too fast for my steppers
unsigned long stepperSpeedSlow = 15; //Higher is slower
unsigned long previousMillis = 0;

enum {clearRegister,
      runStepper1Clockwise,
      runStepper1CounterClockwise,
      runStepper2Clockwise,
      runStepper2CounterClockwise,
      runStepper3Clockwise,
      runStepper3CounterClockwise
     };

int currentStage;
int stepper1_Array[] = {B10100000, B01100000, B01010000, B10010000};
int stepper2_Array[] = {B00001010, B00000110, B00000101, B00001001};
int stepper3_Array[] = {B00001010, B00000110, B00000101, B00001001};

int useThisArray;
int stepPulse = 0;
int registerCleared = 0;

//used for testing at this time
const int stepsPerRevolution = 2048; 
int stepCount = 0;

void setup() {
  //Serial.begin(9600); //remove or comment out for final code
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  digitalWrite(latchPin, HIGH);
}//end setup

void loop() {
  //Serial.println(currentStage); //just to see where it's at during testing
  switch (currentStage) {
    case clearRegister:
      //in shiftRegister(0, 0, 0)
      //the first 0 denotes which stepper is being controlled
      //the second 0 is forward(1) or reverse(2)
      //the third is the speed of the stepper
      shiftRegister(0, 0, 0);
      break;

    case runStepper1Clockwise:
      shiftRegister(1, 1, stepperSpeedSlow);
      break;

    case runStepper1CounterClockwise:
      shiftRegister(1, 2, stepperSpeedFast);
      break;

    case runStepper2Clockwise:
      shiftRegister(2, 1, stepperSpeedSlow);
      break;

    case runStepper2CounterClockwise:
      shiftRegister(2, 2, stepperSpeedFast);
      break;

    case runStepper3Clockwise:
      shiftRegister(3, 1, stepperSpeedFast);
      break;

    case runStepper3CounterClockwise:
      shiftRegister(3, 2, stepperSpeedFast);
      break;
  }//end switch
  
  test();
  
}//end loop

void shiftRegister(int thisMotor, int thisDirection, unsigned long thisDelay) {
  if (thisMotor == 0 && registerCleared == 0) {
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0);
    shiftOut(dataPin, clockPin, MSBFIRST, 0);
    digitalWrite(latchPin, HIGH);
    registerCleared = 1;
  } else {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= thisDelay) {
      if (stepPulse > 3) {
        stepPulse = 0; //reset stepPulse
      }//end if stepPulse

      int thisIndex;

      if (thisDirection == 2) {
        thisIndex = 3 - stepPulse; //reverse the stepPulse
      } else {
        thisIndex = stepPulse;
      }//end if/else

      if (thisMotor == 1) {
        useThisArray = stepper1_Array[thisIndex];
      } else if (thisMotor == 2) {
        useThisArray = stepper2_Array[thisIndex];
      } else if (thisMotor == 3) {
        useThisArray = stepper3_Array[thisIndex];
      }//end if thisMotor

      previousMillis = currentMillis;
      digitalWrite(latchPin, LOW);
      if (thisMotor == 1 || thisMotor == 2) {
        shiftOut(dataPin, clockPin, MSBFIRST, 0);
        shiftOut(dataPin, clockPin, MSBFIRST, useThisArray);
      } else if (thisMotor == 3) {
        shiftOut(dataPin, clockPin, MSBFIRST, useThisArray);
        shiftOut(dataPin, clockPin, MSBFIRST,  0);
      }
      digitalWrite(latchPin, HIGH);
      stepPulse++;
      stepCount++;//for testing. Remove in final project
    }
  }
}

void test() { //
  if (currentStage == clearRegister) {
    delay(5000);
    stepCount = 0;
    currentStage = runStepper1Clockwise;
  } else if (stepCount == stepsPerRevolution) {
    if (currentStage == runStepper1Clockwise) {
      stepCount = 0;
      currentStage = runStepper1CounterClockwise;
    } else if (currentStage == runStepper1CounterClockwise) {
      stepCount = 0;
      currentStage = runStepper2Clockwise;
    } else if (currentStage == runStepper2Clockwise) {
      stepCount = 0;
      currentStage = runStepper2CounterClockwise;
    } else if (currentStage == runStepper2CounterClockwise) {
      stepCount = 0;
      currentStage = runStepper3Clockwise;
    } else if (currentStage == runStepper3Clockwise) {
      stepCount = 0;
      currentStage = runStepper3CounterClockwise;
    } else if (currentStage == runStepper3CounterClockwise) {
      stepCount = 0;
      registerCleared = 0;
      currentStage = clearRegister;
    }
  }
}

Could you not have used TPIC6B595s?

Paul__B:
Could you not have used TPIC6B595s?

Certainly could have. I just opted to use what I had on hand from a previous project or two that I managed to get working on breadboards. But never actually built.