TIP-120 bi-direction motor control

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

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

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.

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)


digitalWrite A before you digitalWrite B

something like;

 digitalWrite(2, HIGH);
      break;
	case 'b':    
      digitalWrite(2, LOW);
      break;

but put something between the string for HIGH and LOW?

Thanks.

I am not sure how to write functions.

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

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.

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:

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.

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.

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.

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.

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.

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.

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

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

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

I know the motor shield does this automatically.

Does it?

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.

I know the motor shield does this automatically.

Does it?

  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.

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.

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

if(letter == 'F' || pushButton == true) { // do your stuff

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

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

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:

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.

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.

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.

You haven't posted your schematics and I don't know how you can wire two relays in such a way that the motor could be trying to be driven in two directions at once. It sounds like a poor circuit if this is the case. Using two relays you implement a reversal of the motor as shown in this page:-
http://www.thebox.myzen.co.uk/Workshop/Motors_1.html
There is no way that can be commanded to go wrong.

But where to insert the IF statement?

Don't tempt me!
Read what I said:-
In place of the switch statement just use compound ifs.
So you replace the switch statement with a string of compound ifs

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.

Yes it is that is the syntax where letter is the variable with the command letter in and pushButton is the Boolean variable with the state of the button in.

Read what I said:-
In place of the switch statement just use compound ifs.
So you replace the switch statement with a string of compound ifs

I read what you said, what I am wondering is how will the device know what the different parts are;

if(letter == 'F' || pushButton == true) { // do your stuff

I got the "letter == 'F'" as in You press "F", but how does it know what "letter" is or "pushButton == true" how does it
know what these things refer to? Where is that written?

This is why I was asking for an example and showed my example over again.

The relays I am working with are already built into the motor, I have never actually tried turning them both on at the same time.
Maybe I will disassemble one and see how they are actually wired. I was working on the side of caution as to not wanting both
of them enabled at the same time. It am still testing here and seeing what is available out there. We will call this - still gathering ideas =)

I got the "letter == 'F'" as in You press "F", but how does it know what "letter" is or "pushButton == true" how does it
know what these things refer to? Where is that written?

Well in your code how does it know what inByte is?

Come on put in a bit of effort.

Hint:-

  1. in my code letter is the same as inByte in your code.
  2. how do you think you will get the state of a push button's state into a variable? Could it be something to do with reading the digital pin it is attached to?

inByte is defined in" int inByte = Serial.read(); " so that it is listening for the ASCII value of the keyboards characters.

Could you define anything you wanted to be in the place of the inByte?

Could call it " letter " letter = Serial.read() ?

void loop() {
  int digitalValue = digitalRead(digitalPin);

  if (digitalValue = HIGH) {
    pushbutton = true;
  }

Wow, I am really bad at this.
The reason it take a bit to reply is I am looking at code and trying to figure out different ways to put it
together and syntax.

I bet you would laugh your head off at all of the code I have put together on here then erased before I sent this one.
I promise, I am trying.

Could call it " letter " letter = Serial.read() ?

Yes you can have any variable (of the right type) on the left sign of an equals sign.

if (digitalValue = HIGH)

no it should be:-

if (digitalValue == HIGH)

anyway it is even simpler than this:-

boolean pushbutton = digitalRead(digitalPin);

will do it.