Dual MC33926 Motor Driver Carrier

The driver seems to switch modes randomly during operation. For example, sometimes a duty cycle command of 30% will result in a 30% output to the motors. But sometimes it outputs 70%. This switching of modes occurs very rapidly during operation. I’m using the following pin settings:

FORWARD MOTION:
IN1 = PWM from Arduino board
IN2 = GND

REVERSE MOTION:
IN1 = GND
IN2 = PWM from Arduino board

The other pins are set using Arduino digital output pins as follows:
D1 = LOW
D2 = HIGH
INV = LOW
EN = HIGH
SLEW = LOW

All of the jumper pins are OPEN
VDD is connected to the Arduino board +5v
GND is connected to the Arduino board GND
VIN (the small one) is OPEN
GND (for motor VIN) is connected to the Arduino board GND
VIN (for the motors) is connected to 6 AA (1.2 v nickel metal hy) batteries
The Arduino board uses these same batteries for its power.

I’m driving a HSIANG NENG (HN-35GMB-2513T®) 7.2 volt motor. I measured its stall current at 3.5 amps (which agrees with the manufacturer’s spec).

I’ve tried using an older Parallax USB scope for troubleshooting. But I’ve read on some of the forums that USB scopes may actually cause problems. So I disconitnued its use. Any assistance would be greatly appreciated. Thanks.

First of all, I suggest that you simplify your code as much as possible. Try writing a simple Arduino sketch that just tries to drive the motor forward at 70% and then doesn’t do anything else (your loop() function should be empty). If it still exhibits that strange behavior, then post the simple code here, and include a description of the pin assignments on the Arduino side so we can check your code.

You can also put an LED on your Arduino’s PWM output to see if the Arduino’s PWM output is doing the right thing.

–David Grayson

To check my wiring, I tried using the jumpers on the driver board to set the modes rather than Arduino pins. The same results were seen. Here is the new setup:

D1 = tied to LOW via jumper
D2 = tied to HIGH via jumper
INV = tied to arduino GND
EN = tied to arduino Vdd
SLEW = tied to arduino GND

FORWARD MOTION:
IN1 = PWM from pin 5 on the Arduino board
IN2 = LOW from pin 4 on the Arduino board

REVERSE MOTION:
IN1 = LOW from pin 5 on the Arduino board
IN2 = PWM from pin 4 on the Arduino board

I have enclosed a simple diagram of my circuit. It uses an Arduino Mega.

The code for 3 simple sketches is listed below:

“PWM_Single” is very simple and commands a 16% percent duty cycle. The “loop” section of the sketch is not used. The motor turns at 84%. An 84% duty cycle command results in a 16% duty cycle at the motors.

PWM_Single2" is the same as above, except I have moved the pwm commands to the “loop” section of the sketch. The results are the same… an 84% duty cycle results from a 16% command.

“PWM_Single3” commands forward at 16% for 1 second, then coast for a second, then reverse at 16% for a second, then coast for a second. In this case, after an initial fast rotation transient, the motors turned at the proper 16%!

The observed behavior is strange in that sometimes the proper commanded duty cycle is sent to the motors and other times, the opposite is sent.

CODE

PWM_single:

/* This sketch commands the motor to drive at a 16% duty cycle. 
Running this sketch resulted in the motor driving very fast.  
When I change the duty cycle command to 84%, the motor ran slow.
*/

int  M1D1  =  22;  
int  M1D2  =  24;  
int  EN    =  26;  
int  SLEW  =  27;
int  M1IN2  =  4;  // arduino digital pwm pin
int  M1IN1  =  5;  // arduino digital pwm pin
int  INV    =  6;

void
setup()
{
//  Serial.begin(9600);          //  setup serial

    pinMode(EN,OUTPUT);
    pinMode(M1D1,OUTPUT);
    pinMode(M1D2,OUTPUT);
    pinMode(SLEW,OUTPUT);
    pinMode(INV,OUTPUT);
    
    digitalWrite(M1D1,LOW);
    digitalWrite(M1D2,HIGH);
    digitalWrite(SLEW, LOW);
    digitalWrite(INV, LOW);
    digitalWrite(EN, HIGH);

    analogWrite(M1IN2,214);     // a 16% duty cycle command (40/255) results in fast rotation.
                                // when I changed the command to analogWrite(M1IN1, 214), the motors run slow. 

    digitalWrite(M1IN1, LOW);   // this side tied to gnd.
}

void loop()
{
}

PWM_Single2:

/* This sketch moved the pwm commands inside the loop of the sketch. 
The results were the same.
*/

int  M1D1  =  22;  
int  M1D2  =  24;  
int  EN    =  26;  
int  SLEW  =  27;
int  M1IN2  =  4;  // arduino digital pwm pin
int  M1IN1  =  5;  // arduino digital pwm pin
int  INV    =  6;

void
setup()
{
//  Serial.begin(9600);          //  setup serial

    pinMode(EN,OUTPUT);
    pinMode(M1D1,OUTPUT);
    pinMode(M1D2,OUTPUT);
    pinMode(SLEW,OUTPUT);
    pinMode(INV,OUTPUT);
    
    digitalWrite(M1D1,LOW);
    digitalWrite(M1D2,HIGH);
    digitalWrite(SLEW, LOW);
    digitalWrite(INV, LOW);
    digitalWrite(EN, HIGH);

   
}

void loop()
{
  
   analogWrite(M1IN2,214);     // a 16% duty cycle command (40/255) results in fast rotation.
                                // when I changed the command to analogWrite(M1IN1, 214), the motors run slow. 

    digitalWrite(M1IN1, LOW);   // this side tied to gnd.
  
}


PWM_single3:

/* This sketch commands forward 16% for 1 second, then coast 1 sec, then reverse 16%
for 1 second, then coast for 1 sec.  In this case, there is an initial fast rotation 
transient followed by proper operation... meaning that a 16% command of analogWrite(M1IN1, 40)
results in low speed rotation.
*/

int  M1D1  =  22;  
int  M1D2  =  24;  
int  EN    =  26;  
int  SLEW  =  27;
int  M1IN2  =  4;  // arduino digital pwm pin
int  M1IN1  =  5;  // arduino digital pwm pin
int  INV    =  6;

void
setup()
{
//  Serial.begin(9600);          //  setup serial

    pinMode(EN,OUTPUT);
    pinMode(M1D1,OUTPUT);
    pinMode(M1D2,OUTPUT);
    pinMode(SLEW,OUTPUT);
    pinMode(INV,OUTPUT);
    
    digitalWrite(M1D1,LOW);
    digitalWrite(M1D2,HIGH);
    digitalWrite(SLEW, LOW);
    digitalWrite(INV, LOW);
    digitalWrite(EN, HIGH);

   
}

void loop()
{
  
    analogWrite(M1IN1,40);     // forward 16%
    digitalWrite(M1IN2, LOW); 
    delay(1000);
    digitalWrite(M1IN1, LOW);  // coast
    delay(1000);
    analogWrite(M1IN2, 40);    // reverse 16%
    delay(1000);
    digitalWrite(M1IN2, LOW);  // coast
    delay(1000);
  
}

Freescale Pinouts.pdf (162 KB)

I’m not very familiar with Arduino code, but I noticed that in your first two sketches you wrote:

analogWrite(M1IN2,214); // a 16% duty cycle command (40/255) results in fast rotation.

It looks like the analogWrite function takes values from 0 (always off) to 255 (always on). So wouldn’t a value of 214 produce a duty cycle of 84%, not 16% as your comment seems to say?

Hello.

It’s hard to follow exactly what you’ve done when you post 3 different pieces of code and within the code comments you talk about alternatives you tried. Can you please post the simplest thing that does not behave the way you expect, and please use the [code][/code] blocks so that your code is formatted nicely.

- Ryan

rudinrt, in the first two sketches you posted, you left pin M1IN1 floating (you forgot pinMode). If you are lucky, then it floats low and you get the duty cycle you expect. If you are unlucky, then it floats high and the motor reverses its direction and goes at the wrong duty cycle.

I think that if you had simplified your code further (removing the ten lines of code controlling wires that were no longer connected) you might have been able to find this problem yourself. But also this is an example of one way in which the Orangutan Digital I/O library is better than the Arduino’s digital I/O library. If you were using an Orangutan board instead of an Arduino then the single command “setDigitalOutput(M1IN1, LOW);” would enable the pin as an output and drive it low, so you wouldn’t have the problem of forgetting to set the pin mode.

–David

Thanks for everyone’s help. It was a stupid error on my part not declaring IN1 and IN2 as output pins on the Arduino. It now seems to be working great, even with gyro feedback. I am working with some folks in India who have the exact same circuitry. My vote was to use the Orangtan. But they wanted to go Arduino and add the motor drivers. It saved them a little money, but has cost us a lot of time. I do have a 1284 Orangtan board and want to migrate to it when I can find a little time. We are building balancing robots together. I truly appreciate the timely feedback and suggestions. Russ

Hello.

I’m glad to hear that things are working for you now. Please let us know how your balancing robot turns out. We’d love to see a video if you get it working!

- Ben