Go Down

Topic: How to access 2nd shift register (Read 670 times) previous topic - next topic

DangerToMyself

I get that
Code: [Select]
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?

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.

Code: [Select]

// 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:

Code: [Select]

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


DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

DangerToMyself

#2
Aug 26, 2019, 02:17 am Last Edit: Aug 26, 2019, 02:39 am by DangerToMyself
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.

Code: [Select]

// 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:

Code: [Select]

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.

DangerToMyself

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

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.

dougp

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.
Everything we call real is made of things that cannot be regarded as real.  If quantum mechanics hasn't profoundly shocked you, you haven't understood it yet. - Niels Bohr

No private consultations undertaken!

DangerToMyself

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.

PaulRB

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

DangerToMyself

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.

Paul__B

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

DangerToMyself

It sounds very much as if you need to put together a "travel kit".  :smiley-roll:
I would. But I wouldn't want to do my job, if I did. LOL

DangerToMyself

#10
Sep 14, 2019, 04:49 pm Last Edit: Sep 14, 2019, 07:30 pm by DangerToMyself
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.

Code: [Select]
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;
    }
  }
}


Paul__B

Could you not have used TPIC6B595s?

DangerToMyself

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.

Go Up