Modifying Motor Angle Control Example for 2 Motors

Hello!

I recently aquired a Bricktronics MegaShield and while I don’t know much about arduino programming, I’ve been trying to learn via the great examples you’ve shared! I want to control multiple motors by using the PID function and assiging angle positions but I’m not sure how to modify the code to add a second motor. I got the example working when I hooked up 1 motor just fine, making it go forward and then reverse. But I’d like the ability to control each wheel with its own motor for better turns. So here’s what I’ve done so far:

I added another motor in the include section, and added an m2 for the begin and the update functions.

Then, in my loop, I want m2 to go forward to the 30 degree angle and return back to the original position and then the other motor do the same motion. However, when I run the code, only m2 moves and nothing else happens. It’s as if it obeys the first line of the code and ignores the rest. What am I doing wrong/how can I fix this? Any help is appreciated! Below is my entire code for reference since I feel like I’m not explaining this well enough.

#include < Encoder.h>
#include < PID_v1.h>
#include < BricktronicsMotor.h>

#include < BricktronicsMegashield.h>
BricktronicsMotor m1(BricktronicsMegashield::MOTOR_1);
BricktronicsMotor m2(BricktronicsMegashield::MOTOR_2);

void setup()
{
Serial.begin(115200);

m1.begin();
m2.begin();
}

void updateMotors()
{

m1.update();
m2.update();

}

void loop()
{

m1.setAngleOutputMultiplier(1);
m2.setAngleOutputMultiplier(1);

// Reset the current position to “angle 0”
m1.setAngle(0);
m2.setAngle(0);

m2.goToAngleWaitForArrivalOrTimeout(30, 1000);
m2.delayUpdateMS(1000);
m2.goToAngleWaitForArrivalOrTimeout(0, 1000);
m2.delayUpdateMS(1000);

m1.goToAngleWaitForArrivalOrTimeout(30, 1000);
m1.delayUpdateMS(1000);
m1.goToAngleWaitForArrivalOrTimeout(0, 1000);
m1.delayUpdateMS(1000);

}

Hello, thanks for the post. Sorry that things aren’t working quite right, I’m sure we’ll be able to figure it out.

To be honest, everything looks great in your code! I can’t see anything obviously wrong, so I’m not sure why it’s not working correctly.

When did you download the BricktronicsMotor and BricktronicsMegashield libraries from github? If it was after October 13, 2016, then we make a slight change to the libraries to make it no-longer-necessary to include the Encoder.h and PID_v1.h files in your sketch code. One person reported a build error if you don’t remove them and are using the post-Oct 13 libraries.

I’d suggest removing the two #include lines for Encoder and PID_v1 and trying it again. If you downloaded the libraries before October 13 of last year, I’d suggest downloading the latest version from github to simplify things:
https://github.com/wayneandlayne/BricktronicsMotor/archive/master.zip
https://github.com/wayneandlayne/BricktronicsMegashield/archive/master.zip

If we can’t get it working here, I’ll have time this weekend to test this out on actual hardware.

Thanks!
-Matthew
Wayne and Layne

Hi! Thanks for your quick response and I’m sorry I took so long to respond, I didn’t realize anyone would response so quickly so left it for a few days. Anyways, thank you so much for your suggestion because that cleared the issue right up! After I deleted the #include lines, it worked like a charm :slight_smile:

I do have a follow up question though, I’ve been trying to do some reading about arduino coding and if I want to make the motors turn at the same time, I have to use an interrupt function, right? For instance, I now have it with the current code that one motor will move and then the other. Do you have any advice on how to get the commands to work at the same time?

Wow, what crazy timing, I was literally just scrounging up my LEGO motors to test this out since you hadn’t replied! Thanks for the reply, I’m glad it started working. One of my TODO list items for tomorrow is to make a blog post and tweet about how to update older sketches to remove the extra #include lines to work with the new libraries.

Yeah, if you want to work with multiple motors, or even just have the code do other things while the motors are running, you probably want to set up a periodic interrupt to call your motors’ update functions. We used to use a separate Timer library to set up a periodic interrupt to update the motors, but then we had an idea to piggy-back on the existing Arduino every-millisecond interrupt feature. Check out the code in the MotorPositionControlInterrupt sketches (Bricktronics Shield example) but here is the important code to add to your sketch:

#1. To the end of your setup() function, add:
// These two lines configure the Timer0 Overflow Interrupt.
OCR0A = 0x7F;
TIMSK0 |= _BV(OCIE0A);

#2. Add this entirely-new function between your setup and loop functions:
// This function will be called every millisecond.
// It just calls update() for each motor, every 50 ms.
ISR(TIMER0_COMPA_vect)
{
static unsigned char count_ms = 0;
if (++count_ms == 50)
{
m1.update();
m2.update();
// If you have other motors, be sure to call all their
// update functions here in the interrupt handler…
// m3.update();
// m4.update();
// …
count_ms = 0;
}
}

Now that we have set up the interrupt to call each motor’s update() function every 50 ms, you can change your main loop to just say m1.goToAngle(30); and the motor will automatically move to and stay at that angle until you use another goToAngle call.

This will only work for an Arduino Uno or Mega, so if you’re using a different board, let us know which board and we’ll figure out what changes are needed.

I hope that helps, let us know how it goes!

Hi!

Thanks so much for the tips, I had to wait to respond until I was able to find the time to work on this. I added the lines you mentioned and it seems to be working well! It’ll take some getting used to to have to call it to an angle and call it back, but they’re moving at the same time now and this’ll be great because now I can integrate other functions while it’s moving like you mentioned :slight_smile: Seriously couldn’t have done it without your help, so thanks again!