Motor Driver Circuit Advice

I don't know much when it comes to... well anything really so can I have some feed back on this circuit please. Will it work, are the components compatible?

Mosfets FQP27P06 at the top. Datasheet here

Mosfet FQP30N06L at the bottom. Datasheet here

24v 8amp motor

10k resistors from the gates to ground

150ohm resistors from PWM pins 5 and 6 to gates

My hope is to drive the motor using PWM. The switch at the bottom will be used to change the direction of rotation. The POT will be used to control the speed.

My current sketch was used in conjunction with a pololu high power driver, which sadly, is no longer with us, may it rest in peace. If I can get this driver working then I have to re-write it.

//Pololu high power motor driver 24v13amp. A potentiometer (variable resistor)
//controls motor speed using pulse width modulation (PWM).
//The forward/revers switch controls the motor direction

const int switchPin = 4;   //Forward/Revers Switch
const int pwm = 5;  //pulse width modulation  
const int dir = 6;  //direction
const int slp = 7;  //sleep mode to dissable motor driver
const int pot = A1; //Potentiometer
int       val = 0;  // variable to store the value coming from the Pot
bool switchState; 


void setup() 
{ 
    Serial.begin(9600);
    pinMode(dir, OUTPUT);
    pinMode(slp, OUTPUT); 
    pinMode(pot, INPUT);
    pinMode(switchPin, INPUT);
  
}
void loop() 
{      
     val = analogRead(pot);           // Read value from potentiometer
     val = map(val, 1023, 0, 0, 255); // and convert it to a value between 0-255

   if(val < 5)     // direction can only be changed when val is less than 5.
   {
     switchState = digitalRead(switchPin); 
     digitalWrite(slp,LOW);      // Disable pololu motor driver
   }
   else
   {
     analogWrite(pwm, val);  // Set PWM to val and send pulses
     digitalWrite(slp,HIGH);     // Enable pololu motor driver
     digitalWrite(dir, switchState); // Turn the motor in the direction selected (when val was less than 5).
   }

 /*    Serial.print(" switchState = ");
     Serial.print(switchState);
     Serial.print(" val = ");
     Serial.println(val);
   */  
}

That circuit won't work at all, for several reasons. This is clearly not the project for you.

Pololu has a great selection of tried and true designs; best to replace the one you had.

jremington: That circuit won't work at all, for several reasons.

Could you explain why so that I can learn?

Found a great post on this forum that explained (in my level of understanding) how a mosfet works.

I update the circuit.

The reason I've chosen to use those particular mosfets is because I have them on hand. This circuit will cost me nothing if I can get it to work. A Pololu driver will set me back $60 + shipping. I'm not even sure why the last one stopped working so I'm a tad cautious to buy another one just to have the same thing happen and waist another $60

I just tweeked it a bit.

The low side MOSFETs are upside-down. Major problem.

10V does not switch off the high MOSFET.

No measures against shoot-through. This will happen the moment you switch on the low MOSFET as you can’t close the high one (always at least -14V at the gate).

Can the high side MOSFETs even withstand -24V Vgs? Many are limited to -20V.

No way to keep either the high or the low pair of MOSFETs enabled - that’s to prevent voltage spikes when switching.

Let’s start with those issues. Plus the part where you haven’t moved on to proper circuit drawing software, such as EagleCAD or KiCAD.

Hi,

Instead of trying to use 2 control wires to control a H-Bridge, use 4 and you will find a lot of your problems will disappear.

Tom.... :)

The gates of MOSFETs have a small capacitor. For most purposes it is insignificant. But as soon as you try to drive them with PWM then it does become significant.

To switch the MOSFETs on and off at the speed required for PWM, you need to charge and discharge those capacitors with several AMPS. Like between 1 and 10A. A 150 Ohm pullup is not going to do it.

The same as you need a motor driver to drive your motor, you need a MOSFET driver to drive your big MOSFETs.

Then you have to consider that it is easier to turn a MOSFET on than it is to turn it off. It starts conducting at the threshold voltage which is usually very low, like 2V. It does not take much charge to go from 0V to 2V. It takes a lot of coulombs to discharge from the max voltage (24V?) to get back under 2V and turn it off. So both top and bottom MOSFETs are switched on for a short period. This is called "shoot through" and the main power just flows through both MOSFETs and not through the motor.

The better MOSFET drivers discharge at a different rate than charging. So you need 4 drivers instead of 2.

Tom's suggestion is also good. Some Arduinos have options in their PWM hardware to switch with a controlled "dead time" to avoid shoot through. I don't know of any libraries which use this feature because most Arduino people like me choose to use pre-built drivers which do this already.

Look at chips like the VNH2SP30 and its replacement VNH5019. They are almost indestructible.

I just looked up some key characteristics of your n-mosfet.

Gate threshold 1-2.5V. Gate capacitance about 1 nF.

To go from 10V to 1V in 1 us a resistor of less than 430Ω will do, and the peak current can be as low as 23 mA. That should be fast enough for 480 or 960 Hz PWM (the Arduino defaults).

Nonetheless it’s better to have it driven rather than pulled, for that you’d need at least two driver transistors per MOSFET (and no, you can’t connect the bases of two BJT transistors as they’ll switch each other on).

Maximum Vgss is 20V so you can’t pull it up to 24V, while the gate of the high side must be pulled up to 24V to switch it off.

It’s an interesting exercise to try and design an H-bridge. And when done, just go and buy one off the shelf. Or better, do that now. Then you can continue to learn about how they work (and how remarkably hard it is to design a good one) while your H-bridge ships to you.

wvmarle: To go from 10V to 1V in 1 us a resistor of less than 430Ω will do,

Nice calculator. But the pullup is charging 2 gates, not 1. Putting in 2nF, I get 270Ω so the 150Ω does not look too bad for the 1us assumption.

The circuit still has major issues, like the 10V pullups won't turn the high side FETs off.

A Pololu driver will set me back $60 + shipping.

That is because the problem of making a usable H-bridge is not NEARLY as simple as you think it is.

The above posts point out some, but not all of the problems with your design. They are fatal problems for motors that draw a significant amount of current.

The Pololu drivers work as advertised. They, like all motor drivers can be destroyed, though, by mishandling. One common mistake is to change the wiring while the circuit is powered.

Thank you all for the great info/teachings. It does sound like this is truly well over my level. I have taken your advice and bought a new driver. I did some research as to the reasons why mine died in the first place and it's looking like when I powered up the arduino before the driver, this may have tried to power the driver using the logic pins on the arduino and done damage that way.

It is hard to know what happened because it worked on the small test motor at about 16v and then did nothing on the big motor at 24v. Then did nothing on the test motor after that. No smoke. There was/is sparks when connecting the driver to the 24v battery. Not sure if it should do that or not. Not sure if it's because the damage was already done?

Drivers typically have a motor power supply, and separately a logic power supply. Make sure you connect the logic level supply to the Arduino's 5V supply, then there should be no problem there as you power up the control logic the moment you switch on the Arduino.

There was/is sparks when connecting the driver to the 24v battery.

Making changes to the wiring while the circuit is powered is one of the very fastest ways to destroy a motor driver.

Here is the circuit with the Pololu driver. I'm using a 5v regulator to power the arduino's 5v pin and a master switch between the batteries to cut power to the entire system. The driver is not the A4988 and D5 is connected to the PWM pin on the G2 24v13 driver.

I can't see anything wrong with the circuit but if anyone can please say so.

I've just got the code sorted so pretty keen try it out.

Here is the sketch. It all checks out in theory and in the serial monitor.

const int pwm = 5;  //pulse width modulation  
const int dir = 6;  //direction
const int slp = 7;  //sleep mode to dissable motor driver
const int joystick = A1; //Potentiometer
int       val = 0;  // variable to store the value coming from the Pot
int       spd = 0;  // variable to store the speed value 
bool forwardSpd;
bool reverseSpd;
const int accel = 10;  // Adjust this value to change speed of acceleration
const int decel = 6;    // Adjust this value to change speed of deceleration
unsigned long lastAccelTime = 0;
unsigned long lastDecelTime = 0;

const int numReadings = 10;
int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int Average = 0;
unsigned long currentTime;                
unsigned long prevdelayMillis;
const int delayInterval = 10;

void setup() 
{
    //    Serial.begin(9600);
    pinMode(dir, OUTPUT);
    pinMode(slp, OUTPUT); 
    pinMode(joystick, INPUT);

    for (int thisReading = 0; thisReading < numReadings; thisReading++)  //Initialize Smoothing values
    readings[thisReading] = 0;

    delay(1000);  //
}

void loop() 
{
    currentTime = millis();     // Take time stamp
    val=analogRead(joystick);   // Read joystick and set the value to val
    smooth();                   //Smooths out joystick values
    
   if(val > 524 && reverseSpd == false)    // Check joystick val and reverseSpd bool and drive motor forward
   {
      val = map(val, 517, 1020, 0, 255);  // Takes values from between 517 and 1023 and converts them to values between 0 and 255
      digitalWrite(slp,HIGH);     // Enable pololu motor driver]
      digitalWrite(dir, HIGH);    //Change to LOW if the cart goes the wrong way
      accelAndDecel();            // Run void accelAndDecel()
      forwardSpd = true;          // Set forwardSpd = true to make sure it can't go into reverse while moving forwards
    //  Serial.print(" Forwards  ");
   }

   else if(val < 510 && forwardSpd == false)// Check forwardSpd bool and drive motor backward.
   {
      val = map(val, 517, 0, 0, 255);
      digitalWrite(slp,HIGH);     // Enable pololu motor driver]
      digitalWrite(dir, LOW);     //Change to HIGH if the cart goes the wrong way
      accelAndDecel();
      reverseSpd = true;
 //     Serial.print(" Reverse  ");
   }
   else
   {
    val = 0;
    accelAndDecel();  // Set val to 0 and finish deleceration
   }
   if(spd == 0)
      {
      digitalWrite(slp,LOW);  // Disable motor driver (set slp pin to LOW)
      forwardSpd = false;    // Bools to make sure spd is at 0 before changing direction
      reverseSpd = false;
      }
   
/*   Serial.print("  Joy Val = ");
   Serial.print(val);
   Serial.print("   Speed = ");
   Serial.println(spd);    */
}

void accelAndDecel()
{
           // ****Acceleration**** 
   if (currentTime - lastAccelTime > accel)
   {
      lastAccelTime = currentTime;
      if (spd < val) 
      {
          spd++;
          spd=constrain(spd,0,255);  // Constrain spd within motor tolerance.    
          analogWrite(pwm, spd);     // 
      }
   }
          // ****Deceleration**** 
   if (currentTime - lastDecelTime > decel)
   {
      lastDecelTime = currentTime;
      if (spd > val) 
      {
          spd = spd / 1.01;
          spd=constrain(spd,0,255);  // Constrain spd within motor tolerance.
          analogWrite(pwm, spd);
      }
   }
}

void smooth()
{
                                                 //if delay interval has past...
  if(currentTime - prevdelayMillis >= delayInterval)
  {   
      total= total - readings[readIndex];       // subtract the last reading:      
      readings[readIndex] = analogRead(joystick);    // read from the joystick:
      total= total + readings[readIndex];          // add the reading to the total:     
      readIndex = readIndex + 1;           // advance to the next position in the array:            

          if (readIndex >= numReadings)         // if we're at the end of the array...          
              readIndex = 0;                    // ...wrap around to the beginning:                           
              Average = total / numReadings; 
              val = Average;                    // Sets the value of val to the average from the last 10 readings
            
              prevdelayMillis = currentTime;
   } 
}

Hi,
What are you trying to do here?
Motor Driverccc.jpg
The gnd of the 4988 and the gnd of the Nano have to be connected together.

Tom… :slight_smile:

Hi
This is better and safer.
Motor Driveredit.jpg

Tom… :slight_smile:

Hi,
You need to read the spec on the regulator, needs caps
reg1.jpg
Tom… :slight_smile:

Thanks Tom for your feed back.

I have a double pole switch that I can use, I'll replace the the single pole that's on there. My intent with that switch was simplicity. One switch to turn off all power is better than 2. It's all for my kids go-cart, so the less they can do wrong the better. I didn't think of using a double pole switch.

The 5v regulator is one from Pololu as well found here. It was one I had lying around. I don't think I would need the 5amps supply to run the arduino but it is what it is. Do you think it would be worth putting a resistor between the regulator and arduino?

And yes I have the grounds of the 5v reg, the driver and arduino all connected. Sorry I missed that in the circuit drawing.

On the Pololu driver I've installed a 35v 2200uf cap. Once again, it was something I had lying around.