Monster Moto Shield Example Code For stepper motor

Hello Everyone.
Quick question does anyone have example code for using the Monster Moto Motor Shield with Arduino to drive a stepper motor (not DC) There is an old thread that says it is possible but without any final code. My students bought basically the wrong thing and I'm hoping the community can help them out. Any code to make a stepper move with this shield is fine. They can work on fine tuning the result.

Thank you in advance
JK

Perhaps you could post a link to the board in question.

You can use all the Arduino Stepper examples with the Monster Moto Shield by adding the below code to the setup() function.

Stepper myStepper(stepsPerRevolution, 7, 8, 4, 9);
pinMode(5, OUTPUT);
analogWrite(5, 1023);
pinMode(6, OUTPUT);
analogWrite(6, 1023);

If PWM Pins on the Monster Moto Shield are not turned on, the low side MosFETs in the H-Bridges will not be turned on.

I also attached an updated Sparkfun Monster Moto Shield updated program that can run a bipolar stepper motor.
Stepper functions:
Function 1: Momentary button for Forward and Reverse (uses interrupt routine)
Function 2: Potentiometer for PWM
Function 3: Potentiometer for speed control

stepper_motor2.ino (6.64 KB)

Hi All,

Here is some code I wrote for controlling a stepper motor using the Sparkfun Monster Moto shield.

Some notes before the code:

1 Although the default Arduino PWM frequency (980Hz) on pins 5 and 6 that control the PWM inputs to the shield will work, the operational envelop is limited and will likely disappoint. I found the noise nauseating!

2 If you have an old style "D" USB input (as for old USB printers) on your Arduino (UNO) board then take care, the "D" USB input could short out the motor outputs.

3 If your using a cheap (Chinese?) power plug it will likely trip out at less than half of the rated capacity (go figure?).

4 A really good idea to read the various datasheets as you could do some damage with the current levels you may be playing with (assuming the power supply is up to it).

5 Play safe, use a low duty factor (say 10%) on for the PWM to begin and use an amp meter (i.e. multi-meter) on the power supply.

Okay, something about the code:
1 It uses Timer2 (as it seems to be the least used timer and unlikely to upset anything except the tone library).
2 It generates a 20kHz (refer to the table 9 of the chip datasheet) PWM in 1% duty steps.
3 The minimum duty is set at 8% as this is the minimum practical pulse width (refer to the table 9 of the chip datasheet).
4 The maximum duty is 92% (why not, I like symmetry and it avoids ISR conflicts).
5 It uses 2 ISR to redirect the normal Timer2 output pins to pins 5 and 6.

Okay here it is:

// The Sparkfun Monster Moto Sheild PWM inputs are rated at 20kHz and the minimum practical pulse inout is about 4 us.
// sheild pin assignments
#define PinInA1 7
#define PinInA2 4
#define PinInB1 8
#define PinInB2 9
#define PinPWM1 5
#define PinPWM2 6
#define PinCS1 A2
#define PinCS2 A3
#define PinEN1 A0
#define PinEN2 A1
#define LED    13

// Timer2 compare A interrupt service routine
ISR(TIMER2_COMPA_vect)
{
 // Turn on PWM pins 5 and 6
 //      76543210 Arduino digital pin number
 PORTD|=B01100000;
}

ISR(TIMER2_COMPB_vect)      // Timer2 compare B interrupt service routine
{
 // Turn off PWN pins 5 and 6
 //      76543210 Arduino digital pin number
 PORTD&=B10011111;
}

void setPWMDuty(int duty)
// PWM duty percent 8% to 92%
{
duty=duty-1;          // 0 to 99 equals 100
if (duty<7) duty=7;   // Minimum pulse width is 4us (see VNH2SP30-E datasheet Table 9)
if (duty>91) duty=91; // Minimum pulse width is 4us (see VNH2SP30-E datasheet Table 9)
OCR2B=duty;
}

void setup()
{
 // Initialise H-Bridge (Monster Moto)
 pinMode(PinInA1,OUTPUT);
 pinMode(PinInA2,OUTPUT);
 pinMode(PinInB1,OUTPUT);
 pinMode(PinInB2,OUTPUT);
 pinMode(PinPWM1,OUTPUT);
 pinMode(PinPWM2,OUTPUT);
 pinMode(PinCS1,INPUT);
 pinMode(PinCS2,INPUT);
 pinMode(PinEN1,OUTPUT);
 pinMode(PinEN2,OUTPUT);
 digitalWrite(PinEN1,HIGH);
 digitalWrite(PinEN2,HIGH);
 digitalWrite(PinInA1,LOW);
 digitalWrite(PinInA2,LOW);
 digitalWrite(PinInB1,LOW);
 digitalWrite(PinInB2,LOW);
 digitalWrite(PinPWM1,25);
 digitalWrite(PinPWM2,25);  
 
 // Initialize timer1 
 noInterrupts();           // Disable all interrupts
 TCCR2A = B00000010;       // Disconnect Arduino D3 and D11 pins and set CTC mode (see AVR datasheet S11.11.1)
 TCCR2B = B00000010;       // Set clock prescaler to 8, now clock is 2MHz (see AVR datasheet S11.11.2)
 TCNT2  = B00000000;       // Reset timer (why not?) (see AVR datasheet S18.11.3)
 OCR2A  = 99;              // Set compare match register A for 20kHz PWM frequency (see AVR datasheet S18.11.4)
 OCR2B  = 7;               // OCR2B (see AVR datasheet S18.11.5) to duty, 1% per step, minimum pulse width is 4 us.
 TIMSK2 = B00000110;       // Enable timer compare interrupt on OCR2A ans 0CR2B (see AVR datasheet S18.11.6)
 interrupts();             // Enable all interrupts

 // PWM duty percent, valid values are between 8% to 92% (limits are imposed)
 setPWMDuty(20);          // 2% is a good alround value for most motors
}

#define CW 1
#define CCW -1
#define Stopped 0
int motorState=0;                   
int motorDirection=Stopped; // Stopped
int motorDelay=5;           // 60 RPM 

void loop()
{
 // Set the stepper parameters
 motorState=0;
 motorDirection=CW;
 motorDelay=5;      // 60 RPM for a 200 steps motora
 setPWMDuty(20);
 while (true) {
   // Full step
   if (motorState==0) {
     digitalWrite(PinInA1,HIGH);digitalWrite(PinInB1,LOW);
     digitalWrite(PinInA2,LOW);digitalWrite(PinInB2,HIGH);
     motorState+=motorDirection;
   } else if (motorState==1) {
     digitalWrite(PinInA1,LOW);digitalWrite(PinInB1,HIGH);
     digitalWrite(PinInA2,LOW);digitalWrite(PinInB2,HIGH);
     motorState+=motorDirection;
   } else if (motorState==2) {
     digitalWrite(PinInA1,LOW);digitalWrite(PinInB1,HIGH);
     digitalWrite(PinInA2,HIGH);digitalWrite(PinInB2,LOW);
     motorState+=motorDirection;
   } else {
     digitalWrite(PinInA1,HIGH);digitalWrite(PinInB1,LOW);
     digitalWrite(PinInA2,HIGH);digitalWrite(PinInB2,LOW);
     motorState+=motorDirection;
   }
   motorState=(motorState+4)%4;    
   delay(motorDelay);
 }
}

Enjoy Alan0

i am mechlogy i can help you

 pinMode(PinInA1,OUTPUT);
 pinMode(PinInA2,OUTPUT);
 pinMode(PinInB1,OUTPUT);
 pinMode(PinInB2,OUTPUT);

It makes no sense to use In in the name of an OUTPUT pin!

Hi PaulS,

Yeah, okay it could have been "OutputToInA1".
I was programming from the MonsterMoto shield point of view rather than the Arduino point of view.
There are other typos so "-1" for proof reading! Joke okay!

Really, was the code useful or not?

Regards Alan

i also try to start using the monster moto. i have no idea what the code does so i have no idea how to change it for my purpuse. could you please explain what the code does Alan0?

Hi aldij,

Not sure how to help?
If you don't know basic concepts behind the code (timers/interrupt service routines etc.) this is not the best place to learn. There are a number of timer and/or interrupt service routine tutorials around (i.e. google arduino and timer and tutorial).

Really this code is useful in two ways:

  1. you have the MonsterMoto Shield and want to run a (high powered) stepper with it, then just copy the code and rewite the main loop function as required.
  2. you are writing your own code and want a worked example as a base for modification.

How to use it?
Solder a 12 v power supply and stepper leads to the MonsterMoto Shield and plug it into an UNO.
Load the code and the motor will run. Make some changes to the code (in the main loop function) and see what happens.
Add a multimeter to the power supply and check the current versus PWM duty and motor speed.

How does it work?
The motor shield turns on motor phases (full step) based on the code in the main loop.
Speed is controlled by a delay variable.
Direction by a direction variable.
Current is controlled by the PWM duty function.
There are good tutorial on google how steppers work.

Why is it important?
The without PWM the MotorShield and Stepper motor will overheat (draw too much current).
Using the analog out does not work because the PWM frequency is to low (980Hz) to be practical.
This code generates a 20kHz PWM frequency that is ideal for this application.
In order to generate a 20kHz PWM frequency I used timer2 and an ISR to redirect the output to pins 5 and 6 that match the shield.
Its a pretty generic approach that may have other applications.

My advice is to plug it in shield, attach a motor and power supply and have a play.

Regards Alan0

Hi AlanO

I wonder why this code of Yours is not compiling for a Leonardo board ? could You help me ?
I am a newbie with Arduino and coding - but glancing trough the datasheet of the atmega 32U4 it seems there is no OCR2A and no OCR2B nor is there any TCCR2A or TCCR2B on this chip.
Is it possible to modify Your code to run on my Leonardo-clone ?
Thanks in advance.

I am a Danish guy - My English writing is not error-free. But I'll understand everything You write back.

Thanks AlanO

I am having a different problem with this motor shield. Perhaps you can help. I have high torque stepper motors that I need to run using a Mega 2650. I fed your sketch through and looked at the output on my o-scope. The problem is that the wave form does not drop off fast enough and does not allow for operation of the motor above about 80 Rpm . It also causes vibrations when operation due to the fact that one coil of the stepper is still engaged when the next coil is fed the next sequence for the step. If you have any insight I would appreciate it.

hi,

i am trying to use the Monster Motor Shield from Sparkfun to drive 4 DC motors and control it using an RC Receiver ( FrSky V8FR-II )

i have 2 questions.

  1. Can i use it directly from an APM 2.6 board?

  2. How can i program an Arduino UNO to control the motors through the motor shield.

thanking you in advance for your help.

hmm.. so now i have the Monster motor shield connected to UNO and loaded with the code given by AlanO as it is.

but... there is no output. the motors don't seem to do anything.

btw.. i found a link on Github ( Arduino-Robot/libraries/Vnh2sp30 at master · OliviliK/Arduino-Robot · GitHub ) and this code just worked out of the box... but alas it is a customized code using its own CPP And Header file hence i don't know how to control it with an RC Servo input.

could someone from the community please chk it.

Hi,
Have you looked at the sparkfun site and selected the Exam Code?

ttps://www.sparkfun.com/products/10182

Tom... :slight_smile: