Method for stacking two Motor Shields to control 4 steppers

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
siliconfish
 
Posts: 2
Joined: Fri Nov 19, 2010 8:01 am

Method for stacking two Motor Shields to control 4 steppers

Post by siliconfish »

I'm sharing a successful method for controlling 4 steppers from Arduino using two Motor Shields from Adafruit
This is so I can control the X Y and Z axis stepper motors of a CNC from one single arduino and can avoid a synchronized communication network and multiple Arduinos. The fourth motor control will be reserved for tool adjustments if needed, it is extra for now.

I needed to be able to allow all the motors to hold while others were running. This hack succeeded in getting me 4 motors with full control. I'm not attempting to microstep, I'm just using this for single stepping, I think maybe the way the library deals with microstepping it may not work because the PWM leads are shared.

We are going to stack two motor shields on top of the Arduino. Using stacking headers on the first instead of the headers that come with it. Got the headers from Adafruit too. http://www.adafruit.com/index.php?main_ ... ucts_id=85 . I used two sets of stacking headers because in order to drive my steppers I stacked another set of H bridge drivers on top and used a small 16pin dip heat sink from digikey.

So here comes the very subtle and elegant hack!
On top motor shield, cut pin 12 out of the header pins so it doesn't connect to the top board. Short pin 12 and 13 on the top motor shield, because pin 13 is the new motor latch for the top shield, and needs to connect to the shield where 12 used to. A nip and a solder blob and Bob's your uncle.

With the stack, one board will use the latch on pin 12, and the other on pin 13.
All the commands/pins are sent to both boards, one board ignores (never latches) the commands for the other. Picked pin 13 for the new latch because it is in the same register as 12 and will be clocked the same way by the port writes. I don't think this technique is extensible to more boards, because there are no more pins. pin3 and the analog pins are in different ports and wouldn't be synchronous.

You need separate function versions that use the different latch pins. So you need to make a copy of the library and make some simple changes to the function names.
Coding wise this may not be the most efficient method because of the redundant libaries, but it made the hack very easy to do w/o risk of messing up the code.

Copy the AFMotor directory in the arduino/libraries directory to AFMotorA. In the copy, change the names of AFMotor.h and AFMotor.cpp to AFMotorA.h and AFMotorA.cpp. Note that you will have to restart the Arduino software to see the new library.

Wish I could post the whole modified library, it is on my blog
http://blog.workingsi.com/2011/03/metho ... -from.html

Now find the line in the AFcontrol.h file in the libraries directory
#define MOTOR_LATCH 12
and change it to

#define MOTOR_LATCHA 13

We need to change the function names to differentiate which board they apply to.
In AFMotorA.h globally replace the text "AFMotor" with "AFMotorA" everywhere it appears.

In AFMotorA.cpp, also globally replace the text "AFMotor" with "AFMotorA" everywhere it appears.
Also replace MOTOR_LATCH with MOTOR_LATCHA everywhere it appears.

Now you have two libraries, which address different boards. So here is a stepper test program that demos the four motors working:
Example Sketch

#include <AFMotor.h>
#include <AFMotorA.h>

AF_Stepper motorX(48, 1);
AF_Stepper motorY(48, 2);
AF_StepperA motorZ(48, 1);
AF_StepperA motorA(48, 2);

void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Stepper test!");

motorX.setSpeed(60); // 60 rpm
motorY.setSpeed(60); // 60 rpm
motorZ.setSpeed(60); // 60 rpm
motorA.setSpeed(60); // 60 rpm

delay(5000); // wait for the supply to come up

//step motors one step and back to power the coils
motorX.step(1, FORWARD, SINGLE);
motorY.step(1, FORWARD, SINGLE);
motorZ.step(1, FORWARD, SINGLE);
motorA.step(1, FORWARD, SINGLE);
motorX.step(1, BACKWARD, SINGLE);
motorY.step(1, BACKWARD, SINGLE);
motorZ.step(1, BACKWARD, SINGLE);
motorA.step(1, BACKWARD, SINGLE);
}

void loop() {
Serial.println("Single coil steps");
motorX.step(480, FORWARD, SINGLE);
delay(1000);
motorY.step(480, FORWARD, SINGLE);
delay(1000);
motorZ.step(480, FORWARD, SINGLE);
delay(1000);
motorA.step(480, FORWARD, SINGLE);
delay(1000);
motorX.step(480, BACKWARD, SINGLE);
delay(1000);
motorY.step(480, BACKWARD, SINGLE);
delay(1000);
motorZ.step(480, BACKWARD, SINGLE);
delay(1000);
motorA.step(480, BACKWARD, SINGLE);
delay(1000);
// Now all runing at once! Bravo!
int i;
for (i=0; i<480; i++) {
motorX.step(2, FORWARD, SINGLE);
motorY.step(1, FORWARD, SINGLE);
motorZ.step(2, FORWARD, SINGLE);
motorA.step(1, FORWARD, SINGLE);
}

}

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Re: Method for stacking two Motor Shields to control 4 steppers

Post by adafruit »

intense! :)

User avatar
pogcarrOld
 
Posts: 19
Joined: Tue Jan 25, 2011 10:21 pm

Re: Method for stacking two Motor Shields to control 4 steppers

Post by pogcarrOld »

Brilliant! I had to try this! Needless to say it works great.
I did have to hunt down a few more little differences in the .cpp and .h files to get everything working right, but if you go check out the code he posted on his website I think that will work fine.

This is really nice and greatly simplifies a design where you have four stepper motors to drive!

User avatar
kabelton
 
Posts: 11
Joined: Tue Jul 12, 2011 6:05 pm

Re: Method for stacking two Motor Shields to control 4 steppers

Post by kabelton »

Hi,

So is it possible to control 8 dc motors (motofader) with two stacked shields?

Thanks a lot!

siliconfish
 
Posts: 2
Joined: Fri Nov 19, 2010 8:01 am

Re: Method for stacking two Motor Shields to control 4 steppers

Post by siliconfish »

Yes you can control 8 DC motors, i tried that too.

A limitation is that you can't easily run all 8 simultaneously at different speeds since the PWM outputs are shared between the shields. Theoretically you could run all 8, but stacked motors would have to share the same speed if you ran them at the same time, or you would have to write your code to alternate moving one then the other in a loop.

User avatar
kabelton
 
Posts: 11
Joined: Tue Jul 12, 2011 6:05 pm

Re: Method for stacking two Motor Shields to control 4 steppers

Post by kabelton »

hi siliconfish,

thank u very much for your answer!!

i want to control 8 motorfader controlled via max/msp (max4live), so each fader should be controlled with an lfo with different speed, but i think not all at the same time, perhaps 4 stand still, 4 are moving...

is this possible?

thanks for sharing your experiences!

gerald

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Method for stacking two Motor Shields to control 4 steppers

Post by adafruit_support_bill »

The limitation will be that you can't run 2 'stacked' motors at the same time at different speeds. For example, M1 on shield 1 and M1 on shield 2 share the same PWM signal, so they would have to be run at the same speed if they are run at the same time.

User avatar
kabelton
 
Posts: 11
Joined: Tue Jul 12, 2011 6:05 pm

Re: Method for stacking two Motor Shields to control 4 steppers

Post by kabelton »

thanks adafruit, but can i run 4 motors with different speed on shield 1 and 4 with same speed on shield 2?

sorry for asking dumb questions...

User avatar
adafruit_support_bill
 
Posts: 88136
Joined: Sat Feb 07, 2009 10:11 am

Re: Method for stacking two Motor Shields to control 4 steppers

Post by adafruit_support_bill »

There are 4 PWM signals to control the motors. Each shield has 4 channels - M1, M2, M3 and M4. Both M1's will run at the same speed. Both M2's will run at the same speed, same for M3's and M4's.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”