PWM Problem with H-bridge

Hi Guys,

I am new to Arduino and I’m having a problem with my current project. What I’m trying to do is send RF signals to the remote receiver on Arduino and control a DC motor through a H-bridge circuit. Now my problem is when I press the forward button on the remote motor starts spinning in one direction and when I press the backward button motor stops. I am bit confused. please help


#include <HT12E.h>
#undef int
#undef abs
#undef double
#undef float
#undef round

int RxInputPin = 7;

HT12E remote(RxInputPin, B01111111); // pin 7,  0111 1111b

int Motor1FwPin = 6;
int Motor1RwPin = 5;
int Motor1EnPin = 4;

int Motor2FwPin = 11;
int Motor2RwPin = 10;
int Motor2EnPin = 12;


void setup()
{
  Serial.begin(9600);
  
  // Setup Motor 1  
  pinMode(Motor1FwPin,OUTPUT);
  analogWrite(Motor1FwPin, 0);
  
  pinMode(Motor1RwPin,OUTPUT);
  analogWrite(Motor1RwPin, 0);
  
  pinMode(Motor1EnPin,OUTPUT);
  digitalWrite(Motor1EnPin, LOW);
  // End Sttup Motor 1
  
  // Setup Motor 2  
  pinMode(Motor2FwPin,OUTPUT);
  analogWrite(Motor1FwPin, 0);
  
  pinMode(Motor2RwPin,OUTPUT);
  analogWrite(Motor1RwPin, 0);
  
  pinMode(Motor2EnPin,OUTPUT);
  digitalWrite(Motor1EnPin, LOW);
  // End Sttup Motor 1
}

void loop()
{
  unsigned int valor;
  valor = remote.read();
  if(valor > 0xFFF0) Serial.println(valor, HEX);
  else
  {
    if (valor == 0x80E)
    {
      analogWrite(Motor1FwPin,20);
      analogWrite(Motor1RwPin,0);
      digitalWrite(Motor1EnPin,LOW);
      
      Serial.print("DATA ");
      Serial.println(valor, BIN);
      
    }  
  
    if (valor == 0x80D)
    {
      analogWrite(Motor1FwPin,0);
      analogWrite(Motor1RwPin,20);
      digitalWrite(Motor1EnPin,LOW);
      
      Serial.print("DATA ");
      Serial.println(valor, BIN);
      
    }      
  }
  
}

DarrenUD:       Serial.print("DATA ");       Serial.println(valor, BIN);

Do the expected things get printed by these debugging outputs? Is the problem with what the remote is sending or the commands the Arduino is receiving?

The circuit diagram shows indicator LEDs on it -- do those LEDs exist? What do they tell you about what the H-bridge is being commanded to do?

      analogWrite(Motor1FwPin,20);     // presumably forward/reverse phase A
      analogWrite(Motor1RwPin,0);      // presumably forward/reverse phase B
      digitalWrite(Motor1EnPin,LOW);   // presumably "enable" line

This strikes me as a bit wonky. Normally one would use digital outputs to control the forward/reverse phases and use PWM on the "enable" line to control the current. Your H-bridge may be designed to work this way, but it would be shame to waste of PWM lines.

Hi Gardner'

Thank you for your reply. Yes I do not have a problem reading debug outputs. everything is OK. except when I try to put the motor in to reverse direction it stops. Sorry, they are not LED's they are Optocouplers. Can I use digitalWirte command for PWM pins. it looks like to me when and try to spin the motor on forward direction that pin state kind of stuck to what I have set itself to initial value. Because, if forward and backward = high then motor breaks. By the way, I am a Mechanical Engineer, so I am still learning about electronics.

Just taking a quick look it seems as if what you do is have the forward or reverse be just high or low, and then use PWM on the output enable. Because forward and reverse are mutually exclusive, you can control the speed of both directions with a single PWM pin to the enable. And yes you can use the digitalWrite function with PWM pins, its the same as doing analogWrite((pin#),255) actually.

I haven’t really looked very much but one thing that jumps out is - you’re going from forward to reverse immediately. Try inserting a stop command and a small delay before changing direction.

Hi,

You problem is likely to be that you are driving the pins incorrectly or that you have a wiring fault. You haven't said how the Arduino is wired to the motor driver. If I have interpreted your diagram correctly, and if I label the 3 inputs 1,2,3 from top to bottom, you need to drive the signals as follows:

Forward: 1 high (optionally with PWM), 2 and 3 low. Reverse: 2 high (optionally with PWM), 1 and 3 low.

I can see a few possible problems with the circuit:

  1. Are you certain that the opto isolators are capable of providing sufficient drive to the power transistors? You haven't provided a part number, so I can't check. As the circuit stands they need to sink around 70mA for 20mA drive

  2. Using the 150 ohm series resistors in your circuit, an Arduino output pin should be able to provide 20mA to one opto isolator. However, your configuration requires that a single pin drives two opto isolators. This operates the Arduino above its recommended current (20mA per pin), so you may be getting insufficient drive.

  3. You should include flyback diodes across all the power transistors.

I suggest the following:

  • Increase the 150 ohm resistors to 330 ohm so that you can better drive 2 opto isolators from one Arduino pin.
  • Unless the opto isolators have a current gain of 10 or more, replace the power transistors with darlington pairs, e.g. TIP102 (npn) and TIP107 (pnp). Then increase the 180 ohm resistors to e.g. 3k3, depending on the gain of the darlington pairs and the maximum motor current. You no longer need the 10k resistors because they are built-in.
  • Check that with 10mA drive the opto isolators saturate, i.e. close to zero volts between collector and emiiter when driven.

Also, as daveg360 says, a short stop interval when switching direction would be kinder to the motor and the transistors.

Thanks for all your replies, now I am really frustrated. The Optoisolators I’m using is 4n35 photo transistor type. I did not know that I can drive the motor using PWM on enable pin. I thought I have to use PWM on Forward and backward pins and just digital Hi and Low on the enable pin. Well, It looks like to me it’s too much trouble. How about using a single chip like l298n from ST wouldn’t it be easier. All I want is a high current motor driver. Any suggestions.

The 4n35 has a minimum current transfer ratio of 100% at 25degC, i.e. a current gain of 1. But you haven't said what the maximum motor current is, so I can't say for sure whether you would need to change the transistors for darlington pairs in order to drive it.

If the maximum motor current is not more than 1A then you could use a low-cost motor driver IC such as the SN754410.

I wanna design it to handle at least 3A. the Transistors I'm using are darlington pairs. Any suggestions.

I've looked up the BDX53/54 data sheet and I see they are indeed darlingtons, with built-in reverse diodes. So your design will probably work as-is, if you apply the PWM as I suggested in my earlier post. However, I suggest the following changes:

  • Increase the 150 ohm resistors to 330 ohm to keep the load on the Arduino output pins below 40mA per pin (330 ohm gives approx. 10 to 15mA drive per opto isolator)
  • Increase the 180 ohm resistors to 820 ohm to limit the power dissipation of the opto isolators. This gives you about 12mA drive to the darlingtons, which is the figure used to specify Vce(sat) at 3A collector current in the datasheet.
  • The 10K resistors are not needed, the BDX53/54 has these built-in.