Notifications
Clear all

controlling stepper motors with shift registers & Arduino

103 Posts
5 Users
20 Likes
12 K Views
Dryden
(@dryden)
Member
Joined: 3 years ago
Posts: 77
Topic starter  

@robotbuilder I got the one shift register working with 2 stepper motors, but started cooking dinner so I haven't tried the second shift register yet.

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@dryden

Hope I got this right ...

To enlarge image right mouse button select then open in another window

stepperController1

   
ReplyQuote
Dryden
(@dryden)
Member
Joined: 3 years ago
Posts: 77
Topic starter  

@robotbuilder

The way I understood it is, each pin has a value double that of the previous pin, and to get two pins to go high at the same time you add those two values together. So when I want pin 0 on sh.R #2 I would call a value of 256... Yes?/No?

sh.R #3 pin 7 ends up being a value of 8,388,608. 


   
ReplyQuote
Dryden
(@dryden)
Member
Joined: 3 years ago
Posts: 77
Topic starter  

@robotbuilder 

That example is how I understand it, I think.


   
ReplyQuote
Dryden
(@dryden)
Member
Joined: 3 years ago
Posts: 77
Topic starter  

@robotbuilder remember I have 6 steppers, so I have 3 shift registers for their pin outs thats 24 bits when they are wired in series. Pin Qh or 9 depending on how you are reading that diagram, goes out to the data pin for the next shift register and then you can send out 24 bits to control 24 pins. just wire the clock and latch pins in series so they all communicate at the same time.


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2527
 

@dryden 

When you move to shift register 2 (which, I think will control steppers 3 and 4), the bit settings will be the same as for 1 and 2.

You'll be sending the combined bit sets to shift register 2 as a single byte, just like you do to shift register 1, so it's still just the same 8 powers of 2 - 128,64,32,16,8,4,2,1.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Dryden
(@dryden)
Member
Joined: 3 years ago
Posts: 77
Topic starter  

@will 

If its in parallel I would understand that, but then you need 3 pins on the Arduino, for each shift register, If they are wired in series in the other examples I've seen you just add 8 bits for each shift register.  Is that not the same in this case with being wired in series?


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2527
 

@dryden 

As I understand it, whenever you push a byte into the input side of the register, it pushes its previous contents out the output side (and thus into the next register in the chain).

So, if you have the three shift registers chained together in series, then you'll need to push three bytes  into the chain to replace all of the bit sets for all 6 steppers.

But you're pushing a BYTE each time, and that byte represents the combined bit sets for two steppers as a pair {stepper1,stepper2}, {stepper3,stepper4}, {stepper5,stepper6}.

Each byte (representing a pair of stepper bit sets) is constructed from the two steppers in the same way that stepper1 and stepper 2 are.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@dryden

The shiftOut(dataPin, clockPin, MSBFIRST, value) function shifts out ONE BYTE which has been coded for two motors. You have to use shiftOut three times for six motors not one big 24 bit shift.
So we create a byte value for each of the three pairs of motors combined and send them out one byte at a time.

Example:
Desired (random) 4 bit values for each motor
motor( 0 ) = 1100
motor( 1 ) = 1110
motor( 2 ) = 0010
motor( 3 ) = 0111
motor( 4 ) = 1111
motor( 5 ) = 0100

Combine as 3 bytes to shift out into three shift registers.
BYTE1 1100 1110 byte for motor(0) and motor(1)
BYTE2 0010 0111 byte for motor(1) and motor(2)
BYTE3 1111 0100 byte for motor(3) and motor(4)

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

Just noticed a mistake.  By the way I have numbered the motor 0 to 5 but you could number them 1 to 6.

Combine as 3 bytes to shift out into three shift registers.
BYTE1 1100 1110 byte for motor(0) and motor(1)
BYTE2 0010 0111 byte for motor(2) and motor(3)
BYTE3 1111 0100 byte for motor(4) and motor(5)

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@dryden

With the OpenCV (from what I understand) what you do is put borders on each side of the frame of the video, then have your recognition output the location of the object that it recognizes, and if that object enters a border it can send a signal saying that the object entered that border, from there I want to take that output and call a command (top border = move up, bottom border = move down, left border = and so on) There is going to be more to it than that obviously, but that is how I understand it anyway.

My interest in machine vision was a long time ago before OpenCV when you had to write it all from the bottom up.

Maybe you are referring to the subject matter of this post by byron?
https://forum.dronebotworkshop.com/user-robot-projects/robot-navigation/paged/2/

There was a thread that had utube examples of a robot arm vision system.
https://forum.dronebotworkshop.com/user-robot-projects/help-with-the-choice-of-motor-type-for-a-5-6dof-robot-arm/#post-13836

 


   
ReplyQuote
Dryden
(@dryden)
Member
Joined: 3 years ago
Posts: 77
Topic starter  

@robotbuilder

Posted by: @robotbuilder

The shiftOut(dataPin, clockPin, MSBFIRST, value) function shifts out ONE BYTE which has been coded for two motors. You have to use shiftOut three times for six motors not one big 24 bit shift.
So we create a byte value for each of the three pairs of motors combined and send them out one byte at a time.

So if Im understanding this correctly the code should look something like this? 

stepper1val = 64, 0, 0;

digitalWrite(latchPin,LOW);

shiftOut(dataPin, clockPin, MSBFIRST, stepper1val + stepper2val); 

shiftOut(dataPin, clockPin, MSBFIRST, stepper3val + stepper4val);

shiftOut(dataPin, clockPin, MSBFIRST, stepper5val + stepper6val);

digitalWrite(latchPin,HIGH);

 

and the stepper value should be taking in 3 separate numbers now, instead of one?


   
ReplyQuote
Dryden
(@dryden)
Member
Joined: 3 years ago
Posts: 77
Topic starter  

@robotbuilder

Posted by: @robotbuilder

Maybe you are referring to the subject matter of this post by byron?
https://forum.dronebotworkshop.com/user-robot-projects/robot-navigation/paged/2/

Ill have to check both of those out, I haven't got to them yet, but here is an example of just a simple turret tracking system.

Here is a bunch of documentation on it from Open CV,

https://docs.opencv.org/master/dc/d6b/group__video__track.html

I can barely get a stepper to move with a shift register, but I am hoping to figure this out lol

The world has changed a lot even since I was young, I have no idea what is was like coding before, I just remember it feeling too difficult for me to even try. I do know that with the invention of the internet and the new technologies coming out, it is making things a lot easier for me to learn. I learnt how to operate machinery by just jumping in and figuring things out as I went, sometimes people come along and give you tips and tricks, sometimes people just watch as you drive off with your E-brake on. Just keep learning as you go though.


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@dryden
So if Im understanding this correctly the code should look something like this?

That would be part of the code to pulse (step) each stepper. It is how you would shift the six bytes into the three shift registers. This would be done six times, each time with only the four bits for the stepper being pulsed. Keep in mind I am figuring this out as I go and would need to test the code to see if it is doing what I think it should be doing. This will take time. To just give a coded solution without testing it would be pointless as it would be full of bugs and probably not work.

The code I gave only pulses stepper2 and the shift register only holds data to pulse that stepper. Each stepper would have its own direction and probably have its own speed (pulses per unit of time). So you would cycle through all the steppers and the stepper's data would be used to decide if to pulse the stepper at that point in time or not and in what direction.

Maybe something like this:

void moveSteppers(){
  currentMillis = micros();
  if (currentMillis - lastTime >=1000 then {
    for (int x = 0;x < 5; x++) {  // cycle through each stepper
        if (stepper[x].stepCount > 0) { // check if needs another pulse
            pulseStepper(x);
        end if
    }
    time = time + micros()-lastTime;
    lastTime = micros();
  }
}

 

The first video in this thread I posted, which controlled six stepper motors, shows you how complex it is even though that example didn't use shift registers which just adds to the complexity. At equal intervals of time you would cycle through each stepper motor's data and decide if to send it a pulse or not.

This is the data used in the six stepper motor tutorial.

 

struct stepperInfo {
  // externally defined parameters
  float acceleration;
  volatile unsigned int minStepInterval;
  void (*dirFunc)(int)
  void (*stepFunc)();

  // derived parameters
  unsigned int c0;
  long stepPosition;

  // per movement variables (only change once per movement)
  volatile int dir;   // direction of movement
  volatile unsigned int totalSteps;
  volatile bool movementDone = false;
  volatile unsigned int rampUpStepCount;

  // per iteration variables (potentially changed every interrupt)
  volatile unsigned int n;
  volatile float d;
  volatile unsigned long di;
  volatile unsigned int stepCount;
};

 

 


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2042
 

@dryden
here is an example of just a simple turret tracking system.

Interesting. I must see if I can duplicate it with my own code. The OpenCV is too complex for me to figure out. Essentially it takes the selected area of the image as a pattern. It can then continually search for that pattern in each video frame. Tracking simply involves using the position of the template image on the screen image to move the camera so as to center the template image.

 


   
ReplyQuote
Page 4 / 7