Problem with driving 2 motors with the Sparkfun TB6612FNG

Hello,

I’ve got a circuit on a breadboard trying to drive 2 motors (independently of each other) with my Arduino and Sparkfun TB6612FNG motor driver.

Here’s the circuit:

(Don’t know if it matters but I’m not actually using an Arduino Uno…I’m using an Arduino Duemilanove)

Up until now, I’ve been just having 1 motor, and it’s been working great. You’ll see in the code that I have a ‘timer’ and what happens when it’s triggered is fairly simple:

Beep the piezo speaker a few times
Turn LED ‘A’ on
Spin motor A for several seconds, then turn it off
Turn LED ‘A’ off

Again, it’s worked great for 1 motor, but now that I’ve hooked up a second motor, and try to run it after the 1st motor (Motor A) runs, this is where I’m having the problem. What’s happening is that the first motor never turns off it seems…it keeps going while the 2nd motor runs for it’s few seconds…then they both turn off at the same time.

You’ll see it in my Arduino file, but the updated ‘pseudo’ code would be this:

Beep the piezo speaker a few times
Turn LED ‘A’ on
Spin motor A for several seconds, then turn it off
Turn LED ‘A’ off
Turn LED ‘B’ on
Spin motor B for several seconds, then turn it off
Turn LED ‘B’ off

I keep looking at my code and don’t see anything wrong, but I’ve obviously done something wrong.

I’m hoping someone will see something dumb in my code that I did wrong and point it out to me.

Here’s a video of it in action:

It’s kind of hard to see, but the 2nd motor does start up (you can hear it) just fine, but you’ll also notice that the motor on the right (Motor A) never seems to stop (until the the 2nd motor stops anyway).

(I was going to post my code ‘inline’ with this post, but the forum said that I exceeded the maximum ‘9000’ characters, so I had to attach the code instead)

Cat_Feeder_Cleaned_For_Forum_Post.pde (12.3 KB)

pinMode(BUTTONA, INPUT); // and BUTTONA is an input
digitalWrite(BUTTONA, HIGH); // (Not sure what this is for, but was done in the One_Button_3_Functions sketch)

This is done to turn on the internal pullup. Since about 3 years ago, the preferred method of doing this is:pinMode(BUTTONA, INPUT_PULLUP);
It's not worth changing, but now you know why, you can remove the comment.

I'm glad I had your description. I missed the alarm-setting function the first time through. (None of the other code seems to use button B or motor B so it took me a while to find where motor B was started.

OK, first problem: you are using "A" and "B" to refer to the motors in your comments but then it's 1 and 0 in the actual code. #define a constant to do this translation, so you always refer to it as A and B everywhere. Or change the whole program and call it motor 1 and motor 0 everywhere. (This may also reduce mixups with the buttons labelled A and B.)

While you're running the motor for 5 seconds, do you expect any other alarms to arrive during that time and require some action BEFORE 5 seconds has expired? If there is an alarm, does it know if the motor is running and should it be switched off? Just use the regular Arduino delay() function instead of Alarm.delay(). Then let the alarms be answered after the critical motor-operating delay.

Now I think I might ave found the real reason. After starting one motor or the other, how does it stop? You call stopMotor() but that takes no parameters - it doesn't know which one to stop. That's OK, maybe it's meant to stop both. But it only writes LOW to one output pin. OK, maybe that's the standby pin for both outputs of the TB6612 chip but there's nowhere that gets set high anywhere other than the setup() function.

Wow, thank you for all of the info Morgan5! :slight_smile: Thanks to you, it's working properly now - I'll get to that in a second...

Regarding what the line 'digitalWrite(BUTTONA, HIGH);' is for, I'm still a little confused. So if I were to change it how you showed me, it will look like this?

pinMode(BUTTONA, INPUT_PULLUP);  // and BUTTONA is an input
digitalWrite(BUTTONA, HIGH); // (Not sure what this is for...)

The only thing is I think this won't work with the current version of Arduino I'm working with, Alpha 0021. I remember coming across the whole INPUT_PULLUP thing before and I had to use a newer version (I also have 1.6.3)

I know, the whole A and B thing is a little confusing when there is motor 0, and motor 1. I think the reason this happened is because I'm not writing all this code myself - I'm taking large chunks from other people's code and kind of mashing them all together. I do want to 'clean' it up a bit - I like your idea of using constants in place of 0 and 1. I'll do that before I declare this project all finished. :wink:

Ok, so the alarm thing. While the motor is running, I do not expect any other alarms, or any other user input to happen before that 5 seconds expire. Now, when you say use the regular Arduino delay() in place of the alarm.delay(), is that only if I was expecting an alarm to happen before the 5 seconds is up? Where would I use that? The reason I'm using alarm.delay() all over the place is that the creator of the Time/Alarm library explicitly says to use alarm.delay() function instead of the regular Arduino delay(), otherwise your alarms/timers may not fire. Check out the 2nd to last paragraph in his first post.
Anyway, so say I did need to handle code/alarms/do something before the 5 seconds are up, how the heck would I code that? Isn't doing the alarm.delay() preventing anything else from running on the Arduino? (Again, I don't need to, but I am curious...but if it's too complicated, then no need to try to explain it to me...I don't want to take up more of your time)

You did find the real reason! Remember how I said that I mostly have taken other people's code and mashed them together? Well I got most of the motor-driving code from:

It seemed like they were stopping the motor with their 'stop()' function (which it was when there was only 1 motor involved). Between you bringing up the whole question about STBY not specifying a motor, and only writing LOW to one pin, I remembered that they said that you have to turn both pins LOW or HIGH to turn the motor off. So as a quick test, I inserted:

  digitalWrite(AIN1, LOW);
  digitalWrite(AIN2, LOW);

like so:

 playBreakfastDinnerTones();
  digitalWrite(LEDA, HIGH);  // turn status LEDA on
  moveMotorHighLevel(secondsToTurnMotorA, 1); // Run motor A
  digitalWrite(LEDA, LOW); // turn status LEDA off
  
  digitalWrite(AIN1, LOW);
  digitalWrite(AIN2, LOW);
  
   digitalWrite(LEDB, HIGH);  // turn status LEDB on
   moveMotorHighLevel(secondsToTurnMotorB, 0); // Run motor B
   digitalWrite(LEDB, LOW); // turn status LEDB off

and that properly turned off the first motor before starting the 2nd one!!

Thanks so much again Morgan5, you are awesome!