Go Down

Topic: TIP-120 bi-direction motor control (Read 6424 times) previous topic - next topic

EnigmaCypher7

So I know to drive a TIP120 transistor you just drive a pin either High or Low for it to turn the switch on or off.

I want to use a pair of these to drive a motor.

Transistor A - Drive the motor in a forward direction.
Transistor B - Drive the motor in a reverse direction.

(Transistors in turn are controlling a heavy relay)

My question is, if you are driving the motor with transistor A and you want to switch the motors direction
by running transistor B, what constraints can you put in place with the code so that it stops the signal to
transistor A BEFORE it runs transistor B? I would really like to not have to worry about both of the transistors
becoming active at the same time and cause a short.

I am using an Arduino UNO.

Thank you for your time.
-Ec7
He who dares, Wins.

WizenedEE

digitalWrite A before you digitalWrite B or use direct port access (that would make it happen at exactly the same time)

wildbill

Write yourself a few functions: MotorForward, MotorReverse and presumably MotorStop. Make sure that the code in them turns one transistor off before it turns the other on. Then, don't directly touch the transistor pins anywhere else in your code.

EnigmaCypher7

Yeah, I am not sure how to write functions. I am guessing these would be similar to the libraries .ccp files? (New to programming, but know electronics pretty well)

---

Quote
digitalWrite A before you digitalWrite B


something like;

Code: [Select]
digitalWrite(2, HIGH);
      break;
case 'b':   
      digitalWrite(2, LOW);
      break;


but put something between the string for HIGH and LOW?

Thanks.
He who dares, Wins.

Grumpy_Mike

Quote
I am not sure how to write functions.

You write them all the time, setup() and loop() are functions.

Quote
I want to use a pair of these to drive a motor.

How are you going to wire it up? I am not sure you can do it with only two transistors.

jwatte

He's using relays for the real power. If he uses two-pole relays, he'll be OK. Wire the motor forward through the 2 poles of relay A, and wire the motor backward through the 2 poles of relay B.

Assuming you use pin 1 for forward and pin 2 for backward, then the functions you need to write are:

Code: [Select]

void motorForward() {
  digitalWrite(2, LOW);
  delay(10);
  digitalWrite(1, HIGH);
}

void motorBackward() {
  digitalWrite(1, LOW);
  delay(10);
  digitalWrite(2, HIGH);
}

void motorStop() {
  digitalWrite(1, LOW);
  digitalWrite(2, LOW);
}


Note that the "delay" in there is to compensate for relay release time -- I'm assuming the relay will release within 10 milliseconds of letting up the driver. You should adjust those based on the "must release" time in your relay data sheet.

Grumpy_Mike

Quote
He's using relays for the real power.

If he is then there is no need at all to worry about the order the relays are energised as taking a motor to the same potential will only help stop the motor before reversing the rotation. In fact it is probable a good idea to have a brief time in this state to prevent damage to the motor. 

EnigmaCypher7

Code: [Select]
void motorForward() {
  digitalWrite(2, LOW);
  delay(10);
  digitalWrite(1, HIGH);
}

void motorBackward() {
  digitalWrite(1, LOW);
  delay(10);
  digitalWrite(2, HIGH);
}

void motorStop() {
  digitalWrite(1, LOW);
  digitalWrite(2, LOW);
}


Kind of makes sense, but I still need to be able to start the motor with a button press from a keyboard
example: a- forward and b-reverse. Haven't really given it any thought, but it would still be feasible
for the motor to run as long as long as the button was being held and stop when it was released.
Actually is there a way to do this? (Would be really great to know)
But it would still be great for both relays not to be powered at the same time.

Quote
If he is then there is no need at all to worry about the order the relays are energised as taking a motor to the same potential will only help stop the
motor before reversing the rotation. In fact it is probable a good idea to have a brief time in this state to prevent damage to the motor.


This is not really important in this project as the motor will never be free spinning and is driving a system that is more of less a wormgear system. Power stops, motor stops.

Thanks.
He who dares, Wins.

Grumpy_Mike

Quote
as the motor will never be free spinning

Doesn't matter, forward, stop, reverse is always going to put less strain on a motor than forward, reverse.

Quote
but it would still be feasible
for the motor to run as long as long as the button was being held and stop when it was released.

Yes nothing simpler, just test the button and call forward if pressed and stop if not.

EnigmaCypher7

Quote
Doesn't matter, forward, stop, reverse is always going to put less strain on a motor than forward, reverse.

Yes agreed and it really should be done this way.

Can this be written into the Arduino's code or does it need to be written into a library somewhere?
I know the motor shield does this automatically. (different project) but its included in the AFmotor.cpp

Quote
Yes nothing simpler, just test the button and call forward if pressed and stop if not.
Quote

Awesome, just not sure how to write this. Absolutely not a programmer but trying to learn.




He who dares, Wins.

Grumpy_Mike

Quote
I know the motor shield does this automatically.

Does it?

Quote
does it need to be written into a library somewhere?

No. It is a simple thing to do and there is no need for a library. In my view libraries are a mixed blessing, anything you can do in a library you can do in normal code. 

EnigmaCypher7

I know the motor shield does this automatically.
Quote
Does it?


Code: [Select]
  switch (inByte) {
    case 'w':   
      motor1.setSpeed(225);
      motor1.run(FORWARD);     // Motor Runs Forward
      break;

    case 'k':   
      motor1.run(RELEASE);     // Motor Stops
      break;

    case 's':   
      motor1.setSpeed(225);
      motor1.run(BACKWARD);    // Motor Runs Backwards
      break;


I wrote this for another project that uses a motor shield. Even though there is a release for the motor to stop in this code,
if you press "w" and then immediately press "s" it will reverse the direction of the motor without needing to press the "k"
for the motor to stop. I would like to do something like this with relays. The motorshield system works perfectly, but
too low power for this project. Also I think the letter being pressed as would a temporary switch is a great idea too, if I
can figure it out.

So since I am not telling the motors in the code to stop before it reverses, I am assuming that it is in the library or somehow
else implemented.

Thanks.
He who dares, Wins.

Grumpy_Mike

Quote
So since I am not telling the motors in the code to stop before it reverses, I am assuming that it is in the library or somehow
else implemented.

Only if the library is written like that, there are a lot of poor libraries around.

Quote
Also I think the letter being pressed as would a temporary switch is a great idea too, if I can figure it out.

In place of the switch statement just use compound ifs
Code: [Select]
if(letter == 'F' || pushButton == true) { // do your stuff

zoomkat

Instead of pushing buttons and such, you might just get a switch like below.

http://www.radioshack.com/product/index.jsp?productId=2062530
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

EnigmaCypher7

A toggle switch won't be much help. For this project I need to be able to control a motor from a remote location, to do this I am simply going to use a keyboard button press through RDP as my trigger. I know with RDP there will be some latency but this really isn't going to be a problem, but also with this latency I think a "momentary button" feel from a keyboard key press would be a much better idea.

I like the idea of
Quote
if(letter == 'F' || pushButton == true) { // do your stuff

although I am sure the coding of this is not quits as simple. It would be nice to know the
Syntax.

Something in the neighborhood of:
Code: [Select]


switch (inByte) {
\\Controls motor polarity (+) (Transistor 1)
case 'a':   
      digitalWrite(2, HIGH); \\Motor start forward
      break;
case 'b':   
      digitalWrite(2, LOW); \\Motor stop forward
      break;
\\Controls motor polarity (-) (Transistor 2)
case 'c':   
      digitalWrite(3, HIGH); \\Motor start reverse
      break;
case 'd':   
      digitalWrite(3, LOW); \\Motor stop reverse
      break;


(sorry for all of the above comments, my code doesn't include them, but thought it would make the idea easier to follow)

But where to insert the IF statement?

Also still need to make sure that these 2 transistors are not going to both be powered trying
to turn the motor in opposite directions of each other and causing a short or other problems.

Quote
Doesn't matter, forward, stop, reverse is always going to put less strain on a motor than forward, reverse.

Still like this idea but don't know where to implement it in the above code either.

Thanks.
He who dares, Wins.

Go Up